Whamcloud - gitweb
LU-9121 lnet: User Defined Selection Policy (UDSP)
[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 -ge 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 test_27p() {
1912         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1914         remote_mds_nodsh && skip "remote MDS with nodsh"
1915         remote_ost_nodsh && skip "remote OST with nodsh"
1916
1917         reset_enospc
1918         rm -f $DIR/$tdir/$tfile
1919         test_mkdir $DIR/$tdir
1920
1921         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1922         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1923         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1924
1925         exhaust_precreations 0 0x80000215
1926         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1927         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1928         $LFS getstripe $DIR/$tdir/$tfile
1929
1930         reset_enospc
1931 }
1932 run_test 27p "append to a truncated file with some full OSTs"
1933
1934 test_27q() {
1935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1937         remote_mds_nodsh && skip "remote MDS with nodsh"
1938         remote_ost_nodsh && skip "remote OST with nodsh"
1939
1940         reset_enospc
1941         rm -f $DIR/$tdir/$tfile
1942
1943         test_mkdir $DIR/$tdir
1944         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1945         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1946                 error "truncate $DIR/$tdir/$tfile failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_all_precreations 0x215
1950
1951         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1952         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1953
1954         reset_enospc
1955 }
1956 run_test 27q "append to truncated file with all OSTs full (should error)"
1957
1958 test_27r() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966         exhaust_precreations 0 0x80000215
1967
1968         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1969
1970         reset_enospc
1971 }
1972 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1973
1974 test_27s() { # bug 10725
1975         test_mkdir $DIR/$tdir
1976         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1977         local stripe_count=0
1978         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1979         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1980                 error "stripe width >= 2^32 succeeded" || true
1981
1982 }
1983 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1984
1985 test_27t() { # bug 10864
1986         WDIR=$(pwd)
1987         WLFS=$(which lfs)
1988         cd $DIR
1989         touch $tfile
1990         $WLFS getstripe $tfile
1991         cd $WDIR
1992 }
1993 run_test 27t "check that utils parse path correctly"
1994
1995 test_27u() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998
1999         local index
2000         local list=$(comma_list $(mdts_nodes))
2001
2002 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2003         do_nodes $list $LCTL set_param fail_loc=0x139
2004         test_mkdir -p $DIR/$tdir
2005         trap simple_cleanup_common EXIT
2006         createmany -o $DIR/$tdir/t- 1000
2007         do_nodes $list $LCTL set_param fail_loc=0
2008
2009         TLOG=$TMP/$tfile.getstripe
2010         $LFS getstripe $DIR/$tdir > $TLOG
2011         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2012         unlinkmany $DIR/$tdir/t- 1000
2013         trap 0
2014         [[ $OBJS -gt 0 ]] &&
2015                 error "$OBJS objects created on OST-0. See $TLOG" ||
2016                 rm -f $TLOG
2017 }
2018 run_test 27u "skip object creation on OSC w/o objects"
2019
2020 test_27v() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2023         remote_mds_nodsh && skip "remote MDS with nodsh"
2024         remote_ost_nodsh && skip "remote OST with nodsh"
2025
2026         exhaust_all_precreations 0x215
2027         reset_enospc
2028
2029         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2030
2031         touch $DIR/$tdir/$tfile
2032         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2033         # all except ost1
2034         for (( i=1; i < OSTCOUNT; i++ )); do
2035                 do_facet ost$i lctl set_param fail_loc=0x705
2036         done
2037         local START=`date +%s`
2038         createmany -o $DIR/$tdir/$tfile 32
2039
2040         local FINISH=`date +%s`
2041         local TIMEOUT=`lctl get_param -n timeout`
2042         local PROCESS=$((FINISH - START))
2043         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2044                error "$FINISH - $START >= $TIMEOUT / 2"
2045         sleep $((TIMEOUT / 2 - PROCESS))
2046         reset_enospc
2047 }
2048 run_test 27v "skip object creation on slow OST"
2049
2050 test_27w() { # bug 10997
2051         test_mkdir $DIR/$tdir
2052         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2053         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2054                 error "stripe size $size != 65536" || true
2055         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2056                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2057 }
2058 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2059
2060 test_27wa() {
2061         [[ $OSTCOUNT -lt 2 ]] &&
2062                 skip_env "skipping multiple stripe count/offset test"
2063
2064         test_mkdir $DIR/$tdir
2065         for i in $(seq 1 $OSTCOUNT); do
2066                 offset=$((i - 1))
2067                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2068                         error "setstripe -c $i -i $offset failed"
2069                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2070                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2071                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2072                 [ $index -ne $offset ] &&
2073                         error "stripe offset $index != $offset" || true
2074         done
2075 }
2076 run_test 27wa "check $LFS setstripe -c -i options"
2077
2078 test_27x() {
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082
2083         OFFSET=$(($OSTCOUNT - 1))
2084         OSTIDX=0
2085         local OST=$(ostname_from_index $OSTIDX)
2086
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2089         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2090         sleep_maxage
2091         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2092         for i in $(seq 0 $OFFSET); do
2093                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2094                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2095                 error "OST0 was degraded but new created file still use it"
2096         done
2097         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2098 }
2099 run_test 27x "create files while OST0 is degraded"
2100
2101 test_27y() {
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         remote_mds_nodsh && skip "remote MDS with nodsh"
2104         remote_ost_nodsh && skip "remote OST with nodsh"
2105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2106
2107         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2108         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2109                 osp.$mdtosc.prealloc_last_id)
2110         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2111                 osp.$mdtosc.prealloc_next_id)
2112         local fcount=$((last_id - next_id))
2113         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2114         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2115
2116         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2117                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2118         local OST_DEACTIVE_IDX=-1
2119         local OSC
2120         local OSTIDX
2121         local OST
2122
2123         for OSC in $MDS_OSCS; do
2124                 OST=$(osc_to_ost $OSC)
2125                 OSTIDX=$(index_from_ostuuid $OST)
2126                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2127                         OST_DEACTIVE_IDX=$OSTIDX
2128                 fi
2129                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2130                         echo $OSC "is Deactivated:"
2131                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2132                 fi
2133         done
2134
2135         OSTIDX=$(index_from_ostuuid $OST)
2136         test_mkdir $DIR/$tdir
2137         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2138
2139         for OSC in $MDS_OSCS; do
2140                 OST=$(osc_to_ost $OSC)
2141                 OSTIDX=$(index_from_ostuuid $OST)
2142                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2143                         echo $OST "is degraded:"
2144                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2145                                                 obdfilter.$OST.degraded=1
2146                 fi
2147         done
2148
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $fcount
2151
2152         for OSC in $MDS_OSCS; do
2153                 OST=$(osc_to_ost $OSC)
2154                 OSTIDX=$(index_from_ostuuid $OST)
2155                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2156                         echo $OST "is recovered from degraded:"
2157                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2158                                                 obdfilter.$OST.degraded=0
2159                 else
2160                         do_facet $SINGLEMDS lctl --device %$OSC activate
2161                 fi
2162         done
2163
2164         # all osp devices get activated, hence -1 stripe count restored
2165         local stripe_count=0
2166
2167         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2168         # devices get activated.
2169         sleep_maxage
2170         $LFS setstripe -c -1 $DIR/$tfile
2171         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2172         rm -f $DIR/$tfile
2173         [ $stripe_count -ne $OSTCOUNT ] &&
2174                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2175         return 0
2176 }
2177 run_test 27y "create files while OST0 is degraded and the rest inactive"
2178
2179 check_seq_oid()
2180 {
2181         log "check file $1"
2182
2183         lmm_count=$($LFS getstripe -c $1)
2184         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2185         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2186
2187         local old_ifs="$IFS"
2188         IFS=$'[:]'
2189         fid=($($LFS path2fid $1))
2190         IFS="$old_ifs"
2191
2192         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2193         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2194
2195         # compare lmm_seq and lu_fid->f_seq
2196         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2197         # compare lmm_object_id and lu_fid->oid
2198         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2199
2200         # check the trusted.fid attribute of the OST objects of the file
2201         local have_obdidx=false
2202         local stripe_nr=0
2203         $LFS getstripe $1 | while read obdidx oid hex seq; do
2204                 # skip lines up to and including "obdidx"
2205                 [ -z "$obdidx" ] && break
2206                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2207                 $have_obdidx || continue
2208
2209                 local ost=$((obdidx + 1))
2210                 local dev=$(ostdevname $ost)
2211                 local oid_hex
2212
2213                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2214
2215                 seq=$(echo $seq | sed -e "s/^0x//g")
2216                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2217                         oid_hex=$(echo $oid)
2218                 else
2219                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2220                 fi
2221                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2222
2223                 local ff=""
2224                 #
2225                 # Don't unmount/remount the OSTs if we don't need to do that.
2226                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2227                 # update too, until that use mount/ll_decode_filter_fid/mount.
2228                 # Re-enable when debugfs will understand new filter_fid.
2229                 #
2230                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2231                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2232                                 $dev 2>/dev/null" | grep "parent=")
2233                 fi
2234                 if [ -z "$ff" ]; then
2235                         stop ost$ost
2236                         mount_fstype ost$ost
2237                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2238                                 $(facet_mntpt ost$ost)/$obj_file)
2239                         unmount_fstype ost$ost
2240                         start ost$ost $dev $OST_MOUNT_OPTS
2241                         clients_up
2242                 fi
2243
2244                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2245
2246                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2247
2248                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2249                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2250                 #
2251                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2252                 #       stripe_size=1048576 component_id=1 component_start=0 \
2253                 #       component_end=33554432
2254                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2255                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2256                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2257                 local ff_pstripe
2258                 if grep -q 'stripe=' <<<$ff; then
2259                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2260                 else
2261                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2262                         # into f_ver in this case.  See comment on ff_parent.
2263                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2264                 fi
2265
2266                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2267                 [ $ff_pseq = $lmm_seq ] ||
2268                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2269                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2270                 [ $ff_poid = $lmm_oid ] ||
2271                         error "FF parent OID $ff_poid != $lmm_oid"
2272                 (($ff_pstripe == $stripe_nr)) ||
2273                         error "FF stripe $ff_pstripe != $stripe_nr"
2274
2275                 stripe_nr=$((stripe_nr + 1))
2276                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2277                         continue
2278                 if grep -q 'stripe_count=' <<<$ff; then
2279                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2280                                             -e 's/ .*//' <<<$ff)
2281                         [ $lmm_count = $ff_scnt ] ||
2282                                 error "FF stripe count $lmm_count != $ff_scnt"
2283                 fi
2284         done
2285 }
2286
2287 test_27z() {
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2293                 { error "setstripe -c -1 failed"; return 1; }
2294         # We need to send a write to every object to get parent FID info set.
2295         # This _should_ also work for setattr, but does not currently.
2296         # touch $DIR/$tdir/$tfile-1 ||
2297         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2298                 { error "dd $tfile-1 failed"; return 2; }
2299         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2300                 { error "setstripe -c -1 failed"; return 3; }
2301         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2302                 { error "dd $tfile-2 failed"; return 4; }
2303
2304         # make sure write RPCs have been sent to OSTs
2305         sync; sleep 5; sync
2306
2307         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2308         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2309 }
2310 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2311
2312 test_27A() { # b=19102
2313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2314
2315         save_layout_restore_at_exit $MOUNT
2316         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2317         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2318                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2319         local default_size=$($LFS getstripe -S $MOUNT)
2320         local default_offset=$($LFS getstripe -i $MOUNT)
2321         local dsize=$(do_facet $SINGLEMDS \
2322                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2323         [ $default_size -eq $dsize ] ||
2324                 error "stripe size $default_size != $dsize"
2325         [ $default_offset -eq -1 ] ||
2326                 error "stripe offset $default_offset != -1"
2327 }
2328 run_test 27A "check filesystem-wide default LOV EA values"
2329
2330 test_27B() { # LU-2523
2331         test_mkdir $DIR/$tdir
2332         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2333         touch $DIR/$tdir/f0
2334         # open f1 with O_LOV_DELAY_CREATE
2335         # rename f0 onto f1
2336         # call setstripe ioctl on open file descriptor for f1
2337         # close
2338         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2339                 $DIR/$tdir/f0
2340
2341         rm -f $DIR/$tdir/f1
2342         # open f1 with O_LOV_DELAY_CREATE
2343         # unlink f1
2344         # call setstripe ioctl on open file descriptor for f1
2345         # close
2346         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2347
2348         # Allow multiop to fail in imitation of NFS's busted semantics.
2349         true
2350 }
2351 run_test 27B "call setstripe on open unlinked file/rename victim"
2352
2353 # 27C family tests full striping and overstriping
2354 test_27Ca() { #LU-2871
2355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2356
2357         declare -a ost_idx
2358         local index
2359         local found
2360         local i
2361         local j
2362
2363         test_mkdir $DIR/$tdir
2364         cd $DIR/$tdir
2365         for i in $(seq 0 $((OSTCOUNT - 1))); do
2366                 # set stripe across all OSTs starting from OST$i
2367                 $LFS setstripe -i $i -c -1 $tfile$i
2368                 # get striping information
2369                 ost_idx=($($LFS getstripe $tfile$i |
2370                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2371                 echo ${ost_idx[@]}
2372
2373                 # check the layout
2374                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2375                         error "${#ost_idx[@]} != $OSTCOUNT"
2376
2377                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2378                         found=0
2379                         for j in $(echo ${ost_idx[@]}); do
2380                                 if [ $index -eq $j ]; then
2381                                         found=1
2382                                         break
2383                                 fi
2384                         done
2385                         [ $found = 1 ] ||
2386                                 error "Can not find $index in ${ost_idx[@]}"
2387                 done
2388         done
2389 }
2390 run_test 27Ca "check full striping across all OSTs"
2391
2392 test_27Cb() {
2393         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2394                 skip "server does not support overstriping"
2395         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2396                 skip_env "too many osts, skipping"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT * 2))
2400         [ $setcount -ge 160 ] || large_xattr_enabled ||
2401                 skip_env "ea_inode feature disabled"
2402
2403         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2404                 error "setstripe failed"
2405
2406         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2407         [ $count -eq $setcount ] ||
2408                 error "stripe count $count, should be $setcount"
2409
2410         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2411                 error "overstriped should be set in pattern"
2412
2413         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2414                 error "dd failed"
2415 }
2416 run_test 27Cb "more stripes than OSTs with -C"
2417
2418 test_27Cc() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2422
2423         test_mkdir -p $DIR/$tdir
2424         local setcount=$(($OSTCOUNT - 1))
2425
2426         [ $setcount -ge 160 ] || large_xattr_enabled ||
2427                 skip_env "ea_inode feature disabled"
2428
2429         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2430                 error "setstripe failed"
2431
2432         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2433         [ $count -eq $setcount ] ||
2434                 error "stripe count $count, should be $setcount"
2435
2436         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2437                 error "overstriped should not be set in pattern"
2438
2439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2440                 error "dd failed"
2441 }
2442 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2443
2444 test_27Cd() {
2445         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2446                 skip "server does not support overstriping"
2447         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2448         large_xattr_enabled || skip_env "ea_inode feature disabled"
2449
2450         test_mkdir -p $DIR/$tdir
2451         local setcount=$LOV_MAX_STRIPE_COUNT
2452
2453         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2454                 error "setstripe failed"
2455
2456         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2457         [ $count -eq $setcount ] ||
2458                 error "stripe count $count, should be $setcount"
2459
2460         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2461                 error "overstriped should be set in pattern"
2462
2463         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2464                 error "dd failed"
2465
2466         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2467 }
2468 run_test 27Cd "test maximum stripe count"
2469
2470 test_27Ce() {
2471         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2472                 skip "server does not support overstriping"
2473         test_mkdir -p $DIR/$tdir
2474
2475         pool_add $TESTNAME || error "Pool creation failed"
2476         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2477
2478         local setcount=8
2479
2480         $LFS setstripe  -C $setcount -p "$TESTNAME" $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 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         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2494 }
2495 run_test 27Ce "test pool with overstriping"
2496
2497 test_27Cf() {
2498         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2499                 skip "server does not support overstriping"
2500         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2501                 skip_env "too many osts, skipping"
2502
2503         test_mkdir -p $DIR/$tdir
2504
2505         local setcount=$(($OSTCOUNT * 2))
2506         [ $setcount -ge 160 ] || large_xattr_enabled ||
2507                 skip_env "ea_inode feature disabled"
2508
2509         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2510                 error "setstripe failed"
2511
2512         echo 1 > $DIR/$tdir/$tfile
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2519                 error "overstriped should be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523
2524         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2525 }
2526 run_test 27Cf "test default inheritance with overstriping"
2527
2528 test_27D() {
2529         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2530         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2531         remote_mds_nodsh && skip "remote MDS with nodsh"
2532
2533         local POOL=${POOL:-testpool}
2534         local first_ost=0
2535         local last_ost=$(($OSTCOUNT - 1))
2536         local ost_step=1
2537         local ost_list=$(seq $first_ost $ost_step $last_ost)
2538         local ost_range="$first_ost $last_ost $ost_step"
2539
2540         test_mkdir $DIR/$tdir
2541         pool_add $POOL || error "pool_add failed"
2542         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2543
2544         local skip27D
2545         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2546                 skip27D+="-s 29"
2547         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2548                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2549                         skip27D+=" -s 30,31"
2550         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2551           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip27D+=" -s 32,33"
2553         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2554                 skip27D+=" -s 34"
2555         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2556                 error "llapi_layout_test failed"
2557
2558         destroy_test_pools || error "destroy test pools failed"
2559 }
2560 run_test 27D "validate llapi_layout API"
2561
2562 # Verify that default_easize is increased from its initial value after
2563 # accessing a widely striped file.
2564 test_27E() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2567                 skip "client does not have LU-3338 fix"
2568
2569         # 72 bytes is the minimum space required to store striping
2570         # information for a file striped across one OST:
2571         # (sizeof(struct lov_user_md_v3) +
2572         #  sizeof(struct lov_user_ost_data_v1))
2573         local min_easize=72
2574         $LCTL set_param -n llite.*.default_easize $min_easize ||
2575                 error "lctl set_param failed"
2576         local easize=$($LCTL get_param -n llite.*.default_easize)
2577
2578         [ $easize -eq $min_easize ] ||
2579                 error "failed to set default_easize"
2580
2581         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2582                 error "setstripe failed"
2583         # In order to ensure stat() call actually talks to MDS we need to
2584         # do something drastic to this file to shake off all lock, e.g.
2585         # rename it (kills lookup lock forcing cache cleaning)
2586         mv $DIR/$tfile $DIR/${tfile}-1
2587         ls -l $DIR/${tfile}-1
2588         rm $DIR/${tfile}-1
2589
2590         easize=$($LCTL get_param -n llite.*.default_easize)
2591
2592         [ $easize -gt $min_easize ] ||
2593                 error "default_easize not updated"
2594 }
2595 run_test 27E "check that default extended attribute size properly increases"
2596
2597 test_27F() { # LU-5346/LU-7975
2598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2599         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2600         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2601                 skip "Need MDS version at least 2.8.51"
2602         remote_ost_nodsh && skip "remote OST with nodsh"
2603
2604         test_mkdir $DIR/$tdir
2605         rm -f $DIR/$tdir/f0
2606         $LFS setstripe -c 2 $DIR/$tdir
2607
2608         # stop all OSTs to reproduce situation for LU-7975 ticket
2609         for num in $(seq $OSTCOUNT); do
2610                 stop ost$num
2611         done
2612
2613         # open/create f0 with O_LOV_DELAY_CREATE
2614         # truncate f0 to a non-0 size
2615         # close
2616         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2617
2618         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2619         # open/write it again to force delayed layout creation
2620         cat /etc/hosts > $DIR/$tdir/f0 &
2621         catpid=$!
2622
2623         # restart OSTs
2624         for num in $(seq $OSTCOUNT); do
2625                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2626                         error "ost$num failed to start"
2627         done
2628
2629         wait $catpid || error "cat failed"
2630
2631         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2632         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2633                 error "wrong stripecount"
2634
2635 }
2636 run_test 27F "Client resend delayed layout creation with non-zero size"
2637
2638 test_27G() { #LU-10629
2639         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2640                 skip "Need MDS version at least 2.11.51"
2641         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2642         remote_mds_nodsh && skip "remote MDS with nodsh"
2643         local POOL=${POOL:-testpool}
2644         local ostrange="0 0 1"
2645
2646         test_mkdir $DIR/$tdir
2647         touch $DIR/$tdir/$tfile.nopool
2648         pool_add $POOL || error "pool_add failed"
2649         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2650         $LFS setstripe -p $POOL $DIR/$tdir
2651
2652         local pool=$($LFS getstripe -p $DIR/$tdir)
2653
2654         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2655         touch $DIR/$tdir/$tfile.default
2656         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2657         $LFS find $DIR/$tdir -type f --pool $POOL
2658         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2659         [[ "$found" == "2" ]] ||
2660                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2661
2662         $LFS setstripe -d $DIR/$tdir
2663
2664         pool=$($LFS getstripe -p -d $DIR/$tdir)
2665
2666         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2667 }
2668 run_test 27G "Clear OST pool from stripe"
2669
2670 test_27H() {
2671         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2672                 skip "Need MDS version newer than 2.11.54"
2673         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2674         test_mkdir $DIR/$tdir
2675         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2676         touch $DIR/$tdir/$tfile
2677         $LFS getstripe -c $DIR/$tdir/$tfile
2678         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2679                 error "two-stripe file doesn't have two stripes"
2680
2681         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2682         $LFS getstripe -y $DIR/$tdir/$tfile
2683         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2684              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2685                 error "expected l_ost_idx: [02]$ not matched"
2686
2687         # make sure ost list has been cleared
2688         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2689         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2690                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2691         touch $DIR/$tdir/f3
2692         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2693 }
2694 run_test 27H "Set specific OSTs stripe"
2695
2696 test_27I() {
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2699         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2700                 skip "Need MDS version newer than 2.12.52"
2701         local pool=$TESTNAME
2702         local ostrange="1 1 1"
2703
2704         save_layout_restore_at_exit $MOUNT
2705         $LFS setstripe -c 2 -i 0 $MOUNT
2706         pool_add $pool || error "pool_add failed"
2707         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2708         test_mkdir $DIR/$tdir
2709         $LFS setstripe -p $pool $DIR/$tdir
2710         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2711         $LFS getstripe $DIR/$tdir/$tfile
2712 }
2713 run_test 27I "check that root dir striping does not break parent dir one"
2714
2715 test_27J() {
2716         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2717                 skip "Need MDS version newer than 2.12.51"
2718
2719         test_mkdir $DIR/$tdir
2720         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2721         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2722
2723         # create foreign file (raw way)
2724         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2725                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2726
2727         # verify foreign file (raw way)
2728         parse_foreign_file -f $DIR/$tdir/$tfile |
2729                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2730                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2731         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2732                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2733         parse_foreign_file -f $DIR/$tdir/$tfile |
2734                 grep "lov_foreign_size: 73" ||
2735                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2736         parse_foreign_file -f $DIR/$tdir/$tfile |
2737                 grep "lov_foreign_type: 1" ||
2738                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2739         parse_foreign_file -f $DIR/$tdir/$tfile |
2740                 grep "lov_foreign_flags: 0x0000DA08" ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2742         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2743                 grep "lov_foreign_value: 0x" |
2744                 sed -e 's/lov_foreign_value: 0x//')
2745         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2746         [[ $lov = ${lov2// /} ]] ||
2747                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2748
2749         # create foreign file (lfs + API)
2750         $LFS setstripe --foreign=daos --flags 0xda08 \
2751                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2752                 error "$DIR/$tdir/${tfile}2: create failed"
2753
2754         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2755                 grep "lfm_magic:.*0x0BD70BD0" ||
2756                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2757         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2758         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2759                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2760         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2761                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2762         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2763                 grep "lfm_flags:.*0x0000DA08" ||
2764                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2765         $LFS getstripe $DIR/$tdir/${tfile}2 |
2766                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2767                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2768
2769         # modify striping should fail
2770         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2771                 error "$DIR/$tdir/$tfile: setstripe should fail"
2772         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2773                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2774
2775         # R/W should fail
2776         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2777         cat $DIR/$tdir/${tfile}2 &&
2778                 error "$DIR/$tdir/${tfile}2: read should fail"
2779         cat /etc/passwd > $DIR/$tdir/$tfile &&
2780                 error "$DIR/$tdir/$tfile: write should fail"
2781         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2782                 error "$DIR/$tdir/${tfile}2: write should fail"
2783
2784         # chmod should work
2785         chmod 222 $DIR/$tdir/$tfile ||
2786                 error "$DIR/$tdir/$tfile: chmod failed"
2787         chmod 222 $DIR/$tdir/${tfile}2 ||
2788                 error "$DIR/$tdir/${tfile}2: chmod failed"
2789
2790         # chown should work
2791         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2792                 error "$DIR/$tdir/$tfile: chown failed"
2793         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2794                 error "$DIR/$tdir/${tfile}2: chown failed"
2795
2796         # rename should work
2797         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2798                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2799         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2800                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2801
2802         #remove foreign file
2803         rm $DIR/$tdir/${tfile}.new ||
2804                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2805         rm $DIR/$tdir/${tfile}2.new ||
2806                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2807 }
2808 run_test 27J "basic ops on file with foreign LOV"
2809
2810 test_27K() {
2811         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2812                 skip "Need MDS version newer than 2.12.49"
2813
2814         test_mkdir $DIR/$tdir
2815         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2816         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2817
2818         # create foreign dir (raw way)
2819         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2820                 error "create_foreign_dir FAILED"
2821
2822         # verify foreign dir (raw way)
2823         parse_foreign_dir -d $DIR/$tdir/$tdir |
2824                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2825                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2826         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2827                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2828         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2829                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2830         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2831                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2832         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2833                 grep "lmv_foreign_value: 0x" |
2834                 sed 's/lmv_foreign_value: 0x//')
2835         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2836                 sed 's/ //g')
2837         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2838
2839         # create foreign dir (lfs + API)
2840         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2841                 $DIR/$tdir/${tdir}2 ||
2842                 error "$DIR/$tdir/${tdir}2: create failed"
2843
2844         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2845                 grep "lfm_magic:.*0x0CD50CD0" ||
2846                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2847         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2848         # - sizeof(lfm_type) - sizeof(lfm_flags)
2849         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2850                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2851         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2852                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2853         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2854                 grep "lfm_flags:.*0x0000DA05" ||
2855                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2856         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2857                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2858                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2859
2860         # file create in dir should fail
2861         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2862         touch $DIR/$tdir/${tdir}2/$tfile &&
2863                 "$DIR/${tdir}2: file create should fail"
2864
2865         # chmod should work
2866         chmod 777 $DIR/$tdir/$tdir ||
2867                 error "$DIR/$tdir: chmod failed"
2868         chmod 777 $DIR/$tdir/${tdir}2 ||
2869                 error "$DIR/${tdir}2: chmod failed"
2870
2871         # chown should work
2872         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2873                 error "$DIR/$tdir: chown failed"
2874         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2875                 error "$DIR/${tdir}2: chown failed"
2876
2877         # rename should work
2878         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2879                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2880         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2881                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2882
2883         #remove foreign dir
2884         rmdir $DIR/$tdir/${tdir}.new ||
2885                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2886         rmdir $DIR/$tdir/${tdir}2.new ||
2887                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2888 }
2889 run_test 27K "basic ops on dir with foreign LMV"
2890
2891 test_27L() {
2892         remote_mds_nodsh && skip "remote MDS with nodsh"
2893
2894         local POOL=${POOL:-$TESTNAME}
2895
2896         pool_add $POOL || error "pool_add failed"
2897
2898         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2899                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2900                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2901 }
2902 run_test 27L "lfs pool_list gives correct pool name"
2903
2904 test_27M() {
2905         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2906                 skip "Need MDS version >= than 2.12.57"
2907         remote_mds_nodsh && skip "remote MDS with nodsh"
2908         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2909
2910         test_mkdir $DIR/$tdir
2911
2912         # Set default striping on directory
2913         $LFS setstripe -C 4 $DIR/$tdir
2914
2915         echo 1 > $DIR/$tdir/${tfile}.1
2916         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2917         local setcount=4
2918         [ $count -eq $setcount ] ||
2919                 error "(1) stripe count $count, should be $setcount"
2920
2921         # Capture existing append_stripe_count setting for restore
2922         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2923         local mdts=$(comma_list $(mdts_nodes))
2924         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2925
2926         local appendcount=$orig_count
2927         echo 1 >> $DIR/$tdir/${tfile}.2_append
2928         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2929         [ $count -eq $appendcount ] ||
2930                 error "(2)stripe count $count, should be $appendcount for append"
2931
2932         # Disable O_APPEND striping, verify it works
2933         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2934
2935         # Should now get the default striping, which is 4
2936         setcount=4
2937         echo 1 >> $DIR/$tdir/${tfile}.3_append
2938         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2939         [ $count -eq $setcount ] ||
2940                 error "(3) stripe count $count, should be $setcount"
2941
2942         # Try changing the stripe count for append files
2943         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2944
2945         # Append striping is now 2 (directory default is still 4)
2946         appendcount=2
2947         echo 1 >> $DIR/$tdir/${tfile}.4_append
2948         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2949         [ $count -eq $appendcount ] ||
2950                 error "(4) stripe count $count, should be $appendcount for append"
2951
2952         # Test append stripe count of -1
2953         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2954         appendcount=$OSTCOUNT
2955         echo 1 >> $DIR/$tdir/${tfile}.5
2956         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2957         [ $count -eq $appendcount ] ||
2958                 error "(5) stripe count $count, should be $appendcount for append"
2959
2960         # Set append striping back to default of 1
2961         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2962
2963         # Try a new default striping, PFL + DOM
2964         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2965
2966         # Create normal DOM file, DOM returns stripe count == 0
2967         setcount=0
2968         touch $DIR/$tdir/${tfile}.6
2969         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2970         [ $count -eq $setcount ] ||
2971                 error "(6) stripe count $count, should be $setcount"
2972
2973         # Show
2974         appendcount=1
2975         echo 1 >> $DIR/$tdir/${tfile}.7_append
2976         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2977         [ $count -eq $appendcount ] ||
2978                 error "(7) stripe count $count, should be $appendcount for append"
2979
2980         # Clean up DOM layout
2981         $LFS setstripe -d $DIR/$tdir
2982
2983         # Now test that append striping works when layout is from root
2984         $LFS setstripe -c 2 $MOUNT
2985         # Make a special directory for this
2986         mkdir $DIR/${tdir}/${tdir}.2
2987         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2988
2989         # Verify for normal file
2990         setcount=2
2991         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2992         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2993         [ $count -eq $setcount ] ||
2994                 error "(8) stripe count $count, should be $setcount"
2995
2996         appendcount=1
2997         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2998         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2999         [ $count -eq $appendcount ] ||
3000                 error "(9) stripe count $count, should be $appendcount for append"
3001
3002         # Now test O_APPEND striping with pools
3003         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3004         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3005
3006         # Create the pool
3007         pool_add $TESTNAME || error "pool creation failed"
3008         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3009
3010         echo 1 >> $DIR/$tdir/${tfile}.10_append
3011
3012         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3013         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3014
3015         # Check that count is still correct
3016         appendcount=1
3017         echo 1 >> $DIR/$tdir/${tfile}.11_append
3018         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3019         [ $count -eq $appendcount ] ||
3020                 error "(11) stripe count $count, should be $appendcount for append"
3021
3022         # Disable O_APPEND stripe count, verify pool works separately
3023         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3024
3025         echo 1 >> $DIR/$tdir/${tfile}.12_append
3026
3027         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3028         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3029
3030         # Remove pool setting, verify it's not applied
3031         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3032
3033         echo 1 >> $DIR/$tdir/${tfile}.13_append
3034
3035         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3036         [ "$pool" = "" ] || error "(13) pool found: $pool"
3037 }
3038 run_test 27M "test O_APPEND striping"
3039
3040 test_27N() {
3041         combined_mgs_mds && skip "needs separate MGS/MDT"
3042
3043         pool_add $TESTNAME || error "pool_add failed"
3044         do_facet mgs "$LCTL pool_list $FSNAME" |
3045                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3046                 error "lctl pool_list on MGS failed"
3047 }
3048 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3049
3050 # createtest also checks that device nodes are created and
3051 # then visible correctly (#2091)
3052 test_28() { # bug 2091
3053         test_mkdir $DIR/d28
3054         $CREATETEST $DIR/d28/ct || error "createtest failed"
3055 }
3056 run_test 28 "create/mknod/mkdir with bad file types ============"
3057
3058 test_29() {
3059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3060
3061         sync; sleep 1; sync # flush out any dirty pages from previous tests
3062         cancel_lru_locks
3063         test_mkdir $DIR/d29
3064         touch $DIR/d29/foo
3065         log 'first d29'
3066         ls -l $DIR/d29
3067
3068         declare -i LOCKCOUNTORIG=0
3069         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3070                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3071         done
3072         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3073
3074         declare -i LOCKUNUSEDCOUNTORIG=0
3075         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3076                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3077         done
3078
3079         log 'second d29'
3080         ls -l $DIR/d29
3081         log 'done'
3082
3083         declare -i LOCKCOUNTCURRENT=0
3084         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3085                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3086         done
3087
3088         declare -i LOCKUNUSEDCOUNTCURRENT=0
3089         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3090                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3091         done
3092
3093         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3094                 $LCTL set_param -n ldlm.dump_namespaces ""
3095                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3096                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3097                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3098                 return 2
3099         fi
3100         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3101                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3102                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3103                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3104                 return 3
3105         fi
3106 }
3107 run_test 29 "IT_GETATTR regression  ============================"
3108
3109 test_30a() { # was test_30
3110         cp $(which ls) $DIR || cp /bin/ls $DIR
3111         $DIR/ls / || error "Can't execute binary from lustre"
3112         rm $DIR/ls
3113 }
3114 run_test 30a "execute binary from Lustre (execve) =============="
3115
3116 test_30b() {
3117         cp `which ls` $DIR || cp /bin/ls $DIR
3118         chmod go+rx $DIR/ls
3119         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3120         rm $DIR/ls
3121 }
3122 run_test 30b "execute binary from Lustre as non-root ==========="
3123
3124 test_30c() { # b=22376
3125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3126
3127         cp $(which ls) $DIR || cp /bin/ls $DIR
3128         chmod a-rw $DIR/ls
3129         cancel_lru_locks mdc
3130         cancel_lru_locks osc
3131         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3132         rm -f $DIR/ls
3133 }
3134 run_test 30c "execute binary from Lustre without read perms ===="
3135
3136 test_30d() {
3137         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3138
3139         for i in {1..10}; do
3140                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3141                 local PID=$!
3142                 sleep 1
3143                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3144                 wait $PID || error "executing dd from Lustre failed"
3145                 rm -f $DIR/$tfile
3146         done
3147
3148         rm -f $DIR/dd
3149 }
3150 run_test 30d "execute binary from Lustre while clear locks"
3151
3152 test_31a() {
3153         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3154         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3155 }
3156 run_test 31a "open-unlink file =================================="
3157
3158 test_31b() {
3159         touch $DIR/f31 || error "touch $DIR/f31 failed"
3160         ln $DIR/f31 $DIR/f31b || error "ln failed"
3161         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3162         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3163 }
3164 run_test 31b "unlink file with multiple links while open ======="
3165
3166 test_31c() {
3167         touch $DIR/f31 || error "touch $DIR/f31 failed"
3168         ln $DIR/f31 $DIR/f31c || error "ln failed"
3169         multiop_bg_pause $DIR/f31 O_uc ||
3170                 error "multiop_bg_pause for $DIR/f31 failed"
3171         MULTIPID=$!
3172         $MULTIOP $DIR/f31c Ouc
3173         kill -USR1 $MULTIPID
3174         wait $MULTIPID
3175 }
3176 run_test 31c "open-unlink file with multiple links ============="
3177
3178 test_31d() {
3179         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3180         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3181 }
3182 run_test 31d "remove of open directory ========================="
3183
3184 test_31e() { # bug 2904
3185         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3186 }
3187 run_test 31e "remove of open non-empty directory ==============="
3188
3189 test_31f() { # bug 4554
3190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3191
3192         set -vx
3193         test_mkdir $DIR/d31f
3194         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3195         cp /etc/hosts $DIR/d31f
3196         ls -l $DIR/d31f
3197         $LFS getstripe $DIR/d31f/hosts
3198         multiop_bg_pause $DIR/d31f D_c || return 1
3199         MULTIPID=$!
3200
3201         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3202         test_mkdir $DIR/d31f
3203         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3204         cp /etc/hosts $DIR/d31f
3205         ls -l $DIR/d31f
3206         $LFS getstripe $DIR/d31f/hosts
3207         multiop_bg_pause $DIR/d31f D_c || return 1
3208         MULTIPID2=$!
3209
3210         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3211         wait $MULTIPID || error "first opendir $MULTIPID failed"
3212
3213         sleep 6
3214
3215         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3216         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3217         set +vx
3218 }
3219 run_test 31f "remove of open directory with open-unlink file ==="
3220
3221 test_31g() {
3222         echo "-- cross directory link --"
3223         test_mkdir -c1 $DIR/${tdir}ga
3224         test_mkdir -c1 $DIR/${tdir}gb
3225         touch $DIR/${tdir}ga/f
3226         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3227         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3228         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3229         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3230         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3231 }
3232 run_test 31g "cross directory link==============="
3233
3234 test_31h() {
3235         echo "-- cross directory link --"
3236         test_mkdir -c1 $DIR/${tdir}
3237         test_mkdir -c1 $DIR/${tdir}/dir
3238         touch $DIR/${tdir}/f
3239         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3240         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3241         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3242         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3243         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3244 }
3245 run_test 31h "cross directory link under child==============="
3246
3247 test_31i() {
3248         echo "-- cross directory link --"
3249         test_mkdir -c1 $DIR/$tdir
3250         test_mkdir -c1 $DIR/$tdir/dir
3251         touch $DIR/$tdir/dir/f
3252         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3253         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3254         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3255         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3256         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3257 }
3258 run_test 31i "cross directory link under parent==============="
3259
3260 test_31j() {
3261         test_mkdir -c1 -p $DIR/$tdir
3262         test_mkdir -c1 -p $DIR/$tdir/dir1
3263         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3264         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3265         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3266         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3267         return 0
3268 }
3269 run_test 31j "link for directory==============="
3270
3271 test_31k() {
3272         test_mkdir -c1 -p $DIR/$tdir
3273         touch $DIR/$tdir/s
3274         touch $DIR/$tdir/exist
3275         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3276         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3277         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3278         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3279         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3280         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3281         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3282         return 0
3283 }
3284 run_test 31k "link to file: the same, non-existing, dir==============="
3285
3286 test_31m() {
3287         mkdir $DIR/d31m
3288         touch $DIR/d31m/s
3289         mkdir $DIR/d31m2
3290         touch $DIR/d31m2/exist
3291         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3292         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3293         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3294         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3295         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3296         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3297         return 0
3298 }
3299 run_test 31m "link to file: the same, non-existing, dir==============="
3300
3301 test_31n() {
3302         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3303         nlink=$(stat --format=%h $DIR/$tfile)
3304         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3305         local fd=$(free_fd)
3306         local cmd="exec $fd<$DIR/$tfile"
3307         eval $cmd
3308         cmd="exec $fd<&-"
3309         trap "eval $cmd" EXIT
3310         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3311         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3312         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3313         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3314         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3315         eval $cmd
3316 }
3317 run_test 31n "check link count of unlinked file"
3318
3319 link_one() {
3320         local tempfile=$(mktemp $1_XXXXXX)
3321         mlink $tempfile $1 2> /dev/null &&
3322                 echo "$BASHPID: link $tempfile to $1 succeeded"
3323         munlink $tempfile
3324 }
3325
3326 test_31o() { # LU-2901
3327         test_mkdir $DIR/$tdir
3328         for LOOP in $(seq 100); do
3329                 rm -f $DIR/$tdir/$tfile*
3330                 for THREAD in $(seq 8); do
3331                         link_one $DIR/$tdir/$tfile.$LOOP &
3332                 done
3333                 wait
3334                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3335                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3336                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3337                         break || true
3338         done
3339 }
3340 run_test 31o "duplicate hard links with same filename"
3341
3342 test_31p() {
3343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3344
3345         test_mkdir $DIR/$tdir
3346         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3347         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3348
3349         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3350                 error "open unlink test1 failed"
3351         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3352                 error "open unlink test2 failed"
3353
3354         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3355                 error "test1 still exists"
3356         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3357                 error "test2 still exists"
3358 }
3359 run_test 31p "remove of open striped directory"
3360
3361 test_31q() {
3362         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3363
3364         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3365         index=$($LFS getdirstripe -i $DIR/$tdir)
3366         [ $index -eq 3 ] || error "first stripe index $index != 3"
3367         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3368         [ $index -eq 1 ] || error "second stripe index $index != 1"
3369
3370         # when "-c <stripe_count>" is set, the number of MDTs specified after
3371         # "-i" should equal to the stripe count
3372         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3373 }
3374 run_test 31q "create striped directory on specific MDTs"
3375
3376 cleanup_test32_mount() {
3377         local rc=0
3378         trap 0
3379         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3380         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3381         losetup -d $loopdev || true
3382         rm -rf $DIR/$tdir
3383         return $rc
3384 }
3385
3386 test_32a() {
3387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3388
3389         echo "== more mountpoints and symlinks ================="
3390         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3391         trap cleanup_test32_mount EXIT
3392         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3393         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3394                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3395         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3396                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3397         cleanup_test32_mount
3398 }
3399 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3400
3401 test_32b() {
3402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3403
3404         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3405         trap cleanup_test32_mount EXIT
3406         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3407         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3408                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3409         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3410                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3411         cleanup_test32_mount
3412 }
3413 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3414
3415 test_32c() {
3416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3417
3418         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3419         trap cleanup_test32_mount EXIT
3420         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3421         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3422                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3423         test_mkdir -p $DIR/$tdir/d2/test_dir
3424         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3425                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3426         cleanup_test32_mount
3427 }
3428 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3429
3430 test_32d() {
3431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3432
3433         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3434         trap cleanup_test32_mount EXIT
3435         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3436         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3437                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3438         test_mkdir -p $DIR/$tdir/d2/test_dir
3439         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3440                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3441         cleanup_test32_mount
3442 }
3443 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3444
3445 test_32e() {
3446         rm -fr $DIR/$tdir
3447         test_mkdir -p $DIR/$tdir/tmp
3448         local tmp_dir=$DIR/$tdir/tmp
3449         ln -s $DIR/$tdir $tmp_dir/symlink11
3450         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3451         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3452         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3453 }
3454 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3455
3456 test_32f() {
3457         rm -fr $DIR/$tdir
3458         test_mkdir -p $DIR/$tdir/tmp
3459         local tmp_dir=$DIR/$tdir/tmp
3460         ln -s $DIR/$tdir $tmp_dir/symlink11
3461         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3462         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3463         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3464 }
3465 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3466
3467 test_32g() {
3468         local tmp_dir=$DIR/$tdir/tmp
3469         test_mkdir -p $tmp_dir
3470         test_mkdir $DIR/${tdir}2
3471         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3472         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3473         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3474         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3475         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3476         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3477 }
3478 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3479
3480 test_32h() {
3481         rm -fr $DIR/$tdir $DIR/${tdir}2
3482         tmp_dir=$DIR/$tdir/tmp
3483         test_mkdir -p $tmp_dir
3484         test_mkdir $DIR/${tdir}2
3485         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3486         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3487         ls $tmp_dir/symlink12 || error "listing symlink12"
3488         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3489 }
3490 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3491
3492 test_32i() {
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3496         trap cleanup_test32_mount EXIT
3497         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3498         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3499                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3500         touch $DIR/$tdir/test_file
3501         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3502                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3503         cleanup_test32_mount
3504 }
3505 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3506
3507 test_32j() {
3508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3509
3510         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3511         trap cleanup_test32_mount EXIT
3512         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3513         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3514                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3515         touch $DIR/$tdir/test_file
3516         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3517                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3518         cleanup_test32_mount
3519 }
3520 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3521
3522 test_32k() {
3523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3524
3525         rm -fr $DIR/$tdir
3526         trap cleanup_test32_mount EXIT
3527         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3528         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3529                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3530         test_mkdir -p $DIR/$tdir/d2
3531         touch $DIR/$tdir/d2/test_file || error "touch failed"
3532         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3533                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3534         cleanup_test32_mount
3535 }
3536 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3537
3538 test_32l() {
3539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3540
3541         rm -fr $DIR/$tdir
3542         trap cleanup_test32_mount EXIT
3543         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3544         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3545                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3546         test_mkdir -p $DIR/$tdir/d2
3547         touch $DIR/$tdir/d2/test_file || error "touch failed"
3548         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3549                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3550         cleanup_test32_mount
3551 }
3552 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3553
3554 test_32m() {
3555         rm -fr $DIR/d32m
3556         test_mkdir -p $DIR/d32m/tmp
3557         TMP_DIR=$DIR/d32m/tmp
3558         ln -s $DIR $TMP_DIR/symlink11
3559         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3560         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3561                 error "symlink11 not a link"
3562         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3563                 error "symlink01 not a link"
3564 }
3565 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3566
3567 test_32n() {
3568         rm -fr $DIR/d32n
3569         test_mkdir -p $DIR/d32n/tmp
3570         TMP_DIR=$DIR/d32n/tmp
3571         ln -s $DIR $TMP_DIR/symlink11
3572         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3573         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3574         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3575 }
3576 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3577
3578 test_32o() {
3579         touch $DIR/$tfile
3580         test_mkdir -p $DIR/d32o/tmp
3581         TMP_DIR=$DIR/d32o/tmp
3582         ln -s $DIR/$tfile $TMP_DIR/symlink12
3583         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3584         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3585                 error "symlink12 not a link"
3586         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3587         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3588                 error "$DIR/d32o/tmp/symlink12 not file type"
3589         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3590                 error "$DIR/d32o/symlink02 not file type"
3591 }
3592 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3593
3594 test_32p() {
3595         log 32p_1
3596         rm -fr $DIR/d32p
3597         log 32p_2
3598         rm -f $DIR/$tfile
3599         log 32p_3
3600         touch $DIR/$tfile
3601         log 32p_4
3602         test_mkdir -p $DIR/d32p/tmp
3603         log 32p_5
3604         TMP_DIR=$DIR/d32p/tmp
3605         log 32p_6
3606         ln -s $DIR/$tfile $TMP_DIR/symlink12
3607         log 32p_7
3608         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3609         log 32p_8
3610         cat $DIR/d32p/tmp/symlink12 ||
3611                 error "Can't open $DIR/d32p/tmp/symlink12"
3612         log 32p_9
3613         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3614         log 32p_10
3615 }
3616 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3617
3618 test_32q() {
3619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3620
3621         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3622         trap cleanup_test32_mount EXIT
3623         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3624         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3625         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3626                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3627         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3628         cleanup_test32_mount
3629 }
3630 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3631
3632 test_32r() {
3633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3634
3635         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3636         trap cleanup_test32_mount EXIT
3637         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3638         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3639         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3640                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3641         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3642         cleanup_test32_mount
3643 }
3644 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3645
3646 test_33aa() {
3647         rm -f $DIR/$tfile
3648         touch $DIR/$tfile
3649         chmod 444 $DIR/$tfile
3650         chown $RUNAS_ID $DIR/$tfile
3651         log 33_1
3652         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3653         log 33_2
3654 }
3655 run_test 33aa "write file with mode 444 (should return error)"
3656
3657 test_33a() {
3658         rm -fr $DIR/$tdir
3659         test_mkdir $DIR/$tdir
3660         chown $RUNAS_ID $DIR/$tdir
3661         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3662                 error "$RUNAS create $tdir/$tfile failed"
3663         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3664                 error "open RDWR" || true
3665 }
3666 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3667
3668 test_33b() {
3669         rm -fr $DIR/$tdir
3670         test_mkdir $DIR/$tdir
3671         chown $RUNAS_ID $DIR/$tdir
3672         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3673 }
3674 run_test 33b "test open file with malformed flags (No panic)"
3675
3676 test_33c() {
3677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3678         remote_ost_nodsh && skip "remote OST with nodsh"
3679
3680         local ostnum
3681         local ostname
3682         local write_bytes
3683         local all_zeros
3684
3685         all_zeros=:
3686         rm -fr $DIR/$tdir
3687         test_mkdir $DIR/$tdir
3688         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3689
3690         sync
3691         for ostnum in $(seq $OSTCOUNT); do
3692                 # test-framework's OST numbering is one-based, while Lustre's
3693                 # is zero-based
3694                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3695                 # Parsing llobdstat's output sucks; we could grep the /proc
3696                 # path, but that's likely to not be as portable as using the
3697                 # llobdstat utility.  So we parse lctl output instead.
3698                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3699                         obdfilter/$ostname/stats |
3700                         awk '/^write_bytes/ {print $7}' )
3701                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3702                 if (( ${write_bytes:-0} > 0 ))
3703                 then
3704                         all_zeros=false
3705                         break;
3706                 fi
3707         done
3708
3709         $all_zeros || return 0
3710
3711         # Write four bytes
3712         echo foo > $DIR/$tdir/bar
3713         # Really write them
3714         sync
3715
3716         # Total up write_bytes after writing.  We'd better find non-zeros.
3717         for ostnum in $(seq $OSTCOUNT); do
3718                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3719                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3720                         obdfilter/$ostname/stats |
3721                         awk '/^write_bytes/ {print $7}' )
3722                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3723                 if (( ${write_bytes:-0} > 0 ))
3724                 then
3725                         all_zeros=false
3726                         break;
3727                 fi
3728         done
3729
3730         if $all_zeros
3731         then
3732                 for ostnum in $(seq $OSTCOUNT); do
3733                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3734                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3735                         do_facet ost$ostnum lctl get_param -n \
3736                                 obdfilter/$ostname/stats
3737                 done
3738                 error "OST not keeping write_bytes stats (b22312)"
3739         fi
3740 }
3741 run_test 33c "test llobdstat and write_bytes"
3742
3743 test_33d() {
3744         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3746
3747         local MDTIDX=1
3748         local remote_dir=$DIR/$tdir/remote_dir
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS mkdir -i $MDTIDX $remote_dir ||
3752                 error "create remote directory failed"
3753
3754         touch $remote_dir/$tfile
3755         chmod 444 $remote_dir/$tfile
3756         chown $RUNAS_ID $remote_dir/$tfile
3757
3758         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3759
3760         chown $RUNAS_ID $remote_dir
3761         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3762                                         error "create" || true
3763         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3764                                     error "open RDWR" || true
3765         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3766 }
3767 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3768
3769 test_33e() {
3770         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3771
3772         mkdir $DIR/$tdir
3773
3774         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3775         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3776         mkdir $DIR/$tdir/local_dir
3777
3778         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3779         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3780         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3781
3782         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3783                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3784
3785         rmdir $DIR/$tdir/* || error "rmdir failed"
3786
3787         umask 777
3788         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3789         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3790         mkdir $DIR/$tdir/local_dir
3791
3792         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3793         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3794         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3795
3796         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3797                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3798
3799         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3800
3801         umask 000
3802         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3803         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3804         mkdir $DIR/$tdir/local_dir
3805
3806         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3807         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3808         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3809
3810         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3811                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3812 }
3813 run_test 33e "mkdir and striped directory should have same mode"
3814
3815 cleanup_33f() {
3816         trap 0
3817         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3818 }
3819
3820 test_33f() {
3821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3822         remote_mds_nodsh && skip "remote MDS with nodsh"
3823
3824         mkdir $DIR/$tdir
3825         chmod go+rwx $DIR/$tdir
3826         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3827         trap cleanup_33f EXIT
3828
3829         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3830                 error "cannot create striped directory"
3831
3832         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3833                 error "cannot create files in striped directory"
3834
3835         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3836                 error "cannot remove files in striped directory"
3837
3838         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3839                 error "cannot remove striped directory"
3840
3841         cleanup_33f
3842 }
3843 run_test 33f "nonroot user can create, access, and remove a striped directory"
3844
3845 test_33g() {
3846         mkdir -p $DIR/$tdir/dir2
3847
3848         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3849         echo $err
3850         [[ $err =~ "exists" ]] || error "Not exists error"
3851 }
3852 run_test 33g "nonroot user create already existing root created file"
3853
3854 test_33h() {
3855         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3856         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3857                 skip "Need MDS version at least 2.13.50"
3858
3859         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3860                 error "mkdir $tdir failed"
3861         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3862
3863         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3864         local index2
3865
3866         for fname in $DIR/$tdir/$tfile.bak \
3867                      $DIR/$tdir/$tfile.SAV \
3868                      $DIR/$tdir/$tfile.orig \
3869                      $DIR/$tdir/$tfile~; do
3870                 touch $fname  || error "touch $fname failed"
3871                 index2=$($LFS getstripe -m $fname)
3872                 [ $index -eq $index2 ] ||
3873                         error "$fname MDT index mismatch $index != $index2"
3874         done
3875
3876         local failed=0
3877         for i in {1..250}; do
3878                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3879                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3880                         touch $fname  || error "touch $fname failed"
3881                         index2=$($LFS getstripe -m $fname)
3882                         if [[ $index != $index2 ]]; then
3883                                 failed=$((failed + 1))
3884                                 echo "$fname MDT index mismatch $index != $index2"
3885                         fi
3886                 done
3887         done
3888         echo "$failed MDT index mismatches"
3889         (( failed < 20 )) || error "MDT index mismatch $failed times"
3890
3891 }
3892 run_test 33h "temp file is located on the same MDT as target"
3893
3894 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3895 test_34a() {
3896         rm -f $DIR/f34
3897         $MCREATE $DIR/f34 || error "mcreate failed"
3898         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3899                 error "getstripe failed"
3900         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3901         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3902                 error "getstripe failed"
3903         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3904                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3905 }
3906 run_test 34a "truncate file that has not been opened ==========="
3907
3908 test_34b() {
3909         [ ! -f $DIR/f34 ] && test_34a
3910         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3911                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3912         $OPENFILE -f O_RDONLY $DIR/f34
3913         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3914                 error "getstripe failed"
3915         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3916                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3917 }
3918 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3919
3920 test_34c() {
3921         [ ! -f $DIR/f34 ] && test_34a
3922         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3923                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3924         $OPENFILE -f O_RDWR $DIR/f34
3925         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3926                 error "$LFS getstripe failed"
3927         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3928                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3929 }
3930 run_test 34c "O_RDWR opening file-with-size works =============="
3931
3932 test_34d() {
3933         [ ! -f $DIR/f34 ] && test_34a
3934         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3935                 error "dd failed"
3936         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3937                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3938         rm $DIR/f34
3939 }
3940 run_test 34d "write to sparse file ============================="
3941
3942 test_34e() {
3943         rm -f $DIR/f34e
3944         $MCREATE $DIR/f34e || error "mcreate failed"
3945         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3946         $CHECKSTAT -s 1000 $DIR/f34e ||
3947                 error "Size of $DIR/f34e not equal to 1000 bytes"
3948         $OPENFILE -f O_RDWR $DIR/f34e
3949         $CHECKSTAT -s 1000 $DIR/f34e ||
3950                 error "Size of $DIR/f34e not equal to 1000 bytes"
3951 }
3952 run_test 34e "create objects, some with size and some without =="
3953
3954 test_34f() { # bug 6242, 6243
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         SIZE34F=48000
3958         rm -f $DIR/f34f
3959         $MCREATE $DIR/f34f || error "mcreate failed"
3960         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3961         dd if=$DIR/f34f of=$TMP/f34f
3962         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3963         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3964         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3965         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3966         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3967 }
3968 run_test 34f "read from a file with no objects until EOF ======="
3969
3970 test_34g() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3974                 error "dd failed"
3975         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3976         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3977                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3978         cancel_lru_locks osc
3979         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3980                 error "wrong size after lock cancel"
3981
3982         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3983         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3984                 error "expanding truncate failed"
3985         cancel_lru_locks osc
3986         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3987                 error "wrong expanded size after lock cancel"
3988 }
3989 run_test 34g "truncate long file ==============================="
3990
3991 test_34h() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         local gid=10
3995         local sz=1000
3996
3997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3998         sync # Flush the cache so that multiop below does not block on cache
3999              # flush when getting the group lock
4000         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4001         MULTIPID=$!
4002
4003         # Since just timed wait is not good enough, let's do a sync write
4004         # that way we are sure enough time for a roundtrip + processing
4005         # passed + 2 seconds of extra margin.
4006         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4007         rm $DIR/${tfile}-1
4008         sleep 2
4009
4010         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4011                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4012                 kill -9 $MULTIPID
4013         fi
4014         wait $MULTIPID
4015         local nsz=`stat -c %s $DIR/$tfile`
4016         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4017 }
4018 run_test 34h "ftruncate file under grouplock should not block"
4019
4020 test_35a() {
4021         cp /bin/sh $DIR/f35a
4022         chmod 444 $DIR/f35a
4023         chown $RUNAS_ID $DIR/f35a
4024         $RUNAS $DIR/f35a && error || true
4025         rm $DIR/f35a
4026 }
4027 run_test 35a "exec file with mode 444 (should return and not leak)"
4028
4029 test_36a() {
4030         rm -f $DIR/f36
4031         utime $DIR/f36 || error "utime failed for MDS"
4032 }
4033 run_test 36a "MDS utime check (mknod, utime)"
4034
4035 test_36b() {
4036         echo "" > $DIR/f36
4037         utime $DIR/f36 || error "utime failed for OST"
4038 }
4039 run_test 36b "OST utime check (open, utime)"
4040
4041 test_36c() {
4042         rm -f $DIR/d36/f36
4043         test_mkdir $DIR/d36
4044         chown $RUNAS_ID $DIR/d36
4045         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4046 }
4047 run_test 36c "non-root MDS utime check (mknod, utime)"
4048
4049 test_36d() {
4050         [ ! -d $DIR/d36 ] && test_36c
4051         echo "" > $DIR/d36/f36
4052         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4053 }
4054 run_test 36d "non-root OST utime check (open, utime)"
4055
4056 test_36e() {
4057         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4058
4059         test_mkdir $DIR/$tdir
4060         touch $DIR/$tdir/$tfile
4061         $RUNAS utime $DIR/$tdir/$tfile &&
4062                 error "utime worked, expected failure" || true
4063 }
4064 run_test 36e "utime on non-owned file (should return error)"
4065
4066 subr_36fh() {
4067         local fl="$1"
4068         local LANG_SAVE=$LANG
4069         local LC_LANG_SAVE=$LC_LANG
4070         export LANG=C LC_LANG=C # for date language
4071
4072         DATESTR="Dec 20  2000"
4073         test_mkdir $DIR/$tdir
4074         lctl set_param fail_loc=$fl
4075         date; date +%s
4076         cp /etc/hosts $DIR/$tdir/$tfile
4077         sync & # write RPC generated with "current" inode timestamp, but delayed
4078         sleep 1
4079         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4080         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4081         cancel_lru_locks $OSC
4082         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4083         date; date +%s
4084         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4085                 echo "BEFORE: $LS_BEFORE" && \
4086                 echo "AFTER : $LS_AFTER" && \
4087                 echo "WANT  : $DATESTR" && \
4088                 error "$DIR/$tdir/$tfile timestamps changed" || true
4089
4090         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4091 }
4092
4093 test_36f() {
4094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4095
4096         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4097         subr_36fh "0x80000214"
4098 }
4099 run_test 36f "utime on file racing with OST BRW write =========="
4100
4101 test_36g() {
4102         remote_ost_nodsh && skip "remote OST with nodsh"
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4105                 skip "Need MDS version at least 2.12.51"
4106
4107         local fmd_max_age
4108         local fmd
4109         local facet="ost1"
4110         local tgt="obdfilter"
4111
4112         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4113
4114         test_mkdir $DIR/$tdir
4115         fmd_max_age=$(do_facet $facet \
4116                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4117                 head -n 1")
4118
4119         echo "FMD max age: ${fmd_max_age}s"
4120         touch $DIR/$tdir/$tfile
4121         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4122                 gawk '{cnt=cnt+$1}  END{print cnt}')
4123         echo "FMD before: $fmd"
4124         [[ $fmd == 0 ]] &&
4125                 error "FMD wasn't create by touch"
4126         sleep $((fmd_max_age + 12))
4127         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4128                 gawk '{cnt=cnt+$1}  END{print cnt}')
4129         echo "FMD after: $fmd"
4130         [[ $fmd == 0 ]] ||
4131                 error "FMD wasn't expired by ping"
4132 }
4133 run_test 36g "FMD cache expiry ====================="
4134
4135 test_36h() {
4136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4137
4138         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4139         subr_36fh "0x80000227"
4140 }
4141 run_test 36h "utime on file racing with OST BRW write =========="
4142
4143 test_36i() {
4144         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4145
4146         test_mkdir $DIR/$tdir
4147         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4148
4149         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4150         local new_mtime=$((mtime + 200))
4151
4152         #change Modify time of striped dir
4153         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4154                         error "change mtime failed"
4155
4156         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4157
4158         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4159 }
4160 run_test 36i "change mtime on striped directory"
4161
4162 # test_37 - duplicate with tests 32q 32r
4163
4164 test_38() {
4165         local file=$DIR/$tfile
4166         touch $file
4167         openfile -f O_DIRECTORY $file
4168         local RC=$?
4169         local ENOTDIR=20
4170         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4171         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4172 }
4173 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4174
4175 test_39a() { # was test_39
4176         touch $DIR/$tfile
4177         touch $DIR/${tfile}2
4178 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4179 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4180 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4181         sleep 2
4182         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4183         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4184                 echo "mtime"
4185                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4186                 echo "atime"
4187                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4188                 echo "ctime"
4189                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4190                 error "O_TRUNC didn't change timestamps"
4191         fi
4192 }
4193 run_test 39a "mtime changed on create"
4194
4195 test_39b() {
4196         test_mkdir -c1 $DIR/$tdir
4197         cp -p /etc/passwd $DIR/$tdir/fopen
4198         cp -p /etc/passwd $DIR/$tdir/flink
4199         cp -p /etc/passwd $DIR/$tdir/funlink
4200         cp -p /etc/passwd $DIR/$tdir/frename
4201         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4202
4203         sleep 1
4204         echo "aaaaaa" >> $DIR/$tdir/fopen
4205         echo "aaaaaa" >> $DIR/$tdir/flink
4206         echo "aaaaaa" >> $DIR/$tdir/funlink
4207         echo "aaaaaa" >> $DIR/$tdir/frename
4208
4209         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4210         local link_new=`stat -c %Y $DIR/$tdir/flink`
4211         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4212         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4213
4214         cat $DIR/$tdir/fopen > /dev/null
4215         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4216         rm -f $DIR/$tdir/funlink2
4217         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4221                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4222                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4223                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4224
4225                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4226                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4227                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4228                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4229
4230                 cancel_lru_locks $OSC
4231                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4232         done
4233 }
4234 run_test 39b "mtime change on open, link, unlink, rename  ======"
4235
4236 # this should be set to past
4237 TEST_39_MTIME=`date -d "1 year ago" +%s`
4238
4239 # bug 11063
4240 test_39c() {
4241         touch $DIR1/$tfile
4242         sleep 2
4243         local mtime0=`stat -c %Y $DIR1/$tfile`
4244
4245         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4246         local mtime1=`stat -c %Y $DIR1/$tfile`
4247         [ "$mtime1" = $TEST_39_MTIME ] || \
4248                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4249
4250         local d1=`date +%s`
4251         echo hello >> $DIR1/$tfile
4252         local d2=`date +%s`
4253         local mtime2=`stat -c %Y $DIR1/$tfile`
4254         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4255                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4256
4257         mv $DIR1/$tfile $DIR1/$tfile-1
4258
4259         for (( i=0; i < 2; i++ )) ; do
4260                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4261                 [ "$mtime2" = "$mtime3" ] || \
4262                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4263
4264                 cancel_lru_locks $OSC
4265                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4266         done
4267 }
4268 run_test 39c "mtime change on rename ==========================="
4269
4270 # bug 21114
4271 test_39d() {
4272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4273
4274         touch $DIR1/$tfile
4275         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4276
4277         for (( i=0; i < 2; i++ )) ; do
4278                 local mtime=`stat -c %Y $DIR1/$tfile`
4279                 [ $mtime = $TEST_39_MTIME ] || \
4280                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4281
4282                 cancel_lru_locks $OSC
4283                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4284         done
4285 }
4286 run_test 39d "create, utime, stat =============================="
4287
4288 # bug 21114
4289 test_39e() {
4290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4291
4292         touch $DIR1/$tfile
4293         local mtime1=`stat -c %Y $DIR1/$tfile`
4294
4295         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4296
4297         for (( i=0; i < 2; i++ )) ; do
4298                 local mtime2=`stat -c %Y $DIR1/$tfile`
4299                 [ $mtime2 = $TEST_39_MTIME ] || \
4300                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4301
4302                 cancel_lru_locks $OSC
4303                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4304         done
4305 }
4306 run_test 39e "create, stat, utime, stat ========================"
4307
4308 # bug 21114
4309 test_39f() {
4310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4311
4312         touch $DIR1/$tfile
4313         mtime1=`stat -c %Y $DIR1/$tfile`
4314
4315         sleep 2
4316         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4317
4318         for (( i=0; i < 2; i++ )) ; do
4319                 local mtime2=`stat -c %Y $DIR1/$tfile`
4320                 [ $mtime2 = $TEST_39_MTIME ] || \
4321                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4322
4323                 cancel_lru_locks $OSC
4324                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4325         done
4326 }
4327 run_test 39f "create, stat, sleep, utime, stat ================="
4328
4329 # bug 11063
4330 test_39g() {
4331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4332
4333         echo hello >> $DIR1/$tfile
4334         local mtime1=`stat -c %Y $DIR1/$tfile`
4335
4336         sleep 2
4337         chmod o+r $DIR1/$tfile
4338
4339         for (( i=0; i < 2; i++ )) ; do
4340                 local mtime2=`stat -c %Y $DIR1/$tfile`
4341                 [ "$mtime1" = "$mtime2" ] || \
4342                         error "lost mtime: $mtime2, should be $mtime1"
4343
4344                 cancel_lru_locks $OSC
4345                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4346         done
4347 }
4348 run_test 39g "write, chmod, stat ==============================="
4349
4350 # bug 11063
4351 test_39h() {
4352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4353
4354         touch $DIR1/$tfile
4355         sleep 1
4356
4357         local d1=`date`
4358         echo hello >> $DIR1/$tfile
4359         local mtime1=`stat -c %Y $DIR1/$tfile`
4360
4361         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4362         local d2=`date`
4363         if [ "$d1" != "$d2" ]; then
4364                 echo "write and touch not within one second"
4365         else
4366                 for (( i=0; i < 2; i++ )) ; do
4367                         local mtime2=`stat -c %Y $DIR1/$tfile`
4368                         [ "$mtime2" = $TEST_39_MTIME ] || \
4369                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4370
4371                         cancel_lru_locks $OSC
4372                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4373                 done
4374         fi
4375 }
4376 run_test 39h "write, utime within one second, stat ============="
4377
4378 test_39i() {
4379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4380
4381         touch $DIR1/$tfile
4382         sleep 1
4383
4384         echo hello >> $DIR1/$tfile
4385         local mtime1=`stat -c %Y $DIR1/$tfile`
4386
4387         mv $DIR1/$tfile $DIR1/$tfile-1
4388
4389         for (( i=0; i < 2; i++ )) ; do
4390                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4391
4392                 [ "$mtime1" = "$mtime2" ] || \
4393                         error "lost mtime: $mtime2, should be $mtime1"
4394
4395                 cancel_lru_locks $OSC
4396                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4397         done
4398 }
4399 run_test 39i "write, rename, stat =============================="
4400
4401 test_39j() {
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403
4404         start_full_debug_logging
4405         touch $DIR1/$tfile
4406         sleep 1
4407
4408         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4409         lctl set_param fail_loc=0x80000412
4410         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4411                 error "multiop failed"
4412         local multipid=$!
4413         local mtime1=`stat -c %Y $DIR1/$tfile`
4414
4415         mv $DIR1/$tfile $DIR1/$tfile-1
4416
4417         kill -USR1 $multipid
4418         wait $multipid || error "multiop close failed"
4419
4420         for (( i=0; i < 2; i++ )) ; do
4421                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4422                 [ "$mtime1" = "$mtime2" ] ||
4423                         error "mtime is lost on close: $mtime2, " \
4424                               "should be $mtime1"
4425
4426                 cancel_lru_locks
4427                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4428         done
4429         lctl set_param fail_loc=0
4430         stop_full_debug_logging
4431 }
4432 run_test 39j "write, rename, close, stat ======================="
4433
4434 test_39k() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         touch $DIR1/$tfile
4438         sleep 1
4439
4440         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4441         local multipid=$!
4442         local mtime1=`stat -c %Y $DIR1/$tfile`
4443
4444         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4445
4446         kill -USR1 $multipid
4447         wait $multipid || error "multiop close failed"
4448
4449         for (( i=0; i < 2; i++ )) ; do
4450                 local mtime2=`stat -c %Y $DIR1/$tfile`
4451
4452                 [ "$mtime2" = $TEST_39_MTIME ] || \
4453                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4454
4455                 cancel_lru_locks
4456                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4457         done
4458 }
4459 run_test 39k "write, utime, close, stat ========================"
4460
4461 # this should be set to future
4462 TEST_39_ATIME=`date -d "1 year" +%s`
4463
4464 test_39l() {
4465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4466         remote_mds_nodsh && skip "remote MDS with nodsh"
4467
4468         local atime_diff=$(do_facet $SINGLEMDS \
4469                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4470         rm -rf $DIR/$tdir
4471         mkdir -p $DIR/$tdir
4472
4473         # test setting directory atime to future
4474         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4475         local atime=$(stat -c %X $DIR/$tdir)
4476         [ "$atime" = $TEST_39_ATIME ] ||
4477                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4478
4479         # test setting directory atime from future to now
4480         local now=$(date +%s)
4481         touch -a -d @$now $DIR/$tdir
4482
4483         atime=$(stat -c %X $DIR/$tdir)
4484         [ "$atime" -eq "$now"  ] ||
4485                 error "atime is not updated from future: $atime, $now"
4486
4487         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4488         sleep 3
4489
4490         # test setting directory atime when now > dir atime + atime_diff
4491         local d1=$(date +%s)
4492         ls $DIR/$tdir
4493         local d2=$(date +%s)
4494         cancel_lru_locks mdc
4495         atime=$(stat -c %X $DIR/$tdir)
4496         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4497                 error "atime is not updated  : $atime, should be $d2"
4498
4499         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4500         sleep 3
4501
4502         # test not setting directory atime when now < dir atime + atime_diff
4503         ls $DIR/$tdir
4504         cancel_lru_locks mdc
4505         atime=$(stat -c %X $DIR/$tdir)
4506         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4507                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4508
4509         do_facet $SINGLEMDS \
4510                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4511 }
4512 run_test 39l "directory atime update ==========================="
4513
4514 test_39m() {
4515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4516
4517         touch $DIR1/$tfile
4518         sleep 2
4519         local far_past_mtime=$(date -d "May 29 1953" +%s)
4520         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4521
4522         touch -m -d @$far_past_mtime $DIR1/$tfile
4523         touch -a -d @$far_past_atime $DIR1/$tfile
4524
4525         for (( i=0; i < 2; i++ )) ; do
4526                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4527                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4528                         error "atime or mtime set incorrectly"
4529
4530                 cancel_lru_locks $OSC
4531                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4532         done
4533 }
4534 run_test 39m "test atime and mtime before 1970"
4535
4536 test_39n() { # LU-3832
4537         remote_mds_nodsh && skip "remote MDS with nodsh"
4538
4539         local atime_diff=$(do_facet $SINGLEMDS \
4540                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4541         local atime0
4542         local atime1
4543         local atime2
4544
4545         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4546
4547         rm -rf $DIR/$tfile
4548         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4549         atime0=$(stat -c %X $DIR/$tfile)
4550
4551         sleep 5
4552         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4553         atime1=$(stat -c %X $DIR/$tfile)
4554
4555         sleep 5
4556         cancel_lru_locks mdc
4557         cancel_lru_locks osc
4558         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4559         atime2=$(stat -c %X $DIR/$tfile)
4560
4561         do_facet $SINGLEMDS \
4562                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4563
4564         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4565         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4566 }
4567 run_test 39n "check that O_NOATIME is honored"
4568
4569 test_39o() {
4570         TESTDIR=$DIR/$tdir/$tfile
4571         [ -e $TESTDIR ] && rm -rf $TESTDIR
4572         mkdir -p $TESTDIR
4573         cd $TESTDIR
4574         links1=2
4575         ls
4576         mkdir a b
4577         ls
4578         links2=$(stat -c %h .)
4579         [ $(($links1 + 2)) != $links2 ] &&
4580                 error "wrong links count $(($links1 + 2)) != $links2"
4581         rmdir b
4582         links3=$(stat -c %h .)
4583         [ $(($links1 + 1)) != $links3 ] &&
4584                 error "wrong links count $links1 != $links3"
4585         return 0
4586 }
4587 run_test 39o "directory cached attributes updated after create"
4588
4589 test_39p() {
4590         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4591
4592         local MDTIDX=1
4593         TESTDIR=$DIR/$tdir/$tdir
4594         [ -e $TESTDIR ] && rm -rf $TESTDIR
4595         test_mkdir -p $TESTDIR
4596         cd $TESTDIR
4597         links1=2
4598         ls
4599         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4600         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4601         ls
4602         links2=$(stat -c %h .)
4603         [ $(($links1 + 2)) != $links2 ] &&
4604                 error "wrong links count $(($links1 + 2)) != $links2"
4605         rmdir remote_dir2
4606         links3=$(stat -c %h .)
4607         [ $(($links1 + 1)) != $links3 ] &&
4608                 error "wrong links count $links1 != $links3"
4609         return 0
4610 }
4611 run_test 39p "remote directory cached attributes updated after create ========"
4612
4613 test_39r() {
4614         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4615                 skip "no atime update on old OST"
4616         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4617                 skip_env "ldiskfs only test"
4618         fi
4619
4620         local saved_adiff
4621         saved_adiff=$(do_facet ost1 \
4622                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4623         stack_trap "do_facet ost1 \
4624                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4625
4626         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4627
4628         $LFS setstripe -i 0 $DIR/$tfile
4629         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4630                 error "can't write initial file"
4631         cancel_lru_locks osc
4632
4633         # exceed atime_diff and access file
4634         sleep 6
4635         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4636                 error "can't udpate atime"
4637
4638         local atime_cli=$(stat -c %X $DIR/$tfile)
4639         echo "client atime: $atime_cli"
4640         # allow atime update to be written to device
4641         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4642         sleep 5
4643
4644         local ostdev=$(ostdevname 1)
4645         local fid=($(lfs getstripe -y $DIR/$tfile |
4646                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4647         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4648         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4649
4650         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4651         local atime_ost=$(do_facet ost1 "$cmd" |&
4652                           awk -F'[: ]' '/atime:/ { print $4 }')
4653         (( atime_cli == atime_ost )) ||
4654                 error "atime on client $atime_cli != ost $atime_ost"
4655 }
4656 run_test 39r "lazy atime update on OST"
4657
4658 test_39q() { # LU-8041
4659         local testdir=$DIR/$tdir
4660         mkdir -p $testdir
4661         multiop_bg_pause $testdir D_c || error "multiop failed"
4662         local multipid=$!
4663         cancel_lru_locks mdc
4664         kill -USR1 $multipid
4665         local atime=$(stat -c %X $testdir)
4666         [ "$atime" -ne 0 ] || error "atime is zero"
4667 }
4668 run_test 39q "close won't zero out atime"
4669
4670 test_40() {
4671         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4672         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4673                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4674         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4675                 error "$tfile is not 4096 bytes in size"
4676 }
4677 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4678
4679 test_41() {
4680         # bug 1553
4681         small_write $DIR/f41 18
4682 }
4683 run_test 41 "test small file write + fstat ====================="
4684
4685 count_ost_writes() {
4686         lctl get_param -n ${OSC}.*.stats |
4687                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4688                         END { printf("%0.0f", writes) }'
4689 }
4690
4691 # decent default
4692 WRITEBACK_SAVE=500
4693 DIRTY_RATIO_SAVE=40
4694 MAX_DIRTY_RATIO=50
4695 BG_DIRTY_RATIO_SAVE=10
4696 MAX_BG_DIRTY_RATIO=25
4697
4698 start_writeback() {
4699         trap 0
4700         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4701         # dirty_ratio, dirty_background_ratio
4702         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4703                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4704                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4705                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4706         else
4707                 # if file not here, we are a 2.4 kernel
4708                 kill -CONT `pidof kupdated`
4709         fi
4710 }
4711
4712 stop_writeback() {
4713         # setup the trap first, so someone cannot exit the test at the
4714         # exact wrong time and mess up a machine
4715         trap start_writeback EXIT
4716         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4717         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4718                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4719                 sysctl -w vm.dirty_writeback_centisecs=0
4720                 sysctl -w vm.dirty_writeback_centisecs=0
4721                 # save and increase /proc/sys/vm/dirty_ratio
4722                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4723                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4724                 # save and increase /proc/sys/vm/dirty_background_ratio
4725                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4726                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4727         else
4728                 # if file not here, we are a 2.4 kernel
4729                 kill -STOP `pidof kupdated`
4730         fi
4731 }
4732
4733 # ensure that all stripes have some grant before we test client-side cache
4734 setup_test42() {
4735         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4736                 dd if=/dev/zero of=$i bs=4k count=1
4737                 rm $i
4738         done
4739 }
4740
4741 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4742 # file truncation, and file removal.
4743 test_42a() {
4744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4745
4746         setup_test42
4747         cancel_lru_locks $OSC
4748         stop_writeback
4749         sync; sleep 1; sync # just to be safe
4750         BEFOREWRITES=`count_ost_writes`
4751         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4752         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4753         AFTERWRITES=`count_ost_writes`
4754         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4755                 error "$BEFOREWRITES < $AFTERWRITES"
4756         start_writeback
4757 }
4758 run_test 42a "ensure that we don't flush on close"
4759
4760 test_42b() {
4761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4762
4763         setup_test42
4764         cancel_lru_locks $OSC
4765         stop_writeback
4766         sync
4767         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4768         BEFOREWRITES=$(count_ost_writes)
4769         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4770         AFTERWRITES=$(count_ost_writes)
4771         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4772                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4773         fi
4774         BEFOREWRITES=$(count_ost_writes)
4775         sync || error "sync: $?"
4776         AFTERWRITES=$(count_ost_writes)
4777         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4778                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4779         fi
4780         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4781         start_writeback
4782         return 0
4783 }
4784 run_test 42b "test destroy of file with cached dirty data ======"
4785
4786 # if these tests just want to test the effect of truncation,
4787 # they have to be very careful.  consider:
4788 # - the first open gets a {0,EOF}PR lock
4789 # - the first write conflicts and gets a {0, count-1}PW
4790 # - the rest of the writes are under {count,EOF}PW
4791 # - the open for truncate tries to match a {0,EOF}PR
4792 #   for the filesize and cancels the PWs.
4793 # any number of fixes (don't get {0,EOF} on open, match
4794 # composite locks, do smarter file size management) fix
4795 # this, but for now we want these tests to verify that
4796 # the cancellation with truncate intent works, so we
4797 # start the file with a full-file pw lock to match against
4798 # until the truncate.
4799 trunc_test() {
4800         test=$1
4801         file=$DIR/$test
4802         offset=$2
4803         cancel_lru_locks $OSC
4804         stop_writeback
4805         # prime the file with 0,EOF PW to match
4806         touch $file
4807         $TRUNCATE $file 0
4808         sync; sync
4809         # now the real test..
4810         dd if=/dev/zero of=$file bs=1024 count=100
4811         BEFOREWRITES=`count_ost_writes`
4812         $TRUNCATE $file $offset
4813         cancel_lru_locks $OSC
4814         AFTERWRITES=`count_ost_writes`
4815         start_writeback
4816 }
4817
4818 test_42c() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         trunc_test 42c 1024
4822         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4823                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4824         rm $file
4825 }
4826 run_test 42c "test partial truncate of file with cached dirty data"
4827
4828 test_42d() {
4829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4830
4831         trunc_test 42d 0
4832         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4833                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4834         rm $file
4835 }
4836 run_test 42d "test complete truncate of file with cached dirty data"
4837
4838 test_42e() { # bug22074
4839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4840
4841         local TDIR=$DIR/${tdir}e
4842         local pages=16 # hardcoded 16 pages, don't change it.
4843         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4844         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4845         local max_dirty_mb
4846         local warmup_files
4847
4848         test_mkdir $DIR/${tdir}e
4849         $LFS setstripe -c 1 $TDIR
4850         createmany -o $TDIR/f $files
4851
4852         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4853
4854         # we assume that with $OSTCOUNT files, at least one of them will
4855         # be allocated on OST0.
4856         warmup_files=$((OSTCOUNT * max_dirty_mb))
4857         createmany -o $TDIR/w $warmup_files
4858
4859         # write a large amount of data into one file and sync, to get good
4860         # avail_grant number from OST.
4861         for ((i=0; i<$warmup_files; i++)); do
4862                 idx=$($LFS getstripe -i $TDIR/w$i)
4863                 [ $idx -ne 0 ] && continue
4864                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4865                 break
4866         done
4867         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4868         sync
4869         $LCTL get_param $proc_osc0/cur_dirty_bytes
4870         $LCTL get_param $proc_osc0/cur_grant_bytes
4871
4872         # create as much dirty pages as we can while not to trigger the actual
4873         # RPCs directly. but depends on the env, VFS may trigger flush during this
4874         # period, hopefully we are good.
4875         for ((i=0; i<$warmup_files; i++)); do
4876                 idx=$($LFS getstripe -i $TDIR/w$i)
4877                 [ $idx -ne 0 ] && continue
4878                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4879         done
4880         $LCTL get_param $proc_osc0/cur_dirty_bytes
4881         $LCTL get_param $proc_osc0/cur_grant_bytes
4882
4883         # perform the real test
4884         $LCTL set_param $proc_osc0/rpc_stats 0
4885         for ((;i<$files; i++)); do
4886                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4887                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4888         done
4889         sync
4890         $LCTL get_param $proc_osc0/rpc_stats
4891
4892         local percent=0
4893         local have_ppr=false
4894         $LCTL get_param $proc_osc0/rpc_stats |
4895                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4896                         # skip lines until we are at the RPC histogram data
4897                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4898                         $have_ppr || continue
4899
4900                         # we only want the percent stat for < 16 pages
4901                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4902
4903                         percent=$((percent + WPCT))
4904                         if [[ $percent -gt 15 ]]; then
4905                                 error "less than 16-pages write RPCs" \
4906                                       "$percent% > 15%"
4907                                 break
4908                         fi
4909                 done
4910         rm -rf $TDIR
4911 }
4912 run_test 42e "verify sub-RPC writes are not done synchronously"
4913
4914 test_43A() { # was test_43
4915         test_mkdir $DIR/$tdir
4916         cp -p /bin/ls $DIR/$tdir/$tfile
4917         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4918         pid=$!
4919         # give multiop a chance to open
4920         sleep 1
4921
4922         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4923         kill -USR1 $pid
4924         # Wait for multiop to exit
4925         wait $pid
4926 }
4927 run_test 43A "execution of file opened for write should return -ETXTBSY"
4928
4929 test_43a() {
4930         test_mkdir $DIR/$tdir
4931         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4932         $DIR/$tdir/sleep 60 &
4933         SLEEP_PID=$!
4934         # Make sure exec of $tdir/sleep wins race with truncate
4935         sleep 1
4936         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4937         kill $SLEEP_PID
4938 }
4939 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4940
4941 test_43b() {
4942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4943
4944         test_mkdir $DIR/$tdir
4945         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4946         $DIR/$tdir/sleep 60 &
4947         SLEEP_PID=$!
4948         # Make sure exec of $tdir/sleep wins race with truncate
4949         sleep 1
4950         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4951         kill $SLEEP_PID
4952 }
4953 run_test 43b "truncate of file being executed should return -ETXTBSY"
4954
4955 test_43c() {
4956         local testdir="$DIR/$tdir"
4957         test_mkdir $testdir
4958         cp $SHELL $testdir/
4959         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4960                 ( cd $testdir && md5sum -c )
4961 }
4962 run_test 43c "md5sum of copy into lustre"
4963
4964 test_44A() { # was test_44
4965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4966
4967         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4968         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4969 }
4970 run_test 44A "zero length read from a sparse stripe"
4971
4972 test_44a() {
4973         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4974                 awk '{ print $2 }')
4975         [ -z "$nstripe" ] && skip "can't get stripe info"
4976         [[ $nstripe -gt $OSTCOUNT ]] &&
4977                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4978
4979         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4980                 awk '{ print $2 }')
4981         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4982                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4983                         awk '{ print $2 }')
4984         fi
4985
4986         OFFSETS="0 $((stride/2)) $((stride-1))"
4987         for offset in $OFFSETS; do
4988                 for i in $(seq 0 $((nstripe-1))); do
4989                         local GLOBALOFFSETS=""
4990                         # size in Bytes
4991                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4992                         local myfn=$DIR/d44a-$size
4993                         echo "--------writing $myfn at $size"
4994                         ll_sparseness_write $myfn $size ||
4995                                 error "ll_sparseness_write"
4996                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4997                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4998                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4999
5000                         for j in $(seq 0 $((nstripe-1))); do
5001                                 # size in Bytes
5002                                 size=$((((j + $nstripe )*$stride + $offset)))
5003                                 ll_sparseness_write $myfn $size ||
5004                                         error "ll_sparseness_write"
5005                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5006                         done
5007                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5008                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5009                         rm -f $myfn
5010                 done
5011         done
5012 }
5013 run_test 44a "test sparse pwrite ==============================="
5014
5015 dirty_osc_total() {
5016         tot=0
5017         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5018                 tot=$(($tot + $d))
5019         done
5020         echo $tot
5021 }
5022 do_dirty_record() {
5023         before=`dirty_osc_total`
5024         echo executing "\"$*\""
5025         eval $*
5026         after=`dirty_osc_total`
5027         echo before $before, after $after
5028 }
5029 test_45() {
5030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5031
5032         f="$DIR/f45"
5033         # Obtain grants from OST if it supports it
5034         echo blah > ${f}_grant
5035         stop_writeback
5036         sync
5037         do_dirty_record "echo blah > $f"
5038         [[ $before -eq $after ]] && error "write wasn't cached"
5039         do_dirty_record "> $f"
5040         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5041         do_dirty_record "echo blah > $f"
5042         [[ $before -eq $after ]] && error "write wasn't cached"
5043         do_dirty_record "sync"
5044         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5045         do_dirty_record "echo blah > $f"
5046         [[ $before -eq $after ]] && error "write wasn't cached"
5047         do_dirty_record "cancel_lru_locks osc"
5048         [[ $before -gt $after ]] ||
5049                 error "lock cancellation didn't lower dirty count"
5050         start_writeback
5051 }
5052 run_test 45 "osc io page accounting ============================"
5053
5054 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5055 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5056 # objects offset and an assert hit when an rpc was built with 1023's mapped
5057 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5058 test_46() {
5059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5060
5061         f="$DIR/f46"
5062         stop_writeback
5063         sync
5064         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5065         sync
5066         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5067         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5068         sync
5069         start_writeback
5070 }
5071 run_test 46 "dirtying a previously written page ================"
5072
5073 # test_47 is removed "Device nodes check" is moved to test_28
5074
5075 test_48a() { # bug 2399
5076         [ "$mds1_FSTYPE" = "zfs" ] &&
5077         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5078                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5079
5080         test_mkdir $DIR/$tdir
5081         cd $DIR/$tdir
5082         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5083         test_mkdir $DIR/$tdir
5084         touch foo || error "'touch foo' failed after recreating cwd"
5085         test_mkdir bar
5086         touch .foo || error "'touch .foo' failed after recreating cwd"
5087         test_mkdir .bar
5088         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5089         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5090         cd . || error "'cd .' failed after recreating cwd"
5091         mkdir . && error "'mkdir .' worked after recreating cwd"
5092         rmdir . && error "'rmdir .' worked after recreating cwd"
5093         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5094         cd .. || error "'cd ..' failed after recreating cwd"
5095 }
5096 run_test 48a "Access renamed working dir (should return errors)="
5097
5098 test_48b() { # bug 2399
5099         rm -rf $DIR/$tdir
5100         test_mkdir $DIR/$tdir
5101         cd $DIR/$tdir
5102         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5103         touch foo && error "'touch foo' worked after removing cwd"
5104         mkdir foo && error "'mkdir foo' worked after removing cwd"
5105         touch .foo && error "'touch .foo' worked after removing cwd"
5106         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5107         ls . > /dev/null && error "'ls .' worked after removing cwd"
5108         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5109         mkdir . && error "'mkdir .' worked after removing cwd"
5110         rmdir . && error "'rmdir .' worked after removing cwd"
5111         ln -s . foo && error "'ln -s .' worked after removing cwd"
5112         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5113 }
5114 run_test 48b "Access removed working dir (should return errors)="
5115
5116 test_48c() { # bug 2350
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE touch foo && error "touch foo worked after removing cwd"
5124         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5125         touch .foo && error "touch .foo worked after removing cwd"
5126         mkdir .foo && error "mkdir .foo worked after removing cwd"
5127         $TRACE ls . && error "'ls .' worked after removing cwd"
5128         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5129         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5130         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5131         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5132         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5133 }
5134 run_test 48c "Access removed working subdir (should return errors)"
5135
5136 test_48d() { # bug 2350
5137         #lctl set_param debug=-1
5138         #set -vx
5139         rm -rf $DIR/$tdir
5140         test_mkdir -p $DIR/$tdir/dir
5141         cd $DIR/$tdir/dir
5142         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5143         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5144         $TRACE touch foo && error "'touch foo' worked after removing parent"
5145         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5146         touch .foo && error "'touch .foo' worked after removing parent"
5147         mkdir .foo && error "mkdir .foo worked after removing parent"
5148         $TRACE ls . && error "'ls .' worked after removing parent"
5149         $TRACE ls .. && error "'ls ..' worked after removing parent"
5150         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5151         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5152         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5153         true
5154 }
5155 run_test 48d "Access removed parent subdir (should return errors)"
5156
5157 test_48e() { # bug 4134
5158         #lctl set_param debug=-1
5159         #set -vx
5160         rm -rf $DIR/$tdir
5161         test_mkdir -p $DIR/$tdir/dir
5162         cd $DIR/$tdir/dir
5163         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5164         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5165         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5166         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5167         # On a buggy kernel addition of "touch foo" after cd .. will
5168         # produce kernel oops in lookup_hash_it
5169         touch ../foo && error "'cd ..' worked after recreate parent"
5170         cd $DIR
5171         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5172 }
5173 run_test 48e "Access to recreated parent subdir (should return errors)"
5174
5175 test_48f() {
5176         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5177                 skip "need MDS >= 2.13.55"
5178         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5179         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5180                 skip "needs different host for mdt1 mdt2"
5181         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5182
5183         $LFS mkdir -i0 $DIR/$tdir
5184         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5185
5186         for d in sub1 sub2 sub3; do
5187                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5188                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5189                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5190         done
5191
5192         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5193 }
5194 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5195
5196 test_49() { # LU-1030
5197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5198         remote_ost_nodsh && skip "remote OST with nodsh"
5199
5200         # get ost1 size - $FSNAME-OST0000
5201         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5202                 awk '{ print $4 }')
5203         # write 800M at maximum
5204         [[ $ost1_size -lt 2 ]] && ost1_size=2
5205         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5206
5207         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5209         local dd_pid=$!
5210
5211         # change max_pages_per_rpc while writing the file
5212         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5213         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5214         # loop until dd process exits
5215         while ps ax -opid | grep -wq $dd_pid; do
5216                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5217                 sleep $((RANDOM % 5 + 1))
5218         done
5219         # restore original max_pages_per_rpc
5220         $LCTL set_param $osc1_mppc=$orig_mppc
5221         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5222 }
5223 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5224
5225 test_50() {
5226         # bug 1485
5227         test_mkdir $DIR/$tdir
5228         cd $DIR/$tdir
5229         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5230 }
5231 run_test 50 "special situations: /proc symlinks  ==============="
5232
5233 test_51a() {    # was test_51
5234         # bug 1516 - create an empty entry right after ".." then split dir
5235         test_mkdir -c1 $DIR/$tdir
5236         touch $DIR/$tdir/foo
5237         $MCREATE $DIR/$tdir/bar
5238         rm $DIR/$tdir/foo
5239         createmany -m $DIR/$tdir/longfile 201
5240         FNUM=202
5241         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5242                 $MCREATE $DIR/$tdir/longfile$FNUM
5243                 FNUM=$(($FNUM + 1))
5244                 echo -n "+"
5245         done
5246         echo
5247         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5248 }
5249 run_test 51a "special situations: split htree with empty entry =="
5250
5251 cleanup_print_lfs_df () {
5252         trap 0
5253         $LFS df
5254         $LFS df -i
5255 }
5256
5257 test_51b() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259
5260         local dir=$DIR/$tdir
5261         local nrdirs=$((65536 + 100))
5262
5263         # cleanup the directory
5264         rm -fr $dir
5265
5266         test_mkdir -c1 $dir
5267
5268         $LFS df
5269         $LFS df -i
5270         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5271         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5272         [[ $numfree -lt $nrdirs ]] &&
5273                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5274
5275         # need to check free space for the directories as well
5276         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5277         numfree=$(( blkfree / $(fs_inode_ksize) ))
5278         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5279
5280         trap cleanup_print_lfs_df EXIT
5281
5282         # create files
5283         createmany -d $dir/d $nrdirs || {
5284                 unlinkmany $dir/d $nrdirs
5285                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5286         }
5287
5288         # really created :
5289         nrdirs=$(ls -U $dir | wc -l)
5290
5291         # unlink all but 100 subdirectories, then check it still works
5292         local left=100
5293         local delete=$((nrdirs - left))
5294
5295         $LFS df
5296         $LFS df -i
5297
5298         # for ldiskfs the nlink count should be 1, but this is OSD specific
5299         # and so this is listed for informational purposes only
5300         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5301         unlinkmany -d $dir/d $delete ||
5302                 error "unlink of first $delete subdirs failed"
5303
5304         echo "nlink between: $(stat -c %h $dir)"
5305         local found=$(ls -U $dir | wc -l)
5306         [ $found -ne $left ] &&
5307                 error "can't find subdirs: found only $found, expected $left"
5308
5309         unlinkmany -d $dir/d $delete $left ||
5310                 error "unlink of second $left subdirs failed"
5311         # regardless of whether the backing filesystem tracks nlink accurately
5312         # or not, the nlink count shouldn't be more than "." and ".." here
5313         local after=$(stat -c %h $dir)
5314         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5315                 echo "nlink after: $after"
5316
5317         cleanup_print_lfs_df
5318 }
5319 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5320
5321 test_51d() {
5322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5323         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5324
5325         test_mkdir $DIR/$tdir
5326         createmany -o $DIR/$tdir/t- 1000
5327         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5328         for N in $(seq 0 $((OSTCOUNT - 1))); do
5329                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5330                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5331                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5332                         '($1 == '$N') { objs += 1 } \
5333                         END { printf("%0.0f", objs) }')
5334                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5335         done
5336         unlinkmany $DIR/$tdir/t- 1000
5337
5338         NLAST=0
5339         for N in $(seq 1 $((OSTCOUNT - 1))); do
5340                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5341                         error "OST $N has less objects vs OST $NLAST" \
5342                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5343                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5344                         error "OST $N has less objects vs OST $NLAST" \
5345                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5346
5347                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5348                         error "OST $N has less #0 objects vs OST $NLAST" \
5349                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5350                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5351                         error "OST $N has less #0 objects vs OST $NLAST" \
5352                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5353                 NLAST=$N
5354         done
5355         rm -f $TMP/$tfile
5356 }
5357 run_test 51d "check object distribution"
5358
5359 test_51e() {
5360         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5361                 skip_env "ldiskfs only test"
5362         fi
5363
5364         test_mkdir -c1 $DIR/$tdir
5365         test_mkdir -c1 $DIR/$tdir/d0
5366
5367         touch $DIR/$tdir/d0/foo
5368         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5369                 error "file exceed 65000 nlink limit!"
5370         unlinkmany $DIR/$tdir/d0/f- 65001
5371         return 0
5372 }
5373 run_test 51e "check file nlink limit"
5374
5375 test_51f() {
5376         test_mkdir $DIR/$tdir
5377
5378         local max=100000
5379         local ulimit_old=$(ulimit -n)
5380         local spare=20 # number of spare fd's for scripts/libraries, etc.
5381         local mdt=$($LFS getstripe -m $DIR/$tdir)
5382         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5383
5384         echo "MDT$mdt numfree=$numfree, max=$max"
5385         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5386         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5387                 while ! ulimit -n $((numfree + spare)); do
5388                         numfree=$((numfree * 3 / 4))
5389                 done
5390                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5391         else
5392                 echo "left ulimit at $ulimit_old"
5393         fi
5394
5395         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5396                 unlinkmany $DIR/$tdir/f $numfree
5397                 error "create+open $numfree files in $DIR/$tdir failed"
5398         }
5399         ulimit -n $ulimit_old
5400
5401         # if createmany exits at 120s there will be fewer than $numfree files
5402         unlinkmany $DIR/$tdir/f $numfree || true
5403 }
5404 run_test 51f "check many open files limit"
5405
5406 test_52a() {
5407         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5408         test_mkdir $DIR/$tdir
5409         touch $DIR/$tdir/foo
5410         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5411         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5412         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5413         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5414         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5415                                         error "link worked"
5416         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5417         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5418         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5419                                                      error "lsattr"
5420         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5421         cp -r $DIR/$tdir $TMP/
5422         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5423 }
5424 run_test 52a "append-only flag test (should return errors)"
5425
5426 test_52b() {
5427         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5428         test_mkdir $DIR/$tdir
5429         touch $DIR/$tdir/foo
5430         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5431         cat test > $DIR/$tdir/foo && error "cat test worked"
5432         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5433         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5434         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5435                                         error "link worked"
5436         echo foo >> $DIR/$tdir/foo && error "echo worked"
5437         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5438         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5439         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5440         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5441                                                         error "lsattr"
5442         chattr -i $DIR/$tdir/foo || error "chattr failed"
5443
5444         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5445 }
5446 run_test 52b "immutable flag test (should return errors) ======="
5447
5448 test_53() {
5449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5450         remote_mds_nodsh && skip "remote MDS with nodsh"
5451         remote_ost_nodsh && skip "remote OST with nodsh"
5452
5453         local param
5454         local param_seq
5455         local ostname
5456         local mds_last
5457         local mds_last_seq
5458         local ost_last
5459         local ost_last_seq
5460         local ost_last_id
5461         local ostnum
5462         local node
5463         local found=false
5464         local support_last_seq=true
5465
5466         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5467                 support_last_seq=false
5468
5469         # only test MDT0000
5470         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5471         local value
5472         for value in $(do_facet $SINGLEMDS \
5473                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5474                 param=$(echo ${value[0]} | cut -d "=" -f1)
5475                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5476
5477                 if $support_last_seq; then
5478                         param_seq=$(echo $param |
5479                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5480                         mds_last_seq=$(do_facet $SINGLEMDS \
5481                                        $LCTL get_param -n $param_seq)
5482                 fi
5483                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5484
5485                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5486                 node=$(facet_active_host ost$((ostnum+1)))
5487                 param="obdfilter.$ostname.last_id"
5488                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5489                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5490                         ost_last_id=$ost_last
5491
5492                         if $support_last_seq; then
5493                                 ost_last_id=$(echo $ost_last |
5494                                               awk -F':' '{print $2}' |
5495                                               sed -e "s/^0x//g")
5496                                 ost_last_seq=$(echo $ost_last |
5497                                                awk -F':' '{print $1}')
5498                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5499                         fi
5500
5501                         if [[ $ost_last_id != $mds_last ]]; then
5502                                 error "$ost_last_id != $mds_last"
5503                         else
5504                                 found=true
5505                                 break
5506                         fi
5507                 done
5508         done
5509         $found || error "can not match last_seq/last_id for $mdtosc"
5510         return 0
5511 }
5512 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5513
5514 test_54a() {
5515         perl -MSocket -e ';' || skip "no Socket perl module installed"
5516
5517         $SOCKETSERVER $DIR/socket ||
5518                 error "$SOCKETSERVER $DIR/socket failed: $?"
5519         $SOCKETCLIENT $DIR/socket ||
5520                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5521         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5522 }
5523 run_test 54a "unix domain socket test =========================="
5524
5525 test_54b() {
5526         f="$DIR/f54b"
5527         mknod $f c 1 3
5528         chmod 0666 $f
5529         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5530 }
5531 run_test 54b "char device works in lustre ======================"
5532
5533 find_loop_dev() {
5534         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5535         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5536         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5537
5538         for i in $(seq 3 7); do
5539                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5540                 LOOPDEV=$LOOPBASE$i
5541                 LOOPNUM=$i
5542                 break
5543         done
5544 }
5545
5546 cleanup_54c() {
5547         local rc=0
5548         loopdev="$DIR/loop54c"
5549
5550         trap 0
5551         $UMOUNT $DIR/$tdir || rc=$?
5552         losetup -d $loopdev || true
5553         losetup -d $LOOPDEV || true
5554         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5555         return $rc
5556 }
5557
5558 test_54c() {
5559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5560
5561         loopdev="$DIR/loop54c"
5562
5563         find_loop_dev
5564         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5565         trap cleanup_54c EXIT
5566         mknod $loopdev b 7 $LOOPNUM
5567         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5568         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5569         losetup $loopdev $DIR/$tfile ||
5570                 error "can't set up $loopdev for $DIR/$tfile"
5571         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5572         test_mkdir $DIR/$tdir
5573         mount -t ext2 $loopdev $DIR/$tdir ||
5574                 error "error mounting $loopdev on $DIR/$tdir"
5575         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5576                 error "dd write"
5577         df $DIR/$tdir
5578         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5579                 error "dd read"
5580         cleanup_54c
5581 }
5582 run_test 54c "block device works in lustre ====================="
5583
5584 test_54d() {
5585         f="$DIR/f54d"
5586         string="aaaaaa"
5587         mknod $f p
5588         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5589 }
5590 run_test 54d "fifo device works in lustre ======================"
5591
5592 test_54e() {
5593         f="$DIR/f54e"
5594         string="aaaaaa"
5595         cp -aL /dev/console $f
5596         echo $string > $f || error "echo $string to $f failed"
5597 }
5598 run_test 54e "console/tty device works in lustre ======================"
5599
5600 test_56a() {
5601         local numfiles=3
5602         local dir=$DIR/$tdir
5603
5604         rm -rf $dir
5605         test_mkdir -p $dir/dir
5606         for i in $(seq $numfiles); do
5607                 touch $dir/file$i
5608                 touch $dir/dir/file$i
5609         done
5610
5611         local numcomp=$($LFS getstripe --component-count $dir)
5612
5613         [[ $numcomp == 0 ]] && numcomp=1
5614
5615         # test lfs getstripe with --recursive
5616         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5617
5618         [[ $filenum -eq $((numfiles * 2)) ]] ||
5619                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5620         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5621         [[ $filenum -eq $numfiles ]] ||
5622                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5623         echo "$LFS getstripe showed obdidx or l_ost_idx"
5624
5625         # test lfs getstripe with file instead of dir
5626         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5627         [[ $filenum -eq 1 ]] ||
5628                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5629         echo "$LFS getstripe file1 passed"
5630
5631         #test lfs getstripe with --verbose
5632         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5633         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5634                 error "$LFS getstripe --verbose $dir: "\
5635                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5636         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5637                 error "$LFS getstripe $dir: showed lmm_magic"
5638
5639         #test lfs getstripe with -v prints lmm_fid
5640         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5641         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5642                 error "$LFS getstripe -v $dir: "\
5643                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5644         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5645                 error "$LFS getstripe $dir: showed lmm_fid by default"
5646         echo "$LFS getstripe --verbose passed"
5647
5648         #check for FID information
5649         local fid1=$($LFS getstripe --fid $dir/file1)
5650         local fid2=$($LFS getstripe --verbose $dir/file1 |
5651                      awk '/lmm_fid: / { print $2; exit; }')
5652         local fid3=$($LFS path2fid $dir/file1)
5653
5654         [ "$fid1" != "$fid2" ] &&
5655                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5656         [ "$fid1" != "$fid3" ] &&
5657                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5658         echo "$LFS getstripe --fid passed"
5659
5660         #test lfs getstripe with --obd
5661         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5662                 error "$LFS getstripe --obd wrong_uuid: should return error"
5663
5664         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5665
5666         local ostidx=1
5667         local obduuid=$(ostuuid_from_index $ostidx)
5668         local found=$($LFS getstripe -r --obd $obduuid $dir |
5669                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5670
5671         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5672         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5673                 ((filenum--))
5674         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5675                 ((filenum--))
5676
5677         [[ $found -eq $filenum ]] ||
5678                 error "$LFS getstripe --obd: found $found expect $filenum"
5679         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5680                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5681                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5682                 error "$LFS getstripe --obd: should not show file on other obd"
5683         echo "$LFS getstripe --obd passed"
5684 }
5685 run_test 56a "check $LFS getstripe"
5686
5687 test_56b() {
5688         local dir=$DIR/$tdir
5689         local numdirs=3
5690
5691         test_mkdir $dir
5692         for i in $(seq $numdirs); do
5693                 test_mkdir $dir/dir$i
5694         done
5695
5696         # test lfs getdirstripe default mode is non-recursion, which is
5697         # different from lfs getstripe
5698         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5699
5700         [[ $dircnt -eq 1 ]] ||
5701                 error "$LFS getdirstripe: found $dircnt, not 1"
5702         dircnt=$($LFS getdirstripe --recursive $dir |
5703                 grep -c lmv_stripe_count)
5704         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5705                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5706 }
5707 run_test 56b "check $LFS getdirstripe"
5708
5709 test_56c() {
5710         remote_ost_nodsh && skip "remote OST with nodsh"
5711
5712         local ost_idx=0
5713         local ost_name=$(ostname_from_index $ost_idx)
5714         local old_status=$(ost_dev_status $ost_idx)
5715         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5716
5717         [[ -z "$old_status" ]] ||
5718                 skip_env "OST $ost_name is in $old_status status"
5719
5720         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5721         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5722                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5723         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5724                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5725                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5726         fi
5727
5728         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5729                 error "$LFS df -v showing inactive devices"
5730         sleep_maxage
5731
5732         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5733
5734         [[ "$new_status" =~ "D" ]] ||
5735                 error "$ost_name status is '$new_status', missing 'D'"
5736         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5737                 [[ "$new_status" =~ "N" ]] ||
5738                         error "$ost_name status is '$new_status', missing 'N'"
5739         fi
5740         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5741                 [[ "$new_status" =~ "f" ]] ||
5742                         error "$ost_name status is '$new_status', missing 'f'"
5743         fi
5744
5745         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5746         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5747                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5748         [[ -z "$p" ]] && restore_lustre_params < $p || true
5749         sleep_maxage
5750
5751         new_status=$(ost_dev_status $ost_idx)
5752         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5753                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5754         # can't check 'f' as devices may actually be on flash
5755 }
5756 run_test 56c "check 'lfs df' showing device status"
5757
5758 test_56d() {
5759         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5760         local osts=$($LFS df -v $MOUNT | grep -c OST)
5761
5762         $LFS df $MOUNT
5763
5764         (( mdts == MDSCOUNT )) ||
5765                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5766         (( osts == OSTCOUNT )) ||
5767                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5768 }
5769 run_test 56d "'lfs df -v' prints only configured devices"
5770
5771 NUMFILES=3
5772 NUMDIRS=3
5773 setup_56() {
5774         local local_tdir="$1"
5775         local local_numfiles="$2"
5776         local local_numdirs="$3"
5777         local dir_params="$4"
5778         local dir_stripe_params="$5"
5779
5780         if [ ! -d "$local_tdir" ] ; then
5781                 test_mkdir -p $dir_stripe_params $local_tdir
5782                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5783                 for i in $(seq $local_numfiles) ; do
5784                         touch $local_tdir/file$i
5785                 done
5786                 for i in $(seq $local_numdirs) ; do
5787                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5788                         for j in $(seq $local_numfiles) ; do
5789                                 touch $local_tdir/dir$i/file$j
5790                         done
5791                 done
5792         fi
5793 }
5794
5795 setup_56_special() {
5796         local local_tdir=$1
5797         local local_numfiles=$2
5798         local local_numdirs=$3
5799
5800         setup_56 $local_tdir $local_numfiles $local_numdirs
5801
5802         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5803                 for i in $(seq $local_numfiles) ; do
5804                         mknod $local_tdir/loop${i}b b 7 $i
5805                         mknod $local_tdir/null${i}c c 1 3
5806                         ln -s $local_tdir/file1 $local_tdir/link${i}
5807                 done
5808                 for i in $(seq $local_numdirs) ; do
5809                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5810                         mknod $local_tdir/dir$i/null${i}c c 1 3
5811                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5812                 done
5813         fi
5814 }
5815
5816 test_56g() {
5817         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5818         local expected=$(($NUMDIRS + 2))
5819
5820         setup_56 $dir $NUMFILES $NUMDIRS
5821
5822         # test lfs find with -name
5823         for i in $(seq $NUMFILES) ; do
5824                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5825
5826                 [ $nums -eq $expected ] ||
5827                         error "lfs find -name '*$i' $dir wrong: "\
5828                               "found $nums, expected $expected"
5829         done
5830 }
5831 run_test 56g "check lfs find -name"
5832
5833 test_56h() {
5834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5835         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5836
5837         setup_56 $dir $NUMFILES $NUMDIRS
5838
5839         # test lfs find with ! -name
5840         for i in $(seq $NUMFILES) ; do
5841                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5842
5843                 [ $nums -eq $expected ] ||
5844                         error "lfs find ! -name '*$i' $dir wrong: "\
5845                               "found $nums, expected $expected"
5846         done
5847 }
5848 run_test 56h "check lfs find ! -name"
5849
5850 test_56i() {
5851         local dir=$DIR/$tdir
5852
5853         test_mkdir $dir
5854
5855         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5856         local out=$($cmd)
5857
5858         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5859 }
5860 run_test 56i "check 'lfs find -ost UUID' skips directories"
5861
5862 test_56j() {
5863         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5864
5865         setup_56_special $dir $NUMFILES $NUMDIRS
5866
5867         local expected=$((NUMDIRS + 1))
5868         local cmd="$LFS find -type d $dir"
5869         local nums=$($cmd | wc -l)
5870
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56j "check lfs find -type d"
5875
5876 test_56k() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878
5879         setup_56_special $dir $NUMFILES $NUMDIRS
5880
5881         local expected=$(((NUMDIRS + 1) * NUMFILES))
5882         local cmd="$LFS find -type f $dir"
5883         local nums=$($cmd | wc -l)
5884
5885         [ $nums -eq $expected ] ||
5886                 error "'$cmd' wrong: found $nums, expected $expected"
5887 }
5888 run_test 56k "check lfs find -type f"
5889
5890 test_56l() {
5891         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5892
5893         setup_56_special $dir $NUMFILES $NUMDIRS
5894
5895         local expected=$((NUMDIRS + NUMFILES))
5896         local cmd="$LFS find -type b $dir"
5897         local nums=$($cmd | wc -l)
5898
5899         [ $nums -eq $expected ] ||
5900                 error "'$cmd' wrong: found $nums, expected $expected"
5901 }
5902 run_test 56l "check lfs find -type b"
5903
5904 test_56m() {
5905         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5906
5907         setup_56_special $dir $NUMFILES $NUMDIRS
5908
5909         local expected=$((NUMDIRS + NUMFILES))
5910         local cmd="$LFS find -type c $dir"
5911         local nums=$($cmd | wc -l)
5912         [ $nums -eq $expected ] ||
5913                 error "'$cmd' wrong: found $nums, expected $expected"
5914 }
5915 run_test 56m "check lfs find -type c"
5916
5917 test_56n() {
5918         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5919         setup_56_special $dir $NUMFILES $NUMDIRS
5920
5921         local expected=$((NUMDIRS + NUMFILES))
5922         local cmd="$LFS find -type l $dir"
5923         local nums=$($cmd | wc -l)
5924
5925         [ $nums -eq $expected ] ||
5926                 error "'$cmd' wrong: found $nums, expected $expected"
5927 }
5928 run_test 56n "check lfs find -type l"
5929
5930 test_56o() {
5931         local dir=$DIR/$tdir
5932
5933         setup_56 $dir $NUMFILES $NUMDIRS
5934         utime $dir/file1 > /dev/null || error "utime (1)"
5935         utime $dir/file2 > /dev/null || error "utime (2)"
5936         utime $dir/dir1 > /dev/null || error "utime (3)"
5937         utime $dir/dir2 > /dev/null || error "utime (4)"
5938         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5939         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5940
5941         local expected=4
5942         local nums=$($LFS find -mtime +0 $dir | wc -l)
5943
5944         [ $nums -eq $expected ] ||
5945                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5946
5947         expected=12
5948         cmd="$LFS find -mtime 0 $dir"
5949         nums=$($cmd | wc -l)
5950         [ $nums -eq $expected ] ||
5951                 error "'$cmd' wrong: found $nums, expected $expected"
5952 }
5953 run_test 56o "check lfs find -mtime for old files"
5954
5955 test_56ob() {
5956         local dir=$DIR/$tdir
5957         local expected=1
5958         local count=0
5959
5960         # just to make sure there is something that won't be found
5961         test_mkdir $dir
5962         touch $dir/$tfile.now
5963
5964         for age in year week day hour min; do
5965                 count=$((count + 1))
5966
5967                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5968                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5969                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5970
5971                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5972                 local nums=$($cmd | wc -l)
5973                 [ $nums -eq $expected ] ||
5974                         error "'$cmd' wrong: found $nums, expected $expected"
5975
5976                 cmd="$LFS find $dir -atime $count${age:0:1}"
5977                 nums=$($cmd | wc -l)
5978                 [ $nums -eq $expected ] ||
5979                         error "'$cmd' wrong: found $nums, expected $expected"
5980         done
5981
5982         sleep 2
5983         cmd="$LFS find $dir -ctime +1s -type f"
5984         nums=$($cmd | wc -l)
5985         (( $nums == $count * 2 + 1)) ||
5986                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5987 }
5988 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5989
5990 test_newerXY_base() {
5991         local x=$1
5992         local y=$2
5993         local dir=$DIR/$tdir
5994         local ref
5995         local negref
5996
5997         if [ $y == "t" ]; then
5998                 if [ $x == "b" ]; then
5999                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6000                 else
6001                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6002                 fi
6003         else
6004                 ref=$DIR/$tfile.newer.$x$y
6005                 touch $ref || error "touch $ref failed"
6006         fi
6007
6008         echo "before = $ref"
6009         sleep 2
6010         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6011         sleep 2
6012         if [ $y == "t" ]; then
6013                 if [ $x == "b" ]; then
6014                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6015                 else
6016                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6017                 fi
6018         else
6019                 negref=$DIR/$tfile.negnewer.$x$y
6020                 touch $negref || error "touch $negref failed"
6021         fi
6022
6023         echo "after = $negref"
6024         local cmd="$LFS find $dir -newer$x$y $ref"
6025         local nums=$(eval $cmd | wc -l)
6026         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6027
6028         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6029                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6030
6031         cmd="$LFS find $dir ! -newer$x$y $negref"
6032         nums=$(eval $cmd | wc -l)
6033         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6034                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6035
6036         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6037         nums=$(eval $cmd | wc -l)
6038         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6039                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6040
6041         rm -rf $DIR/*
6042 }
6043
6044 test_56oc() {
6045         test_newerXY_base "a" "a"
6046         test_newerXY_base "a" "m"
6047         test_newerXY_base "a" "c"
6048         test_newerXY_base "m" "a"
6049         test_newerXY_base "m" "m"
6050         test_newerXY_base "m" "c"
6051         test_newerXY_base "c" "a"
6052         test_newerXY_base "c" "m"
6053         test_newerXY_base "c" "c"
6054
6055         [[ -n "$sles_version" ]] &&
6056                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6057
6058         test_newerXY_base "a" "t"
6059         test_newerXY_base "m" "t"
6060         test_newerXY_base "c" "t"
6061
6062         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6063            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6064                 ! btime_supported && echo "btime unsupported" && return 0
6065
6066         test_newerXY_base "b" "b"
6067         test_newerXY_base "b" "t"
6068 }
6069 run_test 56oc "check lfs find -newerXY work"
6070
6071 btime_supported() {
6072         local dir=$DIR/$tdir
6073         local rc
6074
6075         mkdir -p $dir
6076         touch $dir/$tfile
6077         $LFS find $dir -btime -1d -type f
6078         rc=$?
6079         rm -rf $dir
6080         return $rc
6081 }
6082
6083 test_56od() {
6084         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6085                 ! btime_supported && skip "btime unsupported on MDS"
6086
6087         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6088                 ! btime_supported && skip "btime unsupported on clients"
6089
6090         local dir=$DIR/$tdir
6091         local ref=$DIR/$tfile.ref
6092         local negref=$DIR/$tfile.negref
6093
6094         mkdir $dir || error "mkdir $dir failed"
6095         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6096         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6097         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6098         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6099         touch $ref || error "touch $ref failed"
6100         # sleep 3 seconds at least
6101         sleep 3
6102
6103         local before=$(do_facet mds1 date +%s)
6104         local skew=$(($(date +%s) - before + 1))
6105
6106         if (( skew < 0 && skew > -5 )); then
6107                 sleep $((0 - skew + 1))
6108                 skew=0
6109         fi
6110
6111         # Set the dir stripe params to limit files all on MDT0,
6112         # otherwise we need to calc the max clock skew between
6113         # the client and MDTs.
6114         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6115         sleep 2
6116         touch $negref || error "touch $negref failed"
6117
6118         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6119         local nums=$($cmd | wc -l)
6120         local expected=$(((NUMFILES + 1) * NUMDIRS))
6121
6122         [ $nums -eq $expected ] ||
6123                 error "'$cmd' wrong: found $nums, expected $expected"
6124
6125         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6126         nums=$($cmd | wc -l)
6127         expected=$((NUMFILES + 1))
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130
6131         [ $skew -lt 0 ] && return
6132
6133         local after=$(do_facet mds1 date +%s)
6134         local age=$((after - before + 1 + skew))
6135
6136         cmd="$LFS find $dir -btime -${age}s -type f"
6137         nums=$($cmd | wc -l)
6138         expected=$(((NUMFILES + 1) * NUMDIRS))
6139
6140         echo "Clock skew between client and server: $skew, age:$age"
6141         [ $nums -eq $expected ] ||
6142                 error "'$cmd' wrong: found $nums, expected $expected"
6143
6144         expected=$(($NUMDIRS + 1))
6145         cmd="$LFS find $dir -btime -${age}s -type d"
6146         nums=$($cmd | wc -l)
6147         [ $nums -eq $expected ] ||
6148                 error "'$cmd' wrong: found $nums, expected $expected"
6149         rm -f $ref $negref || error "Failed to remove $ref $negref"
6150 }
6151 run_test 56od "check lfs find -btime with units"
6152
6153 test_56p() {
6154         [ $RUNAS_ID -eq $UID ] &&
6155                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6156
6157         local dir=$DIR/$tdir
6158
6159         setup_56 $dir $NUMFILES $NUMDIRS
6160         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6161
6162         local expected=$NUMFILES
6163         local cmd="$LFS find -uid $RUNAS_ID $dir"
6164         local nums=$($cmd | wc -l)
6165
6166         [ $nums -eq $expected ] ||
6167                 error "'$cmd' wrong: found $nums, expected $expected"
6168
6169         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6170         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174 }
6175 run_test 56p "check lfs find -uid and ! -uid"
6176
6177 test_56q() {
6178         [ $RUNAS_ID -eq $UID ] &&
6179                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6180
6181         local dir=$DIR/$tdir
6182
6183         setup_56 $dir $NUMFILES $NUMDIRS
6184         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6185
6186         local expected=$NUMFILES
6187         local cmd="$LFS find -gid $RUNAS_GID $dir"
6188         local nums=$($cmd | wc -l)
6189
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192
6193         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6194         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6195         nums=$($cmd | wc -l)
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198 }
6199 run_test 56q "check lfs find -gid and ! -gid"
6200
6201 test_56r() {
6202         local dir=$DIR/$tdir
6203
6204         setup_56 $dir $NUMFILES $NUMDIRS
6205
6206         local expected=12
6207         local cmd="$LFS find -size 0 -type f -lazy $dir"
6208         local nums=$($cmd | wc -l)
6209
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find -size 0 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=0
6218         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find ! -size 0 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226
6227         echo "test" > $dir/$tfile
6228         echo "test2" > $dir/$tfile.2 && sync
6229         expected=1
6230         cmd="$LFS find -size 5 -type f -lazy $dir"
6231         nums=$($cmd | wc -l)
6232         [ $nums -eq $expected ] ||
6233                 error "'$cmd' wrong: found $nums, expected $expected"
6234         cmd="$LFS find -size 5 -type f $dir"
6235         nums=$($cmd | wc -l)
6236         [ $nums -eq $expected ] ||
6237                 error "'$cmd' wrong: found $nums, expected $expected"
6238
6239         expected=1
6240         cmd="$LFS find -size +5 -type f -lazy $dir"
6241         nums=$($cmd | wc -l)
6242         [ $nums -eq $expected ] ||
6243                 error "'$cmd' wrong: found $nums, expected $expected"
6244         cmd="$LFS find -size +5 -type f $dir"
6245         nums=$($cmd | wc -l)
6246         [ $nums -eq $expected ] ||
6247                 error "'$cmd' wrong: found $nums, expected $expected"
6248
6249         expected=2
6250         cmd="$LFS find -size +0 -type f -lazy $dir"
6251         nums=$($cmd | wc -l)
6252         [ $nums -eq $expected ] ||
6253                 error "'$cmd' wrong: found $nums, expected $expected"
6254         cmd="$LFS find -size +0 -type f $dir"
6255         nums=$($cmd | wc -l)
6256         [ $nums -eq $expected ] ||
6257                 error "'$cmd' wrong: found $nums, expected $expected"
6258
6259         expected=2
6260         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6261         nums=$($cmd | wc -l)
6262         [ $nums -eq $expected ] ||
6263                 error "'$cmd' wrong: found $nums, expected $expected"
6264         cmd="$LFS find ! -size -5 -type f $dir"
6265         nums=$($cmd | wc -l)
6266         [ $nums -eq $expected ] ||
6267                 error "'$cmd' wrong: found $nums, expected $expected"
6268
6269         expected=12
6270         cmd="$LFS find -size -5 -type f -lazy $dir"
6271         nums=$($cmd | wc -l)
6272         [ $nums -eq $expected ] ||
6273                 error "'$cmd' wrong: found $nums, expected $expected"
6274         cmd="$LFS find -size -5 -type f $dir"
6275         nums=$($cmd | wc -l)
6276         [ $nums -eq $expected ] ||
6277                 error "'$cmd' wrong: found $nums, expected $expected"
6278 }
6279 run_test 56r "check lfs find -size works"
6280
6281 test_56ra_sub() {
6282         local expected=$1
6283         local glimpses=$2
6284         local cmd="$3"
6285
6286         cancel_lru_locks $OSC
6287
6288         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6289         local nums=$($cmd | wc -l)
6290
6291         [ $nums -eq $expected ] ||
6292                 error "'$cmd' wrong: found $nums, expected $expected"
6293
6294         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6295
6296         if (( rpcs_before + glimpses != rpcs_after )); then
6297                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6298                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6299
6300                 if [[ $glimpses == 0 ]]; then
6301                         error "'$cmd' should not send glimpse RPCs to OST"
6302                 else
6303                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6304                 fi
6305         fi
6306 }
6307
6308 test_56ra() {
6309         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6310                 skip "MDS < 2.12.58 doesn't return LSOM data"
6311         local dir=$DIR/$tdir
6312         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6313
6314         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6315
6316         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6317         $LCTL set_param -n llite.*.statahead_agl=0
6318         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6319
6320         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6321         # open and close all files to ensure LSOM is updated
6322         cancel_lru_locks $OSC
6323         find $dir -type f | xargs cat > /dev/null
6324
6325         #   expect_found  glimpse_rpcs  command_to_run
6326         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6327         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6328         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6329         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6330
6331         echo "test" > $dir/$tfile
6332         echo "test2" > $dir/$tfile.2 && sync
6333         cancel_lru_locks $OSC
6334         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6335
6336         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6337         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6338         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6339         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6340
6341         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6342         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6343         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6344         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6345         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6346         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6347 }
6348 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6349
6350 test_56rb() {
6351         local dir=$DIR/$tdir
6352         local tmp=$TMP/$tfile.log
6353         local mdt_idx;
6354
6355         test_mkdir -p $dir || error "failed to mkdir $dir"
6356         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6357                 error "failed to setstripe $dir/$tfile"
6358         mdt_idx=$($LFS getdirstripe -i $dir)
6359         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6360
6361         stack_trap "rm -f $tmp" EXIT
6362         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6363         ! grep -q obd_uuid $tmp ||
6364                 error "failed to find --size +100K --ost 0 $dir"
6365         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6366         ! grep -q obd_uuid $tmp ||
6367                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6368 }
6369 run_test 56rb "check lfs find --size --ost/--mdt works"
6370
6371 test_56s() { # LU-611 #LU-9369
6372         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6373
6374         local dir=$DIR/$tdir
6375         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6376
6377         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6378         for i in $(seq $NUMDIRS); do
6379                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6380         done
6381
6382         local expected=$NUMDIRS
6383         local cmd="$LFS find -c $OSTCOUNT $dir"
6384         local nums=$($cmd | wc -l)
6385
6386         [ $nums -eq $expected ] || {
6387                 $LFS getstripe -R $dir
6388                 error "'$cmd' wrong: found $nums, expected $expected"
6389         }
6390
6391         expected=$((NUMDIRS + onestripe))
6392         cmd="$LFS find -stripe-count +0 -type f $dir"
6393         nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] || {
6395                 $LFS getstripe -R $dir
6396                 error "'$cmd' wrong: found $nums, expected $expected"
6397         }
6398
6399         expected=$onestripe
6400         cmd="$LFS find -stripe-count 1 -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] || {
6403                 $LFS getstripe -R $dir
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405         }
6406
6407         cmd="$LFS find -stripe-count -2 -type f $dir"
6408         nums=$($cmd | wc -l)
6409         [ $nums -eq $expected ] || {
6410                 $LFS getstripe -R $dir
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         }
6413
6414         expected=0
6415         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6416         nums=$($cmd | wc -l)
6417         [ $nums -eq $expected ] || {
6418                 $LFS getstripe -R $dir
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420         }
6421 }
6422 run_test 56s "check lfs find -stripe-count works"
6423
6424 test_56t() { # LU-611 #LU-9369
6425         local dir=$DIR/$tdir
6426
6427         setup_56 $dir 0 $NUMDIRS
6428         for i in $(seq $NUMDIRS); do
6429                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6430         done
6431
6432         local expected=$NUMDIRS
6433         local cmd="$LFS find -S 8M $dir"
6434         local nums=$($cmd | wc -l)
6435
6436         [ $nums -eq $expected ] || {
6437                 $LFS getstripe -R $dir
6438                 error "'$cmd' wrong: found $nums, expected $expected"
6439         }
6440         rm -rf $dir
6441
6442         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6443
6444         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6445
6446         expected=$(((NUMDIRS + 1) * NUMFILES))
6447         cmd="$LFS find -stripe-size 512k -type f $dir"
6448         nums=$($cmd | wc -l)
6449         [ $nums -eq $expected ] ||
6450                 error "'$cmd' wrong: found $nums, expected $expected"
6451
6452         cmd="$LFS find -stripe-size +320k -type f $dir"
6453         nums=$($cmd | wc -l)
6454         [ $nums -eq $expected ] ||
6455                 error "'$cmd' wrong: found $nums, expected $expected"
6456
6457         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6458         cmd="$LFS find -stripe-size +200k -type f $dir"
6459         nums=$($cmd | wc -l)
6460         [ $nums -eq $expected ] ||
6461                 error "'$cmd' wrong: found $nums, expected $expected"
6462
6463         cmd="$LFS find -stripe-size -640k -type f $dir"
6464         nums=$($cmd | wc -l)
6465         [ $nums -eq $expected ] ||
6466                 error "'$cmd' wrong: found $nums, expected $expected"
6467
6468         expected=4
6469         cmd="$LFS find -stripe-size 256k -type f $dir"
6470         nums=$($cmd | wc -l)
6471         [ $nums -eq $expected ] ||
6472                 error "'$cmd' wrong: found $nums, expected $expected"
6473
6474         cmd="$LFS find -stripe-size -320k -type f $dir"
6475         nums=$($cmd | wc -l)
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478
6479         expected=0
6480         cmd="$LFS find -stripe-size 1024k -type f $dir"
6481         nums=$($cmd | wc -l)
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484 }
6485 run_test 56t "check lfs find -stripe-size works"
6486
6487 test_56u() { # LU-611
6488         local dir=$DIR/$tdir
6489
6490         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6491
6492         if [[ $OSTCOUNT -gt 1 ]]; then
6493                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6494                 onestripe=4
6495         else
6496                 onestripe=0
6497         fi
6498
6499         local expected=$(((NUMDIRS + 1) * NUMFILES))
6500         local cmd="$LFS find -stripe-index 0 -type f $dir"
6501         local nums=$($cmd | wc -l)
6502
6503         [ $nums -eq $expected ] ||
6504                 error "'$cmd' wrong: found $nums, expected $expected"
6505
6506         expected=$onestripe
6507         cmd="$LFS find -stripe-index 1 -type f $dir"
6508         nums=$($cmd | wc -l)
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511
6512         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6513         nums=$($cmd | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516
6517         expected=0
6518         # This should produce an error and not return any files
6519         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6520         nums=$($cmd 2>/dev/null | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523
6524         if [[ $OSTCOUNT -gt 1 ]]; then
6525                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6526                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6527                 nums=$($cmd | wc -l)
6528                 [ $nums -eq $expected ] ||
6529                         error "'$cmd' wrong: found $nums, expected $expected"
6530         fi
6531 }
6532 run_test 56u "check lfs find -stripe-index works"
6533
6534 test_56v() {
6535         local mdt_idx=0
6536         local dir=$DIR/$tdir
6537
6538         setup_56 $dir $NUMFILES $NUMDIRS
6539
6540         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6541         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6542
6543         for file in $($LFS find -m $UUID $dir); do
6544                 file_midx=$($LFS getstripe -m $file)
6545                 [ $file_midx -eq $mdt_idx ] ||
6546                         error "lfs find -m $UUID != getstripe -m $file_midx"
6547         done
6548 }
6549 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6550
6551 test_56w() {
6552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6554
6555         local dir=$DIR/$tdir
6556
6557         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6558
6559         local stripe_size=$($LFS getstripe -S -d $dir) ||
6560                 error "$LFS getstripe -S -d $dir failed"
6561         stripe_size=${stripe_size%% *}
6562
6563         local file_size=$((stripe_size * OSTCOUNT))
6564         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6565         local required_space=$((file_num * file_size))
6566         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6567                            head -n1)
6568         [[ $free_space -le $((required_space / 1024)) ]] &&
6569                 skip_env "need $required_space, have $free_space kbytes"
6570
6571         local dd_bs=65536
6572         local dd_count=$((file_size / dd_bs))
6573
6574         # write data into the files
6575         local i
6576         local j
6577         local file
6578
6579         for i in $(seq $NUMFILES); do
6580                 file=$dir/file$i
6581                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6582                         error "write data into $file failed"
6583         done
6584         for i in $(seq $NUMDIRS); do
6585                 for j in $(seq $NUMFILES); do
6586                         file=$dir/dir$i/file$j
6587                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6588                                 error "write data into $file failed"
6589                 done
6590         done
6591
6592         # $LFS_MIGRATE will fail if hard link migration is unsupported
6593         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6594                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6595                         error "creating links to $dir/dir1/file1 failed"
6596         fi
6597
6598         local expected=-1
6599
6600         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6601
6602         # lfs_migrate file
6603         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6604
6605         echo "$cmd"
6606         eval $cmd || error "$cmd failed"
6607
6608         check_stripe_count $dir/file1 $expected
6609
6610         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6611         then
6612                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6613                 # OST 1 if it is on OST 0. This file is small enough to
6614                 # be on only one stripe.
6615                 file=$dir/migr_1_ost
6616                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6617                         error "write data into $file failed"
6618                 local obdidx=$($LFS getstripe -i $file)
6619                 local oldmd5=$(md5sum $file)
6620                 local newobdidx=0
6621
6622                 [[ $obdidx -eq 0 ]] && newobdidx=1
6623                 cmd="$LFS migrate -i $newobdidx $file"
6624                 echo $cmd
6625                 eval $cmd || error "$cmd failed"
6626
6627                 local realobdix=$($LFS getstripe -i $file)
6628                 local newmd5=$(md5sum $file)
6629
6630                 [[ $newobdidx -ne $realobdix ]] &&
6631                         error "new OST is different (was=$obdidx, "\
6632                               "wanted=$newobdidx, got=$realobdix)"
6633                 [[ "$oldmd5" != "$newmd5" ]] &&
6634                         error "md5sum differ: $oldmd5, $newmd5"
6635         fi
6636
6637         # lfs_migrate dir
6638         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6639         echo "$cmd"
6640         eval $cmd || error "$cmd failed"
6641
6642         for j in $(seq $NUMFILES); do
6643                 check_stripe_count $dir/dir1/file$j $expected
6644         done
6645
6646         # lfs_migrate works with lfs find
6647         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6648              $LFS_MIGRATE -y -c $expected"
6649         echo "$cmd"
6650         eval $cmd || error "$cmd failed"
6651
6652         for i in $(seq 2 $NUMFILES); do
6653                 check_stripe_count $dir/file$i $expected
6654         done
6655         for i in $(seq 2 $NUMDIRS); do
6656                 for j in $(seq $NUMFILES); do
6657                 check_stripe_count $dir/dir$i/file$j $expected
6658                 done
6659         done
6660 }
6661 run_test 56w "check lfs_migrate -c stripe_count works"
6662
6663 test_56wb() {
6664         local file1=$DIR/$tdir/file1
6665         local create_pool=false
6666         local initial_pool=$($LFS getstripe -p $DIR)
6667         local pool_list=()
6668         local pool=""
6669
6670         echo -n "Creating test dir..."
6671         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6672         echo "done."
6673
6674         echo -n "Creating test file..."
6675         touch $file1 || error "cannot create file"
6676         echo "done."
6677
6678         echo -n "Detecting existing pools..."
6679         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6680
6681         if [ ${#pool_list[@]} -gt 0 ]; then
6682                 echo "${pool_list[@]}"
6683                 for thispool in "${pool_list[@]}"; do
6684                         if [[ -z "$initial_pool" ||
6685                               "$initial_pool" != "$thispool" ]]; then
6686                                 pool="$thispool"
6687                                 echo "Using existing pool '$pool'"
6688                                 break
6689                         fi
6690                 done
6691         else
6692                 echo "none detected."
6693         fi
6694         if [ -z "$pool" ]; then
6695                 pool=${POOL:-testpool}
6696                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6697                 echo -n "Creating pool '$pool'..."
6698                 create_pool=true
6699                 pool_add $pool &> /dev/null ||
6700                         error "pool_add failed"
6701                 echo "done."
6702
6703                 echo -n "Adding target to pool..."
6704                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6705                         error "pool_add_targets failed"
6706                 echo "done."
6707         fi
6708
6709         echo -n "Setting pool using -p option..."
6710         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6711                 error "migrate failed rc = $?"
6712         echo "done."
6713
6714         echo -n "Verifying test file is in pool after migrating..."
6715         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6716                 error "file was not migrated to pool $pool"
6717         echo "done."
6718
6719         echo -n "Removing test file from pool '$pool'..."
6720         # "lfs migrate $file" won't remove the file from the pool
6721         # until some striping information is changed.
6722         $LFS migrate -c 1 $file1 &> /dev/null ||
6723                 error "cannot remove from pool"
6724         [ "$($LFS getstripe -p $file1)" ] &&
6725                 error "pool still set"
6726         echo "done."
6727
6728         echo -n "Setting pool using --pool option..."
6729         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6730                 error "migrate failed rc = $?"
6731         echo "done."
6732
6733         # Clean up
6734         rm -f $file1
6735         if $create_pool; then
6736                 destroy_test_pools 2> /dev/null ||
6737                         error "destroy test pools failed"
6738         fi
6739 }
6740 run_test 56wb "check lfs_migrate pool support"
6741
6742 test_56wc() {
6743         local file1="$DIR/$tdir/file1"
6744         local parent_ssize
6745         local parent_scount
6746         local cur_ssize
6747         local cur_scount
6748         local orig_ssize
6749
6750         echo -n "Creating test dir..."
6751         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6752         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6753                 error "cannot set stripe by '-S 1M -c 1'"
6754         echo "done"
6755
6756         echo -n "Setting initial stripe for test file..."
6757         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6758                 error "cannot set stripe"
6759         cur_ssize=$($LFS getstripe -S "$file1")
6760         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6761         echo "done."
6762
6763         # File currently set to -S 512K -c 1
6764
6765         # Ensure -c and -S options are rejected when -R is set
6766         echo -n "Verifying incompatible options are detected..."
6767         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6768                 error "incompatible -c and -R options not detected"
6769         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6770                 error "incompatible -S and -R options not detected"
6771         echo "done."
6772
6773         # Ensure unrecognized options are passed through to 'lfs migrate'
6774         echo -n "Verifying -S option is passed through to lfs migrate..."
6775         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6776                 error "migration failed"
6777         cur_ssize=$($LFS getstripe -S "$file1")
6778         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6779         echo "done."
6780
6781         # File currently set to -S 1M -c 1
6782
6783         # Ensure long options are supported
6784         echo -n "Verifying long options supported..."
6785         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6786                 error "long option without argument not supported"
6787         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6788                 error "long option with argument not supported"
6789         cur_ssize=$($LFS getstripe -S "$file1")
6790         [ $cur_ssize -eq 524288 ] ||
6791                 error "migrate --stripe-size $cur_ssize != 524288"
6792         echo "done."
6793
6794         # File currently set to -S 512K -c 1
6795
6796         if [ "$OSTCOUNT" -gt 1 ]; then
6797                 echo -n "Verifying explicit stripe count can be set..."
6798                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6799                         error "migrate failed"
6800                 cur_scount=$($LFS getstripe -c "$file1")
6801                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6802                 echo "done."
6803         fi
6804
6805         # File currently set to -S 512K -c 1 or -S 512K -c 2
6806
6807         # Ensure parent striping is used if -R is set, and no stripe
6808         # count or size is specified
6809         echo -n "Setting stripe for parent directory..."
6810         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6811                 error "cannot set stripe '-S 2M -c 1'"
6812         echo "done."
6813
6814         echo -n "Verifying restripe option uses parent stripe settings..."
6815         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6816         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6817         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6818                 error "migrate failed"
6819         cur_ssize=$($LFS getstripe -S "$file1")
6820         [ $cur_ssize -eq $parent_ssize ] ||
6821                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6822         cur_scount=$($LFS getstripe -c "$file1")
6823         [ $cur_scount -eq $parent_scount ] ||
6824                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6825         echo "done."
6826
6827         # File currently set to -S 1M -c 1
6828
6829         # Ensure striping is preserved if -R is not set, and no stripe
6830         # count or size is specified
6831         echo -n "Verifying striping size preserved when not specified..."
6832         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6833         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6834                 error "cannot set stripe on parent directory"
6835         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6836                 error "migrate failed"
6837         cur_ssize=$($LFS getstripe -S "$file1")
6838         [ $cur_ssize -eq $orig_ssize ] ||
6839                 error "migrate by default $cur_ssize != $orig_ssize"
6840         echo "done."
6841
6842         # Ensure file name properly detected when final option has no argument
6843         echo -n "Verifying file name properly detected..."
6844         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6845                 error "file name interpreted as option argument"
6846         echo "done."
6847
6848         # Clean up
6849         rm -f "$file1"
6850 }
6851 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6852
6853 test_56wd() {
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6855
6856         local file1=$DIR/$tdir/file1
6857
6858         echo -n "Creating test dir..."
6859         test_mkdir $DIR/$tdir || error "cannot create dir"
6860         echo "done."
6861
6862         echo -n "Creating test file..."
6863         touch $file1
6864         echo "done."
6865
6866         # Ensure 'lfs migrate' will fail by using a non-existent option,
6867         # and make sure rsync is not called to recover
6868         echo -n "Make sure --no-rsync option works..."
6869         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6870                 grep -q 'refusing to fall back to rsync' ||
6871                 error "rsync was called with --no-rsync set"
6872         echo "done."
6873
6874         # Ensure rsync is called without trying 'lfs migrate' first
6875         echo -n "Make sure --rsync option works..."
6876         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6877                 grep -q 'falling back to rsync' &&
6878                 error "lfs migrate was called with --rsync set"
6879         echo "done."
6880
6881         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6882         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6883                 grep -q 'at the same time' ||
6884                 error "--rsync and --no-rsync accepted concurrently"
6885         echo "done."
6886
6887         # Clean up
6888         rm -f $file1
6889 }
6890 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6891
6892 test_56we() {
6893         local td=$DIR/$tdir
6894         local tf=$td/$tfile
6895
6896         test_mkdir $td || error "cannot create $td"
6897         touch $tf || error "cannot touch $tf"
6898
6899         echo -n "Make sure --non-direct|-D works..."
6900         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6901                 grep -q "lfs migrate --non-direct" ||
6902                 error "--non-direct option cannot work correctly"
6903         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6904                 grep -q "lfs migrate -D" ||
6905                 error "-D option cannot work correctly"
6906         echo "done."
6907 }
6908 run_test 56we "check lfs_migrate --non-direct|-D support"
6909
6910 test_56x() {
6911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6912         check_swap_layouts_support
6913
6914         local dir=$DIR/$tdir
6915         local ref1=/etc/passwd
6916         local file1=$dir/file1
6917
6918         test_mkdir $dir || error "creating dir $dir"
6919         $LFS setstripe -c 2 $file1
6920         cp $ref1 $file1
6921         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6922         stripe=$($LFS getstripe -c $file1)
6923         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6924         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6925
6926         # clean up
6927         rm -f $file1
6928 }
6929 run_test 56x "lfs migration support"
6930
6931 test_56xa() {
6932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6933         check_swap_layouts_support
6934
6935         local dir=$DIR/$tdir/$testnum
6936
6937         test_mkdir -p $dir
6938
6939         local ref1=/etc/passwd
6940         local file1=$dir/file1
6941
6942         $LFS setstripe -c 2 $file1
6943         cp $ref1 $file1
6944         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6945
6946         local stripe=$($LFS getstripe -c $file1)
6947
6948         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6949         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6950
6951         # clean up
6952         rm -f $file1
6953 }
6954 run_test 56xa "lfs migration --block support"
6955
6956 check_migrate_links() {
6957         local dir="$1"
6958         local file1="$dir/file1"
6959         local begin="$2"
6960         local count="$3"
6961         local runas="$4"
6962         local total_count=$(($begin + $count - 1))
6963         local symlink_count=10
6964         local uniq_count=10
6965
6966         if [ ! -f "$file1" ]; then
6967                 echo -n "creating initial file..."
6968                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6969                         error "cannot setstripe initial file"
6970                 echo "done"
6971
6972                 echo -n "creating symlinks..."
6973                 for s in $(seq 1 $symlink_count); do
6974                         ln -s "$file1" "$dir/slink$s" ||
6975                                 error "cannot create symlinks"
6976                 done
6977                 echo "done"
6978
6979                 echo -n "creating nonlinked files..."
6980                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6981                         error "cannot create nonlinked files"
6982                 echo "done"
6983         fi
6984
6985         # create hard links
6986         if [ ! -f "$dir/file$total_count" ]; then
6987                 echo -n "creating hard links $begin:$total_count..."
6988                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6989                         /dev/null || error "cannot create hard links"
6990                 echo "done"
6991         fi
6992
6993         echo -n "checking number of hard links listed in xattrs..."
6994         local fid=$($LFS getstripe -F "$file1")
6995         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6996
6997         echo "${#paths[*]}"
6998         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6999                         skip "hard link list has unexpected size, skipping test"
7000         fi
7001         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7002                         error "link names should exceed xattrs size"
7003         fi
7004
7005         echo -n "migrating files..."
7006         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7007         local rc=$?
7008         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7009         echo "done"
7010
7011         # make sure all links have been properly migrated
7012         echo -n "verifying files..."
7013         fid=$($LFS getstripe -F "$file1") ||
7014                 error "cannot get fid for file $file1"
7015         for i in $(seq 2 $total_count); do
7016                 local fid2=$($LFS getstripe -F $dir/file$i)
7017
7018                 [ "$fid2" == "$fid" ] ||
7019                         error "migrated hard link has mismatched FID"
7020         done
7021
7022         # make sure hard links were properly detected, and migration was
7023         # performed only once for the entire link set; nonlinked files should
7024         # also be migrated
7025         local actual=$(grep -c 'done' <<< "$migrate_out")
7026         local expected=$(($uniq_count + 1))
7027
7028         [ "$actual" -eq  "$expected" ] ||
7029                 error "hard links individually migrated ($actual != $expected)"
7030
7031         # make sure the correct number of hard links are present
7032         local hardlinks=$(stat -c '%h' "$file1")
7033
7034         [ $hardlinks -eq $total_count ] ||
7035                 error "num hard links $hardlinks != $total_count"
7036         echo "done"
7037
7038         return 0
7039 }
7040
7041 test_56xb() {
7042         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7043                 skip "Need MDS version at least 2.10.55"
7044
7045         local dir="$DIR/$tdir"
7046
7047         test_mkdir "$dir" || error "cannot create dir $dir"
7048
7049         echo "testing lfs migrate mode when all links fit within xattrs"
7050         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7051
7052         echo "testing rsync mode when all links fit within xattrs"
7053         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7054
7055         echo "testing lfs migrate mode when all links do not fit within xattrs"
7056         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7057
7058         echo "testing rsync mode when all links do not fit within xattrs"
7059         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7060
7061         chown -R $RUNAS_ID $dir
7062         echo "testing non-root lfs migrate mode when not all links are in xattr"
7063         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7064
7065         # clean up
7066         rm -rf $dir
7067 }
7068 run_test 56xb "lfs migration hard link support"
7069
7070 test_56xc() {
7071         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7072
7073         local dir="$DIR/$tdir"
7074
7075         test_mkdir "$dir" || error "cannot create dir $dir"
7076
7077         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7078         echo -n "Setting initial stripe for 20MB test file..."
7079         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7080                 error "cannot setstripe 20MB file"
7081         echo "done"
7082         echo -n "Sizing 20MB test file..."
7083         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7084         echo "done"
7085         echo -n "Verifying small file autostripe count is 1..."
7086         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7087                 error "cannot migrate 20MB file"
7088         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7089                 error "cannot get stripe for $dir/20mb"
7090         [ $stripe_count -eq 1 ] ||
7091                 error "unexpected stripe count $stripe_count for 20MB file"
7092         rm -f "$dir/20mb"
7093         echo "done"
7094
7095         # Test 2: File is small enough to fit within the available space on
7096         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7097         # have at least an additional 1KB for each desired stripe for test 3
7098         echo -n "Setting stripe for 1GB test file..."
7099         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7100         echo "done"
7101         echo -n "Sizing 1GB test file..."
7102         # File size is 1GB + 3KB
7103         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7104         echo "done"
7105
7106         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7107         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7108         if (( avail > 524288 * OSTCOUNT )); then
7109                 echo -n "Migrating 1GB file..."
7110                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7111                         error "cannot migrate 1GB file"
7112                 echo "done"
7113                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7114                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7115                         error "cannot getstripe for 1GB file"
7116                 [ $stripe_count -eq 2 ] ||
7117                         error "unexpected stripe count $stripe_count != 2"
7118                 echo "done"
7119         fi
7120
7121         # Test 3: File is too large to fit within the available space on
7122         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7123         if [ $OSTCOUNT -ge 3 ]; then
7124                 # The required available space is calculated as
7125                 # file size (1GB + 3KB) / OST count (3).
7126                 local kb_per_ost=349526
7127
7128                 echo -n "Migrating 1GB file with limit..."
7129                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7130                         error "cannot migrate 1GB file with limit"
7131                 echo "done"
7132
7133                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7134                 echo -n "Verifying 1GB autostripe count with limited space..."
7135                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7136                         error "unexpected stripe count $stripe_count (min 3)"
7137                 echo "done"
7138         fi
7139
7140         # clean up
7141         rm -rf $dir
7142 }
7143 run_test 56xc "lfs migration autostripe"
7144
7145 test_56xd() {
7146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7147
7148         local dir=$DIR/$tdir
7149         local f_mgrt=$dir/$tfile.mgrt
7150         local f_yaml=$dir/$tfile.yaml
7151         local f_copy=$dir/$tfile.copy
7152         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7153         local layout_copy="-c 2 -S 2M -i 1"
7154         local yamlfile=$dir/yamlfile
7155         local layout_before;
7156         local layout_after;
7157
7158         test_mkdir "$dir" || error "cannot create dir $dir"
7159         $LFS setstripe $layout_yaml $f_yaml ||
7160                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7161         $LFS getstripe --yaml $f_yaml > $yamlfile
7162         $LFS setstripe $layout_copy $f_copy ||
7163                 error "cannot setstripe $f_copy with layout $layout_copy"
7164         touch $f_mgrt
7165         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7166
7167         # 1. test option --yaml
7168         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7169                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7170         layout_before=$(get_layout_param $f_yaml)
7171         layout_after=$(get_layout_param $f_mgrt)
7172         [ "$layout_after" == "$layout_before" ] ||
7173                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7174
7175         # 2. test option --copy
7176         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7177                 error "cannot migrate $f_mgrt with --copy $f_copy"
7178         layout_before=$(get_layout_param $f_copy)
7179         layout_after=$(get_layout_param $f_mgrt)
7180         [ "$layout_after" == "$layout_before" ] ||
7181                 error "lfs_migrate --copy: $layout_after != $layout_before"
7182 }
7183 run_test 56xd "check lfs_migrate --yaml and --copy support"
7184
7185 test_56xe() {
7186         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7187
7188         local dir=$DIR/$tdir
7189         local f_comp=$dir/$tfile
7190         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7191         local layout_before=""
7192         local layout_after=""
7193
7194         test_mkdir "$dir" || error "cannot create dir $dir"
7195         $LFS setstripe $layout $f_comp ||
7196                 error "cannot setstripe $f_comp with layout $layout"
7197         layout_before=$(get_layout_param $f_comp)
7198         dd if=/dev/zero of=$f_comp bs=1M count=4
7199
7200         # 1. migrate a comp layout file by lfs_migrate
7201         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7202         layout_after=$(get_layout_param $f_comp)
7203         [ "$layout_before" == "$layout_after" ] ||
7204                 error "lfs_migrate: $layout_before != $layout_after"
7205
7206         # 2. migrate a comp layout file by lfs migrate
7207         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7208         layout_after=$(get_layout_param $f_comp)
7209         [ "$layout_before" == "$layout_after" ] ||
7210                 error "lfs migrate: $layout_before != $layout_after"
7211 }
7212 run_test 56xe "migrate a composite layout file"
7213
7214 test_56xf() {
7215         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7216
7217         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7218                 skip "Need server version at least 2.13.53"
7219
7220         local dir=$DIR/$tdir
7221         local f_comp=$dir/$tfile
7222         local layout="-E 1M -c1 -E -1 -c2"
7223         local fid_before=""
7224         local fid_after=""
7225
7226         test_mkdir "$dir" || error "cannot create dir $dir"
7227         $LFS setstripe $layout $f_comp ||
7228                 error "cannot setstripe $f_comp with layout $layout"
7229         fid_before=$($LFS getstripe --fid $f_comp)
7230         dd if=/dev/zero of=$f_comp bs=1M count=4
7231
7232         # 1. migrate a comp layout file to a comp layout
7233         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7234         fid_after=$($LFS getstripe --fid $f_comp)
7235         [ "$fid_before" == "$fid_after" ] ||
7236                 error "comp-to-comp migrate: $fid_before != $fid_after"
7237
7238         # 2. migrate a comp layout file to a plain layout
7239         $LFS migrate -c2 $f_comp ||
7240                 error "cannot migrate $f_comp by lfs migrate"
7241         fid_after=$($LFS getstripe --fid $f_comp)
7242         [ "$fid_before" == "$fid_after" ] ||
7243                 error "comp-to-plain migrate: $fid_before != $fid_after"
7244
7245         # 3. migrate a plain layout file to a comp layout
7246         $LFS migrate $layout $f_comp ||
7247                 error "cannot migrate $f_comp by lfs migrate"
7248         fid_after=$($LFS getstripe --fid $f_comp)
7249         [ "$fid_before" == "$fid_after" ] ||
7250                 error "plain-to-comp migrate: $fid_before != $fid_after"
7251 }
7252 run_test 56xf "FID is not lost during migration of a composite layout file"
7253
7254 test_56y() {
7255         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7256                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7257
7258         local res=""
7259         local dir=$DIR/$tdir
7260         local f1=$dir/file1
7261         local f2=$dir/file2
7262
7263         test_mkdir -p $dir || error "creating dir $dir"
7264         touch $f1 || error "creating std file $f1"
7265         $MULTIOP $f2 H2c || error "creating released file $f2"
7266
7267         # a directory can be raid0, so ask only for files
7268         res=$($LFS find $dir -L raid0 -type f | wc -l)
7269         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7270
7271         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7272         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7273
7274         # only files can be released, so no need to force file search
7275         res=$($LFS find $dir -L released)
7276         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7277
7278         res=$($LFS find $dir -type f \! -L released)
7279         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7280 }
7281 run_test 56y "lfs find -L raid0|released"
7282
7283 test_56z() { # LU-4824
7284         # This checks to make sure 'lfs find' continues after errors
7285         # There are two classes of errors that should be caught:
7286         # - If multiple paths are provided, all should be searched even if one
7287         #   errors out
7288         # - If errors are encountered during the search, it should not terminate
7289         #   early
7290         local dir=$DIR/$tdir
7291         local i
7292
7293         test_mkdir $dir
7294         for i in d{0..9}; do
7295                 test_mkdir $dir/$i
7296                 touch $dir/$i/$tfile
7297         done
7298         $LFS find $DIR/non_existent_dir $dir &&
7299                 error "$LFS find did not return an error"
7300         # Make a directory unsearchable. This should NOT be the last entry in
7301         # directory order.  Arbitrarily pick the 6th entry
7302         chmod 700 $($LFS find $dir -type d | sed '6!d')
7303
7304         $RUNAS $LFS find $DIR/non_existent $dir
7305         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7306
7307         # The user should be able to see 10 directories and 9 files
7308         (( count == 19 )) ||
7309                 error "$LFS find found $count != 19 entries after error"
7310 }
7311 run_test 56z "lfs find should continue after an error"
7312
7313 test_56aa() { # LU-5937
7314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7315
7316         local dir=$DIR/$tdir
7317
7318         mkdir $dir
7319         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7320
7321         createmany -o $dir/striped_dir/${tfile}- 1024
7322         local dirs=$($LFS find --size +8k $dir/)
7323
7324         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7325 }
7326 run_test 56aa "lfs find --size under striped dir"
7327
7328 test_56ab() { # LU-10705
7329         test_mkdir $DIR/$tdir
7330         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7331         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7332         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7333         # Flush writes to ensure valid blocks.  Need to be more thorough for
7334         # ZFS, since blocks are not allocated/returned to client immediately.
7335         sync_all_data
7336         wait_zfs_commit ost1 2
7337         cancel_lru_locks osc
7338         ls -ls $DIR/$tdir
7339
7340         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7341
7342         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7343
7344         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7345         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7346
7347         rm -f $DIR/$tdir/$tfile.[123]
7348 }
7349 run_test 56ab "lfs find --blocks"
7350
7351 test_56ba() {
7352         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7353                 skip "Need MDS version at least 2.10.50"
7354
7355         # Create composite files with one component
7356         local dir=$DIR/$tdir
7357
7358         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7359         # Create composite files with three components
7360         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7361         # Create non-composite files
7362         createmany -o $dir/${tfile}- 10
7363
7364         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7365
7366         [[ $nfiles == 10 ]] ||
7367                 error "lfs find -E 1M found $nfiles != 10 files"
7368
7369         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7370         [[ $nfiles == 25 ]] ||
7371                 error "lfs find ! -E 1M found $nfiles != 25 files"
7372
7373         # All files have a component that starts at 0
7374         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7375         [[ $nfiles == 35 ]] ||
7376                 error "lfs find --component-start 0 - $nfiles != 35 files"
7377
7378         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7379         [[ $nfiles == 15 ]] ||
7380                 error "lfs find --component-start 2M - $nfiles != 15 files"
7381
7382         # All files created here have a componenet that does not starts at 2M
7383         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7384         [[ $nfiles == 35 ]] ||
7385                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7386
7387         # Find files with a specified number of components
7388         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7389         [[ $nfiles == 15 ]] ||
7390                 error "lfs find --component-count 3 - $nfiles != 15 files"
7391
7392         # Remember non-composite files have a component count of zero
7393         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7394         [[ $nfiles == 10 ]] ||
7395                 error "lfs find --component-count 0 - $nfiles != 10 files"
7396
7397         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7398         [[ $nfiles == 20 ]] ||
7399                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7400
7401         # All files have a flag called "init"
7402         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7403         [[ $nfiles == 35 ]] ||
7404                 error "lfs find --component-flags init - $nfiles != 35 files"
7405
7406         # Multi-component files will have a component not initialized
7407         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7408         [[ $nfiles == 15 ]] ||
7409                 error "lfs find !--component-flags init - $nfiles != 15 files"
7410
7411         rm -rf $dir
7412
7413 }
7414 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7415
7416 test_56ca() {
7417         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7418                 skip "Need MDS version at least 2.10.57"
7419
7420         local td=$DIR/$tdir
7421         local tf=$td/$tfile
7422         local dir
7423         local nfiles
7424         local cmd
7425         local i
7426         local j
7427
7428         # create mirrored directories and mirrored files
7429         mkdir $td || error "mkdir $td failed"
7430         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7431         createmany -o $tf- 10 || error "create $tf- failed"
7432
7433         for i in $(seq 2); do
7434                 dir=$td/dir$i
7435                 mkdir $dir || error "mkdir $dir failed"
7436                 $LFS mirror create -N$((3 + i)) $dir ||
7437                         error "create mirrored dir $dir failed"
7438                 createmany -o $dir/$tfile- 10 ||
7439                         error "create $dir/$tfile- failed"
7440         done
7441
7442         # change the states of some mirrored files
7443         echo foo > $tf-6
7444         for i in $(seq 2); do
7445                 dir=$td/dir$i
7446                 for j in $(seq 4 9); do
7447                         echo foo > $dir/$tfile-$j
7448                 done
7449         done
7450
7451         # find mirrored files with specific mirror count
7452         cmd="$LFS find --mirror-count 3 --type f $td"
7453         nfiles=$($cmd | wc -l)
7454         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7455
7456         cmd="$LFS find ! --mirror-count 3 --type f $td"
7457         nfiles=$($cmd | wc -l)
7458         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7459
7460         cmd="$LFS find --mirror-count +2 --type f $td"
7461         nfiles=$($cmd | wc -l)
7462         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7463
7464         cmd="$LFS find --mirror-count -6 --type f $td"
7465         nfiles=$($cmd | wc -l)
7466         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7467
7468         # find mirrored files with specific file state
7469         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7470         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7471
7472         cmd="$LFS find --mirror-state=ro --type f $td"
7473         nfiles=$($cmd | wc -l)
7474         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7475
7476         cmd="$LFS find ! --mirror-state=ro --type f $td"
7477         nfiles=$($cmd | wc -l)
7478         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7479
7480         cmd="$LFS find --mirror-state=wp --type f $td"
7481         nfiles=$($cmd | wc -l)
7482         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7483
7484         cmd="$LFS find ! --mirror-state=sp --type f $td"
7485         nfiles=$($cmd | wc -l)
7486         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7487 }
7488 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7489
7490 test_57a() {
7491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7492         # note test will not do anything if MDS is not local
7493         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7494                 skip_env "ldiskfs only test"
7495         fi
7496         remote_mds_nodsh && skip "remote MDS with nodsh"
7497
7498         local MNTDEV="osd*.*MDT*.mntdev"
7499         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7500         [ -z "$DEV" ] && error "can't access $MNTDEV"
7501         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7502                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7503                         error "can't access $DEV"
7504                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7505                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7506                 rm $TMP/t57a.dump
7507         done
7508 }
7509 run_test 57a "verify MDS filesystem created with large inodes =="
7510
7511 test_57b() {
7512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7513         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7514                 skip_env "ldiskfs only test"
7515         fi
7516         remote_mds_nodsh && skip "remote MDS with nodsh"
7517
7518         local dir=$DIR/$tdir
7519         local filecount=100
7520         local file1=$dir/f1
7521         local fileN=$dir/f$filecount
7522
7523         rm -rf $dir || error "removing $dir"
7524         test_mkdir -c1 $dir
7525         local mdtidx=$($LFS getstripe -m $dir)
7526         local mdtname=MDT$(printf %04x $mdtidx)
7527         local facet=mds$((mdtidx + 1))
7528
7529         echo "mcreating $filecount files"
7530         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7531
7532         # verify that files do not have EAs yet
7533         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7534                 error "$file1 has an EA"
7535         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7536                 error "$fileN has an EA"
7537
7538         sync
7539         sleep 1
7540         df $dir  #make sure we get new statfs data
7541         local mdsfree=$(do_facet $facet \
7542                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7543         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7544         local file
7545
7546         echo "opening files to create objects/EAs"
7547         for file in $(seq -f $dir/f%g 1 $filecount); do
7548                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7549                         error "opening $file"
7550         done
7551
7552         # verify that files have EAs now
7553         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7554         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7555
7556         sleep 1  #make sure we get new statfs data
7557         df $dir
7558         local mdsfree2=$(do_facet $facet \
7559                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7560         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7561
7562         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7563                 if [ "$mdsfree" != "$mdsfree2" ]; then
7564                         error "MDC before $mdcfree != after $mdcfree2"
7565                 else
7566                         echo "MDC before $mdcfree != after $mdcfree2"
7567                         echo "unable to confirm if MDS has large inodes"
7568                 fi
7569         fi
7570         rm -rf $dir
7571 }
7572 run_test 57b "default LOV EAs are stored inside large inodes ==="
7573
7574 test_58() {
7575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7576         [ -z "$(which wiretest 2>/dev/null)" ] &&
7577                         skip_env "could not find wiretest"
7578
7579         wiretest
7580 }
7581 run_test 58 "verify cross-platform wire constants =============="
7582
7583 test_59() {
7584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7585
7586         echo "touch 130 files"
7587         createmany -o $DIR/f59- 130
7588         echo "rm 130 files"
7589         unlinkmany $DIR/f59- 130
7590         sync
7591         # wait for commitment of removal
7592         wait_delete_completed
7593 }
7594 run_test 59 "verify cancellation of llog records async ========="
7595
7596 TEST60_HEAD="test_60 run $RANDOM"
7597 test_60a() {
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599         remote_mgs_nodsh && skip "remote MGS with nodsh"
7600         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7601                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7602                         skip_env "missing subtest run-llog.sh"
7603
7604         log "$TEST60_HEAD - from kernel mode"
7605         do_facet mgs "$LCTL dk > /dev/null"
7606         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7607         do_facet mgs $LCTL dk > $TMP/$tfile
7608
7609         # LU-6388: test llog_reader
7610         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7611         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7612         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7613                         skip_env "missing llog_reader"
7614         local fstype=$(facet_fstype mgs)
7615         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7616                 skip_env "Only for ldiskfs or zfs type mgs"
7617
7618         local mntpt=$(facet_mntpt mgs)
7619         local mgsdev=$(mgsdevname 1)
7620         local fid_list
7621         local fid
7622         local rec_list
7623         local rec
7624         local rec_type
7625         local obj_file
7626         local path
7627         local seq
7628         local oid
7629         local pass=true
7630
7631         #get fid and record list
7632         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7633                 tail -n 4))
7634         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7635                 tail -n 4))
7636         #remount mgs as ldiskfs or zfs type
7637         stop mgs || error "stop mgs failed"
7638         mount_fstype mgs || error "remount mgs failed"
7639         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7640                 fid=${fid_list[i]}
7641                 rec=${rec_list[i]}
7642                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7643                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7644                 oid=$((16#$oid))
7645
7646                 case $fstype in
7647                         ldiskfs )
7648                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7649                         zfs )
7650                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7651                 esac
7652                 echo "obj_file is $obj_file"
7653                 do_facet mgs $llog_reader $obj_file
7654
7655                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7656                         awk '{ print $3 }' | sed -e "s/^type=//g")
7657                 if [ $rec_type != $rec ]; then
7658                         echo "FAILED test_60a wrong record type $rec_type," \
7659                               "should be $rec"
7660                         pass=false
7661                         break
7662                 fi
7663
7664                 #check obj path if record type is LLOG_LOGID_MAGIC
7665                 if [ "$rec" == "1064553b" ]; then
7666                         path=$(do_facet mgs $llog_reader $obj_file |
7667                                 grep "path=" | awk '{ print $NF }' |
7668                                 sed -e "s/^path=//g")
7669                         if [ $obj_file != $mntpt/$path ]; then
7670                                 echo "FAILED test_60a wrong obj path" \
7671                                       "$montpt/$path, should be $obj_file"
7672                                 pass=false
7673                                 break
7674                         fi
7675                 fi
7676         done
7677         rm -f $TMP/$tfile
7678         #restart mgs before "error", otherwise it will block the next test
7679         stop mgs || error "stop mgs failed"
7680         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7681         $pass || error "test failed, see FAILED test_60a messages for specifics"
7682 }
7683 run_test 60a "llog_test run from kernel module and test llog_reader"
7684
7685 test_60b() { # bug 6411
7686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7687
7688         dmesg > $DIR/$tfile
7689         LLOG_COUNT=$(do_facet mgs dmesg |
7690                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7691                           /llog_[a-z]*.c:[0-9]/ {
7692                                 if (marker)
7693                                         from_marker++
7694                                 from_begin++
7695                           }
7696                           END {
7697                                 if (marker)
7698                                         print from_marker
7699                                 else
7700                                         print from_begin
7701                           }")
7702
7703         [[ $LLOG_COUNT -gt 120 ]] &&
7704                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7705 }
7706 run_test 60b "limit repeated messages from CERROR/CWARN"
7707
7708 test_60c() {
7709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7710
7711         echo "create 5000 files"
7712         createmany -o $DIR/f60c- 5000
7713 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7714         lctl set_param fail_loc=0x80000137
7715         unlinkmany $DIR/f60c- 5000
7716         lctl set_param fail_loc=0
7717 }
7718 run_test 60c "unlink file when mds full"
7719
7720 test_60d() {
7721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7722
7723         SAVEPRINTK=$(lctl get_param -n printk)
7724         # verify "lctl mark" is even working"
7725         MESSAGE="test message ID $RANDOM $$"
7726         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7727         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7728
7729         lctl set_param printk=0 || error "set lnet.printk failed"
7730         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7731         MESSAGE="new test message ID $RANDOM $$"
7732         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7733         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7734         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7735
7736         lctl set_param -n printk="$SAVEPRINTK"
7737 }
7738 run_test 60d "test printk console message masking"
7739
7740 test_60e() {
7741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7742         remote_mds_nodsh && skip "remote MDS with nodsh"
7743
7744         touch $DIR/$tfile
7745 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7746         do_facet mds1 lctl set_param fail_loc=0x15b
7747         rm $DIR/$tfile
7748 }
7749 run_test 60e "no space while new llog is being created"
7750
7751 test_60g() {
7752         local pid
7753         local i
7754
7755         test_mkdir -c $MDSCOUNT $DIR/$tdir
7756
7757         (
7758                 local index=0
7759                 while true; do
7760                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7761                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7762                                 2>/dev/null
7763                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7764                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7765                         index=$((index + 1))
7766                 done
7767         ) &
7768
7769         pid=$!
7770
7771         for i in {0..100}; do
7772                 # define OBD_FAIL_OSD_TXN_START    0x19a
7773                 local index=$((i % MDSCOUNT + 1))
7774
7775                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7776                         > /dev/null
7777                 sleep 0.01
7778         done
7779
7780         kill -9 $pid
7781
7782         for i in $(seq $MDSCOUNT); do
7783                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7784         done
7785
7786         mkdir $DIR/$tdir/new || error "mkdir failed"
7787         rmdir $DIR/$tdir/new || error "rmdir failed"
7788
7789         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7790                 -t namespace
7791         for i in $(seq $MDSCOUNT); do
7792                 wait_update_facet mds$i "$LCTL get_param -n \
7793                         mdd.$(facet_svc mds$i).lfsck_namespace |
7794                         awk '/^status/ { print \\\$2 }'" "completed"
7795         done
7796
7797         ls -R $DIR/$tdir || error "ls failed"
7798         rm -rf $DIR/$tdir || error "rmdir failed"
7799 }
7800 run_test 60g "transaction abort won't cause MDT hung"
7801
7802 test_60h() {
7803         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7804                 skip "Need MDS version at least 2.12.52"
7805         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7806
7807         local f
7808
7809         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7810         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7811         for fail_loc in 0x80000188 0x80000189; do
7812                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7813                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7814                         error "mkdir $dir-$fail_loc failed"
7815                 for i in {0..10}; do
7816                         # create may fail on missing stripe
7817                         echo $i > $DIR/$tdir-$fail_loc/$i
7818                 done
7819                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7820                         error "getdirstripe $tdir-$fail_loc failed"
7821                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7822                         error "migrate $tdir-$fail_loc failed"
7823                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7824                         error "getdirstripe $tdir-$fail_loc failed"
7825                 pushd $DIR/$tdir-$fail_loc
7826                 for f in *; do
7827                         echo $f | cmp $f - || error "$f data mismatch"
7828                 done
7829                 popd
7830                 rm -rf $DIR/$tdir-$fail_loc
7831         done
7832 }
7833 run_test 60h "striped directory with missing stripes can be accessed"
7834
7835 test_61a() {
7836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7837
7838         f="$DIR/f61"
7839         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7840         cancel_lru_locks osc
7841         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7842         sync
7843 }
7844 run_test 61a "mmap() writes don't make sync hang ================"
7845
7846 test_61b() {
7847         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7848 }
7849 run_test 61b "mmap() of unstriped file is successful"
7850
7851 # bug 2330 - insufficient obd_match error checking causes LBUG
7852 test_62() {
7853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7854
7855         f="$DIR/f62"
7856         echo foo > $f
7857         cancel_lru_locks osc
7858         lctl set_param fail_loc=0x405
7859         cat $f && error "cat succeeded, expect -EIO"
7860         lctl set_param fail_loc=0
7861 }
7862 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7863 # match every page all of the time.
7864 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7865
7866 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7867 # Though this test is irrelevant anymore, it helped to reveal some
7868 # other grant bugs (LU-4482), let's keep it.
7869 test_63a() {   # was test_63
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871
7872         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7873
7874         for i in `seq 10` ; do
7875                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7876                 sleep 5
7877                 kill $!
7878                 sleep 1
7879         done
7880
7881         rm -f $DIR/f63 || true
7882 }
7883 run_test 63a "Verify oig_wait interruption does not crash ======="
7884
7885 # bug 2248 - async write errors didn't return to application on sync
7886 # bug 3677 - async write errors left page locked
7887 test_63b() {
7888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7889
7890         debugsave
7891         lctl set_param debug=-1
7892
7893         # ensure we have a grant to do async writes
7894         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7895         rm $DIR/$tfile
7896
7897         sync    # sync lest earlier test intercept the fail_loc
7898
7899         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7900         lctl set_param fail_loc=0x80000406
7901         $MULTIOP $DIR/$tfile Owy && \
7902                 error "sync didn't return ENOMEM"
7903         sync; sleep 2; sync     # do a real sync this time to flush page
7904         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7905                 error "locked page left in cache after async error" || true
7906         debugrestore
7907 }
7908 run_test 63b "async write errors should be returned to fsync ==="
7909
7910 test_64a () {
7911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7912
7913         lfs df $DIR
7914         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7915 }
7916 run_test 64a "verify filter grant calculations (in kernel) ====="
7917
7918 test_64b () {
7919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7920
7921         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7922 }
7923 run_test 64b "check out-of-space detection on client"
7924
7925 test_64c() {
7926         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7927 }
7928 run_test 64c "verify grant shrink"
7929
7930 import_param() {
7931         local tgt=$1
7932         local param=$2
7933
7934         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7935 }
7936
7937 # this does exactly what osc_request.c:osc_announce_cached() does in
7938 # order to calculate max amount of grants to ask from server
7939 want_grant() {
7940         local tgt=$1
7941
7942         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7943         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7944
7945         ((rpc_in_flight++));
7946         nrpages=$((nrpages * rpc_in_flight))
7947
7948         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7949
7950         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7951
7952         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7953         local undirty=$((nrpages * PAGE_SIZE))
7954
7955         local max_extent_pages
7956         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7957         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7958         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7959         local grant_extent_tax
7960         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7961
7962         undirty=$((undirty + nrextents * grant_extent_tax))
7963
7964         echo $undirty
7965 }
7966
7967 # this is size of unit for grant allocation. It should be equal to
7968 # what tgt_grant.c:tgt_grant_chunk() calculates
7969 grant_chunk() {
7970         local tgt=$1
7971         local max_brw_size
7972         local grant_extent_tax
7973
7974         max_brw_size=$(import_param $tgt max_brw_size)
7975
7976         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7977
7978         echo $(((max_brw_size + grant_extent_tax) * 2))
7979 }
7980
7981 test_64d() {
7982         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7983                 skip "OST < 2.10.55 doesn't limit grants enough"
7984
7985         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7986
7987         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7988                 skip "no grant_param connect flag"
7989
7990         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7991
7992         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7993         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7994
7995
7996         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7997         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7998
7999         $LFS setstripe $DIR/$tfile -i 0 -c 1
8000         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8001         ddpid=$!
8002
8003         while kill -0 $ddpid; do
8004                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8005
8006                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8007                         kill $ddpid
8008                         error "cur_grant $cur_grant > $max_cur_granted"
8009                 fi
8010
8011                 sleep 1
8012         done
8013 }
8014 run_test 64d "check grant limit exceed"
8015
8016 check_grants() {
8017         local tgt=$1
8018         local expected=$2
8019         local msg=$3
8020         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8021
8022         ((cur_grants == expected)) ||
8023                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8024 }
8025
8026 round_up_p2() {
8027         echo $((($1 + $2 - 1) & ~($2 - 1)))
8028 }
8029
8030 test_64e() {
8031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8032         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8033                 skip "Need OSS version at least 2.11.56"
8034
8035         # Remount client to reset grant
8036         remount_client $MOUNT || error "failed to remount client"
8037         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8038
8039         local init_grants=$(import_param $osc_tgt initial_grant)
8040
8041         check_grants $osc_tgt $init_grants "init grants"
8042
8043         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8044         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8045         local gbs=$(import_param $osc_tgt grant_block_size)
8046
8047         # write random number of bytes from max_brw_size / 4 to max_brw_size
8048         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8049         # align for direct io
8050         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8051         # round to grant consumption unit
8052         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8053
8054         local grants=$((wb_round_up + extent_tax))
8055
8056         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8057
8058         # define OBD_FAIL_TGT_NO_GRANT 0x725
8059         # make the server not grant more back
8060         do_facet ost1 $LCTL set_param fail_loc=0x725
8061         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8062
8063         do_facet ost1 $LCTL set_param fail_loc=0
8064
8065         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8066
8067         rm -f $DIR/$tfile || error "rm failed"
8068
8069         # Remount client to reset grant
8070         remount_client $MOUNT || error "failed to remount client"
8071         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8072
8073         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8074
8075         # define OBD_FAIL_TGT_NO_GRANT 0x725
8076         # make the server not grant more back
8077         do_facet ost1 $LCTL set_param fail_loc=0x725
8078         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8079         do_facet ost1 $LCTL set_param fail_loc=0
8080
8081         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8082 }
8083 run_test 64e "check grant consumption (no grant allocation)"
8084
8085 test_64f() {
8086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8087
8088         # Remount client to reset grant
8089         remount_client $MOUNT || error "failed to remount client"
8090         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8091
8092         local init_grants=$(import_param $osc_tgt initial_grant)
8093         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8094         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8095         local gbs=$(import_param $osc_tgt grant_block_size)
8096         local chunk=$(grant_chunk $osc_tgt)
8097
8098         # write random number of bytes from max_brw_size / 4 to max_brw_size
8099         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8100         # align for direct io
8101         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8102         # round to grant consumption unit
8103         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8104
8105         local grants=$((wb_round_up + extent_tax))
8106
8107         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8108         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8109                 error "error writing to $DIR/$tfile"
8110
8111         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8112                 "direct io with grant allocation"
8113
8114         rm -f $DIR/$tfile || error "rm failed"
8115
8116         # Remount client to reset grant
8117         remount_client $MOUNT || error "failed to remount client"
8118         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8119
8120         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8121
8122         local cmd="oO_WRONLY:w${write_bytes}_yc"
8123
8124         $MULTIOP $DIR/$tfile $cmd &
8125         MULTIPID=$!
8126         sleep 1
8127
8128         check_grants $osc_tgt $((init_grants - grants)) \
8129                 "buffered io, not write rpc"
8130
8131         kill -USR1 $MULTIPID
8132         wait
8133
8134         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8135                 "buffered io, one RPC"
8136 }
8137 run_test 64f "check grant consumption (with grant allocation)"
8138
8139 # bug 1414 - set/get directories' stripe info
8140 test_65a() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142
8143         test_mkdir $DIR/$tdir
8144         touch $DIR/$tdir/f1
8145         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8146 }
8147 run_test 65a "directory with no stripe info"
8148
8149 test_65b() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         test_mkdir $DIR/$tdir
8153         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8154
8155         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8156                                                 error "setstripe"
8157         touch $DIR/$tdir/f2
8158         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8159 }
8160 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8161
8162 test_65c() {
8163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8164         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8165
8166         test_mkdir $DIR/$tdir
8167         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8168
8169         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8170                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8171         touch $DIR/$tdir/f3
8172         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8173 }
8174 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8175
8176 test_65d() {
8177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8178
8179         test_mkdir $DIR/$tdir
8180         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8181         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8182
8183         if [[ $STRIPECOUNT -le 0 ]]; then
8184                 sc=1
8185         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8186                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8187                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8188         else
8189                 sc=$(($STRIPECOUNT - 1))
8190         fi
8191         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8192         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8193         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8194                 error "lverify failed"
8195 }
8196 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8197
8198 test_65e() {
8199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8200
8201         test_mkdir $DIR/$tdir
8202
8203         $LFS setstripe $DIR/$tdir || error "setstripe"
8204         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8205                                         error "no stripe info failed"
8206         touch $DIR/$tdir/f6
8207         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8208 }
8209 run_test 65e "directory setstripe defaults"
8210
8211 test_65f() {
8212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8213
8214         test_mkdir $DIR/${tdir}f
8215         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8216                 error "setstripe succeeded" || true
8217 }
8218 run_test 65f "dir setstripe permission (should return error) ==="
8219
8220 test_65g() {
8221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8222
8223         test_mkdir $DIR/$tdir
8224         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8225
8226         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8227                 error "setstripe -S failed"
8228         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8229         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8230                 error "delete default stripe failed"
8231 }
8232 run_test 65g "directory setstripe -d"
8233
8234 test_65h() {
8235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8236
8237         test_mkdir $DIR/$tdir
8238         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8239
8240         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8241                 error "setstripe -S failed"
8242         test_mkdir $DIR/$tdir/dd1
8243         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8244                 error "stripe info inherit failed"
8245 }
8246 run_test 65h "directory stripe info inherit ===================="
8247
8248 test_65i() {
8249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8250
8251         save_layout_restore_at_exit $MOUNT
8252
8253         # bug6367: set non-default striping on root directory
8254         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8255
8256         # bug12836: getstripe on -1 default directory striping
8257         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8258
8259         # bug12836: getstripe -v on -1 default directory striping
8260         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8261
8262         # bug12836: new find on -1 default directory striping
8263         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8264 }
8265 run_test 65i "various tests to set root directory striping"
8266
8267 test_65j() { # bug6367
8268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8269
8270         sync; sleep 1
8271
8272         # if we aren't already remounting for each test, do so for this test
8273         if [ "$I_MOUNTED" = "yes" ]; then
8274                 cleanup || error "failed to unmount"
8275                 setup
8276         fi
8277
8278         save_layout_restore_at_exit $MOUNT
8279
8280         $LFS setstripe -d $MOUNT || error "setstripe failed"
8281 }
8282 run_test 65j "set default striping on root directory (bug 6367)="
8283
8284 cleanup_65k() {
8285         rm -rf $DIR/$tdir
8286         wait_delete_completed
8287         do_facet $SINGLEMDS "lctl set_param -n \
8288                 osp.$ost*MDT0000.max_create_count=$max_count"
8289         do_facet $SINGLEMDS "lctl set_param -n \
8290                 osp.$ost*MDT0000.create_count=$count"
8291         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8292         echo $INACTIVE_OSC "is Activate"
8293
8294         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8295 }
8296
8297 test_65k() { # bug11679
8298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8299         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8300         remote_mds_nodsh && skip "remote MDS with nodsh"
8301
8302         local disable_precreate=true
8303         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8304                 disable_precreate=false
8305
8306         echo "Check OST status: "
8307         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8308                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8309
8310         for OSC in $MDS_OSCS; do
8311                 echo $OSC "is active"
8312                 do_facet $SINGLEMDS lctl --device %$OSC activate
8313         done
8314
8315         for INACTIVE_OSC in $MDS_OSCS; do
8316                 local ost=$(osc_to_ost $INACTIVE_OSC)
8317                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8318                                lov.*md*.target_obd |
8319                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8320
8321                 mkdir -p $DIR/$tdir
8322                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8323                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8324
8325                 echo "Deactivate: " $INACTIVE_OSC
8326                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8327
8328                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8329                               osp.$ost*MDT0000.create_count")
8330                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8331                                   osp.$ost*MDT0000.max_create_count")
8332                 $disable_precreate &&
8333                         do_facet $SINGLEMDS "lctl set_param -n \
8334                                 osp.$ost*MDT0000.max_create_count=0"
8335
8336                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8337                         [ -f $DIR/$tdir/$idx ] && continue
8338                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8339                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8340                                 { cleanup_65k;
8341                                   error "setstripe $idx should succeed"; }
8342                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8343                 done
8344                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8345                 rmdir $DIR/$tdir
8346
8347                 do_facet $SINGLEMDS "lctl set_param -n \
8348                         osp.$ost*MDT0000.max_create_count=$max_count"
8349                 do_facet $SINGLEMDS "lctl set_param -n \
8350                         osp.$ost*MDT0000.create_count=$count"
8351                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8352                 echo $INACTIVE_OSC "is Activate"
8353
8354                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8355         done
8356 }
8357 run_test 65k "validate manual striping works properly with deactivated OSCs"
8358
8359 test_65l() { # bug 12836
8360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8361
8362         test_mkdir -p $DIR/$tdir/test_dir
8363         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8364         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8365 }
8366 run_test 65l "lfs find on -1 stripe dir ========================"
8367
8368 test_65m() {
8369         local layout=$(save_layout $MOUNT)
8370         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8371                 restore_layout $MOUNT $layout
8372                 error "setstripe should fail by non-root users"
8373         }
8374         true
8375 }
8376 run_test 65m "normal user can't set filesystem default stripe"
8377
8378 test_65n() {
8379         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8380         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8381                 skip "Need MDS version at least 2.12.50"
8382         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8383
8384         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8385         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8386         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8387
8388         local root_layout=$(save_layout $MOUNT)
8389         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8390
8391         # new subdirectory under root directory should not inherit
8392         # the default layout from root
8393         local dir1=$MOUNT/$tdir-1
8394         mkdir $dir1 || error "mkdir $dir1 failed"
8395         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8396                 error "$dir1 shouldn't have LOV EA"
8397
8398         # delete the default layout on root directory
8399         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8400
8401         local dir2=$MOUNT/$tdir-2
8402         mkdir $dir2 || error "mkdir $dir2 failed"
8403         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8404                 error "$dir2 shouldn't have LOV EA"
8405
8406         # set a new striping pattern on root directory
8407         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8408         local new_def_stripe_size=$((def_stripe_size * 2))
8409         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8410                 error "set stripe size on $MOUNT failed"
8411
8412         # new file created in $dir2 should inherit the new stripe size from
8413         # the filesystem default
8414         local file2=$dir2/$tfile-2
8415         touch $file2 || error "touch $file2 failed"
8416
8417         local file2_stripe_size=$($LFS getstripe -S $file2)
8418         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8419         {
8420                 echo "file2_stripe_size: '$file2_stripe_size'"
8421                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8422                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8423         }
8424
8425         local dir3=$MOUNT/$tdir-3
8426         mkdir $dir3 || error "mkdir $dir3 failed"
8427         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8428         # the root layout, which is the actual default layout that will be used
8429         # when new files are created in $dir3.
8430         local dir3_layout=$(get_layout_param $dir3)
8431         local root_dir_layout=$(get_layout_param $MOUNT)
8432         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8433         {
8434                 echo "dir3_layout: '$dir3_layout'"
8435                 echo "root_dir_layout: '$root_dir_layout'"
8436                 error "$dir3 should show the default layout from $MOUNT"
8437         }
8438
8439         # set OST pool on root directory
8440         local pool=$TESTNAME
8441         pool_add $pool || error "add $pool failed"
8442         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8443                 error "add targets to $pool failed"
8444
8445         $LFS setstripe -p $pool $MOUNT ||
8446                 error "set OST pool on $MOUNT failed"
8447
8448         # new file created in $dir3 should inherit the pool from
8449         # the filesystem default
8450         local file3=$dir3/$tfile-3
8451         touch $file3 || error "touch $file3 failed"
8452
8453         local file3_pool=$($LFS getstripe -p $file3)
8454         [[ "$file3_pool" = "$pool" ]] ||
8455                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8456
8457         local dir4=$MOUNT/$tdir-4
8458         mkdir $dir4 || error "mkdir $dir4 failed"
8459         local dir4_layout=$(get_layout_param $dir4)
8460         root_dir_layout=$(get_layout_param $MOUNT)
8461         echo "$LFS getstripe -d $dir4"
8462         $LFS getstripe -d $dir4
8463         echo "$LFS getstripe -d $MOUNT"
8464         $LFS getstripe -d $MOUNT
8465         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8466         {
8467                 echo "dir4_layout: '$dir4_layout'"
8468                 echo "root_dir_layout: '$root_dir_layout'"
8469                 error "$dir4 should show the default layout from $MOUNT"
8470         }
8471
8472         # new file created in $dir4 should inherit the pool from
8473         # the filesystem default
8474         local file4=$dir4/$tfile-4
8475         touch $file4 || error "touch $file4 failed"
8476
8477         local file4_pool=$($LFS getstripe -p $file4)
8478         [[ "$file4_pool" = "$pool" ]] ||
8479                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8480
8481         # new subdirectory under non-root directory should inherit
8482         # the default layout from its parent directory
8483         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8484                 error "set directory layout on $dir4 failed"
8485
8486         local dir5=$dir4/$tdir-5
8487         mkdir $dir5 || error "mkdir $dir5 failed"
8488
8489         dir4_layout=$(get_layout_param $dir4)
8490         local dir5_layout=$(get_layout_param $dir5)
8491         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8492         {
8493                 echo "dir4_layout: '$dir4_layout'"
8494                 echo "dir5_layout: '$dir5_layout'"
8495                 error "$dir5 should inherit the default layout from $dir4"
8496         }
8497
8498         # though subdir under ROOT doesn't inherit default layout, but
8499         # its sub dir/file should be created with default layout.
8500         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8501         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8502                 skip "Need MDS version at least 2.12.59"
8503
8504         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8505         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8506         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8507
8508         if [ $default_lmv_hash == "none" ]; then
8509                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8510         else
8511                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8512                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8513         fi
8514
8515         $LFS setdirstripe -D -c 2 $MOUNT ||
8516                 error "setdirstripe -D -c 2 failed"
8517         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8518         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8519         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8520 }
8521 run_test 65n "don't inherit default layout from root for new subdirectories"
8522
8523 # bug 2543 - update blocks count on client
8524 test_66() {
8525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8526
8527         COUNT=${COUNT:-8}
8528         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8529         sync; sync_all_data; sync; sync_all_data
8530         cancel_lru_locks osc
8531         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8532         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8533 }
8534 run_test 66 "update inode blocks count on client ==============="
8535
8536 meminfo() {
8537         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8538 }
8539
8540 swap_used() {
8541         swapon -s | awk '($1 == "'$1'") { print $4 }'
8542 }
8543
8544 # bug5265, obdfilter oa2dentry return -ENOENT
8545 # #define OBD_FAIL_SRV_ENOENT 0x217
8546 test_69() {
8547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8548         remote_ost_nodsh && skip "remote OST with nodsh"
8549
8550         f="$DIR/$tfile"
8551         $LFS setstripe -c 1 -i 0 $f
8552
8553         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8554
8555         do_facet ost1 lctl set_param fail_loc=0x217
8556         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8557         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8558
8559         do_facet ost1 lctl set_param fail_loc=0
8560         $DIRECTIO write $f 0 2 || error "write error"
8561
8562         cancel_lru_locks osc
8563         $DIRECTIO read $f 0 1 || error "read error"
8564
8565         do_facet ost1 lctl set_param fail_loc=0x217
8566         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8567
8568         do_facet ost1 lctl set_param fail_loc=0
8569         rm -f $f
8570 }
8571 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8572
8573 test_71() {
8574         test_mkdir $DIR/$tdir
8575         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8576         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8577 }
8578 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8579
8580 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582         [ "$RUNAS_ID" = "$UID" ] &&
8583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8584         # Check that testing environment is properly set up. Skip if not
8585         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8586                 skip_env "User $RUNAS_ID does not exist - skipping"
8587
8588         touch $DIR/$tfile
8589         chmod 777 $DIR/$tfile
8590         chmod ug+s $DIR/$tfile
8591         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8592                 error "$RUNAS dd $DIR/$tfile failed"
8593         # See if we are still setuid/sgid
8594         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8595                 error "S/gid is not dropped on write"
8596         # Now test that MDS is updated too
8597         cancel_lru_locks mdc
8598         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8599                 error "S/gid is not dropped on MDS"
8600         rm -f $DIR/$tfile
8601 }
8602 run_test 72a "Test that remove suid works properly (bug5695) ===="
8603
8604 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8605         local perm
8606
8607         [ "$RUNAS_ID" = "$UID" ] &&
8608                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8609         [ "$RUNAS_ID" -eq 0 ] &&
8610                 skip_env "RUNAS_ID = 0 -- skipping"
8611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8612         # Check that testing environment is properly set up. Skip if not
8613         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8614                 skip_env "User $RUNAS_ID does not exist - skipping"
8615
8616         touch $DIR/${tfile}-f{g,u}
8617         test_mkdir $DIR/${tfile}-dg
8618         test_mkdir $DIR/${tfile}-du
8619         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8620         chmod g+s $DIR/${tfile}-{f,d}g
8621         chmod u+s $DIR/${tfile}-{f,d}u
8622         for perm in 777 2777 4777; do
8623                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8624                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8625                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8626                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8627         done
8628         true
8629 }
8630 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8631
8632 # bug 3462 - multiple simultaneous MDC requests
8633 test_73() {
8634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8635
8636         test_mkdir $DIR/d73-1
8637         test_mkdir $DIR/d73-2
8638         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8639         pid1=$!
8640
8641         lctl set_param fail_loc=0x80000129
8642         $MULTIOP $DIR/d73-1/f73-2 Oc &
8643         sleep 1
8644         lctl set_param fail_loc=0
8645
8646         $MULTIOP $DIR/d73-2/f73-3 Oc &
8647         pid3=$!
8648
8649         kill -USR1 $pid1
8650         wait $pid1 || return 1
8651
8652         sleep 25
8653
8654         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8655         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8656         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8657
8658         rm -rf $DIR/d73-*
8659 }
8660 run_test 73 "multiple MDC requests (should not deadlock)"
8661
8662 test_74a() { # bug 6149, 6184
8663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8664
8665         touch $DIR/f74a
8666         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8667         #
8668         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8669         # will spin in a tight reconnection loop
8670         $LCTL set_param fail_loc=0x8000030e
8671         # get any lock that won't be difficult - lookup works.
8672         ls $DIR/f74a
8673         $LCTL set_param fail_loc=0
8674         rm -f $DIR/f74a
8675         true
8676 }
8677 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8678
8679 test_74b() { # bug 13310
8680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8681
8682         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8683         #
8684         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8685         # will spin in a tight reconnection loop
8686         $LCTL set_param fail_loc=0x8000030e
8687         # get a "difficult" lock
8688         touch $DIR/f74b
8689         $LCTL set_param fail_loc=0
8690         rm -f $DIR/f74b
8691         true
8692 }
8693 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8694
8695 test_74c() {
8696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8697
8698         #define OBD_FAIL_LDLM_NEW_LOCK
8699         $LCTL set_param fail_loc=0x319
8700         touch $DIR/$tfile && error "touch successful"
8701         $LCTL set_param fail_loc=0
8702         true
8703 }
8704 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8705
8706 slab_lic=/sys/kernel/slab/lustre_inode_cache
8707 num_objects() {
8708         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8709         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8710                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8711 }
8712
8713 test_76a() { # Now for b=20433, added originally in b=1443
8714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8715
8716         cancel_lru_locks osc
8717         # there may be some slab objects cached per core
8718         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8719         local before=$(num_objects)
8720         local count=$((512 * cpus))
8721         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8722         local margin=$((count / 10))
8723         if [[ -f $slab_lic/aliases ]]; then
8724                 local aliases=$(cat $slab_lic/aliases)
8725                 (( aliases > 0 )) && margin=$((margin * aliases))
8726         fi
8727
8728         echo "before slab objects: $before"
8729         for i in $(seq $count); do
8730                 touch $DIR/$tfile
8731                 rm -f $DIR/$tfile
8732         done
8733         cancel_lru_locks osc
8734         local after=$(num_objects)
8735         echo "created: $count, after slab objects: $after"
8736         # shared slab counts are not very accurate, allow significant margin
8737         # the main goal is that the cache growth is not permanently > $count
8738         while (( after > before + margin )); do
8739                 sleep 1
8740                 after=$(num_objects)
8741                 wait=$((wait + 1))
8742                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8743                 if (( wait > 60 )); then
8744                         error "inode slab grew from $before+$margin to $after"
8745                 fi
8746         done
8747 }
8748 run_test 76a "confirm clients recycle inodes properly ===="
8749
8750 test_76b() {
8751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8752         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8753
8754         local count=512
8755         local before=$(num_objects)
8756
8757         for i in $(seq $count); do
8758                 mkdir $DIR/$tdir
8759                 rmdir $DIR/$tdir
8760         done
8761
8762         local after=$(num_objects)
8763         local wait=0
8764
8765         while (( after > before )); do
8766                 sleep 1
8767                 after=$(num_objects)
8768                 wait=$((wait + 1))
8769                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8770                 if (( wait > 60 )); then
8771                         error "inode slab grew from $before to $after"
8772                 fi
8773         done
8774
8775         echo "slab objects before: $before, after: $after"
8776 }
8777 run_test 76b "confirm clients recycle directory inodes properly ===="
8778
8779 export ORIG_CSUM=""
8780 set_checksums()
8781 {
8782         # Note: in sptlrpc modes which enable its own bulk checksum, the
8783         # original crc32_le bulk checksum will be automatically disabled,
8784         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8785         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8786         # In this case set_checksums() will not be no-op, because sptlrpc
8787         # bulk checksum will be enabled all through the test.
8788
8789         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8790         lctl set_param -n osc.*.checksums $1
8791         return 0
8792 }
8793
8794 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8795                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8796 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8797                              tr -d [] | head -n1)}
8798 set_checksum_type()
8799 {
8800         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8801         rc=$?
8802         log "set checksum type to $1, rc = $rc"
8803         return $rc
8804 }
8805
8806 get_osc_checksum_type()
8807 {
8808         # arugment 1: OST name, like OST0000
8809         ost=$1
8810         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8811                         sed 's/.*\[\(.*\)\].*/\1/g')
8812         rc=$?
8813         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8814         echo $checksum_type
8815 }
8816
8817 F77_TMP=$TMP/f77-temp
8818 F77SZ=8
8819 setup_f77() {
8820         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8821                 error "error writing to $F77_TMP"
8822 }
8823
8824 test_77a() { # bug 10889
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826         $GSS && skip_env "could not run with gss"
8827
8828         [ ! -f $F77_TMP ] && setup_f77
8829         set_checksums 1
8830         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8831         set_checksums 0
8832         rm -f $DIR/$tfile
8833 }
8834 run_test 77a "normal checksum read/write operation"
8835
8836 test_77b() { # bug 10889
8837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8838         $GSS && skip_env "could not run with gss"
8839
8840         [ ! -f $F77_TMP ] && setup_f77
8841         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8842         $LCTL set_param fail_loc=0x80000409
8843         set_checksums 1
8844
8845         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8846                 error "dd error: $?"
8847         $LCTL set_param fail_loc=0
8848
8849         for algo in $CKSUM_TYPES; do
8850                 cancel_lru_locks osc
8851                 set_checksum_type $algo
8852                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8853                 $LCTL set_param fail_loc=0x80000408
8854                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8855                 $LCTL set_param fail_loc=0
8856         done
8857         set_checksums 0
8858         set_checksum_type $ORIG_CSUM_TYPE
8859         rm -f $DIR/$tfile
8860 }
8861 run_test 77b "checksum error on client write, read"
8862
8863 cleanup_77c() {
8864         trap 0
8865         set_checksums 0
8866         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8867         $check_ost &&
8868                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8869         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8870         $check_ost && [ -n "$ost_file_prefix" ] &&
8871                 do_facet ost1 rm -f ${ost_file_prefix}\*
8872 }
8873
8874 test_77c() {
8875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8876         $GSS && skip_env "could not run with gss"
8877         remote_ost_nodsh && skip "remote OST with nodsh"
8878
8879         local bad1
8880         local osc_file_prefix
8881         local osc_file
8882         local check_ost=false
8883         local ost_file_prefix
8884         local ost_file
8885         local orig_cksum
8886         local dump_cksum
8887         local fid
8888
8889         # ensure corruption will occur on first OSS/OST
8890         $LFS setstripe -i 0 $DIR/$tfile
8891
8892         [ ! -f $F77_TMP ] && setup_f77
8893         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8894                 error "dd write error: $?"
8895         fid=$($LFS path2fid $DIR/$tfile)
8896
8897         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8898         then
8899                 check_ost=true
8900                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8901                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8902         else
8903                 echo "OSS do not support bulk pages dump upon error"
8904         fi
8905
8906         osc_file_prefix=$($LCTL get_param -n debug_path)
8907         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8908
8909         trap cleanup_77c EXIT
8910
8911         set_checksums 1
8912         # enable bulk pages dump upon error on Client
8913         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8914         # enable bulk pages dump upon error on OSS
8915         $check_ost &&
8916                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8917
8918         # flush Client cache to allow next read to reach OSS
8919         cancel_lru_locks osc
8920
8921         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8922         $LCTL set_param fail_loc=0x80000408
8923         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8924         $LCTL set_param fail_loc=0
8925
8926         rm -f $DIR/$tfile
8927
8928         # check cksum dump on Client
8929         osc_file=$(ls ${osc_file_prefix}*)
8930         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8931         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8932         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8933         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8934         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8935                      cksum)
8936         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8937         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8938                 error "dump content does not match on Client"
8939
8940         $check_ost || skip "No need to check cksum dump on OSS"
8941
8942         # check cksum dump on OSS
8943         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8944         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8945         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8946         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8947         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8948                 error "dump content does not match on OSS"
8949
8950         cleanup_77c
8951 }
8952 run_test 77c "checksum error on client read with debug"
8953
8954 test_77d() { # bug 10889
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956         $GSS && skip_env "could not run with gss"
8957
8958         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8959         $LCTL set_param fail_loc=0x80000409
8960         set_checksums 1
8961         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8962                 error "direct write: rc=$?"
8963         $LCTL set_param fail_loc=0
8964         set_checksums 0
8965
8966         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8967         $LCTL set_param fail_loc=0x80000408
8968         set_checksums 1
8969         cancel_lru_locks osc
8970         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8971                 error "direct read: rc=$?"
8972         $LCTL set_param fail_loc=0
8973         set_checksums 0
8974 }
8975 run_test 77d "checksum error on OST direct write, read"
8976
8977 test_77f() { # bug 10889
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         $GSS && skip_env "could not run with gss"
8980
8981         set_checksums 1
8982         for algo in $CKSUM_TYPES; do
8983                 cancel_lru_locks osc
8984                 set_checksum_type $algo
8985                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8986                 $LCTL set_param fail_loc=0x409
8987                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8988                         error "direct write succeeded"
8989                 $LCTL set_param fail_loc=0
8990         done
8991         set_checksum_type $ORIG_CSUM_TYPE
8992         set_checksums 0
8993 }
8994 run_test 77f "repeat checksum error on write (expect error)"
8995
8996 test_77g() { # bug 10889
8997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8998         $GSS && skip_env "could not run with gss"
8999         remote_ost_nodsh && skip "remote OST with nodsh"
9000
9001         [ ! -f $F77_TMP ] && setup_f77
9002
9003         local file=$DIR/$tfile
9004         stack_trap "rm -f $file" EXIT
9005
9006         $LFS setstripe -c 1 -i 0 $file
9007         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9008         do_facet ost1 lctl set_param fail_loc=0x8000021a
9009         set_checksums 1
9010         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9011                 error "write error: rc=$?"
9012         do_facet ost1 lctl set_param fail_loc=0
9013         set_checksums 0
9014
9015         cancel_lru_locks osc
9016         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9017         do_facet ost1 lctl set_param fail_loc=0x8000021b
9018         set_checksums 1
9019         cmp $F77_TMP $file || error "file compare failed"
9020         do_facet ost1 lctl set_param fail_loc=0
9021         set_checksums 0
9022 }
9023 run_test 77g "checksum error on OST write, read"
9024
9025 test_77k() { # LU-10906
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027         $GSS && skip_env "could not run with gss"
9028
9029         local cksum_param="osc.$FSNAME*.checksums"
9030         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9031         local checksum
9032         local i
9033
9034         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9035         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9036         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9037
9038         for i in 0 1; do
9039                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9040                         error "failed to set checksum=$i on MGS"
9041                 wait_update $HOSTNAME "$get_checksum" $i
9042                 #remount
9043                 echo "remount client, checksum should be $i"
9044                 remount_client $MOUNT || error "failed to remount client"
9045                 checksum=$(eval $get_checksum)
9046                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9047         done
9048         # remove persistent param to avoid races with checksum mountopt below
9049         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9050                 error "failed to delete checksum on MGS"
9051
9052         for opt in "checksum" "nochecksum"; do
9053                 #remount with mount option
9054                 echo "remount client with option $opt, checksum should be $i"
9055                 umount_client $MOUNT || error "failed to umount client"
9056                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9057                         error "failed to mount client with option '$opt'"
9058                 checksum=$(eval $get_checksum)
9059                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9060                 i=$((i - 1))
9061         done
9062
9063         remount_client $MOUNT || error "failed to remount client"
9064 }
9065 run_test 77k "enable/disable checksum correctly"
9066
9067 test_77l() {
9068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9069         $GSS && skip_env "could not run with gss"
9070
9071         set_checksums 1
9072         stack_trap "set_checksums $ORIG_CSUM" EXIT
9073         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9074
9075         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9076
9077         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9078         for algo in $CKSUM_TYPES; do
9079                 set_checksum_type $algo || error "fail to set checksum type $algo"
9080                 osc_algo=$(get_osc_checksum_type OST0000)
9081                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9082
9083                 # no locks, no reqs to let the connection idle
9084                 cancel_lru_locks osc
9085                 lru_resize_disable osc
9086                 wait_osc_import_state client ost1 IDLE
9087
9088                 # ensure ost1 is connected
9089                 stat $DIR/$tfile >/dev/null || error "can't stat"
9090                 wait_osc_import_state client ost1 FULL
9091
9092                 osc_algo=$(get_osc_checksum_type OST0000)
9093                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9094         done
9095         return 0
9096 }
9097 run_test 77l "preferred checksum type is remembered after reconnected"
9098
9099 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9100 rm -f $F77_TMP
9101 unset F77_TMP
9102
9103 cleanup_test_78() {
9104         trap 0
9105         rm -f $DIR/$tfile
9106 }
9107
9108 test_78() { # bug 10901
9109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9110         remote_ost || skip_env "local OST"
9111
9112         NSEQ=5
9113         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9114         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9115         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9116         echo "MemTotal: $MEMTOTAL"
9117
9118         # reserve 256MB of memory for the kernel and other running processes,
9119         # and then take 1/2 of the remaining memory for the read/write buffers.
9120         if [ $MEMTOTAL -gt 512 ] ;then
9121                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9122         else
9123                 # for those poor memory-starved high-end clusters...
9124                 MEMTOTAL=$((MEMTOTAL / 2))
9125         fi
9126         echo "Mem to use for directio: $MEMTOTAL"
9127
9128         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9129         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9130         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9131         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9132                 head -n1)
9133         echo "Smallest OST: $SMALLESTOST"
9134         [[ $SMALLESTOST -lt 10240 ]] &&
9135                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9136
9137         trap cleanup_test_78 EXIT
9138
9139         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9140                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9141
9142         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9143         echo "File size: $F78SIZE"
9144         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9145         for i in $(seq 1 $NSEQ); do
9146                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9147                 echo directIO rdwr round $i of $NSEQ
9148                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9149         done
9150
9151         cleanup_test_78
9152 }
9153 run_test 78 "handle large O_DIRECT writes correctly ============"
9154
9155 test_79() { # bug 12743
9156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9157
9158         wait_delete_completed
9159
9160         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9161         BKFREE=$(calc_osc_kbytes kbytesfree)
9162         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9163
9164         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9165         DFTOTAL=`echo $STRING | cut -d, -f1`
9166         DFUSED=`echo $STRING  | cut -d, -f2`
9167         DFAVAIL=`echo $STRING | cut -d, -f3`
9168         DFFREE=$(($DFTOTAL - $DFUSED))
9169
9170         ALLOWANCE=$((64 * $OSTCOUNT))
9171
9172         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9173            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9174                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9175         fi
9176         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9177            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9178                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9179         fi
9180         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9181            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9182                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9183         fi
9184 }
9185 run_test 79 "df report consistency check ======================="
9186
9187 test_80() { # bug 10718
9188         remote_ost_nodsh && skip "remote OST with nodsh"
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         # relax strong synchronous semantics for slow backends like ZFS
9192         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9193                 local soc="obdfilter.*.sync_lock_cancel"
9194                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9195
9196                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9197                 if [ -z "$save" ]; then
9198                         soc="obdfilter.*.sync_on_lock_cancel"
9199                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9200                 fi
9201
9202                 if [ "$save" != "never" ]; then
9203                         local hosts=$(comma_list $(osts_nodes))
9204
9205                         do_nodes $hosts $LCTL set_param $soc=never
9206                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9207                 fi
9208         fi
9209
9210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9211         sync; sleep 1; sync
9212         local before=$(date +%s)
9213         cancel_lru_locks osc
9214         local after=$(date +%s)
9215         local diff=$((after - before))
9216         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9217
9218         rm -f $DIR/$tfile
9219 }
9220 run_test 80 "Page eviction is equally fast at high offsets too"
9221
9222 test_81a() { # LU-456
9223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9224         remote_ost_nodsh && skip "remote OST with nodsh"
9225
9226         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9227         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9228         do_facet ost1 lctl set_param fail_loc=0x80000228
9229
9230         # write should trigger a retry and success
9231         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9232         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9233         RC=$?
9234         if [ $RC -ne 0 ] ; then
9235                 error "write should success, but failed for $RC"
9236         fi
9237 }
9238 run_test 81a "OST should retry write when get -ENOSPC ==============="
9239
9240 test_81b() { # LU-456
9241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9242         remote_ost_nodsh && skip "remote OST with nodsh"
9243
9244         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9245         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9246         do_facet ost1 lctl set_param fail_loc=0x228
9247
9248         # write should retry several times and return -ENOSPC finally
9249         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9250         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9251         RC=$?
9252         ENOSPC=28
9253         if [ $RC -ne $ENOSPC ] ; then
9254                 error "dd should fail for -ENOSPC, but succeed."
9255         fi
9256 }
9257 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9258
9259 test_99() {
9260         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9261
9262         test_mkdir $DIR/$tdir.cvsroot
9263         chown $RUNAS_ID $DIR/$tdir.cvsroot
9264
9265         cd $TMP
9266         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9267
9268         cd /etc/init.d
9269         # some versions of cvs import exit(1) when asked to import links or
9270         # files they can't read.  ignore those files.
9271         local toignore=$(find . -type l -printf '-I %f\n' -o \
9272                          ! -perm /4 -printf '-I %f\n')
9273         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9274                 $tdir.reposname vtag rtag
9275
9276         cd $DIR
9277         test_mkdir $DIR/$tdir.reposname
9278         chown $RUNAS_ID $DIR/$tdir.reposname
9279         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9280
9281         cd $DIR/$tdir.reposname
9282         $RUNAS touch foo99
9283         $RUNAS cvs add -m 'addmsg' foo99
9284         $RUNAS cvs update
9285         $RUNAS cvs commit -m 'nomsg' foo99
9286         rm -fr $DIR/$tdir.cvsroot
9287 }
9288 run_test 99 "cvs strange file/directory operations"
9289
9290 test_100() {
9291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9292         [[ "$NETTYPE" =~ tcp ]] ||
9293                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9294         remote_ost_nodsh && skip "remote OST with nodsh"
9295         remote_mds_nodsh && skip "remote MDS with nodsh"
9296         remote_servers ||
9297                 skip "useless for local single node setup"
9298
9299         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9300                 [ "$PROT" != "tcp" ] && continue
9301                 RPORT=$(echo $REMOTE | cut -d: -f2)
9302                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9303
9304                 rc=0
9305                 LPORT=`echo $LOCAL | cut -d: -f2`
9306                 if [ $LPORT -ge 1024 ]; then
9307                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9308                         netstat -tna
9309                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9310                 fi
9311         done
9312         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9313 }
9314 run_test 100 "check local port using privileged port ==========="
9315
9316 function get_named_value()
9317 {
9318     local tag
9319
9320     tag=$1
9321     while read ;do
9322         line=$REPLY
9323         case $line in
9324         $tag*)
9325             echo $line | sed "s/^$tag[ ]*//"
9326             break
9327             ;;
9328         esac
9329     done
9330 }
9331
9332 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9333                    awk '/^max_cached_mb/ { print $2 }')
9334
9335 cleanup_101a() {
9336         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9337         trap 0
9338 }
9339
9340 test_101a() {
9341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9342
9343         local s
9344         local discard
9345         local nreads=10000
9346         local cache_limit=32
9347
9348         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9349         trap cleanup_101a EXIT
9350         $LCTL set_param -n llite.*.read_ahead_stats 0
9351         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9352
9353         #
9354         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9355         #
9356         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9357         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9358
9359         discard=0
9360         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9361                 get_named_value 'read but discarded' | cut -d" " -f1); do
9362                         discard=$(($discard + $s))
9363         done
9364         cleanup_101a
9365
9366         $LCTL get_param osc.*-osc*.rpc_stats
9367         $LCTL get_param llite.*.read_ahead_stats
9368
9369         # Discard is generally zero, but sometimes a few random reads line up
9370         # and trigger larger readahead, which is wasted & leads to discards.
9371         if [[ $(($discard)) -gt $nreads ]]; then
9372                 error "too many ($discard) discarded pages"
9373         fi
9374         rm -f $DIR/$tfile || true
9375 }
9376 run_test 101a "check read-ahead for random reads"
9377
9378 setup_test101bc() {
9379         test_mkdir $DIR/$tdir
9380         local ssize=$1
9381         local FILE_LENGTH=$2
9382         STRIPE_OFFSET=0
9383
9384         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9385
9386         local list=$(comma_list $(osts_nodes))
9387         set_osd_param $list '' read_cache_enable 0
9388         set_osd_param $list '' writethrough_cache_enable 0
9389
9390         trap cleanup_test101bc EXIT
9391         # prepare the read-ahead file
9392         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9393
9394         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9395                                 count=$FILE_SIZE_MB 2> /dev/null
9396
9397 }
9398
9399 cleanup_test101bc() {
9400         trap 0
9401         rm -rf $DIR/$tdir
9402         rm -f $DIR/$tfile
9403
9404         local list=$(comma_list $(osts_nodes))
9405         set_osd_param $list '' read_cache_enable 1
9406         set_osd_param $list '' writethrough_cache_enable 1
9407 }
9408
9409 calc_total() {
9410         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9411 }
9412
9413 ra_check_101() {
9414         local READ_SIZE=$1
9415         local STRIPE_SIZE=$2
9416         local FILE_LENGTH=$3
9417         local RA_INC=1048576
9418         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9419         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9420                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9421         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9422                         get_named_value 'read but discarded' |
9423                         cut -d" " -f1 | calc_total)
9424         if [[ $DISCARD -gt $discard_limit ]]; then
9425                 $LCTL get_param llite.*.read_ahead_stats
9426                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9427         else
9428                 echo "Read-ahead success for size ${READ_SIZE}"
9429         fi
9430 }
9431
9432 test_101b() {
9433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9434         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9435
9436         local STRIPE_SIZE=1048576
9437         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9438
9439         if [ $SLOW == "yes" ]; then
9440                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9441         else
9442                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9443         fi
9444
9445         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9446
9447         # prepare the read-ahead file
9448         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9449         cancel_lru_locks osc
9450         for BIDX in 2 4 8 16 32 64 128 256
9451         do
9452                 local BSIZE=$((BIDX*4096))
9453                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9454                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9455                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9456                 $LCTL set_param -n llite.*.read_ahead_stats 0
9457                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9458                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9459                 cancel_lru_locks osc
9460                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9461         done
9462         cleanup_test101bc
9463         true
9464 }
9465 run_test 101b "check stride-io mode read-ahead ================="
9466
9467 test_101c() {
9468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9469
9470         local STRIPE_SIZE=1048576
9471         local FILE_LENGTH=$((STRIPE_SIZE*100))
9472         local nreads=10000
9473         local rsize=65536
9474         local osc_rpc_stats
9475
9476         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9477
9478         cancel_lru_locks osc
9479         $LCTL set_param osc.*.rpc_stats 0
9480         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9481         $LCTL get_param osc.*.rpc_stats
9482         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9483                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9484                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9485                 local size
9486
9487                 if [ $lines -le 20 ]; then
9488                         echo "continue debug"
9489                         continue
9490                 fi
9491                 for size in 1 2 4 8; do
9492                         local rpc=$(echo "$stats" |
9493                                     awk '($1 == "'$size':") {print $2; exit; }')
9494                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9495                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9496                 done
9497                 echo "$osc_rpc_stats check passed!"
9498         done
9499         cleanup_test101bc
9500         true
9501 }
9502 run_test 101c "check stripe_size aligned read-ahead ================="
9503
9504 test_101d() {
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506
9507         local file=$DIR/$tfile
9508         local sz_MB=${FILESIZE_101d:-80}
9509         local ra_MB=${READAHEAD_MB:-40}
9510
9511         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9512         [ $free_MB -lt $sz_MB ] &&
9513                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9514
9515         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9516         $LFS setstripe -c -1 $file || error "setstripe failed"
9517
9518         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9519         echo Cancel LRU locks on lustre client to flush the client cache
9520         cancel_lru_locks osc
9521
9522         echo Disable read-ahead
9523         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9524         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9525         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9526         $LCTL get_param -n llite.*.max_read_ahead_mb
9527
9528         echo "Reading the test file $file with read-ahead disabled"
9529         local sz_KB=$((sz_MB * 1024 / 4))
9530         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9531         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9532         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9533                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9534
9535         echo "Cancel LRU locks on lustre client to flush the client cache"
9536         cancel_lru_locks osc
9537         echo Enable read-ahead with ${ra_MB}MB
9538         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9539
9540         echo "Reading the test file $file with read-ahead enabled"
9541         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9542                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9543
9544         echo "read-ahead disabled time read $raOFF"
9545         echo "read-ahead enabled time read $raON"
9546
9547         rm -f $file
9548         wait_delete_completed
9549
9550         # use awk for this check instead of bash because it handles decimals
9551         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9552                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9553 }
9554 run_test 101d "file read with and without read-ahead enabled"
9555
9556 test_101e() {
9557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9558
9559         local file=$DIR/$tfile
9560         local size_KB=500  #KB
9561         local count=100
9562         local bsize=1024
9563
9564         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9565         local need_KB=$((count * size_KB))
9566         [[ $free_KB -le $need_KB ]] &&
9567                 skip_env "Need free space $need_KB, have $free_KB"
9568
9569         echo "Creating $count ${size_KB}K test files"
9570         for ((i = 0; i < $count; i++)); do
9571                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9572         done
9573
9574         echo "Cancel LRU locks on lustre client to flush the client cache"
9575         cancel_lru_locks $OSC
9576
9577         echo "Reset readahead stats"
9578         $LCTL set_param -n llite.*.read_ahead_stats 0
9579
9580         for ((i = 0; i < $count; i++)); do
9581                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9582         done
9583
9584         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9585                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9586
9587         for ((i = 0; i < $count; i++)); do
9588                 rm -rf $file.$i 2>/dev/null
9589         done
9590
9591         #10000 means 20% reads are missing in readahead
9592         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9593 }
9594 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9595
9596 test_101f() {
9597         which iozone || skip_env "no iozone installed"
9598
9599         local old_debug=$($LCTL get_param debug)
9600         old_debug=${old_debug#*=}
9601         $LCTL set_param debug="reada mmap"
9602
9603         # create a test file
9604         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9605
9606         echo Cancel LRU locks on lustre client to flush the client cache
9607         cancel_lru_locks osc
9608
9609         echo Reset readahead stats
9610         $LCTL set_param -n llite.*.read_ahead_stats 0
9611
9612         echo mmap read the file with small block size
9613         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9614                 > /dev/null 2>&1
9615
9616         echo checking missing pages
9617         $LCTL get_param llite.*.read_ahead_stats
9618         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9619                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9620
9621         $LCTL set_param debug="$old_debug"
9622         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9623         rm -f $DIR/$tfile
9624 }
9625 run_test 101f "check mmap read performance"
9626
9627 test_101g_brw_size_test() {
9628         local mb=$1
9629         local pages=$((mb * 1048576 / PAGE_SIZE))
9630         local file=$DIR/$tfile
9631
9632         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9633                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9634         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9635                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9636                         return 2
9637         done
9638
9639         stack_trap "rm -f $file" EXIT
9640         $LCTL set_param -n osc.*.rpc_stats=0
9641
9642         # 10 RPCs should be enough for the test
9643         local count=10
9644         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9645                 { error "dd write ${mb} MB blocks failed"; return 3; }
9646         cancel_lru_locks osc
9647         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9648                 { error "dd write ${mb} MB blocks failed"; return 4; }
9649
9650         # calculate number of full-sized read and write RPCs
9651         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9652                 sed -n '/pages per rpc/,/^$/p' |
9653                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9654                 END { print reads,writes }'))
9655         # allow one extra full-sized read RPC for async readahead
9656         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9657                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9658         [[ ${rpcs[1]} == $count ]] ||
9659                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9660 }
9661
9662 test_101g() {
9663         remote_ost_nodsh && skip "remote OST with nodsh"
9664
9665         local rpcs
9666         local osts=$(get_facets OST)
9667         local list=$(comma_list $(osts_nodes))
9668         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9669         local brw_size="obdfilter.*.brw_size"
9670
9671         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9672
9673         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9674
9675         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9676                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9677                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9678            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9679                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9680                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9681
9682                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9683                         suffix="M"
9684
9685                 if [[ $orig_mb -lt 16 ]]; then
9686                         save_lustre_params $osts "$brw_size" > $p
9687                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9688                                 error "set 16MB RPC size failed"
9689
9690                         echo "remount client to enable new RPC size"
9691                         remount_client $MOUNT || error "remount_client failed"
9692                 fi
9693
9694                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9695                 # should be able to set brw_size=12, but no rpc_stats for that
9696                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9697         fi
9698
9699         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9700
9701         if [[ $orig_mb -lt 16 ]]; then
9702                 restore_lustre_params < $p
9703                 remount_client $MOUNT || error "remount_client restore failed"
9704         fi
9705
9706         rm -f $p $DIR/$tfile
9707 }
9708 run_test 101g "Big bulk(4/16 MiB) readahead"
9709
9710 test_101h() {
9711         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9712
9713         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9714                 error "dd 70M file failed"
9715         echo Cancel LRU locks on lustre client to flush the client cache
9716         cancel_lru_locks osc
9717
9718         echo "Reset readahead stats"
9719         $LCTL set_param -n llite.*.read_ahead_stats 0
9720
9721         echo "Read 10M of data but cross 64M bundary"
9722         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9723         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9724                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9725         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9726         rm -f $p $DIR/$tfile
9727 }
9728 run_test 101h "Readahead should cover current read window"
9729
9730 test_101i() {
9731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9732                 error "dd 10M file failed"
9733
9734         local max_per_file_mb=$($LCTL get_param -n \
9735                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9736         cancel_lru_locks osc
9737         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9738         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9739                 error "set max_read_ahead_per_file_mb to 1 failed"
9740
9741         echo "Reset readahead stats"
9742         $LCTL set_param llite.*.read_ahead_stats=0
9743
9744         dd if=$DIR/$tfile of=/dev/null bs=2M
9745
9746         $LCTL get_param llite.*.read_ahead_stats
9747         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9748                      awk '/misses/ { print $2 }')
9749         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9750         rm -f $DIR/$tfile
9751 }
9752 run_test 101i "allow current readahead to exceed reservation"
9753
9754 test_101j() {
9755         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9756                 error "setstripe $DIR/$tfile failed"
9757         local file_size=$((1048576 * 16))
9758         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9759         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9760
9761         echo Disable read-ahead
9762         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9763
9764         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9765         for blk in $PAGE_SIZE 1048576 $file_size; do
9766                 cancel_lru_locks osc
9767                 echo "Reset readahead stats"
9768                 $LCTL set_param -n llite.*.read_ahead_stats=0
9769                 local count=$(($file_size / $blk))
9770                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9771                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9772                              get_named_value 'failed to fast read' |
9773                              cut -d" " -f1 | calc_total)
9774                 $LCTL get_param -n llite.*.read_ahead_stats
9775                 [ $miss -eq $count ] || error "expected $count got $miss"
9776         done
9777
9778         rm -f $p $DIR/$tfile
9779 }
9780 run_test 101j "A complete read block should be submitted when no RA"
9781
9782 setup_test102() {
9783         test_mkdir $DIR/$tdir
9784         chown $RUNAS_ID $DIR/$tdir
9785         STRIPE_SIZE=65536
9786         STRIPE_OFFSET=1
9787         STRIPE_COUNT=$OSTCOUNT
9788         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9789
9790         trap cleanup_test102 EXIT
9791         cd $DIR
9792         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9793         cd $DIR/$tdir
9794         for num in 1 2 3 4; do
9795                 for count in $(seq 1 $STRIPE_COUNT); do
9796                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9797                                 local size=`expr $STRIPE_SIZE \* $num`
9798                                 local file=file"$num-$idx-$count"
9799                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9800                         done
9801                 done
9802         done
9803
9804         cd $DIR
9805         $1 tar cf $TMP/f102.tar $tdir --xattrs
9806 }
9807
9808 cleanup_test102() {
9809         trap 0
9810         rm -f $TMP/f102.tar
9811         rm -rf $DIR/d0.sanity/d102
9812 }
9813
9814 test_102a() {
9815         [ "$UID" != 0 ] && skip "must run as root"
9816         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9817                 skip_env "must have user_xattr"
9818
9819         [ -z "$(which setfattr 2>/dev/null)" ] &&
9820                 skip_env "could not find setfattr"
9821
9822         local testfile=$DIR/$tfile
9823
9824         touch $testfile
9825         echo "set/get xattr..."
9826         setfattr -n trusted.name1 -v value1 $testfile ||
9827                 error "setfattr -n trusted.name1=value1 $testfile failed"
9828         getfattr -n trusted.name1 $testfile 2> /dev/null |
9829           grep "trusted.name1=.value1" ||
9830                 error "$testfile missing trusted.name1=value1"
9831
9832         setfattr -n user.author1 -v author1 $testfile ||
9833                 error "setfattr -n user.author1=author1 $testfile failed"
9834         getfattr -n user.author1 $testfile 2> /dev/null |
9835           grep "user.author1=.author1" ||
9836                 error "$testfile missing trusted.author1=author1"
9837
9838         echo "listxattr..."
9839         setfattr -n trusted.name2 -v value2 $testfile ||
9840                 error "$testfile unable to set trusted.name2"
9841         setfattr -n trusted.name3 -v value3 $testfile ||
9842                 error "$testfile unable to set trusted.name3"
9843         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9844             grep "trusted.name" | wc -l) -eq 3 ] ||
9845                 error "$testfile missing 3 trusted.name xattrs"
9846
9847         setfattr -n user.author2 -v author2 $testfile ||
9848                 error "$testfile unable to set user.author2"
9849         setfattr -n user.author3 -v author3 $testfile ||
9850                 error "$testfile unable to set user.author3"
9851         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9852             grep "user.author" | wc -l) -eq 3 ] ||
9853                 error "$testfile missing 3 user.author xattrs"
9854
9855         echo "remove xattr..."
9856         setfattr -x trusted.name1 $testfile ||
9857                 error "$testfile error deleting trusted.name1"
9858         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9859                 error "$testfile did not delete trusted.name1 xattr"
9860
9861         setfattr -x user.author1 $testfile ||
9862                 error "$testfile error deleting user.author1"
9863         echo "set lustre special xattr ..."
9864         $LFS setstripe -c1 $testfile
9865         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9866                 awk -F "=" '/trusted.lov/ { print $2 }' )
9867         setfattr -n "trusted.lov" -v $lovea $testfile ||
9868                 error "$testfile doesn't ignore setting trusted.lov again"
9869         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9870                 error "$testfile allow setting invalid trusted.lov"
9871         rm -f $testfile
9872 }
9873 run_test 102a "user xattr test =================================="
9874
9875 check_102b_layout() {
9876         local layout="$*"
9877         local testfile=$DIR/$tfile
9878
9879         echo "test layout '$layout'"
9880         $LFS setstripe $layout $testfile || error "setstripe failed"
9881         $LFS getstripe -y $testfile
9882
9883         echo "get/set/list trusted.lov xattr ..." # b=10930
9884         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9885         [[ "$value" =~ "trusted.lov" ]] ||
9886                 error "can't get trusted.lov from $testfile"
9887         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9888                 error "getstripe failed"
9889
9890         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9891
9892         value=$(cut -d= -f2 <<<$value)
9893         # LU-13168: truncated xattr should fail if short lov_user_md header
9894         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9895                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9896         for len in $lens; do
9897                 echo "setfattr $len $testfile.2"
9898                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9899                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9900         done
9901         local stripe_size=$($LFS getstripe -S $testfile.2)
9902         local stripe_count=$($LFS getstripe -c $testfile.2)
9903         [[ $stripe_size -eq 65536 ]] ||
9904                 error "stripe size $stripe_size != 65536"
9905         [[ $stripe_count -eq $stripe_count_orig ]] ||
9906                 error "stripe count $stripe_count != $stripe_count_orig"
9907         rm $testfile $testfile.2
9908 }
9909
9910 test_102b() {
9911         [ -z "$(which setfattr 2>/dev/null)" ] &&
9912                 skip_env "could not find setfattr"
9913         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9914
9915         # check plain layout
9916         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9917
9918         # and also check composite layout
9919         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9920
9921 }
9922 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9923
9924 test_102c() {
9925         [ -z "$(which setfattr 2>/dev/null)" ] &&
9926                 skip_env "could not find setfattr"
9927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9928
9929         # b10930: get/set/list lustre.lov xattr
9930         echo "get/set/list lustre.lov xattr ..."
9931         test_mkdir $DIR/$tdir
9932         chown $RUNAS_ID $DIR/$tdir
9933         local testfile=$DIR/$tdir/$tfile
9934         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9935                 error "setstripe failed"
9936         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9937                 error "getstripe failed"
9938         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9939         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9940
9941         local testfile2=${testfile}2
9942         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9943                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9944
9945         $RUNAS $MCREATE $testfile2
9946         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9947         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9948         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9949         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9950         [ $stripe_count -eq $STRIPECOUNT ] ||
9951                 error "stripe count $stripe_count != $STRIPECOUNT"
9952 }
9953 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9954
9955 compare_stripe_info1() {
9956         local stripe_index_all_zero=true
9957
9958         for num in 1 2 3 4; do
9959                 for count in $(seq 1 $STRIPE_COUNT); do
9960                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9961                                 local size=$((STRIPE_SIZE * num))
9962                                 local file=file"$num-$offset-$count"
9963                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9964                                 [[ $stripe_size -ne $size ]] &&
9965                                     error "$file: size $stripe_size != $size"
9966                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9967                                 # allow fewer stripes to be created, ORI-601
9968                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9969                                     error "$file: count $stripe_count != $count"
9970                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9971                                 [[ $stripe_index -ne 0 ]] &&
9972                                         stripe_index_all_zero=false
9973                         done
9974                 done
9975         done
9976         $stripe_index_all_zero &&
9977                 error "all files are being extracted starting from OST index 0"
9978         return 0
9979 }
9980
9981 have_xattrs_include() {
9982         tar --help | grep -q xattrs-include &&
9983                 echo --xattrs-include="lustre.*"
9984 }
9985
9986 test_102d() {
9987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9989
9990         XINC=$(have_xattrs_include)
9991         setup_test102
9992         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9993         cd $DIR/$tdir/$tdir
9994         compare_stripe_info1
9995 }
9996 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9997
9998 test_102f() {
9999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10000         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10001
10002         XINC=$(have_xattrs_include)
10003         setup_test102
10004         test_mkdir $DIR/$tdir.restore
10005         cd $DIR
10006         tar cf - --xattrs $tdir | tar xf - \
10007                 -C $DIR/$tdir.restore --xattrs $XINC
10008         cd $DIR/$tdir.restore/$tdir
10009         compare_stripe_info1
10010 }
10011 run_test 102f "tar copy files, not keep osts"
10012
10013 grow_xattr() {
10014         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10015                 skip "must have user_xattr"
10016         [ -z "$(which setfattr 2>/dev/null)" ] &&
10017                 skip_env "could not find setfattr"
10018         [ -z "$(which getfattr 2>/dev/null)" ] &&
10019                 skip_env "could not find getfattr"
10020
10021         local xsize=${1:-1024}  # in bytes
10022         local file=$DIR/$tfile
10023         local value="$(generate_string $xsize)"
10024         local xbig=trusted.big
10025         local toobig=$2
10026
10027         touch $file
10028         log "save $xbig on $file"
10029         if [ -z "$toobig" ]
10030         then
10031                 setfattr -n $xbig -v $value $file ||
10032                         error "saving $xbig on $file failed"
10033         else
10034                 setfattr -n $xbig -v $value $file &&
10035                         error "saving $xbig on $file succeeded"
10036                 return 0
10037         fi
10038
10039         local orig=$(get_xattr_value $xbig $file)
10040         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10041
10042         local xsml=trusted.sml
10043         log "save $xsml on $file"
10044         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10045
10046         local new=$(get_xattr_value $xbig $file)
10047         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10048
10049         log "grow $xsml on $file"
10050         setfattr -n $xsml -v "$value" $file ||
10051                 error "growing $xsml on $file failed"
10052
10053         new=$(get_xattr_value $xbig $file)
10054         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10055         log "$xbig still valid after growing $xsml"
10056
10057         rm -f $file
10058 }
10059
10060 test_102h() { # bug 15777
10061         grow_xattr 1024
10062 }
10063 run_test 102h "grow xattr from inside inode to external block"
10064
10065 test_102ha() {
10066         large_xattr_enabled || skip_env "ea_inode feature disabled"
10067
10068         echo "setting xattr of max xattr size: $(max_xattr_size)"
10069         grow_xattr $(max_xattr_size)
10070
10071         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10072         echo "This should fail:"
10073         grow_xattr $(($(max_xattr_size) + 10)) 1
10074 }
10075 run_test 102ha "grow xattr from inside inode to external inode"
10076
10077 test_102i() { # bug 17038
10078         [ -z "$(which getfattr 2>/dev/null)" ] &&
10079                 skip "could not find getfattr"
10080
10081         touch $DIR/$tfile
10082         ln -s $DIR/$tfile $DIR/${tfile}link
10083         getfattr -n trusted.lov $DIR/$tfile ||
10084                 error "lgetxattr on $DIR/$tfile failed"
10085         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10086                 grep -i "no such attr" ||
10087                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10088         rm -f $DIR/$tfile $DIR/${tfile}link
10089 }
10090 run_test 102i "lgetxattr test on symbolic link ============"
10091
10092 test_102j() {
10093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10095
10096         XINC=$(have_xattrs_include)
10097         setup_test102 "$RUNAS"
10098         chown $RUNAS_ID $DIR/$tdir
10099         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10100         cd $DIR/$tdir/$tdir
10101         compare_stripe_info1 "$RUNAS"
10102 }
10103 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10104
10105 test_102k() {
10106         [ -z "$(which setfattr 2>/dev/null)" ] &&
10107                 skip "could not find setfattr"
10108
10109         touch $DIR/$tfile
10110         # b22187 just check that does not crash for regular file.
10111         setfattr -n trusted.lov $DIR/$tfile
10112         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10113         local test_kdir=$DIR/$tdir
10114         test_mkdir $test_kdir
10115         local default_size=$($LFS getstripe -S $test_kdir)
10116         local default_count=$($LFS getstripe -c $test_kdir)
10117         local default_offset=$($LFS getstripe -i $test_kdir)
10118         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10119                 error 'dir setstripe failed'
10120         setfattr -n trusted.lov $test_kdir
10121         local stripe_size=$($LFS getstripe -S $test_kdir)
10122         local stripe_count=$($LFS getstripe -c $test_kdir)
10123         local stripe_offset=$($LFS getstripe -i $test_kdir)
10124         [ $stripe_size -eq $default_size ] ||
10125                 error "stripe size $stripe_size != $default_size"
10126         [ $stripe_count -eq $default_count ] ||
10127                 error "stripe count $stripe_count != $default_count"
10128         [ $stripe_offset -eq $default_offset ] ||
10129                 error "stripe offset $stripe_offset != $default_offset"
10130         rm -rf $DIR/$tfile $test_kdir
10131 }
10132 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10133
10134 test_102l() {
10135         [ -z "$(which getfattr 2>/dev/null)" ] &&
10136                 skip "could not find getfattr"
10137
10138         # LU-532 trusted. xattr is invisible to non-root
10139         local testfile=$DIR/$tfile
10140
10141         touch $testfile
10142
10143         echo "listxattr as user..."
10144         chown $RUNAS_ID $testfile
10145         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10146             grep -q "trusted" &&
10147                 error "$testfile trusted xattrs are user visible"
10148
10149         return 0;
10150 }
10151 run_test 102l "listxattr size test =================================="
10152
10153 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10154         local path=$DIR/$tfile
10155         touch $path
10156
10157         listxattr_size_check $path || error "listattr_size_check $path failed"
10158 }
10159 run_test 102m "Ensure listxattr fails on small bufffer ========"
10160
10161 cleanup_test102
10162
10163 getxattr() { # getxattr path name
10164         # Return the base64 encoding of the value of xattr name on path.
10165         local path=$1
10166         local name=$2
10167
10168         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10169         # file: $path
10170         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10171         #
10172         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10173
10174         getfattr --absolute-names --encoding=base64 --name=$name $path |
10175                 awk -F= -v name=$name '$1 == name {
10176                         print substr($0, index($0, "=") + 1);
10177         }'
10178 }
10179
10180 test_102n() { # LU-4101 mdt: protect internal xattrs
10181         [ -z "$(which setfattr 2>/dev/null)" ] &&
10182                 skip "could not find setfattr"
10183         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10184         then
10185                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10186         fi
10187
10188         local file0=$DIR/$tfile.0
10189         local file1=$DIR/$tfile.1
10190         local xattr0=$TMP/$tfile.0
10191         local xattr1=$TMP/$tfile.1
10192         local namelist="lov lma lmv link fid version som hsm"
10193         local name
10194         local value
10195
10196         rm -rf $file0 $file1 $xattr0 $xattr1
10197         touch $file0 $file1
10198
10199         # Get 'before' xattrs of $file1.
10200         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10201
10202         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10203                 namelist+=" lfsck_namespace"
10204         for name in $namelist; do
10205                 # Try to copy xattr from $file0 to $file1.
10206                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10207
10208                 setfattr --name=trusted.$name --value="$value" $file1 ||
10209                         error "setxattr 'trusted.$name' failed"
10210
10211                 # Try to set a garbage xattr.
10212                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10213
10214                 if [[ x$name == "xlov" ]]; then
10215                         setfattr --name=trusted.lov --value="$value" $file1 &&
10216                         error "setxattr invalid 'trusted.lov' success"
10217                 else
10218                         setfattr --name=trusted.$name --value="$value" $file1 ||
10219                                 error "setxattr invalid 'trusted.$name' failed"
10220                 fi
10221
10222                 # Try to remove the xattr from $file1. We don't care if this
10223                 # appears to succeed or fail, we just don't want there to be
10224                 # any changes or crashes.
10225                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10226         done
10227
10228         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10229         then
10230                 name="lfsck_ns"
10231                 # Try to copy xattr from $file0 to $file1.
10232                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10233
10234                 setfattr --name=trusted.$name --value="$value" $file1 ||
10235                         error "setxattr 'trusted.$name' failed"
10236
10237                 # Try to set a garbage xattr.
10238                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10239
10240                 setfattr --name=trusted.$name --value="$value" $file1 ||
10241                         error "setxattr 'trusted.$name' failed"
10242
10243                 # Try to remove the xattr from $file1. We don't care if this
10244                 # appears to succeed or fail, we just don't want there to be
10245                 # any changes or crashes.
10246                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10247         fi
10248
10249         # Get 'after' xattrs of file1.
10250         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10251
10252         if ! diff $xattr0 $xattr1; then
10253                 error "before and after xattrs of '$file1' differ"
10254         fi
10255
10256         rm -rf $file0 $file1 $xattr0 $xattr1
10257
10258         return 0
10259 }
10260 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10261
10262 test_102p() { # LU-4703 setxattr did not check ownership
10263         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10264                 skip "MDS needs to be at least 2.5.56"
10265
10266         local testfile=$DIR/$tfile
10267
10268         touch $testfile
10269
10270         echo "setfacl as user..."
10271         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10272         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10273
10274         echo "setfattr as user..."
10275         setfacl -m "u:$RUNAS_ID:---" $testfile
10276         $RUNAS setfattr -x system.posix_acl_access $testfile
10277         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10278 }
10279 run_test 102p "check setxattr(2) correctly fails without permission"
10280
10281 test_102q() {
10282         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10283                 skip "MDS needs to be at least 2.6.92"
10284
10285         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10286 }
10287 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10288
10289 test_102r() {
10290         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10291                 skip "MDS needs to be at least 2.6.93"
10292
10293         touch $DIR/$tfile || error "touch"
10294         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10295         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10296         rm $DIR/$tfile || error "rm"
10297
10298         #normal directory
10299         mkdir -p $DIR/$tdir || error "mkdir"
10300         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10301         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10302         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10303                 error "$testfile error deleting user.author1"
10304         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10305                 grep "user.$(basename $tdir)" &&
10306                 error "$tdir did not delete user.$(basename $tdir)"
10307         rmdir $DIR/$tdir || error "rmdir"
10308
10309         #striped directory
10310         test_mkdir $DIR/$tdir
10311         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10312         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10313         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10314                 error "$testfile error deleting user.author1"
10315         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10316                 grep "user.$(basename $tdir)" &&
10317                 error "$tdir did not delete user.$(basename $tdir)"
10318         rmdir $DIR/$tdir || error "rm striped dir"
10319 }
10320 run_test 102r "set EAs with empty values"
10321
10322 test_102s() {
10323         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10324                 skip "MDS needs to be at least 2.11.52"
10325
10326         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10327
10328         save_lustre_params client "llite.*.xattr_cache" > $save
10329
10330         for cache in 0 1; do
10331                 lctl set_param llite.*.xattr_cache=$cache
10332
10333                 rm -f $DIR/$tfile
10334                 touch $DIR/$tfile || error "touch"
10335                 for prefix in lustre security system trusted user; do
10336                         # Note getxattr() may fail with 'Operation not
10337                         # supported' or 'No such attribute' depending
10338                         # on prefix and cache.
10339                         getfattr -n $prefix.n102s $DIR/$tfile &&
10340                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10341                 done
10342         done
10343
10344         restore_lustre_params < $save
10345 }
10346 run_test 102s "getting nonexistent xattrs should fail"
10347
10348 test_102t() {
10349         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10350                 skip "MDS needs to be at least 2.11.52"
10351
10352         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10353
10354         save_lustre_params client "llite.*.xattr_cache" > $save
10355
10356         for cache in 0 1; do
10357                 lctl set_param llite.*.xattr_cache=$cache
10358
10359                 for buf_size in 0 256; do
10360                         rm -f $DIR/$tfile
10361                         touch $DIR/$tfile || error "touch"
10362                         setfattr -n user.multiop $DIR/$tfile
10363                         $MULTIOP $DIR/$tfile oa$buf_size ||
10364                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10365                 done
10366         done
10367
10368         restore_lustre_params < $save
10369 }
10370 run_test 102t "zero length xattr values handled correctly"
10371
10372 run_acl_subtest()
10373 {
10374     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10375     return $?
10376 }
10377
10378 test_103a() {
10379         [ "$UID" != 0 ] && skip "must run as root"
10380         $GSS && skip_env "could not run under gss"
10381         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10382                 skip_env "must have acl enabled"
10383         [ -z "$(which setfacl 2>/dev/null)" ] &&
10384                 skip_env "could not find setfacl"
10385         remote_mds_nodsh && skip "remote MDS with nodsh"
10386
10387         gpasswd -a daemon bin                           # LU-5641
10388         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10389
10390         declare -a identity_old
10391
10392         for num in $(seq $MDSCOUNT); do
10393                 switch_identity $num true || identity_old[$num]=$?
10394         done
10395
10396         SAVE_UMASK=$(umask)
10397         umask 0022
10398         mkdir -p $DIR/$tdir
10399         cd $DIR/$tdir
10400
10401         echo "performing cp ..."
10402         run_acl_subtest cp || error "run_acl_subtest cp failed"
10403         echo "performing getfacl-noacl..."
10404         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10405         echo "performing misc..."
10406         run_acl_subtest misc || error  "misc test failed"
10407         echo "performing permissions..."
10408         run_acl_subtest permissions || error "permissions failed"
10409         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10410         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10411                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10412                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10413         then
10414                 echo "performing permissions xattr..."
10415                 run_acl_subtest permissions_xattr ||
10416                         error "permissions_xattr failed"
10417         fi
10418         echo "performing setfacl..."
10419         run_acl_subtest setfacl || error  "setfacl test failed"
10420
10421         # inheritance test got from HP
10422         echo "performing inheritance..."
10423         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10424         chmod +x make-tree || error "chmod +x failed"
10425         run_acl_subtest inheritance || error "inheritance test failed"
10426         rm -f make-tree
10427
10428         echo "LU-974 ignore umask when acl is enabled..."
10429         run_acl_subtest 974 || error "LU-974 umask test failed"
10430         if [ $MDSCOUNT -ge 2 ]; then
10431                 run_acl_subtest 974_remote ||
10432                         error "LU-974 umask test failed under remote dir"
10433         fi
10434
10435         echo "LU-2561 newly created file is same size as directory..."
10436         if [ "$mds1_FSTYPE" != "zfs" ]; then
10437                 run_acl_subtest 2561 || error "LU-2561 test failed"
10438         else
10439                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10440         fi
10441
10442         run_acl_subtest 4924 || error "LU-4924 test failed"
10443
10444         cd $SAVE_PWD
10445         umask $SAVE_UMASK
10446
10447         for num in $(seq $MDSCOUNT); do
10448                 if [ "${identity_old[$num]}" = 1 ]; then
10449                         switch_identity $num false || identity_old[$num]=$?
10450                 fi
10451         done
10452 }
10453 run_test 103a "acl test"
10454
10455 test_103b() {
10456         declare -a pids
10457         local U
10458
10459         for U in {0..511}; do
10460                 {
10461                 local O=$(printf "%04o" $U)
10462
10463                 umask $(printf "%04o" $((511 ^ $O)))
10464                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10465                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10466
10467                 (( $S == ($O & 0666) )) ||
10468                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10469
10470                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10471                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10472                 (( $S == ($O & 0666) )) ||
10473                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10474
10475                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10476                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10477                 (( $S == ($O & 0666) )) ||
10478                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10479                 rm -f $DIR/$tfile.[smp]$0
10480                 } &
10481                 local pid=$!
10482
10483                 # limit the concurrently running threads to 64. LU-11878
10484                 local idx=$((U % 64))
10485                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10486                 pids[idx]=$pid
10487         done
10488         wait
10489 }
10490 run_test 103b "umask lfs setstripe"
10491
10492 test_103c() {
10493         mkdir -p $DIR/$tdir
10494         cp -rp $DIR/$tdir $DIR/$tdir.bak
10495
10496         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10497                 error "$DIR/$tdir shouldn't contain default ACL"
10498         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10499                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10500         true
10501 }
10502 run_test 103c "'cp -rp' won't set empty acl"
10503
10504 test_104a() {
10505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10506
10507         touch $DIR/$tfile
10508         lfs df || error "lfs df failed"
10509         lfs df -ih || error "lfs df -ih failed"
10510         lfs df -h $DIR || error "lfs df -h $DIR failed"
10511         lfs df -i $DIR || error "lfs df -i $DIR failed"
10512         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10513         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10514
10515         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10516         lctl --device %$OSC deactivate
10517         lfs df || error "lfs df with deactivated OSC failed"
10518         lctl --device %$OSC activate
10519         # wait the osc back to normal
10520         wait_osc_import_ready client ost
10521
10522         lfs df || error "lfs df with reactivated OSC failed"
10523         rm -f $DIR/$tfile
10524 }
10525 run_test 104a "lfs df [-ih] [path] test ========================="
10526
10527 test_104b() {
10528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10529         [ $RUNAS_ID -eq $UID ] &&
10530                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10531
10532         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10533                         grep "Permission denied" | wc -l)))
10534         if [ $denied_cnt -ne 0 ]; then
10535                 error "lfs check servers test failed"
10536         fi
10537 }
10538 run_test 104b "$RUNAS lfs check servers test ===================="
10539
10540 test_105a() {
10541         # doesn't work on 2.4 kernels
10542         touch $DIR/$tfile
10543         if $(flock_is_enabled); then
10544                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10545         else
10546                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10547         fi
10548         rm -f $DIR/$tfile
10549 }
10550 run_test 105a "flock when mounted without -o flock test ========"
10551
10552 test_105b() {
10553         touch $DIR/$tfile
10554         if $(flock_is_enabled); then
10555                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10556         else
10557                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10558         fi
10559         rm -f $DIR/$tfile
10560 }
10561 run_test 105b "fcntl when mounted without -o flock test ========"
10562
10563 test_105c() {
10564         touch $DIR/$tfile
10565         if $(flock_is_enabled); then
10566                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10567         else
10568                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10569         fi
10570         rm -f $DIR/$tfile
10571 }
10572 run_test 105c "lockf when mounted without -o flock test"
10573
10574 test_105d() { # bug 15924
10575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10576
10577         test_mkdir $DIR/$tdir
10578         flock_is_enabled || skip_env "mount w/o flock enabled"
10579         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10580         $LCTL set_param fail_loc=0x80000315
10581         flocks_test 2 $DIR/$tdir
10582 }
10583 run_test 105d "flock race (should not freeze) ========"
10584
10585 test_105e() { # bug 22660 && 22040
10586         flock_is_enabled || skip_env "mount w/o flock enabled"
10587
10588         touch $DIR/$tfile
10589         flocks_test 3 $DIR/$tfile
10590 }
10591 run_test 105e "Two conflicting flocks from same process"
10592
10593 test_106() { #bug 10921
10594         test_mkdir $DIR/$tdir
10595         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10596         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10597 }
10598 run_test 106 "attempt exec of dir followed by chown of that dir"
10599
10600 test_107() {
10601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10602
10603         CDIR=`pwd`
10604         local file=core
10605
10606         cd $DIR
10607         rm -f $file
10608
10609         local save_pattern=$(sysctl -n kernel.core_pattern)
10610         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10611         sysctl -w kernel.core_pattern=$file
10612         sysctl -w kernel.core_uses_pid=0
10613
10614         ulimit -c unlimited
10615         sleep 60 &
10616         SLEEPPID=$!
10617
10618         sleep 1
10619
10620         kill -s 11 $SLEEPPID
10621         wait $SLEEPPID
10622         if [ -e $file ]; then
10623                 size=`stat -c%s $file`
10624                 [ $size -eq 0 ] && error "Fail to create core file $file"
10625         else
10626                 error "Fail to create core file $file"
10627         fi
10628         rm -f $file
10629         sysctl -w kernel.core_pattern=$save_pattern
10630         sysctl -w kernel.core_uses_pid=$save_uses_pid
10631         cd $CDIR
10632 }
10633 run_test 107 "Coredump on SIG"
10634
10635 test_110() {
10636         test_mkdir $DIR/$tdir
10637         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10638         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10639                 error "mkdir with 256 char should fail, but did not"
10640         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10641                 error "create with 255 char failed"
10642         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10643                 error "create with 256 char should fail, but did not"
10644
10645         ls -l $DIR/$tdir
10646         rm -rf $DIR/$tdir
10647 }
10648 run_test 110 "filename length checking"
10649
10650 #
10651 # Purpose: To verify dynamic thread (OSS) creation.
10652 #
10653 test_115() {
10654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10655         remote_ost_nodsh && skip "remote OST with nodsh"
10656
10657         # Lustre does not stop service threads once they are started.
10658         # Reset number of running threads to default.
10659         stopall
10660         setupall
10661
10662         local OSTIO_pre
10663         local save_params="$TMP/sanity-$TESTNAME.parameters"
10664
10665         # Get ll_ost_io count before I/O
10666         OSTIO_pre=$(do_facet ost1 \
10667                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10668         # Exit if lustre is not running (ll_ost_io not running).
10669         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10670
10671         echo "Starting with $OSTIO_pre threads"
10672         local thread_max=$((OSTIO_pre * 2))
10673         local rpc_in_flight=$((thread_max * 2))
10674         # Number of I/O Process proposed to be started.
10675         local nfiles
10676         local facets=$(get_facets OST)
10677
10678         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10679         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10680
10681         # Set in_flight to $rpc_in_flight
10682         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10683                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10684         nfiles=${rpc_in_flight}
10685         # Set ost thread_max to $thread_max
10686         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10687
10688         # 5 Minutes should be sufficient for max number of OSS
10689         # threads(thread_max) to be created.
10690         local timeout=300
10691
10692         # Start I/O.
10693         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10694         test_mkdir $DIR/$tdir
10695         for i in $(seq $nfiles); do
10696                 local file=$DIR/$tdir/${tfile}-$i
10697                 $LFS setstripe -c -1 -i 0 $file
10698                 ($WTL $file $timeout)&
10699         done
10700
10701         # I/O Started - Wait for thread_started to reach thread_max or report
10702         # error if thread_started is more than thread_max.
10703         echo "Waiting for thread_started to reach thread_max"
10704         local thread_started=0
10705         local end_time=$((SECONDS + timeout))
10706
10707         while [ $SECONDS -le $end_time ] ; do
10708                 echo -n "."
10709                 # Get ost i/o thread_started count.
10710                 thread_started=$(do_facet ost1 \
10711                         "$LCTL get_param \
10712                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10713                 # Break out if thread_started is equal/greater than thread_max
10714                 if [[ $thread_started -ge $thread_max ]]; then
10715                         echo ll_ost_io thread_started $thread_started, \
10716                                 equal/greater than thread_max $thread_max
10717                         break
10718                 fi
10719                 sleep 1
10720         done
10721
10722         # Cleanup - We have the numbers, Kill i/o jobs if running.
10723         jobcount=($(jobs -p))
10724         for i in $(seq 0 $((${#jobcount[@]}-1)))
10725         do
10726                 kill -9 ${jobcount[$i]}
10727                 if [ $? -ne 0 ] ; then
10728                         echo Warning: \
10729                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10730                 fi
10731         done
10732
10733         # Cleanup files left by WTL binary.
10734         for i in $(seq $nfiles); do
10735                 local file=$DIR/$tdir/${tfile}-$i
10736                 rm -rf $file
10737                 if [ $? -ne 0 ] ; then
10738                         echo "Warning: Failed to delete file $file"
10739                 fi
10740         done
10741
10742         restore_lustre_params <$save_params
10743         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10744
10745         # Error out if no new thread has started or Thread started is greater
10746         # than thread max.
10747         if [[ $thread_started -le $OSTIO_pre ||
10748                         $thread_started -gt $thread_max ]]; then
10749                 error "ll_ost_io: thread_started $thread_started" \
10750                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10751                       "No new thread started or thread started greater " \
10752                       "than thread_max."
10753         fi
10754 }
10755 run_test 115 "verify dynamic thread creation===================="
10756
10757 free_min_max () {
10758         wait_delete_completed
10759         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10760         echo "OST kbytes available: ${AVAIL[@]}"
10761         MAXV=${AVAIL[0]}
10762         MAXI=0
10763         MINV=${AVAIL[0]}
10764         MINI=0
10765         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10766                 #echo OST $i: ${AVAIL[i]}kb
10767                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10768                         MAXV=${AVAIL[i]}
10769                         MAXI=$i
10770                 fi
10771                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10772                         MINV=${AVAIL[i]}
10773                         MINI=$i
10774                 fi
10775         done
10776         echo "Min free space: OST $MINI: $MINV"
10777         echo "Max free space: OST $MAXI: $MAXV"
10778 }
10779
10780 test_116a() { # was previously test_116()
10781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10782         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10783         remote_mds_nodsh && skip "remote MDS with nodsh"
10784
10785         echo -n "Free space priority "
10786         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10787                 head -n1
10788         declare -a AVAIL
10789         free_min_max
10790
10791         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10792         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10793         trap simple_cleanup_common EXIT
10794
10795         # Check if we need to generate uneven OSTs
10796         test_mkdir -p $DIR/$tdir/OST${MINI}
10797         local FILL=$((MINV / 4))
10798         local DIFF=$((MAXV - MINV))
10799         local DIFF2=$((DIFF * 100 / MINV))
10800
10801         local threshold=$(do_facet $SINGLEMDS \
10802                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10803         threshold=${threshold%%%}
10804         echo -n "Check for uneven OSTs: "
10805         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10806
10807         if [[ $DIFF2 -gt $threshold ]]; then
10808                 echo "ok"
10809                 echo "Don't need to fill OST$MINI"
10810         else
10811                 # generate uneven OSTs. Write 2% over the QOS threshold value
10812                 echo "no"
10813                 DIFF=$((threshold - DIFF2 + 2))
10814                 DIFF2=$((MINV * DIFF / 100))
10815                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10816                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10817                         error "setstripe failed"
10818                 DIFF=$((DIFF2 / 2048))
10819                 i=0
10820                 while [ $i -lt $DIFF ]; do
10821                         i=$((i + 1))
10822                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10823                                 bs=2M count=1 2>/dev/null
10824                         echo -n .
10825                 done
10826                 echo .
10827                 sync
10828                 sleep_maxage
10829                 free_min_max
10830         fi
10831
10832         DIFF=$((MAXV - MINV))
10833         DIFF2=$((DIFF * 100 / MINV))
10834         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10835         if [ $DIFF2 -gt $threshold ]; then
10836                 echo "ok"
10837         else
10838                 echo "failed - QOS mode won't be used"
10839                 simple_cleanup_common
10840                 skip "QOS imbalance criteria not met"
10841         fi
10842
10843         MINI1=$MINI
10844         MINV1=$MINV
10845         MAXI1=$MAXI
10846         MAXV1=$MAXV
10847
10848         # now fill using QOS
10849         $LFS setstripe -c 1 $DIR/$tdir
10850         FILL=$((FILL / 200))
10851         if [ $FILL -gt 600 ]; then
10852                 FILL=600
10853         fi
10854         echo "writing $FILL files to QOS-assigned OSTs"
10855         i=0
10856         while [ $i -lt $FILL ]; do
10857                 i=$((i + 1))
10858                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10859                         count=1 2>/dev/null
10860                 echo -n .
10861         done
10862         echo "wrote $i 200k files"
10863         sync
10864         sleep_maxage
10865
10866         echo "Note: free space may not be updated, so measurements might be off"
10867         free_min_max
10868         DIFF2=$((MAXV - MINV))
10869         echo "free space delta: orig $DIFF final $DIFF2"
10870         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10871         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10872         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10873         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10874         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10875         if [[ $DIFF -gt 0 ]]; then
10876                 FILL=$((DIFF2 * 100 / DIFF - 100))
10877                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10878         fi
10879
10880         # Figure out which files were written where
10881         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10882                awk '/'$MINI1': / {print $2; exit}')
10883         echo $UUID
10884         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10885         echo "$MINC files created on smaller OST $MINI1"
10886         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10887                awk '/'$MAXI1': / {print $2; exit}')
10888         echo $UUID
10889         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10890         echo "$MAXC files created on larger OST $MAXI1"
10891         if [[ $MINC -gt 0 ]]; then
10892                 FILL=$((MAXC * 100 / MINC - 100))
10893                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10894         fi
10895         [[ $MAXC -gt $MINC ]] ||
10896                 error_ignore LU-9 "stripe QOS didn't balance free space"
10897         simple_cleanup_common
10898 }
10899 run_test 116a "stripe QOS: free space balance ==================="
10900
10901 test_116b() { # LU-2093
10902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10903         remote_mds_nodsh && skip "remote MDS with nodsh"
10904
10905 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10906         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10907                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10908         [ -z "$old_rr" ] && skip "no QOS"
10909         do_facet $SINGLEMDS lctl set_param \
10910                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10911         mkdir -p $DIR/$tdir
10912         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10913         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10914         do_facet $SINGLEMDS lctl set_param fail_loc=0
10915         rm -rf $DIR/$tdir
10916         do_facet $SINGLEMDS lctl set_param \
10917                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10918 }
10919 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10920
10921 test_117() # bug 10891
10922 {
10923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10924
10925         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10926         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10927         lctl set_param fail_loc=0x21e
10928         > $DIR/$tfile || error "truncate failed"
10929         lctl set_param fail_loc=0
10930         echo "Truncate succeeded."
10931         rm -f $DIR/$tfile
10932 }
10933 run_test 117 "verify osd extend =========="
10934
10935 NO_SLOW_RESENDCOUNT=4
10936 export OLD_RESENDCOUNT=""
10937 set_resend_count () {
10938         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10939         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10940         lctl set_param -n $PROC_RESENDCOUNT $1
10941         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10942 }
10943
10944 # for reduce test_118* time (b=14842)
10945 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10946
10947 # Reset async IO behavior after error case
10948 reset_async() {
10949         FILE=$DIR/reset_async
10950
10951         # Ensure all OSCs are cleared
10952         $LFS setstripe -c -1 $FILE
10953         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10954         sync
10955         rm $FILE
10956 }
10957
10958 test_118a() #bug 11710
10959 {
10960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10961
10962         reset_async
10963
10964         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10965         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10966         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10967
10968         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10969                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10970                 return 1;
10971         fi
10972         rm -f $DIR/$tfile
10973 }
10974 run_test 118a "verify O_SYNC works =========="
10975
10976 test_118b()
10977 {
10978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10979         remote_ost_nodsh && skip "remote OST with nodsh"
10980
10981         reset_async
10982
10983         #define OBD_FAIL_SRV_ENOENT 0x217
10984         set_nodes_failloc "$(osts_nodes)" 0x217
10985         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10986         RC=$?
10987         set_nodes_failloc "$(osts_nodes)" 0
10988         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10989         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10990                     grep -c writeback)
10991
10992         if [[ $RC -eq 0 ]]; then
10993                 error "Must return error due to dropped pages, rc=$RC"
10994                 return 1;
10995         fi
10996
10997         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10998                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10999                 return 1;
11000         fi
11001
11002         echo "Dirty pages not leaked on ENOENT"
11003
11004         # Due to the above error the OSC will issue all RPCs syncronously
11005         # until a subsequent RPC completes successfully without error.
11006         $MULTIOP $DIR/$tfile Ow4096yc
11007         rm -f $DIR/$tfile
11008
11009         return 0
11010 }
11011 run_test 118b "Reclaim dirty pages on fatal error =========="
11012
11013 test_118c()
11014 {
11015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11016
11017         # for 118c, restore the original resend count, LU-1940
11018         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11019                                 set_resend_count $OLD_RESENDCOUNT
11020         remote_ost_nodsh && skip "remote OST with nodsh"
11021
11022         reset_async
11023
11024         #define OBD_FAIL_OST_EROFS               0x216
11025         set_nodes_failloc "$(osts_nodes)" 0x216
11026
11027         # multiop should block due to fsync until pages are written
11028         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11029         MULTIPID=$!
11030         sleep 1
11031
11032         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11033                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11034         fi
11035
11036         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11037                     grep -c writeback)
11038         if [[ $WRITEBACK -eq 0 ]]; then
11039                 error "No page in writeback, writeback=$WRITEBACK"
11040         fi
11041
11042         set_nodes_failloc "$(osts_nodes)" 0
11043         wait $MULTIPID
11044         RC=$?
11045         if [[ $RC -ne 0 ]]; then
11046                 error "Multiop fsync failed, rc=$RC"
11047         fi
11048
11049         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11050         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11051                     grep -c writeback)
11052         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11053                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11054         fi
11055
11056         rm -f $DIR/$tfile
11057         echo "Dirty pages flushed via fsync on EROFS"
11058         return 0
11059 }
11060 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11061
11062 # continue to use small resend count to reduce test_118* time (b=14842)
11063 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11064
11065 test_118d()
11066 {
11067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11068         remote_ost_nodsh && skip "remote OST with nodsh"
11069
11070         reset_async
11071
11072         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11073         set_nodes_failloc "$(osts_nodes)" 0x214
11074         # multiop should block due to fsync until pages are written
11075         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11076         MULTIPID=$!
11077         sleep 1
11078
11079         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11080                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11081         fi
11082
11083         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11084                     grep -c writeback)
11085         if [[ $WRITEBACK -eq 0 ]]; then
11086                 error "No page in writeback, writeback=$WRITEBACK"
11087         fi
11088
11089         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11090         set_nodes_failloc "$(osts_nodes)" 0
11091
11092         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11093         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11094                     grep -c writeback)
11095         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11096                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11097         fi
11098
11099         rm -f $DIR/$tfile
11100         echo "Dirty pages gaurenteed flushed via fsync"
11101         return 0
11102 }
11103 run_test 118d "Fsync validation inject a delay of the bulk =========="
11104
11105 test_118f() {
11106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11107
11108         reset_async
11109
11110         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11111         lctl set_param fail_loc=0x8000040a
11112
11113         # Should simulate EINVAL error which is fatal
11114         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11115         RC=$?
11116         if [[ $RC -eq 0 ]]; then
11117                 error "Must return error due to dropped pages, rc=$RC"
11118         fi
11119
11120         lctl set_param fail_loc=0x0
11121
11122         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11123         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11124         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11125                     grep -c writeback)
11126         if [[ $LOCKED -ne 0 ]]; then
11127                 error "Locked pages remain in cache, locked=$LOCKED"
11128         fi
11129
11130         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11131                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11132         fi
11133
11134         rm -f $DIR/$tfile
11135         echo "No pages locked after fsync"
11136
11137         reset_async
11138         return 0
11139 }
11140 run_test 118f "Simulate unrecoverable OSC side error =========="
11141
11142 test_118g() {
11143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11144
11145         reset_async
11146
11147         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11148         lctl set_param fail_loc=0x406
11149
11150         # simulate local -ENOMEM
11151         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11152         RC=$?
11153
11154         lctl set_param fail_loc=0
11155         if [[ $RC -eq 0 ]]; then
11156                 error "Must return error due to dropped pages, rc=$RC"
11157         fi
11158
11159         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11160         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11161         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11162                         grep -c writeback)
11163         if [[ $LOCKED -ne 0 ]]; then
11164                 error "Locked pages remain in cache, locked=$LOCKED"
11165         fi
11166
11167         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11168                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11169         fi
11170
11171         rm -f $DIR/$tfile
11172         echo "No pages locked after fsync"
11173
11174         reset_async
11175         return 0
11176 }
11177 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11178
11179 test_118h() {
11180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11181         remote_ost_nodsh && skip "remote OST with nodsh"
11182
11183         reset_async
11184
11185         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11186         set_nodes_failloc "$(osts_nodes)" 0x20e
11187         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11188         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11189         RC=$?
11190
11191         set_nodes_failloc "$(osts_nodes)" 0
11192         if [[ $RC -eq 0 ]]; then
11193                 error "Must return error due to dropped pages, rc=$RC"
11194         fi
11195
11196         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11197         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11198         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11199                     grep -c writeback)
11200         if [[ $LOCKED -ne 0 ]]; then
11201                 error "Locked pages remain in cache, locked=$LOCKED"
11202         fi
11203
11204         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11205                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11206         fi
11207
11208         rm -f $DIR/$tfile
11209         echo "No pages locked after fsync"
11210
11211         return 0
11212 }
11213 run_test 118h "Verify timeout in handling recoverables errors  =========="
11214
11215 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11216
11217 test_118i() {
11218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11219         remote_ost_nodsh && skip "remote OST with nodsh"
11220
11221         reset_async
11222
11223         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11224         set_nodes_failloc "$(osts_nodes)" 0x20e
11225
11226         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11227         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11228         PID=$!
11229         sleep 5
11230         set_nodes_failloc "$(osts_nodes)" 0
11231
11232         wait $PID
11233         RC=$?
11234         if [[ $RC -ne 0 ]]; then
11235                 error "got error, but should be not, rc=$RC"
11236         fi
11237
11238         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11239         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11240         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11241         if [[ $LOCKED -ne 0 ]]; then
11242                 error "Locked pages remain in cache, locked=$LOCKED"
11243         fi
11244
11245         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11246                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11247         fi
11248
11249         rm -f $DIR/$tfile
11250         echo "No pages locked after fsync"
11251
11252         return 0
11253 }
11254 run_test 118i "Fix error before timeout in recoverable error  =========="
11255
11256 [ "$SLOW" = "no" ] && set_resend_count 4
11257
11258 test_118j() {
11259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11260         remote_ost_nodsh && skip "remote OST with nodsh"
11261
11262         reset_async
11263
11264         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11265         set_nodes_failloc "$(osts_nodes)" 0x220
11266
11267         # return -EIO from OST
11268         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11269         RC=$?
11270         set_nodes_failloc "$(osts_nodes)" 0x0
11271         if [[ $RC -eq 0 ]]; then
11272                 error "Must return error due to dropped pages, rc=$RC"
11273         fi
11274
11275         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11276         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11277         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11278         if [[ $LOCKED -ne 0 ]]; then
11279                 error "Locked pages remain in cache, locked=$LOCKED"
11280         fi
11281
11282         # in recoverable error on OST we want resend and stay until it finished
11283         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11284                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11285         fi
11286
11287         rm -f $DIR/$tfile
11288         echo "No pages locked after fsync"
11289
11290         return 0
11291 }
11292 run_test 118j "Simulate unrecoverable OST side error =========="
11293
11294 test_118k()
11295 {
11296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11297         remote_ost_nodsh && skip "remote OSTs with nodsh"
11298
11299         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11300         set_nodes_failloc "$(osts_nodes)" 0x20e
11301         test_mkdir $DIR/$tdir
11302
11303         for ((i=0;i<10;i++)); do
11304                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11305                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11306                 SLEEPPID=$!
11307                 sleep 0.500s
11308                 kill $SLEEPPID
11309                 wait $SLEEPPID
11310         done
11311
11312         set_nodes_failloc "$(osts_nodes)" 0
11313         rm -rf $DIR/$tdir
11314 }
11315 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11316
11317 test_118l() # LU-646
11318 {
11319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11320
11321         test_mkdir $DIR/$tdir
11322         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11323         rm -rf $DIR/$tdir
11324 }
11325 run_test 118l "fsync dir"
11326
11327 test_118m() # LU-3066
11328 {
11329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11330
11331         test_mkdir $DIR/$tdir
11332         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11333         rm -rf $DIR/$tdir
11334 }
11335 run_test 118m "fdatasync dir ========="
11336
11337 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11338
11339 test_118n()
11340 {
11341         local begin
11342         local end
11343
11344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11345         remote_ost_nodsh && skip "remote OSTs with nodsh"
11346
11347         # Sleep to avoid a cached response.
11348         #define OBD_STATFS_CACHE_SECONDS 1
11349         sleep 2
11350
11351         # Inject a 10 second delay in the OST_STATFS handler.
11352         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11353         set_nodes_failloc "$(osts_nodes)" 0x242
11354
11355         begin=$SECONDS
11356         stat --file-system $MOUNT > /dev/null
11357         end=$SECONDS
11358
11359         set_nodes_failloc "$(osts_nodes)" 0
11360
11361         if ((end - begin > 20)); then
11362             error "statfs took $((end - begin)) seconds, expected 10"
11363         fi
11364 }
11365 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11366
11367 test_119a() # bug 11737
11368 {
11369         BSIZE=$((512 * 1024))
11370         directio write $DIR/$tfile 0 1 $BSIZE
11371         # We ask to read two blocks, which is more than a file size.
11372         # directio will indicate an error when requested and actual
11373         # sizes aren't equeal (a normal situation in this case) and
11374         # print actual read amount.
11375         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11376         if [ "$NOB" != "$BSIZE" ]; then
11377                 error "read $NOB bytes instead of $BSIZE"
11378         fi
11379         rm -f $DIR/$tfile
11380 }
11381 run_test 119a "Short directIO read must return actual read amount"
11382
11383 test_119b() # bug 11737
11384 {
11385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11386
11387         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11388         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11389         sync
11390         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11391                 error "direct read failed"
11392         rm -f $DIR/$tfile
11393 }
11394 run_test 119b "Sparse directIO read must return actual read amount"
11395
11396 test_119c() # bug 13099
11397 {
11398         BSIZE=1048576
11399         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11400         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11401         rm -f $DIR/$tfile
11402 }
11403 run_test 119c "Testing for direct read hitting hole"
11404
11405 test_119d() # bug 15950
11406 {
11407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11408
11409         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11410         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11411         BSIZE=1048576
11412         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11413         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11414         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11415         lctl set_param fail_loc=0x40d
11416         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11417         pid_dio=$!
11418         sleep 1
11419         cat $DIR/$tfile > /dev/null &
11420         lctl set_param fail_loc=0
11421         pid_reads=$!
11422         wait $pid_dio
11423         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11424         sleep 2
11425         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11426         error "the read rpcs have not completed in 2s"
11427         rm -f $DIR/$tfile
11428         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11429 }
11430 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11431
11432 test_120a() {
11433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11434         remote_mds_nodsh && skip "remote MDS with nodsh"
11435         test_mkdir -i0 -c1 $DIR/$tdir
11436         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11437                 skip_env "no early lock cancel on server"
11438
11439         lru_resize_disable mdc
11440         lru_resize_disable osc
11441         cancel_lru_locks mdc
11442         # asynchronous object destroy at MDT could cause bl ast to client
11443         cancel_lru_locks osc
11444
11445         stat $DIR/$tdir > /dev/null
11446         can1=$(do_facet mds1 \
11447                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11448                awk '/ldlm_cancel/ {print $2}')
11449         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11450                awk '/ldlm_bl_callback/ {print $2}')
11451         test_mkdir -i0 -c1 $DIR/$tdir/d1
11452         can2=$(do_facet mds1 \
11453                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11454                awk '/ldlm_cancel/ {print $2}')
11455         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11456                awk '/ldlm_bl_callback/ {print $2}')
11457         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11458         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11459         lru_resize_enable mdc
11460         lru_resize_enable osc
11461 }
11462 run_test 120a "Early Lock Cancel: mkdir test"
11463
11464 test_120b() {
11465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11466         remote_mds_nodsh && skip "remote MDS with nodsh"
11467         test_mkdir $DIR/$tdir
11468         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11469                 skip_env "no early lock cancel on server"
11470
11471         lru_resize_disable mdc
11472         lru_resize_disable osc
11473         cancel_lru_locks mdc
11474         stat $DIR/$tdir > /dev/null
11475         can1=$(do_facet $SINGLEMDS \
11476                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11477                awk '/ldlm_cancel/ {print $2}')
11478         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11479                awk '/ldlm_bl_callback/ {print $2}')
11480         touch $DIR/$tdir/f1
11481         can2=$(do_facet $SINGLEMDS \
11482                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11483                awk '/ldlm_cancel/ {print $2}')
11484         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11485                awk '/ldlm_bl_callback/ {print $2}')
11486         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11487         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11488         lru_resize_enable mdc
11489         lru_resize_enable osc
11490 }
11491 run_test 120b "Early Lock Cancel: create test"
11492
11493 test_120c() {
11494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11495         remote_mds_nodsh && skip "remote MDS with nodsh"
11496         test_mkdir -i0 -c1 $DIR/$tdir
11497         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11498                 skip "no early lock cancel on server"
11499
11500         lru_resize_disable mdc
11501         lru_resize_disable osc
11502         test_mkdir -i0 -c1 $DIR/$tdir/d1
11503         test_mkdir -i0 -c1 $DIR/$tdir/d2
11504         touch $DIR/$tdir/d1/f1
11505         cancel_lru_locks mdc
11506         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11507         can1=$(do_facet mds1 \
11508                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11509                awk '/ldlm_cancel/ {print $2}')
11510         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11511                awk '/ldlm_bl_callback/ {print $2}')
11512         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11513         can2=$(do_facet mds1 \
11514                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11515                awk '/ldlm_cancel/ {print $2}')
11516         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11517                awk '/ldlm_bl_callback/ {print $2}')
11518         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11519         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11520         lru_resize_enable mdc
11521         lru_resize_enable osc
11522 }
11523 run_test 120c "Early Lock Cancel: link test"
11524
11525 test_120d() {
11526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11527         remote_mds_nodsh && skip "remote MDS with nodsh"
11528         test_mkdir -i0 -c1 $DIR/$tdir
11529         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11530                 skip_env "no early lock cancel on server"
11531
11532         lru_resize_disable mdc
11533         lru_resize_disable osc
11534         touch $DIR/$tdir
11535         cancel_lru_locks mdc
11536         stat $DIR/$tdir > /dev/null
11537         can1=$(do_facet mds1 \
11538                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11539                awk '/ldlm_cancel/ {print $2}')
11540         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11541                awk '/ldlm_bl_callback/ {print $2}')
11542         chmod a+x $DIR/$tdir
11543         can2=$(do_facet mds1 \
11544                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11545                awk '/ldlm_cancel/ {print $2}')
11546         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11547                awk '/ldlm_bl_callback/ {print $2}')
11548         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11549         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11550         lru_resize_enable mdc
11551         lru_resize_enable osc
11552 }
11553 run_test 120d "Early Lock Cancel: setattr test"
11554
11555 test_120e() {
11556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11557         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11558                 skip_env "no early lock cancel on server"
11559         remote_mds_nodsh && skip "remote MDS with nodsh"
11560
11561         local dlmtrace_set=false
11562
11563         test_mkdir -i0 -c1 $DIR/$tdir
11564         lru_resize_disable mdc
11565         lru_resize_disable osc
11566         ! $LCTL get_param debug | grep -q dlmtrace &&
11567                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11568         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11569         cancel_lru_locks mdc
11570         cancel_lru_locks osc
11571         dd if=$DIR/$tdir/f1 of=/dev/null
11572         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11573         # XXX client can not do early lock cancel of OST lock
11574         # during unlink (LU-4206), so cancel osc lock now.
11575         sleep 2
11576         cancel_lru_locks osc
11577         can1=$(do_facet mds1 \
11578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11579                awk '/ldlm_cancel/ {print $2}')
11580         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11581                awk '/ldlm_bl_callback/ {print $2}')
11582         unlink $DIR/$tdir/f1
11583         sleep 5
11584         can2=$(do_facet mds1 \
11585                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11586                awk '/ldlm_cancel/ {print $2}')
11587         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11588                awk '/ldlm_bl_callback/ {print $2}')
11589         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11590                 $LCTL dk $TMP/cancel.debug.txt
11591         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11592                 $LCTL dk $TMP/blocking.debug.txt
11593         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11594         lru_resize_enable mdc
11595         lru_resize_enable osc
11596 }
11597 run_test 120e "Early Lock Cancel: unlink test"
11598
11599 test_120f() {
11600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11601         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11602                 skip_env "no early lock cancel on server"
11603         remote_mds_nodsh && skip "remote MDS with nodsh"
11604
11605         test_mkdir -i0 -c1 $DIR/$tdir
11606         lru_resize_disable mdc
11607         lru_resize_disable osc
11608         test_mkdir -i0 -c1 $DIR/$tdir/d1
11609         test_mkdir -i0 -c1 $DIR/$tdir/d2
11610         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11611         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11612         cancel_lru_locks mdc
11613         cancel_lru_locks osc
11614         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11615         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11616         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11617         # XXX client can not do early lock cancel of OST lock
11618         # during rename (LU-4206), so cancel osc lock now.
11619         sleep 2
11620         cancel_lru_locks osc
11621         can1=$(do_facet mds1 \
11622                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11623                awk '/ldlm_cancel/ {print $2}')
11624         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11625                awk '/ldlm_bl_callback/ {print $2}')
11626         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11627         sleep 5
11628         can2=$(do_facet mds1 \
11629                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11630                awk '/ldlm_cancel/ {print $2}')
11631         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11632                awk '/ldlm_bl_callback/ {print $2}')
11633         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11634         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11635         lru_resize_enable mdc
11636         lru_resize_enable osc
11637 }
11638 run_test 120f "Early Lock Cancel: rename test"
11639
11640 test_120g() {
11641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11642         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11643                 skip_env "no early lock cancel on server"
11644         remote_mds_nodsh && skip "remote MDS with nodsh"
11645
11646         lru_resize_disable mdc
11647         lru_resize_disable osc
11648         count=10000
11649         echo create $count files
11650         test_mkdir $DIR/$tdir
11651         cancel_lru_locks mdc
11652         cancel_lru_locks osc
11653         t0=$(date +%s)
11654
11655         can0=$(do_facet $SINGLEMDS \
11656                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11657                awk '/ldlm_cancel/ {print $2}')
11658         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11659                awk '/ldlm_bl_callback/ {print $2}')
11660         createmany -o $DIR/$tdir/f $count
11661         sync
11662         can1=$(do_facet $SINGLEMDS \
11663                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11664                awk '/ldlm_cancel/ {print $2}')
11665         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11666                awk '/ldlm_bl_callback/ {print $2}')
11667         t1=$(date +%s)
11668         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11669         echo rm $count files
11670         rm -r $DIR/$tdir
11671         sync
11672         can2=$(do_facet $SINGLEMDS \
11673                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11674                awk '/ldlm_cancel/ {print $2}')
11675         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11676                awk '/ldlm_bl_callback/ {print $2}')
11677         t2=$(date +%s)
11678         echo total: $count removes in $((t2-t1))
11679         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11680         sleep 2
11681         # wait for commitment of removal
11682         lru_resize_enable mdc
11683         lru_resize_enable osc
11684 }
11685 run_test 120g "Early Lock Cancel: performance test"
11686
11687 test_121() { #bug #10589
11688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11689
11690         rm -rf $DIR/$tfile
11691         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11692 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11693         lctl set_param fail_loc=0x310
11694         cancel_lru_locks osc > /dev/null
11695         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11696         lctl set_param fail_loc=0
11697         [[ $reads -eq $writes ]] ||
11698                 error "read $reads blocks, must be $writes blocks"
11699 }
11700 run_test 121 "read cancel race ========="
11701
11702 test_123a_base() { # was test 123, statahead(bug 11401)
11703         local lsx="$1"
11704
11705         SLOWOK=0
11706         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11707                 log "testing UP system. Performance may be lower than expected."
11708                 SLOWOK=1
11709         fi
11710
11711         rm -rf $DIR/$tdir
11712         test_mkdir $DIR/$tdir
11713         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11714         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11715         MULT=10
11716         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11717                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11718
11719                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11720                 lctl set_param -n llite.*.statahead_max 0
11721                 lctl get_param llite.*.statahead_max
11722                 cancel_lru_locks mdc
11723                 cancel_lru_locks osc
11724                 stime=$(date +%s)
11725                 time $lsx $DIR/$tdir | wc -l
11726                 etime=$(date +%s)
11727                 delta=$((etime - stime))
11728                 log "$lsx $i files without statahead: $delta sec"
11729                 lctl set_param llite.*.statahead_max=$max
11730
11731                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11732                         grep "statahead wrong:" | awk '{print $3}')
11733                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11734                 cancel_lru_locks mdc
11735                 cancel_lru_locks osc
11736                 stime=$(date +%s)
11737                 time $lsx $DIR/$tdir | wc -l
11738                 etime=$(date +%s)
11739                 delta_sa=$((etime - stime))
11740                 log "$lsx $i files with statahead: $delta_sa sec"
11741                 lctl get_param -n llite.*.statahead_stats
11742                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11743                         grep "statahead wrong:" | awk '{print $3}')
11744
11745                 [[ $swrong -lt $ewrong ]] &&
11746                         log "statahead was stopped, maybe too many locks held!"
11747                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11748
11749                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11750                         max=$(lctl get_param -n llite.*.statahead_max |
11751                                 head -n 1)
11752                         lctl set_param -n llite.*.statahead_max 0
11753                         lctl get_param llite.*.statahead_max
11754                         cancel_lru_locks mdc
11755                         cancel_lru_locks osc
11756                         stime=$(date +%s)
11757                         time $lsx $DIR/$tdir | wc -l
11758                         etime=$(date +%s)
11759                         delta=$((etime - stime))
11760                         log "$lsx $i files again without statahead: $delta sec"
11761                         lctl set_param llite.*.statahead_max=$max
11762                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11763                                 if [  $SLOWOK -eq 0 ]; then
11764                                         error "$lsx $i files is slower with statahead!"
11765                                 else
11766                                         log "$lsx $i files is slower with statahead!"
11767                                 fi
11768                                 break
11769                         fi
11770                 fi
11771
11772                 [ $delta -gt 20 ] && break
11773                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11774                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11775         done
11776         log "$lsx done"
11777
11778         stime=$(date +%s)
11779         rm -r $DIR/$tdir
11780         sync
11781         etime=$(date +%s)
11782         delta=$((etime - stime))
11783         log "rm -r $DIR/$tdir/: $delta seconds"
11784         log "rm done"
11785         lctl get_param -n llite.*.statahead_stats
11786 }
11787
11788 test_123aa() {
11789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11790
11791         test_123a_base "ls -l"
11792 }
11793 run_test 123aa "verify statahead work"
11794
11795 test_123ab() {
11796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11797
11798         statx_supported || skip_env "Test must be statx() syscall supported"
11799
11800         test_123a_base "$STATX -l"
11801 }
11802 run_test 123ab "verify statahead work by using statx"
11803
11804 test_123ac() {
11805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11806
11807         statx_supported || skip_env "Test must be statx() syscall supported"
11808
11809         local rpcs_before
11810         local rpcs_after
11811         local agl_before
11812         local agl_after
11813
11814         cancel_lru_locks $OSC
11815         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11816         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11817                 awk '/agl.total:/ {print $3}')
11818         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11819         test_123a_base "$STATX --cached=always -D"
11820         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11821                 awk '/agl.total:/ {print $3}')
11822         [ $agl_before -eq $agl_after ] ||
11823                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11824         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11825         [ $rpcs_after -eq $rpcs_before ] ||
11826                 error "$STATX should not send glimpse RPCs to $OSC"
11827 }
11828 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11829
11830 test_123b () { # statahead(bug 15027)
11831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11832
11833         test_mkdir $DIR/$tdir
11834         createmany -o $DIR/$tdir/$tfile-%d 1000
11835
11836         cancel_lru_locks mdc
11837         cancel_lru_locks osc
11838
11839 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11840         lctl set_param fail_loc=0x80000803
11841         ls -lR $DIR/$tdir > /dev/null
11842         log "ls done"
11843         lctl set_param fail_loc=0x0
11844         lctl get_param -n llite.*.statahead_stats
11845         rm -r $DIR/$tdir
11846         sync
11847
11848 }
11849 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11850
11851 test_123c() {
11852         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11853
11854         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11855         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11856         touch $DIR/$tdir.1/{1..3}
11857         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11858
11859         remount_client $MOUNT
11860
11861         $MULTIOP $DIR/$tdir.0 Q
11862
11863         # let statahead to complete
11864         ls -l $DIR/$tdir.0 > /dev/null
11865
11866         testid=$(echo $TESTNAME | tr '_' ' ')
11867         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11868                 error "statahead warning" || true
11869 }
11870 run_test 123c "Can not initialize inode warning on DNE statahead"
11871
11872 test_124a() {
11873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11874         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11875                 skip_env "no lru resize on server"
11876
11877         local NR=2000
11878
11879         test_mkdir $DIR/$tdir
11880
11881         log "create $NR files at $DIR/$tdir"
11882         createmany -o $DIR/$tdir/f $NR ||
11883                 error "failed to create $NR files in $DIR/$tdir"
11884
11885         cancel_lru_locks mdc
11886         ls -l $DIR/$tdir > /dev/null
11887
11888         local NSDIR=""
11889         local LRU_SIZE=0
11890         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11891                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11892                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11893                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11894                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11895                         log "NSDIR=$NSDIR"
11896                         log "NS=$(basename $NSDIR)"
11897                         break
11898                 fi
11899         done
11900
11901         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11902                 skip "Not enough cached locks created!"
11903         fi
11904         log "LRU=$LRU_SIZE"
11905
11906         local SLEEP=30
11907
11908         # We know that lru resize allows one client to hold $LIMIT locks
11909         # for 10h. After that locks begin to be killed by client.
11910         local MAX_HRS=10
11911         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11912         log "LIMIT=$LIMIT"
11913         if [ $LIMIT -lt $LRU_SIZE ]; then
11914                 skip "Limit is too small $LIMIT"
11915         fi
11916
11917         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11918         # killing locks. Some time was spent for creating locks. This means
11919         # that up to the moment of sleep finish we must have killed some of
11920         # them (10-100 locks). This depends on how fast ther were created.
11921         # Many of them were touched in almost the same moment and thus will
11922         # be killed in groups.
11923         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11924
11925         # Use $LRU_SIZE_B here to take into account real number of locks
11926         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11927         local LRU_SIZE_B=$LRU_SIZE
11928         log "LVF=$LVF"
11929         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11930         log "OLD_LVF=$OLD_LVF"
11931         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11932
11933         # Let's make sure that we really have some margin. Client checks
11934         # cached locks every 10 sec.
11935         SLEEP=$((SLEEP+20))
11936         log "Sleep ${SLEEP} sec"
11937         local SEC=0
11938         while ((SEC<$SLEEP)); do
11939                 echo -n "..."
11940                 sleep 5
11941                 SEC=$((SEC+5))
11942                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11943                 echo -n "$LRU_SIZE"
11944         done
11945         echo ""
11946         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11947         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11948
11949         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11950                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11951                 unlinkmany $DIR/$tdir/f $NR
11952                 return
11953         }
11954
11955         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11956         log "unlink $NR files at $DIR/$tdir"
11957         unlinkmany $DIR/$tdir/f $NR
11958 }
11959 run_test 124a "lru resize ======================================="
11960
11961 get_max_pool_limit()
11962 {
11963         local limit=$($LCTL get_param \
11964                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11965         local max=0
11966         for l in $limit; do
11967                 if [[ $l -gt $max ]]; then
11968                         max=$l
11969                 fi
11970         done
11971         echo $max
11972 }
11973
11974 test_124b() {
11975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11976         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11977                 skip_env "no lru resize on server"
11978
11979         LIMIT=$(get_max_pool_limit)
11980
11981         NR=$(($(default_lru_size)*20))
11982         if [[ $NR -gt $LIMIT ]]; then
11983                 log "Limit lock number by $LIMIT locks"
11984                 NR=$LIMIT
11985         fi
11986
11987         IFree=$(mdsrate_inodes_available)
11988         if [ $IFree -lt $NR ]; then
11989                 log "Limit lock number by $IFree inodes"
11990                 NR=$IFree
11991         fi
11992
11993         lru_resize_disable mdc
11994         test_mkdir -p $DIR/$tdir/disable_lru_resize
11995
11996         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11997         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11998         cancel_lru_locks mdc
11999         stime=`date +%s`
12000         PID=""
12001         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12002         PID="$PID $!"
12003         sleep 2
12004         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12005         PID="$PID $!"
12006         sleep 2
12007         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12008         PID="$PID $!"
12009         wait $PID
12010         etime=`date +%s`
12011         nolruresize_delta=$((etime-stime))
12012         log "ls -la time: $nolruresize_delta seconds"
12013         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12014         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12015
12016         lru_resize_enable mdc
12017         test_mkdir -p $DIR/$tdir/enable_lru_resize
12018
12019         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12020         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12021         cancel_lru_locks mdc
12022         stime=`date +%s`
12023         PID=""
12024         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12025         PID="$PID $!"
12026         sleep 2
12027         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12028         PID="$PID $!"
12029         sleep 2
12030         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12031         PID="$PID $!"
12032         wait $PID
12033         etime=`date +%s`
12034         lruresize_delta=$((etime-stime))
12035         log "ls -la time: $lruresize_delta seconds"
12036         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12037
12038         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12039                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12040         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12041                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12042         else
12043                 log "lru resize performs the same with no lru resize"
12044         fi
12045         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12046 }
12047 run_test 124b "lru resize (performance test) ======================="
12048
12049 test_124c() {
12050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12051         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12052                 skip_env "no lru resize on server"
12053
12054         # cache ununsed locks on client
12055         local nr=100
12056         cancel_lru_locks mdc
12057         test_mkdir $DIR/$tdir
12058         createmany -o $DIR/$tdir/f $nr ||
12059                 error "failed to create $nr files in $DIR/$tdir"
12060         ls -l $DIR/$tdir > /dev/null
12061
12062         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12063         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12064         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12065         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12066         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12067
12068         # set lru_max_age to 1 sec
12069         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12070         echo "sleep $((recalc_p * 2)) seconds..."
12071         sleep $((recalc_p * 2))
12072
12073         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12074         # restore lru_max_age
12075         $LCTL set_param -n $nsdir.lru_max_age $max_age
12076         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12077         unlinkmany $DIR/$tdir/f $nr
12078 }
12079 run_test 124c "LRUR cancel very aged locks"
12080
12081 test_124d() {
12082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12083         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12084                 skip_env "no lru resize on server"
12085
12086         # cache ununsed locks on client
12087         local nr=100
12088
12089         lru_resize_disable mdc
12090         stack_trap "lru_resize_enable mdc" EXIT
12091
12092         cancel_lru_locks mdc
12093
12094         # asynchronous object destroy at MDT could cause bl ast to client
12095         test_mkdir $DIR/$tdir
12096         createmany -o $DIR/$tdir/f $nr ||
12097                 error "failed to create $nr files in $DIR/$tdir"
12098         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12099
12100         ls -l $DIR/$tdir > /dev/null
12101
12102         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12103         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12104         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12105         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12106
12107         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12108
12109         # set lru_max_age to 1 sec
12110         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12111         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12112
12113         echo "sleep $((recalc_p * 2)) seconds..."
12114         sleep $((recalc_p * 2))
12115
12116         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12117
12118         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12119 }
12120 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12121
12122 test_125() { # 13358
12123         $LCTL get_param -n llite.*.client_type | grep -q local ||
12124                 skip "must run as local client"
12125         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12126                 skip_env "must have acl enabled"
12127         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12128
12129         test_mkdir $DIR/$tdir
12130         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12131         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12132         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12133 }
12134 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12135
12136 test_126() { # bug 12829/13455
12137         $GSS && skip_env "must run as gss disabled"
12138         $LCTL get_param -n llite.*.client_type | grep -q local ||
12139                 skip "must run as local client"
12140         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12141
12142         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12143         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12144         rm -f $DIR/$tfile
12145         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12146 }
12147 run_test 126 "check that the fsgid provided by the client is taken into account"
12148
12149 test_127a() { # bug 15521
12150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12151         local name count samp unit min max sum sumsq
12152
12153         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12154         echo "stats before reset"
12155         $LCTL get_param osc.*.stats
12156         $LCTL set_param osc.*.stats=0
12157         local fsize=$((2048 * 1024))
12158
12159         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12160         cancel_lru_locks osc
12161         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12162
12163         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12164         stack_trap "rm -f $TMP/$tfile.tmp"
12165         while read name count samp unit min max sum sumsq; do
12166                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12167                 [ ! $min ] && error "Missing min value for $name proc entry"
12168                 eval $name=$count || error "Wrong proc format"
12169
12170                 case $name in
12171                 read_bytes|write_bytes)
12172                         [[ "$unit" =~ "bytes" ]] ||
12173                                 error "unit is not 'bytes': $unit"
12174                         (( $min >= 4096 )) || error "min is too small: $min"
12175                         (( $min <= $fsize )) || error "min is too big: $min"
12176                         (( $max >= 4096 )) || error "max is too small: $max"
12177                         (( $max <= $fsize )) || error "max is too big: $max"
12178                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12179                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12180                                 error "sumsquare is too small: $sumsq"
12181                         (( $sumsq <= $fsize * $fsize )) ||
12182                                 error "sumsquare is too big: $sumsq"
12183                         ;;
12184                 ost_read|ost_write)
12185                         [[ "$unit" =~ "usec" ]] ||
12186                                 error "unit is not 'usec': $unit"
12187                         ;;
12188                 *)      ;;
12189                 esac
12190         done < $DIR/$tfile.tmp
12191
12192         #check that we actually got some stats
12193         [ "$read_bytes" ] || error "Missing read_bytes stats"
12194         [ "$write_bytes" ] || error "Missing write_bytes stats"
12195         [ "$read_bytes" != 0 ] || error "no read done"
12196         [ "$write_bytes" != 0 ] || error "no write done"
12197 }
12198 run_test 127a "verify the client stats are sane"
12199
12200 test_127b() { # bug LU-333
12201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12202         local name count samp unit min max sum sumsq
12203
12204         echo "stats before reset"
12205         $LCTL get_param llite.*.stats
12206         $LCTL set_param llite.*.stats=0
12207
12208         # perform 2 reads and writes so MAX is different from SUM.
12209         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12210         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12211         cancel_lru_locks osc
12212         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12213         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12214
12215         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12216         stack_trap "rm -f $TMP/$tfile.tmp"
12217         while read name count samp unit min max sum sumsq; do
12218                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12219                 eval $name=$count || error "Wrong proc format"
12220
12221                 case $name in
12222                 read_bytes|write_bytes)
12223                         [[ "$unit" =~ "bytes" ]] ||
12224                                 error "unit is not 'bytes': $unit"
12225                         (( $count == 2 )) || error "count is not 2: $count"
12226                         (( $min == $PAGE_SIZE )) ||
12227                                 error "min is not $PAGE_SIZE: $min"
12228                         (( $max == $PAGE_SIZE )) ||
12229                                 error "max is not $PAGE_SIZE: $max"
12230                         (( $sum == $PAGE_SIZE * 2 )) ||
12231                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12232                         ;;
12233                 read|write)
12234                         [[ "$unit" =~ "usec" ]] ||
12235                                 error "unit is not 'usec': $unit"
12236                         ;;
12237                 *)      ;;
12238                 esac
12239         done < $TMP/$tfile.tmp
12240
12241         #check that we actually got some stats
12242         [ "$read_bytes" ] || error "Missing read_bytes stats"
12243         [ "$write_bytes" ] || error "Missing write_bytes stats"
12244         [ "$read_bytes" != 0 ] || error "no read done"
12245         [ "$write_bytes" != 0 ] || error "no write done"
12246 }
12247 run_test 127b "verify the llite client stats are sane"
12248
12249 test_127c() { # LU-12394
12250         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12251         local size
12252         local bsize
12253         local reads
12254         local writes
12255         local count
12256
12257         $LCTL set_param llite.*.extents_stats=1
12258         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12259
12260         # Use two stripes so there is enough space in default config
12261         $LFS setstripe -c 2 $DIR/$tfile
12262
12263         # Extent stats start at 0-4K and go in power of two buckets
12264         # LL_HIST_START = 12 --> 2^12 = 4K
12265         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12266         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12267         # small configs
12268         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12269                 do
12270                 # Write and read, 2x each, second time at a non-zero offset
12271                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12272                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12273                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12274                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12275                 rm -f $DIR/$tfile
12276         done
12277
12278         $LCTL get_param llite.*.extents_stats
12279
12280         count=2
12281         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12282                 do
12283                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12284                                 grep -m 1 $bsize)
12285                 reads=$(echo $bucket | awk '{print $5}')
12286                 writes=$(echo $bucket | awk '{print $9}')
12287                 [ "$reads" -eq $count ] ||
12288                         error "$reads reads in < $bsize bucket, expect $count"
12289                 [ "$writes" -eq $count ] ||
12290                         error "$writes writes in < $bsize bucket, expect $count"
12291         done
12292
12293         # Test mmap write and read
12294         $LCTL set_param llite.*.extents_stats=c
12295         size=512
12296         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12297         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12298         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12299
12300         $LCTL get_param llite.*.extents_stats
12301
12302         count=$(((size*1024) / PAGE_SIZE))
12303
12304         bsize=$((2 * PAGE_SIZE / 1024))K
12305
12306         bucket=$($LCTL get_param -n llite.*.extents_stats |
12307                         grep -m 1 $bsize)
12308         reads=$(echo $bucket | awk '{print $5}')
12309         writes=$(echo $bucket | awk '{print $9}')
12310         # mmap writes fault in the page first, creating an additonal read
12311         [ "$reads" -eq $((2 * count)) ] ||
12312                 error "$reads reads in < $bsize bucket, expect $count"
12313         [ "$writes" -eq $count ] ||
12314                 error "$writes writes in < $bsize bucket, expect $count"
12315 }
12316 run_test 127c "test llite extent stats with regular & mmap i/o"
12317
12318 test_128() { # bug 15212
12319         touch $DIR/$tfile
12320         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12321                 find $DIR/$tfile
12322                 find $DIR/$tfile
12323         EOF
12324
12325         result=$(grep error $TMP/$tfile.log)
12326         rm -f $DIR/$tfile $TMP/$tfile.log
12327         [ -z "$result" ] ||
12328                 error "consecutive find's under interactive lfs failed"
12329 }
12330 run_test 128 "interactive lfs for 2 consecutive find's"
12331
12332 set_dir_limits () {
12333         local mntdev
12334         local canondev
12335         local node
12336
12337         local ldproc=/proc/fs/ldiskfs
12338         local facets=$(get_facets MDS)
12339
12340         for facet in ${facets//,/ }; do
12341                 canondev=$(ldiskfs_canon \
12342                            *.$(convert_facet2label $facet).mntdev $facet)
12343                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12344                         ldproc=/sys/fs/ldiskfs
12345                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12346                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12347         done
12348 }
12349
12350 check_mds_dmesg() {
12351         local facets=$(get_facets MDS)
12352         for facet in ${facets//,/ }; do
12353                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12354         done
12355         return 1
12356 }
12357
12358 test_129() {
12359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12360         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12361                 skip "Need MDS version with at least 2.5.56"
12362         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12363                 skip_env "ldiskfs only test"
12364         fi
12365         remote_mds_nodsh && skip "remote MDS with nodsh"
12366
12367         local ENOSPC=28
12368         local has_warning=false
12369
12370         rm -rf $DIR/$tdir
12371         mkdir -p $DIR/$tdir
12372
12373         # block size of mds1
12374         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12375         set_dir_limits $maxsize $((maxsize * 6 / 8))
12376         stack_trap "set_dir_limits 0 0"
12377         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12378         local dirsize=$(stat -c%s "$DIR/$tdir")
12379         local nfiles=0
12380         while (( $dirsize <= $maxsize )); do
12381                 $MCREATE $DIR/$tdir/file_base_$nfiles
12382                 rc=$?
12383                 # check two errors:
12384                 # ENOSPC for ext4 max_dir_size, which has been used since
12385                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12386                 if (( rc == ENOSPC )); then
12387                         set_dir_limits 0 0
12388                         echo "rc=$rc returned as expected after $nfiles files"
12389
12390                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12391                                 error "create failed w/o dir size limit"
12392
12393                         # messages may be rate limited if test is run repeatedly
12394                         check_mds_dmesg '"is approaching max"' ||
12395                                 echo "warning message should be output"
12396                         check_mds_dmesg '"has reached max"' ||
12397                                 echo "reached message should be output"
12398
12399                         dirsize=$(stat -c%s "$DIR/$tdir")
12400
12401                         [[ $dirsize -ge $maxsize ]] && return 0
12402                         error "dirsize $dirsize < $maxsize after $nfiles files"
12403                 elif (( rc != 0 )); then
12404                         break
12405                 fi
12406                 nfiles=$((nfiles + 1))
12407                 dirsize=$(stat -c%s "$DIR/$tdir")
12408         done
12409
12410         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12411 }
12412 run_test 129 "test directory size limit ========================"
12413
12414 OLDIFS="$IFS"
12415 cleanup_130() {
12416         trap 0
12417         IFS="$OLDIFS"
12418 }
12419
12420 test_130a() {
12421         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12422         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12423
12424         trap cleanup_130 EXIT RETURN
12425
12426         local fm_file=$DIR/$tfile
12427         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12428         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12429                 error "dd failed for $fm_file"
12430
12431         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12432         filefrag -ves $fm_file
12433         RC=$?
12434         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12435                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12436         [ $RC != 0 ] && error "filefrag $fm_file failed"
12437
12438         filefrag_op=$(filefrag -ve -k $fm_file |
12439                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12440         lun=$($LFS getstripe -i $fm_file)
12441
12442         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12443         IFS=$'\n'
12444         tot_len=0
12445         for line in $filefrag_op
12446         do
12447                 frag_lun=`echo $line | cut -d: -f5`
12448                 ext_len=`echo $line | cut -d: -f4`
12449                 if (( $frag_lun != $lun )); then
12450                         cleanup_130
12451                         error "FIEMAP on 1-stripe file($fm_file) failed"
12452                         return
12453                 fi
12454                 (( tot_len += ext_len ))
12455         done
12456
12457         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12458                 cleanup_130
12459                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12460                 return
12461         fi
12462
12463         cleanup_130
12464
12465         echo "FIEMAP on single striped file succeeded"
12466 }
12467 run_test 130a "FIEMAP (1-stripe file)"
12468
12469 test_130b() {
12470         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12471
12472         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12473         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12474
12475         trap cleanup_130 EXIT RETURN
12476
12477         local fm_file=$DIR/$tfile
12478         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12479                         error "setstripe on $fm_file"
12480         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12481                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12482
12483         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12484                 error "dd failed on $fm_file"
12485
12486         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12487         filefrag_op=$(filefrag -ve -k $fm_file |
12488                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12489
12490         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12491                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12492
12493         IFS=$'\n'
12494         tot_len=0
12495         num_luns=1
12496         for line in $filefrag_op
12497         do
12498                 frag_lun=$(echo $line | cut -d: -f5 |
12499                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12500                 ext_len=$(echo $line | cut -d: -f4)
12501                 if (( $frag_lun != $last_lun )); then
12502                         if (( tot_len != 1024 )); then
12503                                 cleanup_130
12504                                 error "FIEMAP on $fm_file failed; returned " \
12505                                 "len $tot_len for OST $last_lun instead of 1024"
12506                                 return
12507                         else
12508                                 (( num_luns += 1 ))
12509                                 tot_len=0
12510                         fi
12511                 fi
12512                 (( tot_len += ext_len ))
12513                 last_lun=$frag_lun
12514         done
12515         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12516                 cleanup_130
12517                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12518                         "luns or wrong len for OST $last_lun"
12519                 return
12520         fi
12521
12522         cleanup_130
12523
12524         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12525 }
12526 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12527
12528 test_130c() {
12529         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12530
12531         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12532         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12533
12534         trap cleanup_130 EXIT RETURN
12535
12536         local fm_file=$DIR/$tfile
12537         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12538         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12539                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12540
12541         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12542                         error "dd failed on $fm_file"
12543
12544         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12545         filefrag_op=$(filefrag -ve -k $fm_file |
12546                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12547
12548         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12549                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12550
12551         IFS=$'\n'
12552         tot_len=0
12553         num_luns=1
12554         for line in $filefrag_op
12555         do
12556                 frag_lun=$(echo $line | cut -d: -f5 |
12557                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12558                 ext_len=$(echo $line | cut -d: -f4)
12559                 if (( $frag_lun != $last_lun )); then
12560                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12561                         if (( logical != 512 )); then
12562                                 cleanup_130
12563                                 error "FIEMAP on $fm_file failed; returned " \
12564                                 "logical start for lun $logical instead of 512"
12565                                 return
12566                         fi
12567                         if (( tot_len != 512 )); then
12568                                 cleanup_130
12569                                 error "FIEMAP on $fm_file failed; returned " \
12570                                 "len $tot_len for OST $last_lun instead of 1024"
12571                                 return
12572                         else
12573                                 (( num_luns += 1 ))
12574                                 tot_len=0
12575                         fi
12576                 fi
12577                 (( tot_len += ext_len ))
12578                 last_lun=$frag_lun
12579         done
12580         if (( num_luns != 2 || tot_len != 512 )); then
12581                 cleanup_130
12582                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12583                         "luns or wrong len for OST $last_lun"
12584                 return
12585         fi
12586
12587         cleanup_130
12588
12589         echo "FIEMAP on 2-stripe file with hole succeeded"
12590 }
12591 run_test 130c "FIEMAP (2-stripe file with hole)"
12592
12593 test_130d() {
12594         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12595
12596         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12597         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12598
12599         trap cleanup_130 EXIT RETURN
12600
12601         local fm_file=$DIR/$tfile
12602         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12603                         error "setstripe on $fm_file"
12604         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12605                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12606
12607         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12608         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12609                 error "dd failed on $fm_file"
12610
12611         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12612         filefrag_op=$(filefrag -ve -k $fm_file |
12613                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12614
12615         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12616                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12617
12618         IFS=$'\n'
12619         tot_len=0
12620         num_luns=1
12621         for line in $filefrag_op
12622         do
12623                 frag_lun=$(echo $line | cut -d: -f5 |
12624                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12625                 ext_len=$(echo $line | cut -d: -f4)
12626                 if (( $frag_lun != $last_lun )); then
12627                         if (( tot_len != 1024 )); then
12628                                 cleanup_130
12629                                 error "FIEMAP on $fm_file failed; returned " \
12630                                 "len $tot_len for OST $last_lun instead of 1024"
12631                                 return
12632                         else
12633                                 (( num_luns += 1 ))
12634                                 tot_len=0
12635                         fi
12636                 fi
12637                 (( tot_len += ext_len ))
12638                 last_lun=$frag_lun
12639         done
12640         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12641                 cleanup_130
12642                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12643                         "luns or wrong len for OST $last_lun"
12644                 return
12645         fi
12646
12647         cleanup_130
12648
12649         echo "FIEMAP on N-stripe file succeeded"
12650 }
12651 run_test 130d "FIEMAP (N-stripe file)"
12652
12653 test_130e() {
12654         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12655
12656         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12657         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12658
12659         trap cleanup_130 EXIT RETURN
12660
12661         local fm_file=$DIR/$tfile
12662         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12663
12664         NUM_BLKS=512
12665         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12666         for ((i = 0; i < $NUM_BLKS; i++)); do
12667                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12668                         conv=notrunc > /dev/null 2>&1
12669         done
12670
12671         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12672         filefrag_op=$(filefrag -ve -k $fm_file |
12673                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12674
12675         last_lun=$(echo $filefrag_op | cut -d: -f5)
12676
12677         IFS=$'\n'
12678         tot_len=0
12679         num_luns=1
12680         for line in $filefrag_op; do
12681                 frag_lun=$(echo $line | cut -d: -f5)
12682                 ext_len=$(echo $line | cut -d: -f4)
12683                 if [[ "$frag_lun" != "$last_lun" ]]; then
12684                         if (( tot_len != $EXPECTED_LEN )); then
12685                                 cleanup_130
12686                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12687                         else
12688                                 (( num_luns += 1 ))
12689                                 tot_len=0
12690                         fi
12691                 fi
12692                 (( tot_len += ext_len ))
12693                 last_lun=$frag_lun
12694         done
12695         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12696                 cleanup_130
12697                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12698         fi
12699
12700         echo "FIEMAP with continuation calls succeeded"
12701 }
12702 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12703
12704 test_130f() {
12705         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12706         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12707
12708         local fm_file=$DIR/$tfile
12709         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12710                 error "multiop create with lov_delay_create on $fm_file"
12711
12712         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12713         filefrag_extents=$(filefrag -vek $fm_file |
12714                            awk '/extents? found/ { print $2 }')
12715         if [[ "$filefrag_extents" != "0" ]]; then
12716                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
12717         fi
12718
12719         rm -f $fm_file
12720 }
12721 run_test 130f "FIEMAP (unstriped file)"
12722
12723 test_130g() {
12724         local file=$DIR/$tfile
12725         local nr=$((OSTCOUNT * 100))
12726
12727         $LFS setstripe -C $nr $file ||
12728                 error "failed to setstripe -C $nr $file"
12729
12730         dd if=/dev/zero of=$file count=$nr bs=1M
12731         sync
12732         nr=$($LFS getstripe -c $file)
12733
12734         local extents=$(filefrag -v $file |
12735                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
12736
12737         echo "filefrag list $extents extents in file with stripecount $nr"
12738         if (( extents < nr )); then
12739                 $LFS getstripe $file
12740                 filefrag -v $file
12741                 error "filefrag printed $extents < $nr extents"
12742         fi
12743
12744         rm -f $file
12745 }
12746 run_test 130g "FIEMAP (overstripe file)"
12747
12748 # Test for writev/readv
12749 test_131a() {
12750         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12751                 error "writev test failed"
12752         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12753                 error "readv failed"
12754         rm -f $DIR/$tfile
12755 }
12756 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12757
12758 test_131b() {
12759         local fsize=$((524288 + 1048576 + 1572864))
12760         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12761                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12762                         error "append writev test failed"
12763
12764         ((fsize += 1572864 + 1048576))
12765         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12766                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12767                         error "append writev test failed"
12768         rm -f $DIR/$tfile
12769 }
12770 run_test 131b "test append writev"
12771
12772 test_131c() {
12773         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12774         error "NOT PASS"
12775 }
12776 run_test 131c "test read/write on file w/o objects"
12777
12778 test_131d() {
12779         rwv -f $DIR/$tfile -w -n 1 1572864
12780         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12781         if [ "$NOB" != 1572864 ]; then
12782                 error "Short read filed: read $NOB bytes instead of 1572864"
12783         fi
12784         rm -f $DIR/$tfile
12785 }
12786 run_test 131d "test short read"
12787
12788 test_131e() {
12789         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12790         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12791         error "read hitting hole failed"
12792         rm -f $DIR/$tfile
12793 }
12794 run_test 131e "test read hitting hole"
12795
12796 check_stats() {
12797         local facet=$1
12798         local op=$2
12799         local want=${3:-0}
12800         local res
12801
12802         case $facet in
12803         mds*) res=$(do_facet $facet \
12804                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12805                  ;;
12806         ost*) res=$(do_facet $facet \
12807                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12808                  ;;
12809         *) error "Wrong facet '$facet'" ;;
12810         esac
12811         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12812         # if the argument $3 is zero, it means any stat increment is ok.
12813         if [[ $want -gt 0 ]]; then
12814                 local count=$(echo $res | awk '{ print $2 }')
12815                 [[ $count -ne $want ]] &&
12816                         error "The $op counter on $facet is $count, not $want"
12817         fi
12818 }
12819
12820 test_133a() {
12821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12822         remote_ost_nodsh && skip "remote OST with nodsh"
12823         remote_mds_nodsh && skip "remote MDS with nodsh"
12824         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12825                 skip_env "MDS doesn't support rename stats"
12826
12827         local testdir=$DIR/${tdir}/stats_testdir
12828
12829         mkdir -p $DIR/${tdir}
12830
12831         # clear stats.
12832         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12833         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12834
12835         # verify mdt stats first.
12836         mkdir ${testdir} || error "mkdir failed"
12837         check_stats $SINGLEMDS "mkdir" 1
12838         touch ${testdir}/${tfile} || error "touch failed"
12839         check_stats $SINGLEMDS "open" 1
12840         check_stats $SINGLEMDS "close" 1
12841         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12842                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12843                 check_stats $SINGLEMDS "mknod" 2
12844         }
12845         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12846         check_stats $SINGLEMDS "unlink" 1
12847         rm -f ${testdir}/${tfile} || error "file remove failed"
12848         check_stats $SINGLEMDS "unlink" 2
12849
12850         # remove working dir and check mdt stats again.
12851         rmdir ${testdir} || error "rmdir failed"
12852         check_stats $SINGLEMDS "rmdir" 1
12853
12854         local testdir1=$DIR/${tdir}/stats_testdir1
12855         mkdir -p ${testdir}
12856         mkdir -p ${testdir1}
12857         touch ${testdir1}/test1
12858         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12859         check_stats $SINGLEMDS "crossdir_rename" 1
12860
12861         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12862         check_stats $SINGLEMDS "samedir_rename" 1
12863
12864         rm -rf $DIR/${tdir}
12865 }
12866 run_test 133a "Verifying MDT stats ========================================"
12867
12868 test_133b() {
12869         local res
12870
12871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12872         remote_ost_nodsh && skip "remote OST with nodsh"
12873         remote_mds_nodsh && skip "remote MDS with nodsh"
12874
12875         local testdir=$DIR/${tdir}/stats_testdir
12876
12877         mkdir -p ${testdir} || error "mkdir failed"
12878         touch ${testdir}/${tfile} || error "touch failed"
12879         cancel_lru_locks mdc
12880
12881         # clear stats.
12882         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12883         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12884
12885         # extra mdt stats verification.
12886         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12887         check_stats $SINGLEMDS "setattr" 1
12888         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12889         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12890         then            # LU-1740
12891                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12892                 check_stats $SINGLEMDS "getattr" 1
12893         fi
12894         rm -rf $DIR/${tdir}
12895
12896         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12897         # so the check below is not reliable
12898         [ $MDSCOUNT -eq 1 ] || return 0
12899
12900         # Sleep to avoid a cached response.
12901         #define OBD_STATFS_CACHE_SECONDS 1
12902         sleep 2
12903         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12904         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12905         $LFS df || error "lfs failed"
12906         check_stats $SINGLEMDS "statfs" 1
12907
12908         # check aggregated statfs (LU-10018)
12909         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12910                 return 0
12911         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12912                 return 0
12913         sleep 2
12914         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12915         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12916         df $DIR
12917         check_stats $SINGLEMDS "statfs" 1
12918
12919         # We want to check that the client didn't send OST_STATFS to
12920         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12921         # extra care is needed here.
12922         if remote_mds; then
12923                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12924                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12925
12926                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12927                 [ "$res" ] && error "OST got STATFS"
12928         fi
12929
12930         return 0
12931 }
12932 run_test 133b "Verifying extra MDT stats =================================="
12933
12934 test_133c() {
12935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12936         remote_ost_nodsh && skip "remote OST with nodsh"
12937         remote_mds_nodsh && skip "remote MDS with nodsh"
12938
12939         local testdir=$DIR/$tdir/stats_testdir
12940
12941         test_mkdir -p $testdir
12942
12943         # verify obdfilter stats.
12944         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12945         sync
12946         cancel_lru_locks osc
12947         wait_delete_completed
12948
12949         # clear stats.
12950         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12951         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12952
12953         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12954                 error "dd failed"
12955         sync
12956         cancel_lru_locks osc
12957         check_stats ost1 "write" 1
12958
12959         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12960         check_stats ost1 "read" 1
12961
12962         > $testdir/$tfile || error "truncate failed"
12963         check_stats ost1 "punch" 1
12964
12965         rm -f $testdir/$tfile || error "file remove failed"
12966         wait_delete_completed
12967         check_stats ost1 "destroy" 1
12968
12969         rm -rf $DIR/$tdir
12970 }
12971 run_test 133c "Verifying OST stats ========================================"
12972
12973 order_2() {
12974         local value=$1
12975         local orig=$value
12976         local order=1
12977
12978         while [ $value -ge 2 ]; do
12979                 order=$((order*2))
12980                 value=$((value/2))
12981         done
12982
12983         if [ $orig -gt $order ]; then
12984                 order=$((order*2))
12985         fi
12986         echo $order
12987 }
12988
12989 size_in_KMGT() {
12990     local value=$1
12991     local size=('K' 'M' 'G' 'T');
12992     local i=0
12993     local size_string=$value
12994
12995     while [ $value -ge 1024 ]; do
12996         if [ $i -gt 3 ]; then
12997             #T is the biggest unit we get here, if that is bigger,
12998             #just return XXXT
12999             size_string=${value}T
13000             break
13001         fi
13002         value=$((value >> 10))
13003         if [ $value -lt 1024 ]; then
13004             size_string=${value}${size[$i]}
13005             break
13006         fi
13007         i=$((i + 1))
13008     done
13009
13010     echo $size_string
13011 }
13012
13013 get_rename_size() {
13014         local size=$1
13015         local context=${2:-.}
13016         local sample=$(do_facet $SINGLEMDS $LCTL \
13017                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13018                 grep -A1 $context |
13019                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13020         echo $sample
13021 }
13022
13023 test_133d() {
13024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13025         remote_ost_nodsh && skip "remote OST with nodsh"
13026         remote_mds_nodsh && skip "remote MDS with nodsh"
13027         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13028                 skip_env "MDS doesn't support rename stats"
13029
13030         local testdir1=$DIR/${tdir}/stats_testdir1
13031         local testdir2=$DIR/${tdir}/stats_testdir2
13032         mkdir -p $DIR/${tdir}
13033
13034         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13035
13036         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13037         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13038
13039         createmany -o $testdir1/test 512 || error "createmany failed"
13040
13041         # check samedir rename size
13042         mv ${testdir1}/test0 ${testdir1}/test_0
13043
13044         local testdir1_size=$(ls -l $DIR/${tdir} |
13045                 awk '/stats_testdir1/ {print $5}')
13046         local testdir2_size=$(ls -l $DIR/${tdir} |
13047                 awk '/stats_testdir2/ {print $5}')
13048
13049         testdir1_size=$(order_2 $testdir1_size)
13050         testdir2_size=$(order_2 $testdir2_size)
13051
13052         testdir1_size=$(size_in_KMGT $testdir1_size)
13053         testdir2_size=$(size_in_KMGT $testdir2_size)
13054
13055         echo "source rename dir size: ${testdir1_size}"
13056         echo "target rename dir size: ${testdir2_size}"
13057
13058         local cmd="do_facet $SINGLEMDS $LCTL "
13059         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13060
13061         eval $cmd || error "$cmd failed"
13062         local samedir=$($cmd | grep 'same_dir')
13063         local same_sample=$(get_rename_size $testdir1_size)
13064         [ -z "$samedir" ] && error "samedir_rename_size count error"
13065         [[ $same_sample -eq 1 ]] ||
13066                 error "samedir_rename_size error $same_sample"
13067         echo "Check same dir rename stats success"
13068
13069         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13070
13071         # check crossdir rename size
13072         mv ${testdir1}/test_0 ${testdir2}/test_0
13073
13074         testdir1_size=$(ls -l $DIR/${tdir} |
13075                 awk '/stats_testdir1/ {print $5}')
13076         testdir2_size=$(ls -l $DIR/${tdir} |
13077                 awk '/stats_testdir2/ {print $5}')
13078
13079         testdir1_size=$(order_2 $testdir1_size)
13080         testdir2_size=$(order_2 $testdir2_size)
13081
13082         testdir1_size=$(size_in_KMGT $testdir1_size)
13083         testdir2_size=$(size_in_KMGT $testdir2_size)
13084
13085         echo "source rename dir size: ${testdir1_size}"
13086         echo "target rename dir size: ${testdir2_size}"
13087
13088         eval $cmd || error "$cmd failed"
13089         local crossdir=$($cmd | grep 'crossdir')
13090         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13091         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13092         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13093         [[ $src_sample -eq 1 ]] ||
13094                 error "crossdir_rename_size error $src_sample"
13095         [[ $tgt_sample -eq 1 ]] ||
13096                 error "crossdir_rename_size error $tgt_sample"
13097         echo "Check cross dir rename stats success"
13098         rm -rf $DIR/${tdir}
13099 }
13100 run_test 133d "Verifying rename_stats ========================================"
13101
13102 test_133e() {
13103         remote_mds_nodsh && skip "remote MDS with nodsh"
13104         remote_ost_nodsh && skip "remote OST with nodsh"
13105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13106
13107         local testdir=$DIR/${tdir}/stats_testdir
13108         local ctr f0 f1 bs=32768 count=42 sum
13109
13110         mkdir -p ${testdir} || error "mkdir failed"
13111
13112         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13113
13114         for ctr in {write,read}_bytes; do
13115                 sync
13116                 cancel_lru_locks osc
13117
13118                 do_facet ost1 $LCTL set_param -n \
13119                         "obdfilter.*.exports.clear=clear"
13120
13121                 if [ $ctr = write_bytes ]; then
13122                         f0=/dev/zero
13123                         f1=${testdir}/${tfile}
13124                 else
13125                         f0=${testdir}/${tfile}
13126                         f1=/dev/null
13127                 fi
13128
13129                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13130                         error "dd failed"
13131                 sync
13132                 cancel_lru_locks osc
13133
13134                 sum=$(do_facet ost1 $LCTL get_param \
13135                         "obdfilter.*.exports.*.stats" |
13136                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13137                                 $1 == ctr { sum += $7 }
13138                                 END { printf("%0.0f", sum) }')
13139
13140                 if ((sum != bs * count)); then
13141                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13142                 fi
13143         done
13144
13145         rm -rf $DIR/${tdir}
13146 }
13147 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13148
13149 test_133f() {
13150         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13151                 skip "too old lustre for get_param -R ($facet_ver)"
13152
13153         # verifying readability.
13154         $LCTL get_param -R '*' &> /dev/null
13155
13156         # Verifing writability with badarea_io.
13157         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13158                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13159                 error "client badarea_io failed"
13160
13161         # remount the FS in case writes/reads /proc break the FS
13162         cleanup || error "failed to unmount"
13163         setup || error "failed to setup"
13164 }
13165 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13166
13167 test_133g() {
13168         remote_mds_nodsh && skip "remote MDS with nodsh"
13169         remote_ost_nodsh && skip "remote OST with nodsh"
13170
13171         local facet
13172         for facet in mds1 ost1; do
13173                 local facet_ver=$(lustre_version_code $facet)
13174                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13175                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13176                 else
13177                         log "$facet: too old lustre for get_param -R"
13178                 fi
13179                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13180                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13181                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13182                                 xargs badarea_io" ||
13183                                         error "$facet badarea_io failed"
13184                 else
13185                         skip_noexit "$facet: too old lustre for get_param -R"
13186                 fi
13187         done
13188
13189         # remount the FS in case writes/reads /proc break the FS
13190         cleanup || error "failed to unmount"
13191         setup || error "failed to setup"
13192 }
13193 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13194
13195 test_133h() {
13196         remote_mds_nodsh && skip "remote MDS with nodsh"
13197         remote_ost_nodsh && skip "remote OST with nodsh"
13198         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13199                 skip "Need MDS version at least 2.9.54"
13200
13201         local facet
13202         for facet in client mds1 ost1; do
13203                 # Get the list of files that are missing the terminating newline
13204                 local plist=$(do_facet $facet
13205                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13206                 local ent
13207                 for ent in $plist; do
13208                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13209                                 awk -v FS='\v' -v RS='\v\v' \
13210                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13211                                         print FILENAME}'" 2>/dev/null)
13212                         [ -z $missing ] || {
13213                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13214                                 error "file does not end with newline: $facet-$ent"
13215                         }
13216                 done
13217         done
13218 }
13219 run_test 133h "Proc files should end with newlines"
13220
13221 test_134a() {
13222         remote_mds_nodsh && skip "remote MDS with nodsh"
13223         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13224                 skip "Need MDS version at least 2.7.54"
13225
13226         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13227         cancel_lru_locks mdc
13228
13229         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13230         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13231         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13232
13233         local nr=1000
13234         createmany -o $DIR/$tdir/f $nr ||
13235                 error "failed to create $nr files in $DIR/$tdir"
13236         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13237
13238         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13239         do_facet mds1 $LCTL set_param fail_loc=0x327
13240         do_facet mds1 $LCTL set_param fail_val=500
13241         touch $DIR/$tdir/m
13242
13243         echo "sleep 10 seconds ..."
13244         sleep 10
13245         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13246
13247         do_facet mds1 $LCTL set_param fail_loc=0
13248         do_facet mds1 $LCTL set_param fail_val=0
13249         [ $lck_cnt -lt $unused ] ||
13250                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13251
13252         rm $DIR/$tdir/m
13253         unlinkmany $DIR/$tdir/f $nr
13254 }
13255 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13256
13257 test_134b() {
13258         remote_mds_nodsh && skip "remote MDS with nodsh"
13259         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13260                 skip "Need MDS version at least 2.7.54"
13261
13262         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13263         cancel_lru_locks mdc
13264
13265         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13266                         ldlm.lock_reclaim_threshold_mb)
13267         # disable reclaim temporarily
13268         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13269
13270         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13271         do_facet mds1 $LCTL set_param fail_loc=0x328
13272         do_facet mds1 $LCTL set_param fail_val=500
13273
13274         $LCTL set_param debug=+trace
13275
13276         local nr=600
13277         createmany -o $DIR/$tdir/f $nr &
13278         local create_pid=$!
13279
13280         echo "Sleep $TIMEOUT seconds ..."
13281         sleep $TIMEOUT
13282         if ! ps -p $create_pid  > /dev/null 2>&1; then
13283                 do_facet mds1 $LCTL set_param fail_loc=0
13284                 do_facet mds1 $LCTL set_param fail_val=0
13285                 do_facet mds1 $LCTL set_param \
13286                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13287                 error "createmany finished incorrectly!"
13288         fi
13289         do_facet mds1 $LCTL set_param fail_loc=0
13290         do_facet mds1 $LCTL set_param fail_val=0
13291         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13292         wait $create_pid || return 1
13293
13294         unlinkmany $DIR/$tdir/f $nr
13295 }
13296 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13297
13298 test_135() {
13299         remote_mds_nodsh && skip "remote MDS with nodsh"
13300         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13301                 skip "Need MDS version at least 2.13.50"
13302         local fname
13303
13304         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13305
13306 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13307         #set only one record at plain llog
13308         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13309
13310         #fill already existed plain llog each 64767
13311         #wrapping whole catalog
13312         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13313
13314         createmany -o $DIR/$tdir/$tfile_ 64700
13315         for (( i = 0; i < 64700; i = i + 2 ))
13316         do
13317                 rm $DIR/$tdir/$tfile_$i &
13318                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13319                 local pid=$!
13320                 wait $pid
13321         done
13322
13323         #waiting osp synchronization
13324         wait_delete_completed
13325 }
13326 run_test 135 "Race catalog processing"
13327
13328 test_136() {
13329         remote_mds_nodsh && skip "remote MDS with nodsh"
13330         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13331                 skip "Need MDS version at least 2.13.50"
13332         local fname
13333
13334         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13335         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13336         #set only one record at plain llog
13337 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13338         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13339
13340         #fill already existed 2 plain llogs each 64767
13341         #wrapping whole catalog
13342         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13343         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13344         wait_delete_completed
13345
13346         createmany -o $DIR/$tdir/$tfile_ 10
13347         sleep 25
13348
13349         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13350         for (( i = 0; i < 10; i = i + 3 ))
13351         do
13352                 rm $DIR/$tdir/$tfile_$i &
13353                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13354                 local pid=$!
13355                 wait $pid
13356                 sleep 7
13357                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13358         done
13359
13360         #waiting osp synchronization
13361         wait_delete_completed
13362 }
13363 run_test 136 "Race catalog processing 2"
13364
13365 test_140() { #bug-17379
13366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13367
13368         test_mkdir $DIR/$tdir
13369         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13370         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13371
13372         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13373         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13374         local i=0
13375         while i=$((i + 1)); do
13376                 test_mkdir $i
13377                 cd $i || error "Changing to $i"
13378                 ln -s ../stat stat || error "Creating stat symlink"
13379                 # Read the symlink until ELOOP present,
13380                 # not LBUGing the system is considered success,
13381                 # we didn't overrun the stack.
13382                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13383                 if [ $ret -ne 0 ]; then
13384                         if [ $ret -eq 40 ]; then
13385                                 break  # -ELOOP
13386                         else
13387                                 error "Open stat symlink"
13388                                         return
13389                         fi
13390                 fi
13391         done
13392         i=$((i - 1))
13393         echo "The symlink depth = $i"
13394         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13395                 error "Invalid symlink depth"
13396
13397         # Test recursive symlink
13398         ln -s symlink_self symlink_self
13399         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13400         echo "open symlink_self returns $ret"
13401         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13402 }
13403 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13404
13405 test_150a() {
13406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13407
13408         local TF="$TMP/$tfile"
13409
13410         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13411         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13412         cp $TF $DIR/$tfile
13413         cancel_lru_locks $OSC
13414         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13415         remount_client $MOUNT
13416         df -P $MOUNT
13417         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13418
13419         $TRUNCATE $TF 6000
13420         $TRUNCATE $DIR/$tfile 6000
13421         cancel_lru_locks $OSC
13422         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13423
13424         echo "12345" >>$TF
13425         echo "12345" >>$DIR/$tfile
13426         cancel_lru_locks $OSC
13427         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13428
13429         echo "12345" >>$TF
13430         echo "12345" >>$DIR/$tfile
13431         cancel_lru_locks $OSC
13432         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13433 }
13434 run_test 150a "truncate/append tests"
13435
13436 test_150b() {
13437         check_set_fallocate_or_skip
13438
13439         touch $DIR/$tfile
13440         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13441         check_fallocate $DIR/$tfile || error "fallocate failed"
13442 }
13443 run_test 150b "Verify fallocate (prealloc) functionality"
13444
13445 test_150bb() {
13446         check_set_fallocate_or_skip
13447
13448         touch $DIR/$tfile
13449         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13450         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13451         > $DIR/$tfile
13452         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13453         # precomputed md5sum for 20MB of zeroes
13454         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13455         local sum=($(md5sum $DIR/$tfile))
13456
13457         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13458
13459         check_set_fallocate 1
13460
13461         > $DIR/$tfile
13462         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13463         sum=($(md5sum $DIR/$tfile))
13464
13465         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13466 }
13467 run_test 150bb "Verify fallocate modes both zero space"
13468
13469 test_150c() {
13470         check_set_fallocate_or_skip
13471
13472         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13473         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13474         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13475         sync; sync_all_data
13476         cancel_lru_locks $OSC
13477         sleep 5
13478         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13479         want=$((OSTCOUNT * 1048576))
13480
13481         # Must allocate all requested space, not more than 5% extra
13482         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13483                 error "bytes $bytes is not $want"
13484
13485         rm -f $DIR/$tfile
13486         # verify fallocate on PFL file
13487         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13488                 error "Create $DIR/$tfile failed"
13489         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13490                         error "fallocate failed"
13491         sync; sync_all_data
13492         cancel_lru_locks $OSC
13493         sleep 5
13494         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13495         local want=$((1024 * 1048576))
13496
13497         # Must allocate all requested space, not more than 5% extra
13498         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13499                 error "bytes $bytes is not $want"
13500 }
13501 run_test 150c "Verify fallocate Size and Blocks"
13502
13503 test_150d() {
13504         check_set_fallocate_or_skip
13505
13506         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13507         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13508         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13509         sync; sync_all_data
13510         cancel_lru_locks $OSC
13511         sleep 5
13512         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13513         local want=$((OSTCOUNT * 1048576))
13514
13515         # Must allocate all requested space, not more than 5% extra
13516         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13517                 error "bytes $bytes is not $want"
13518 }
13519 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13520
13521 test_150e() {
13522         check_set_fallocate_or_skip
13523
13524         echo "df before:"
13525         $LFS df
13526         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13527         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13528                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13529
13530         # Find OST with Minimum Size
13531         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13532                        sort -un | head -1)
13533
13534         # Get 100MB per OST of the available space to reduce run time
13535         # else 60% of the available space if we are running SLOW tests
13536         if [ $SLOW == "no" ]; then
13537                 local space=$((1024 * 100 * OSTCOUNT))
13538         else
13539                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13540         fi
13541
13542         fallocate -l${space}k $DIR/$tfile ||
13543                 error "fallocate ${space}k $DIR/$tfile failed"
13544         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13545
13546         # get size immediately after fallocate. This should be correctly
13547         # updated
13548         local size=$(stat -c '%s' $DIR/$tfile)
13549         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13550
13551         # Sleep for a while for statfs to get updated. And not pull from cache.
13552         sleep 2
13553
13554         echo "df after fallocate:"
13555         $LFS df
13556
13557         (( size / 1024 == space )) || error "size $size != requested $space"
13558         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13559                 error "used $used < space $space"
13560
13561         rm $DIR/$tfile || error "rm failed"
13562         sync
13563         wait_delete_completed
13564
13565         echo "df after unlink:"
13566         $LFS df
13567 }
13568 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13569
13570 #LU-2902 roc_hit was not able to read all values from lproc
13571 function roc_hit_init() {
13572         local list=$(comma_list $(osts_nodes))
13573         local dir=$DIR/$tdir-check
13574         local file=$dir/$tfile
13575         local BEFORE
13576         local AFTER
13577         local idx
13578
13579         test_mkdir $dir
13580         #use setstripe to do a write to every ost
13581         for i in $(seq 0 $((OSTCOUNT-1))); do
13582                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13583                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13584                 idx=$(printf %04x $i)
13585                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13586                         awk '$1 == "cache_access" {sum += $7}
13587                                 END { printf("%0.0f", sum) }')
13588
13589                 cancel_lru_locks osc
13590                 cat $file >/dev/null
13591
13592                 AFTER=$(get_osd_param $list *OST*$idx stats |
13593                         awk '$1 == "cache_access" {sum += $7}
13594                                 END { printf("%0.0f", sum) }')
13595
13596                 echo BEFORE:$BEFORE AFTER:$AFTER
13597                 if ! let "AFTER - BEFORE == 4"; then
13598                         rm -rf $dir
13599                         error "roc_hit is not safe to use"
13600                 fi
13601                 rm $file
13602         done
13603
13604         rm -rf $dir
13605 }
13606
13607 function roc_hit() {
13608         local list=$(comma_list $(osts_nodes))
13609         echo $(get_osd_param $list '' stats |
13610                 awk '$1 == "cache_hit" {sum += $7}
13611                         END { printf("%0.0f", sum) }')
13612 }
13613
13614 function set_cache() {
13615         local on=1
13616
13617         if [ "$2" == "off" ]; then
13618                 on=0;
13619         fi
13620         local list=$(comma_list $(osts_nodes))
13621         set_osd_param $list '' $1_cache_enable $on
13622
13623         cancel_lru_locks osc
13624 }
13625
13626 test_151() {
13627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13628         remote_ost_nodsh && skip "remote OST with nodsh"
13629
13630         local CPAGES=3
13631         local list=$(comma_list $(osts_nodes))
13632
13633         # check whether obdfilter is cache capable at all
13634         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13635                 skip "not cache-capable obdfilter"
13636         fi
13637
13638         # check cache is enabled on all obdfilters
13639         if get_osd_param $list '' read_cache_enable | grep 0; then
13640                 skip "oss cache is disabled"
13641         fi
13642
13643         set_osd_param $list '' writethrough_cache_enable 1
13644
13645         # check write cache is enabled on all obdfilters
13646         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13647                 skip "oss write cache is NOT enabled"
13648         fi
13649
13650         roc_hit_init
13651
13652         #define OBD_FAIL_OBD_NO_LRU  0x609
13653         do_nodes $list $LCTL set_param fail_loc=0x609
13654
13655         # pages should be in the case right after write
13656         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13657                 error "dd failed"
13658
13659         local BEFORE=$(roc_hit)
13660         cancel_lru_locks osc
13661         cat $DIR/$tfile >/dev/null
13662         local AFTER=$(roc_hit)
13663
13664         do_nodes $list $LCTL set_param fail_loc=0
13665
13666         if ! let "AFTER - BEFORE == CPAGES"; then
13667                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13668         fi
13669
13670         cancel_lru_locks osc
13671         # invalidates OST cache
13672         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13673         set_osd_param $list '' read_cache_enable 0
13674         cat $DIR/$tfile >/dev/null
13675
13676         # now data shouldn't be found in the cache
13677         BEFORE=$(roc_hit)
13678         cancel_lru_locks osc
13679         cat $DIR/$tfile >/dev/null
13680         AFTER=$(roc_hit)
13681         if let "AFTER - BEFORE != 0"; then
13682                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13683         fi
13684
13685         set_osd_param $list '' read_cache_enable 1
13686         rm -f $DIR/$tfile
13687 }
13688 run_test 151 "test cache on oss and controls ==============================="
13689
13690 test_152() {
13691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13692
13693         local TF="$TMP/$tfile"
13694
13695         # simulate ENOMEM during write
13696 #define OBD_FAIL_OST_NOMEM      0x226
13697         lctl set_param fail_loc=0x80000226
13698         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13699         cp $TF $DIR/$tfile
13700         sync || error "sync failed"
13701         lctl set_param fail_loc=0
13702
13703         # discard client's cache
13704         cancel_lru_locks osc
13705
13706         # simulate ENOMEM during read
13707         lctl set_param fail_loc=0x80000226
13708         cmp $TF $DIR/$tfile || error "cmp failed"
13709         lctl set_param fail_loc=0
13710
13711         rm -f $TF
13712 }
13713 run_test 152 "test read/write with enomem ============================"
13714
13715 test_153() {
13716         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13717 }
13718 run_test 153 "test if fdatasync does not crash ======================="
13719
13720 dot_lustre_fid_permission_check() {
13721         local fid=$1
13722         local ffid=$MOUNT/.lustre/fid/$fid
13723         local test_dir=$2
13724
13725         echo "stat fid $fid"
13726         stat $ffid > /dev/null || error "stat $ffid failed."
13727         echo "touch fid $fid"
13728         touch $ffid || error "touch $ffid failed."
13729         echo "write to fid $fid"
13730         cat /etc/hosts > $ffid || error "write $ffid failed."
13731         echo "read fid $fid"
13732         diff /etc/hosts $ffid || error "read $ffid failed."
13733         echo "append write to fid $fid"
13734         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13735         echo "rename fid $fid"
13736         mv $ffid $test_dir/$tfile.1 &&
13737                 error "rename $ffid to $tfile.1 should fail."
13738         touch $test_dir/$tfile.1
13739         mv $test_dir/$tfile.1 $ffid &&
13740                 error "rename $tfile.1 to $ffid should fail."
13741         rm -f $test_dir/$tfile.1
13742         echo "truncate fid $fid"
13743         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13744         echo "link fid $fid"
13745         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13746         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13747                 echo "setfacl fid $fid"
13748                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13749                 echo "getfacl fid $fid"
13750                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13751         fi
13752         echo "unlink fid $fid"
13753         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13754         echo "mknod fid $fid"
13755         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13756
13757         fid=[0xf00000400:0x1:0x0]
13758         ffid=$MOUNT/.lustre/fid/$fid
13759
13760         echo "stat non-exist fid $fid"
13761         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13762         echo "write to non-exist fid $fid"
13763         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13764         echo "link new fid $fid"
13765         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13766
13767         mkdir -p $test_dir/$tdir
13768         touch $test_dir/$tdir/$tfile
13769         fid=$($LFS path2fid $test_dir/$tdir)
13770         rc=$?
13771         [ $rc -ne 0 ] &&
13772                 error "error: could not get fid for $test_dir/$dir/$tfile."
13773
13774         ffid=$MOUNT/.lustre/fid/$fid
13775
13776         echo "ls $fid"
13777         ls $ffid > /dev/null || error "ls $ffid failed."
13778         echo "touch $fid/$tfile.1"
13779         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13780
13781         echo "touch $MOUNT/.lustre/fid/$tfile"
13782         touch $MOUNT/.lustre/fid/$tfile && \
13783                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13784
13785         echo "setxattr to $MOUNT/.lustre/fid"
13786         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13787
13788         echo "listxattr for $MOUNT/.lustre/fid"
13789         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13790
13791         echo "delxattr from $MOUNT/.lustre/fid"
13792         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13793
13794         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13795         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13796                 error "touch invalid fid should fail."
13797
13798         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13799         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13800                 error "touch non-normal fid should fail."
13801
13802         echo "rename $tdir to $MOUNT/.lustre/fid"
13803         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13804                 error "rename to $MOUNT/.lustre/fid should fail."
13805
13806         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13807         then            # LU-3547
13808                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13809                 local new_obf_mode=777
13810
13811                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13812                 chmod $new_obf_mode $DIR/.lustre/fid ||
13813                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13814
13815                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13816                 [ $obf_mode -eq $new_obf_mode ] ||
13817                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13818
13819                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13820                 chmod $old_obf_mode $DIR/.lustre/fid ||
13821                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13822         fi
13823
13824         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13825         fid=$($LFS path2fid $test_dir/$tfile-2)
13826
13827         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13828         then # LU-5424
13829                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13830                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13831                         error "create lov data thru .lustre failed"
13832         fi
13833         echo "cp /etc/passwd $test_dir/$tfile-2"
13834         cp /etc/passwd $test_dir/$tfile-2 ||
13835                 error "copy to $test_dir/$tfile-2 failed."
13836         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13837         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13838                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13839
13840         rm -rf $test_dir/tfile.lnk
13841         rm -rf $test_dir/$tfile-2
13842 }
13843
13844 test_154A() {
13845         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13846                 skip "Need MDS version at least 2.4.1"
13847
13848         local tf=$DIR/$tfile
13849         touch $tf
13850
13851         local fid=$($LFS path2fid $tf)
13852         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13853
13854         # check that we get the same pathname back
13855         local rootpath
13856         local found
13857         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13858                 echo "$rootpath $fid"
13859                 found=$($LFS fid2path $rootpath "$fid")
13860                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13861                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13862         done
13863
13864         # check wrong root path format
13865         rootpath=$MOUNT"_wrong"
13866         found=$($LFS fid2path $rootpath "$fid")
13867         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13868 }
13869 run_test 154A "lfs path2fid and fid2path basic checks"
13870
13871 test_154B() {
13872         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13873                 skip "Need MDS version at least 2.4.1"
13874
13875         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13876         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13877         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13878         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13879
13880         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13881         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13882
13883         # check that we get the same pathname
13884         echo "PFID: $PFID, name: $name"
13885         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13886         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13887         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13888                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13889
13890         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13891 }
13892 run_test 154B "verify the ll_decode_linkea tool"
13893
13894 test_154a() {
13895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13896         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13897         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13898                 skip "Need MDS version at least 2.2.51"
13899         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13900
13901         cp /etc/hosts $DIR/$tfile
13902
13903         fid=$($LFS path2fid $DIR/$tfile)
13904         rc=$?
13905         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13906
13907         dot_lustre_fid_permission_check "$fid" $DIR ||
13908                 error "dot lustre permission check $fid failed"
13909
13910         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13911
13912         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13913
13914         touch $MOUNT/.lustre/file &&
13915                 error "creation is not allowed under .lustre"
13916
13917         mkdir $MOUNT/.lustre/dir &&
13918                 error "mkdir is not allowed under .lustre"
13919
13920         rm -rf $DIR/$tfile
13921 }
13922 run_test 154a "Open-by-FID"
13923
13924 test_154b() {
13925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13926         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13928         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13929                 skip "Need MDS version at least 2.2.51"
13930
13931         local remote_dir=$DIR/$tdir/remote_dir
13932         local MDTIDX=1
13933         local rc=0
13934
13935         mkdir -p $DIR/$tdir
13936         $LFS mkdir -i $MDTIDX $remote_dir ||
13937                 error "create remote directory failed"
13938
13939         cp /etc/hosts $remote_dir/$tfile
13940
13941         fid=$($LFS path2fid $remote_dir/$tfile)
13942         rc=$?
13943         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13944
13945         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13946                 error "dot lustre permission check $fid failed"
13947         rm -rf $DIR/$tdir
13948 }
13949 run_test 154b "Open-by-FID for remote directory"
13950
13951 test_154c() {
13952         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13953                 skip "Need MDS version at least 2.4.1"
13954
13955         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13956         local FID1=$($LFS path2fid $DIR/$tfile.1)
13957         local FID2=$($LFS path2fid $DIR/$tfile.2)
13958         local FID3=$($LFS path2fid $DIR/$tfile.3)
13959
13960         local N=1
13961         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13962                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13963                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13964                 local want=FID$N
13965                 [ "$FID" = "${!want}" ] ||
13966                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13967                 N=$((N + 1))
13968         done
13969
13970         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13971         do
13972                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13973                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13974                 N=$((N + 1))
13975         done
13976 }
13977 run_test 154c "lfs path2fid and fid2path multiple arguments"
13978
13979 test_154d() {
13980         remote_mds_nodsh && skip "remote MDS with nodsh"
13981         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13982                 skip "Need MDS version at least 2.5.53"
13983
13984         if remote_mds; then
13985                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13986         else
13987                 nid="0@lo"
13988         fi
13989         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13990         local fd
13991         local cmd
13992
13993         rm -f $DIR/$tfile
13994         touch $DIR/$tfile
13995
13996         local fid=$($LFS path2fid $DIR/$tfile)
13997         # Open the file
13998         fd=$(free_fd)
13999         cmd="exec $fd<$DIR/$tfile"
14000         eval $cmd
14001         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14002         echo "$fid_list" | grep "$fid"
14003         rc=$?
14004
14005         cmd="exec $fd>/dev/null"
14006         eval $cmd
14007         if [ $rc -ne 0 ]; then
14008                 error "FID $fid not found in open files list $fid_list"
14009         fi
14010 }
14011 run_test 154d "Verify open file fid"
14012
14013 test_154e()
14014 {
14015         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14016                 skip "Need MDS version at least 2.6.50"
14017
14018         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14019                 error ".lustre returned by readdir"
14020         fi
14021 }
14022 run_test 154e ".lustre is not returned by readdir"
14023
14024 test_154f() {
14025         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14026
14027         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14028         test_mkdir -p -c1 $DIR/$tdir/d
14029         # test dirs inherit from its stripe
14030         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14031         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14032         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14033         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14034         touch $DIR/f
14035
14036         # get fid of parents
14037         local FID0=$($LFS path2fid $DIR/$tdir/d)
14038         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14039         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14040         local FID3=$($LFS path2fid $DIR)
14041
14042         # check that path2fid --parents returns expected <parent_fid>/name
14043         # 1) test for a directory (single parent)
14044         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14045         [ "$parent" == "$FID0/foo1" ] ||
14046                 error "expected parent: $FID0/foo1, got: $parent"
14047
14048         # 2) test for a file with nlink > 1 (multiple parents)
14049         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14050         echo "$parent" | grep -F "$FID1/$tfile" ||
14051                 error "$FID1/$tfile not returned in parent list"
14052         echo "$parent" | grep -F "$FID2/link" ||
14053                 error "$FID2/link not returned in parent list"
14054
14055         # 3) get parent by fid
14056         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14057         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14058         echo "$parent" | grep -F "$FID1/$tfile" ||
14059                 error "$FID1/$tfile not returned in parent list (by fid)"
14060         echo "$parent" | grep -F "$FID2/link" ||
14061                 error "$FID2/link not returned in parent list (by fid)"
14062
14063         # 4) test for entry in root directory
14064         parent=$($LFS path2fid --parents $DIR/f)
14065         echo "$parent" | grep -F "$FID3/f" ||
14066                 error "$FID3/f not returned in parent list"
14067
14068         # 5) test it on root directory
14069         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14070                 error "$MOUNT should not have parents"
14071
14072         # enable xattr caching and check that linkea is correctly updated
14073         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14074         save_lustre_params client "llite.*.xattr_cache" > $save
14075         lctl set_param llite.*.xattr_cache 1
14076
14077         # 6.1) linkea update on rename
14078         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14079
14080         # get parents by fid
14081         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14082         # foo1 should no longer be returned in parent list
14083         echo "$parent" | grep -F "$FID1" &&
14084                 error "$FID1 should no longer be in parent list"
14085         # the new path should appear
14086         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14087                 error "$FID2/$tfile.moved is not in parent list"
14088
14089         # 6.2) linkea update on unlink
14090         rm -f $DIR/$tdir/d/foo2/link
14091         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14092         # foo2/link should no longer be returned in parent list
14093         echo "$parent" | grep -F "$FID2/link" &&
14094                 error "$FID2/link should no longer be in parent list"
14095         true
14096
14097         rm -f $DIR/f
14098         restore_lustre_params < $save
14099         rm -f $save
14100 }
14101 run_test 154f "get parent fids by reading link ea"
14102
14103 test_154g()
14104 {
14105         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14106         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14107            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14108                 skip "Need MDS version at least 2.6.92"
14109
14110         mkdir -p $DIR/$tdir
14111         llapi_fid_test -d $DIR/$tdir
14112 }
14113 run_test 154g "various llapi FID tests"
14114
14115 test_155_small_load() {
14116     local temp=$TMP/$tfile
14117     local file=$DIR/$tfile
14118
14119     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14120         error "dd of=$temp bs=6096 count=1 failed"
14121     cp $temp $file
14122     cancel_lru_locks $OSC
14123     cmp $temp $file || error "$temp $file differ"
14124
14125     $TRUNCATE $temp 6000
14126     $TRUNCATE $file 6000
14127     cmp $temp $file || error "$temp $file differ (truncate1)"
14128
14129     echo "12345" >>$temp
14130     echo "12345" >>$file
14131     cmp $temp $file || error "$temp $file differ (append1)"
14132
14133     echo "12345" >>$temp
14134     echo "12345" >>$file
14135     cmp $temp $file || error "$temp $file differ (append2)"
14136
14137     rm -f $temp $file
14138     true
14139 }
14140
14141 test_155_big_load() {
14142         remote_ost_nodsh && skip "remote OST with nodsh"
14143
14144         local temp=$TMP/$tfile
14145         local file=$DIR/$tfile
14146
14147         free_min_max
14148         local cache_size=$(do_facet ost$((MAXI+1)) \
14149                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14150         local large_file_size=$((cache_size * 2))
14151
14152         echo "OSS cache size: $cache_size KB"
14153         echo "Large file size: $large_file_size KB"
14154
14155         [ $MAXV -le $large_file_size ] &&
14156                 skip_env "max available OST size needs > $large_file_size KB"
14157
14158         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14159
14160         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14161                 error "dd of=$temp bs=$large_file_size count=1k failed"
14162         cp $temp $file
14163         ls -lh $temp $file
14164         cancel_lru_locks osc
14165         cmp $temp $file || error "$temp $file differ"
14166
14167         rm -f $temp $file
14168         true
14169 }
14170
14171 save_writethrough() {
14172         local facets=$(get_facets OST)
14173
14174         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14175 }
14176
14177 test_155a() {
14178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14179
14180         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14181
14182         save_writethrough $p
14183
14184         set_cache read on
14185         set_cache writethrough on
14186         test_155_small_load
14187         restore_lustre_params < $p
14188         rm -f $p
14189 }
14190 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14191
14192 test_155b() {
14193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14194
14195         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14196
14197         save_writethrough $p
14198
14199         set_cache read on
14200         set_cache writethrough off
14201         test_155_small_load
14202         restore_lustre_params < $p
14203         rm -f $p
14204 }
14205 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14206
14207 test_155c() {
14208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14209
14210         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14211
14212         save_writethrough $p
14213
14214         set_cache read off
14215         set_cache writethrough on
14216         test_155_small_load
14217         restore_lustre_params < $p
14218         rm -f $p
14219 }
14220 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14221
14222 test_155d() {
14223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14224
14225         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14226
14227         save_writethrough $p
14228
14229         set_cache read off
14230         set_cache writethrough off
14231         test_155_small_load
14232         restore_lustre_params < $p
14233         rm -f $p
14234 }
14235 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14236
14237 test_155e() {
14238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14239
14240         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14241
14242         save_writethrough $p
14243
14244         set_cache read on
14245         set_cache writethrough on
14246         test_155_big_load
14247         restore_lustre_params < $p
14248         rm -f $p
14249 }
14250 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14251
14252 test_155f() {
14253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14254
14255         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14256
14257         save_writethrough $p
14258
14259         set_cache read on
14260         set_cache writethrough off
14261         test_155_big_load
14262         restore_lustre_params < $p
14263         rm -f $p
14264 }
14265 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14266
14267 test_155g() {
14268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14269
14270         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14271
14272         save_writethrough $p
14273
14274         set_cache read off
14275         set_cache writethrough on
14276         test_155_big_load
14277         restore_lustre_params < $p
14278         rm -f $p
14279 }
14280 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14281
14282 test_155h() {
14283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14284
14285         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14286
14287         save_writethrough $p
14288
14289         set_cache read off
14290         set_cache writethrough off
14291         test_155_big_load
14292         restore_lustre_params < $p
14293         rm -f $p
14294 }
14295 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14296
14297 test_156() {
14298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14299         remote_ost_nodsh && skip "remote OST with nodsh"
14300         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14301                 skip "stats not implemented on old servers"
14302         [ "$ost1_FSTYPE" = "zfs" ] &&
14303                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14304
14305         local CPAGES=3
14306         local BEFORE
14307         local AFTER
14308         local file="$DIR/$tfile"
14309         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14310
14311         save_writethrough $p
14312         roc_hit_init
14313
14314         log "Turn on read and write cache"
14315         set_cache read on
14316         set_cache writethrough on
14317
14318         log "Write data and read it back."
14319         log "Read should be satisfied from the cache."
14320         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14321         BEFORE=$(roc_hit)
14322         cancel_lru_locks osc
14323         cat $file >/dev/null
14324         AFTER=$(roc_hit)
14325         if ! let "AFTER - BEFORE == CPAGES"; then
14326                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14327         else
14328                 log "cache hits: before: $BEFORE, after: $AFTER"
14329         fi
14330
14331         log "Read again; it should be satisfied from the cache."
14332         BEFORE=$AFTER
14333         cancel_lru_locks osc
14334         cat $file >/dev/null
14335         AFTER=$(roc_hit)
14336         if ! let "AFTER - BEFORE == CPAGES"; then
14337                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14338         else
14339                 log "cache hits:: before: $BEFORE, after: $AFTER"
14340         fi
14341
14342         log "Turn off the read cache and turn on the write cache"
14343         set_cache read off
14344         set_cache writethrough on
14345
14346         log "Read again; it should be satisfied from the cache."
14347         BEFORE=$(roc_hit)
14348         cancel_lru_locks osc
14349         cat $file >/dev/null
14350         AFTER=$(roc_hit)
14351         if ! let "AFTER - BEFORE == CPAGES"; then
14352                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14353         else
14354                 log "cache hits:: before: $BEFORE, after: $AFTER"
14355         fi
14356
14357         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14358                 # > 2.12.56 uses pagecache if cached
14359                 log "Read again; it should not be satisfied from the cache."
14360                 BEFORE=$AFTER
14361                 cancel_lru_locks osc
14362                 cat $file >/dev/null
14363                 AFTER=$(roc_hit)
14364                 if ! let "AFTER - BEFORE == 0"; then
14365                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14366                 else
14367                         log "cache hits:: before: $BEFORE, after: $AFTER"
14368                 fi
14369         fi
14370
14371         log "Write data and read it back."
14372         log "Read should be satisfied from the cache."
14373         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14374         BEFORE=$(roc_hit)
14375         cancel_lru_locks osc
14376         cat $file >/dev/null
14377         AFTER=$(roc_hit)
14378         if ! let "AFTER - BEFORE == CPAGES"; then
14379                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14380         else
14381                 log "cache hits:: before: $BEFORE, after: $AFTER"
14382         fi
14383
14384         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14385                 # > 2.12.56 uses pagecache if cached
14386                 log "Read again; it should not be satisfied from the cache."
14387                 BEFORE=$AFTER
14388                 cancel_lru_locks osc
14389                 cat $file >/dev/null
14390                 AFTER=$(roc_hit)
14391                 if ! let "AFTER - BEFORE == 0"; then
14392                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14393                 else
14394                         log "cache hits:: before: $BEFORE, after: $AFTER"
14395                 fi
14396         fi
14397
14398         log "Turn off read and write cache"
14399         set_cache read off
14400         set_cache writethrough off
14401
14402         log "Write data and read it back"
14403         log "It should not be satisfied from the cache."
14404         rm -f $file
14405         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14406         cancel_lru_locks osc
14407         BEFORE=$(roc_hit)
14408         cat $file >/dev/null
14409         AFTER=$(roc_hit)
14410         if ! let "AFTER - BEFORE == 0"; then
14411                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14412         else
14413                 log "cache hits:: before: $BEFORE, after: $AFTER"
14414         fi
14415
14416         log "Turn on the read cache and turn off the write cache"
14417         set_cache read on
14418         set_cache writethrough off
14419
14420         log "Write data and read it back"
14421         log "It should not be satisfied from the cache."
14422         rm -f $file
14423         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14424         BEFORE=$(roc_hit)
14425         cancel_lru_locks osc
14426         cat $file >/dev/null
14427         AFTER=$(roc_hit)
14428         if ! let "AFTER - BEFORE == 0"; then
14429                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14430         else
14431                 log "cache hits:: before: $BEFORE, after: $AFTER"
14432         fi
14433
14434         log "Read again; it should be satisfied from the cache."
14435         BEFORE=$(roc_hit)
14436         cancel_lru_locks osc
14437         cat $file >/dev/null
14438         AFTER=$(roc_hit)
14439         if ! let "AFTER - BEFORE == CPAGES"; then
14440                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14441         else
14442                 log "cache hits:: before: $BEFORE, after: $AFTER"
14443         fi
14444
14445         restore_lustre_params < $p
14446         rm -f $p $file
14447 }
14448 run_test 156 "Verification of tunables"
14449
14450 test_160a() {
14451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14452         remote_mds_nodsh && skip "remote MDS with nodsh"
14453         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14454                 skip "Need MDS version at least 2.2.0"
14455
14456         changelog_register || error "changelog_register failed"
14457         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14458         changelog_users $SINGLEMDS | grep -q $cl_user ||
14459                 error "User $cl_user not found in changelog_users"
14460
14461         # change something
14462         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14463         changelog_clear 0 || error "changelog_clear failed"
14464         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14465         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14466         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14467         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14468         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14469         rm $DIR/$tdir/pics/desktop.jpg
14470
14471         changelog_dump | tail -10
14472
14473         echo "verifying changelog mask"
14474         changelog_chmask "-MKDIR"
14475         changelog_chmask "-CLOSE"
14476
14477         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14478         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14479
14480         changelog_chmask "+MKDIR"
14481         changelog_chmask "+CLOSE"
14482
14483         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14484         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14485
14486         changelog_dump | tail -10
14487         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14488         CLOSES=$(changelog_dump | grep -c "CLOSE")
14489         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14490         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14491
14492         # verify contents
14493         echo "verifying target fid"
14494         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14495         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14496         [ "$fidc" == "$fidf" ] ||
14497                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14498         echo "verifying parent fid"
14499         # The FID returned from the Changelog may be the directory shard on
14500         # a different MDT, and not the FID returned by path2fid on the parent.
14501         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14502         # since this is what will matter when recreating this file in the tree.
14503         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14504         local pathp=$($LFS fid2path $MOUNT "$fidp")
14505         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14506                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14507
14508         echo "getting records for $cl_user"
14509         changelog_users $SINGLEMDS
14510         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14511         local nclr=3
14512         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14513                 error "changelog_clear failed"
14514         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14515         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14516         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14517                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14518
14519         local min0_rec=$(changelog_users $SINGLEMDS |
14520                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14521         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14522                           awk '{ print $1; exit; }')
14523
14524         changelog_dump | tail -n 5
14525         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14526         [ $first_rec == $((min0_rec + 1)) ] ||
14527                 error "first index should be $min0_rec + 1 not $first_rec"
14528
14529         # LU-3446 changelog index reset on MDT restart
14530         local cur_rec1=$(changelog_users $SINGLEMDS |
14531                          awk '/^current.index:/ { print $NF }')
14532         changelog_clear 0 ||
14533                 error "clear all changelog records for $cl_user failed"
14534         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14535         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14536                 error "Fail to start $SINGLEMDS"
14537         local cur_rec2=$(changelog_users $SINGLEMDS |
14538                          awk '/^current.index:/ { print $NF }')
14539         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14540         [ $cur_rec1 == $cur_rec2 ] ||
14541                 error "current index should be $cur_rec1 not $cur_rec2"
14542
14543         echo "verifying users from this test are deregistered"
14544         changelog_deregister || error "changelog_deregister failed"
14545         changelog_users $SINGLEMDS | grep -q $cl_user &&
14546                 error "User '$cl_user' still in changelog_users"
14547
14548         # lctl get_param -n mdd.*.changelog_users
14549         # current index: 144
14550         # ID    index (idle seconds)
14551         # cl3   144 (2)
14552         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14553                 # this is the normal case where all users were deregistered
14554                 # make sure no new records are added when no users are present
14555                 local last_rec1=$(changelog_users $SINGLEMDS |
14556                                   awk '/^current.index:/ { print $NF }')
14557                 touch $DIR/$tdir/chloe
14558                 local last_rec2=$(changelog_users $SINGLEMDS |
14559                                   awk '/^current.index:/ { print $NF }')
14560                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14561                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14562         else
14563                 # any changelog users must be leftovers from a previous test
14564                 changelog_users $SINGLEMDS
14565                 echo "other changelog users; can't verify off"
14566         fi
14567 }
14568 run_test 160a "changelog sanity"
14569
14570 test_160b() { # LU-3587
14571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14572         remote_mds_nodsh && skip "remote MDS with nodsh"
14573         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14574                 skip "Need MDS version at least 2.2.0"
14575
14576         changelog_register || error "changelog_register failed"
14577         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14578         changelog_users $SINGLEMDS | grep -q $cl_user ||
14579                 error "User '$cl_user' not found in changelog_users"
14580
14581         local longname1=$(str_repeat a 255)
14582         local longname2=$(str_repeat b 255)
14583
14584         cd $DIR
14585         echo "creating very long named file"
14586         touch $longname1 || error "create of '$longname1' failed"
14587         echo "renaming very long named file"
14588         mv $longname1 $longname2
14589
14590         changelog_dump | grep RENME | tail -n 5
14591         rm -f $longname2
14592 }
14593 run_test 160b "Verify that very long rename doesn't crash in changelog"
14594
14595 test_160c() {
14596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14597         remote_mds_nodsh && skip "remote MDS with nodsh"
14598
14599         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14600                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14601                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14602                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14603
14604         local rc=0
14605
14606         # Registration step
14607         changelog_register || error "changelog_register failed"
14608
14609         rm -rf $DIR/$tdir
14610         mkdir -p $DIR/$tdir
14611         $MCREATE $DIR/$tdir/foo_160c
14612         changelog_chmask "-TRUNC"
14613         $TRUNCATE $DIR/$tdir/foo_160c 200
14614         changelog_chmask "+TRUNC"
14615         $TRUNCATE $DIR/$tdir/foo_160c 199
14616         changelog_dump | tail -n 5
14617         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14618         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14619 }
14620 run_test 160c "verify that changelog log catch the truncate event"
14621
14622 test_160d() {
14623         remote_mds_nodsh && skip "remote MDS with nodsh"
14624         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14626         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14627                 skip "Need MDS version at least 2.7.60"
14628
14629         # Registration step
14630         changelog_register || error "changelog_register failed"
14631
14632         mkdir -p $DIR/$tdir/migrate_dir
14633         changelog_clear 0 || error "changelog_clear failed"
14634
14635         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14636         changelog_dump | tail -n 5
14637         local migrates=$(changelog_dump | grep -c "MIGRT")
14638         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14639 }
14640 run_test 160d "verify that changelog log catch the migrate event"
14641
14642 test_160e() {
14643         remote_mds_nodsh && skip "remote MDS with nodsh"
14644
14645         # Create a user
14646         changelog_register || error "changelog_register failed"
14647
14648         # Delete a future user (expect fail)
14649         local MDT0=$(facet_svc $SINGLEMDS)
14650         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14651         local rc=$?
14652
14653         if [ $rc -eq 0 ]; then
14654                 error "Deleted non-existant user cl77"
14655         elif [ $rc -ne 2 ]; then
14656                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14657         fi
14658
14659         # Clear to a bad index (1 billion should be safe)
14660         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14661         rc=$?
14662
14663         if [ $rc -eq 0 ]; then
14664                 error "Successfully cleared to invalid CL index"
14665         elif [ $rc -ne 22 ]; then
14666                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14667         fi
14668 }
14669 run_test 160e "changelog negative testing (should return errors)"
14670
14671 test_160f() {
14672         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14673         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14674                 skip "Need MDS version at least 2.10.56"
14675
14676         local mdts=$(comma_list $(mdts_nodes))
14677
14678         # Create a user
14679         changelog_register || error "first changelog_register failed"
14680         changelog_register || error "second changelog_register failed"
14681         local cl_users
14682         declare -A cl_user1
14683         declare -A cl_user2
14684         local user_rec1
14685         local user_rec2
14686         local i
14687
14688         # generate some changelog records to accumulate on each MDT
14689         # use fnv1a because created files should be evenly distributed
14690         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14691                 error "test_mkdir $tdir failed"
14692         log "$(date +%s): creating first files"
14693         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14694                 error "create $DIR/$tdir/$tfile failed"
14695
14696         # check changelogs have been generated
14697         local start=$SECONDS
14698         local idle_time=$((MDSCOUNT * 5 + 5))
14699         local nbcl=$(changelog_dump | wc -l)
14700         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14701
14702         for param in "changelog_max_idle_time=$idle_time" \
14703                      "changelog_gc=1" \
14704                      "changelog_min_gc_interval=2" \
14705                      "changelog_min_free_cat_entries=3"; do
14706                 local MDT0=$(facet_svc $SINGLEMDS)
14707                 local var="${param%=*}"
14708                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14709
14710                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14711                 do_nodes $mdts $LCTL set_param mdd.*.$param
14712         done
14713
14714         # force cl_user2 to be idle (1st part), but also cancel the
14715         # cl_user1 records so that it is not evicted later in the test.
14716         local sleep1=$((idle_time / 2))
14717         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14718         sleep $sleep1
14719
14720         # simulate changelog catalog almost full
14721         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14722         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14723
14724         for i in $(seq $MDSCOUNT); do
14725                 cl_users=(${CL_USERS[mds$i]})
14726                 cl_user1[mds$i]="${cl_users[0]}"
14727                 cl_user2[mds$i]="${cl_users[1]}"
14728
14729                 [ -n "${cl_user1[mds$i]}" ] ||
14730                         error "mds$i: no user registered"
14731                 [ -n "${cl_user2[mds$i]}" ] ||
14732                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14733
14734                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14735                 [ -n "$user_rec1" ] ||
14736                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14737                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14738                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14739                 [ -n "$user_rec2" ] ||
14740                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14741                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14742                      "$user_rec1 + 2 == $user_rec2"
14743                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14744                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14745                               "$user_rec1 + 2, but is $user_rec2"
14746                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14747                 [ -n "$user_rec2" ] ||
14748                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14749                 [ $user_rec1 == $user_rec2 ] ||
14750                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14751                               "$user_rec1, but is $user_rec2"
14752         done
14753
14754         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14755         local sleep2=$((idle_time - (SECONDS - start) + 1))
14756         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14757         sleep $sleep2
14758
14759         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14760         # cl_user1 should be OK because it recently processed records.
14761         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14762         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14763                 error "create $DIR/$tdir/${tfile}b failed"
14764
14765         # ensure gc thread is done
14766         for i in $(mdts_nodes); do
14767                 wait_update $i \
14768                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14769                         error "$i: GC-thread not done"
14770         done
14771
14772         local first_rec
14773         for i in $(seq $MDSCOUNT); do
14774                 # check cl_user1 still registered
14775                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14776                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14777                 # check cl_user2 unregistered
14778                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14779                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14780
14781                 # check changelogs are present and starting at $user_rec1 + 1
14782                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14783                 [ -n "$user_rec1" ] ||
14784                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14785                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14786                             awk '{ print $1; exit; }')
14787
14788                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14789                 [ $((user_rec1 + 1)) == $first_rec ] ||
14790                         error "mds$i: first index should be $user_rec1 + 1, " \
14791                               "but is $first_rec"
14792         done
14793 }
14794 run_test 160f "changelog garbage collect (timestamped users)"
14795
14796 test_160g() {
14797         remote_mds_nodsh && skip "remote MDS with nodsh"
14798         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14799                 skip "Need MDS version at least 2.10.56"
14800
14801         local mdts=$(comma_list $(mdts_nodes))
14802
14803         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14804         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14805
14806         # Create a user
14807         changelog_register || error "first changelog_register failed"
14808         changelog_register || error "second changelog_register failed"
14809         local cl_users
14810         declare -A cl_user1
14811         declare -A cl_user2
14812         local user_rec1
14813         local user_rec2
14814         local i
14815
14816         # generate some changelog records to accumulate on each MDT
14817         # use fnv1a because created files should be evenly distributed
14818         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14819                 error "mkdir $tdir failed"
14820         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14821                 error "create $DIR/$tdir/$tfile failed"
14822
14823         # check changelogs have been generated
14824         local nbcl=$(changelog_dump | wc -l)
14825         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14826
14827         # reduce the max_idle_indexes value to make sure we exceed it
14828         max_ndx=$((nbcl / 2 - 1))
14829
14830         for param in "changelog_max_idle_indexes=$max_ndx" \
14831                      "changelog_gc=1" \
14832                      "changelog_min_gc_interval=2" \
14833                      "changelog_min_free_cat_entries=3"; do
14834                 local MDT0=$(facet_svc $SINGLEMDS)
14835                 local var="${param%=*}"
14836                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14837
14838                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14839                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14840                         error "unable to set mdd.*.$param"
14841         done
14842
14843         # simulate changelog catalog almost full
14844         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14845         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14846
14847         for i in $(seq $MDSCOUNT); do
14848                 cl_users=(${CL_USERS[mds$i]})
14849                 cl_user1[mds$i]="${cl_users[0]}"
14850                 cl_user2[mds$i]="${cl_users[1]}"
14851
14852                 [ -n "${cl_user1[mds$i]}" ] ||
14853                         error "mds$i: no user registered"
14854                 [ -n "${cl_user2[mds$i]}" ] ||
14855                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14856
14857                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14858                 [ -n "$user_rec1" ] ||
14859                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14860                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14861                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14862                 [ -n "$user_rec2" ] ||
14863                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14864                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14865                      "$user_rec1 + 2 == $user_rec2"
14866                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14867                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14868                               "$user_rec1 + 2, but is $user_rec2"
14869                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14870                 [ -n "$user_rec2" ] ||
14871                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14872                 [ $user_rec1 == $user_rec2 ] ||
14873                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14874                               "$user_rec1, but is $user_rec2"
14875         done
14876
14877         # ensure we are past the previous changelog_min_gc_interval set above
14878         sleep 2
14879
14880         # generate one more changelog to trigger fail_loc
14881         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14882                 error "create $DIR/$tdir/${tfile}bis failed"
14883
14884         # ensure gc thread is done
14885         for i in $(mdts_nodes); do
14886                 wait_update $i \
14887                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14888                         error "$i: GC-thread not done"
14889         done
14890
14891         local first_rec
14892         for i in $(seq $MDSCOUNT); do
14893                 # check cl_user1 still registered
14894                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14895                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14896                 # check cl_user2 unregistered
14897                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14898                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14899
14900                 # check changelogs are present and starting at $user_rec1 + 1
14901                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14902                 [ -n "$user_rec1" ] ||
14903                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14904                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14905                             awk '{ print $1; exit; }')
14906
14907                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14908                 [ $((user_rec1 + 1)) == $first_rec ] ||
14909                         error "mds$i: first index should be $user_rec1 + 1, " \
14910                               "but is $first_rec"
14911         done
14912 }
14913 run_test 160g "changelog garbage collect (old users)"
14914
14915 test_160h() {
14916         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14917         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14918                 skip "Need MDS version at least 2.10.56"
14919
14920         local mdts=$(comma_list $(mdts_nodes))
14921
14922         # Create a user
14923         changelog_register || error "first changelog_register failed"
14924         changelog_register || error "second changelog_register failed"
14925         local cl_users
14926         declare -A cl_user1
14927         declare -A cl_user2
14928         local user_rec1
14929         local user_rec2
14930         local i
14931
14932         # generate some changelog records to accumulate on each MDT
14933         # use fnv1a because created files should be evenly distributed
14934         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14935                 error "test_mkdir $tdir failed"
14936         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14937                 error "create $DIR/$tdir/$tfile failed"
14938
14939         # check changelogs have been generated
14940         local nbcl=$(changelog_dump | wc -l)
14941         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14942
14943         for param in "changelog_max_idle_time=10" \
14944                      "changelog_gc=1" \
14945                      "changelog_min_gc_interval=2"; do
14946                 local MDT0=$(facet_svc $SINGLEMDS)
14947                 local var="${param%=*}"
14948                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14949
14950                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14951                 do_nodes $mdts $LCTL set_param mdd.*.$param
14952         done
14953
14954         # force cl_user2 to be idle (1st part)
14955         sleep 9
14956
14957         for i in $(seq $MDSCOUNT); do
14958                 cl_users=(${CL_USERS[mds$i]})
14959                 cl_user1[mds$i]="${cl_users[0]}"
14960                 cl_user2[mds$i]="${cl_users[1]}"
14961
14962                 [ -n "${cl_user1[mds$i]}" ] ||
14963                         error "mds$i: no user registered"
14964                 [ -n "${cl_user2[mds$i]}" ] ||
14965                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14966
14967                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14968                 [ -n "$user_rec1" ] ||
14969                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14970                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14971                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14972                 [ -n "$user_rec2" ] ||
14973                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14974                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14975                      "$user_rec1 + 2 == $user_rec2"
14976                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14977                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14978                               "$user_rec1 + 2, but is $user_rec2"
14979                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14980                 [ -n "$user_rec2" ] ||
14981                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14982                 [ $user_rec1 == $user_rec2 ] ||
14983                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14984                               "$user_rec1, but is $user_rec2"
14985         done
14986
14987         # force cl_user2 to be idle (2nd part) and to reach
14988         # changelog_max_idle_time
14989         sleep 2
14990
14991         # force each GC-thread start and block then
14992         # one per MDT/MDD, set fail_val accordingly
14993         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14994         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14995
14996         # generate more changelogs to trigger fail_loc
14997         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14998                 error "create $DIR/$tdir/${tfile}bis failed"
14999
15000         # stop MDT to stop GC-thread, should be done in back-ground as it will
15001         # block waiting for the thread to be released and exit
15002         declare -A stop_pids
15003         for i in $(seq $MDSCOUNT); do
15004                 stop mds$i &
15005                 stop_pids[mds$i]=$!
15006         done
15007
15008         for i in $(mdts_nodes); do
15009                 local facet
15010                 local nb=0
15011                 local facets=$(facets_up_on_host $i)
15012
15013                 for facet in ${facets//,/ }; do
15014                         if [[ $facet == mds* ]]; then
15015                                 nb=$((nb + 1))
15016                         fi
15017                 done
15018                 # ensure each MDS's gc threads are still present and all in "R"
15019                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15020                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15021                         error "$i: expected $nb GC-thread"
15022                 wait_update $i \
15023                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15024                         "R" 20 ||
15025                         error "$i: GC-thread not found in R-state"
15026                 # check umounts of each MDT on MDS have reached kthread_stop()
15027                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15028                         error "$i: expected $nb umount"
15029                 wait_update $i \
15030                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15031                         error "$i: umount not found in D-state"
15032         done
15033
15034         # release all GC-threads
15035         do_nodes $mdts $LCTL set_param fail_loc=0
15036
15037         # wait for MDT stop to complete
15038         for i in $(seq $MDSCOUNT); do
15039                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15040         done
15041
15042         # XXX
15043         # may try to check if any orphan changelog records are present
15044         # via ldiskfs/zfs and llog_reader...
15045
15046         # re-start/mount MDTs
15047         for i in $(seq $MDSCOUNT); do
15048                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15049                         error "Fail to start mds$i"
15050         done
15051
15052         local first_rec
15053         for i in $(seq $MDSCOUNT); do
15054                 # check cl_user1 still registered
15055                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15056                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15057                 # check cl_user2 unregistered
15058                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15059                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15060
15061                 # check changelogs are present and starting at $user_rec1 + 1
15062                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15063                 [ -n "$user_rec1" ] ||
15064                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15065                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15066                             awk '{ print $1; exit; }')
15067
15068                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15069                 [ $((user_rec1 + 1)) == $first_rec ] ||
15070                         error "mds$i: first index should be $user_rec1 + 1, " \
15071                               "but is $first_rec"
15072         done
15073 }
15074 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15075               "during mount"
15076
15077 test_160i() {
15078
15079         local mdts=$(comma_list $(mdts_nodes))
15080
15081         changelog_register || error "first changelog_register failed"
15082
15083         # generate some changelog records to accumulate on each MDT
15084         # use fnv1a because created files should be evenly distributed
15085         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15086                 error "mkdir $tdir failed"
15087         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15088                 error "create $DIR/$tdir/$tfile failed"
15089
15090         # check changelogs have been generated
15091         local nbcl=$(changelog_dump | wc -l)
15092         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15093
15094         # simulate race between register and unregister
15095         # XXX as fail_loc is set per-MDS, with DNE configs the race
15096         # simulation will only occur for one MDT per MDS and for the
15097         # others the normal race scenario will take place
15098         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15099         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15100         do_nodes $mdts $LCTL set_param fail_val=1
15101
15102         # unregister 1st user
15103         changelog_deregister &
15104         local pid1=$!
15105         # wait some time for deregister work to reach race rdv
15106         sleep 2
15107         # register 2nd user
15108         changelog_register || error "2nd user register failed"
15109
15110         wait $pid1 || error "1st user deregister failed"
15111
15112         local i
15113         local last_rec
15114         declare -A LAST_REC
15115         for i in $(seq $MDSCOUNT); do
15116                 if changelog_users mds$i | grep "^cl"; then
15117                         # make sure new records are added with one user present
15118                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15119                                           awk '/^current.index:/ { print $NF }')
15120                 else
15121                         error "mds$i has no user registered"
15122                 fi
15123         done
15124
15125         # generate more changelog records to accumulate on each MDT
15126         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15127                 error "create $DIR/$tdir/${tfile}bis failed"
15128
15129         for i in $(seq $MDSCOUNT); do
15130                 last_rec=$(changelog_users $SINGLEMDS |
15131                            awk '/^current.index:/ { print $NF }')
15132                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15133                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15134                         error "changelogs are off on mds$i"
15135         done
15136 }
15137 run_test 160i "changelog user register/unregister race"
15138
15139 test_160j() {
15140         remote_mds_nodsh && skip "remote MDS with nodsh"
15141         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15142                 skip "Need MDS version at least 2.12.56"
15143
15144         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15145         stack_trap "umount $MOUNT2" EXIT
15146
15147         changelog_register || error "first changelog_register failed"
15148         stack_trap "changelog_deregister" EXIT
15149
15150         # generate some changelog
15151         # use fnv1a because created files should be evenly distributed
15152         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15153                 error "mkdir $tdir failed"
15154         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15155                 error "create $DIR/$tdir/${tfile}bis failed"
15156
15157         # open the changelog device
15158         exec 3>/dev/changelog-$FSNAME-MDT0000
15159         stack_trap "exec 3>&-" EXIT
15160         exec 4</dev/changelog-$FSNAME-MDT0000
15161         stack_trap "exec 4<&-" EXIT
15162
15163         # umount the first lustre mount
15164         umount $MOUNT
15165         stack_trap "mount_client $MOUNT" EXIT
15166
15167         # read changelog, which may or may not fail, but should not crash
15168         cat <&4 >/dev/null
15169
15170         # clear changelog
15171         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15172         changelog_users $SINGLEMDS | grep -q $cl_user ||
15173                 error "User $cl_user not found in changelog_users"
15174
15175         printf 'clear:'$cl_user':0' >&3
15176 }
15177 run_test 160j "client can be umounted while its chanangelog is being used"
15178
15179 test_160k() {
15180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15181         remote_mds_nodsh && skip "remote MDS with nodsh"
15182
15183         mkdir -p $DIR/$tdir/1/1
15184
15185         changelog_register || error "changelog_register failed"
15186         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15187
15188         changelog_users $SINGLEMDS | grep -q $cl_user ||
15189                 error "User '$cl_user' not found in changelog_users"
15190 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15191         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15192         rmdir $DIR/$tdir/1/1 & sleep 1
15193         mkdir $DIR/$tdir/2
15194         touch $DIR/$tdir/2/2
15195         rm -rf $DIR/$tdir/2
15196
15197         wait
15198         sleep 4
15199
15200         changelog_dump | grep rmdir || error "rmdir not recorded"
15201
15202         rm -rf $DIR/$tdir
15203         changelog_deregister
15204 }
15205 run_test 160k "Verify that changelog records are not lost"
15206
15207 # Verifies that a file passed as a parameter has recently had an operation
15208 # performed on it that has generated an MTIME changelog which contains the
15209 # correct parent FID. As files might reside on a different MDT from the
15210 # parent directory in DNE configurations, the FIDs are translated to paths
15211 # before being compared, which should be identical
15212 compare_mtime_changelog() {
15213         local file="${1}"
15214         local mdtidx
15215         local mtime
15216         local cl_fid
15217         local pdir
15218         local dir
15219
15220         mdtidx=$($LFS getstripe --mdt-index $file)
15221         mdtidx=$(printf "%04x" $mdtidx)
15222
15223         # Obtain the parent FID from the MTIME changelog
15224         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15225         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15226
15227         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15228         [ -z "$cl_fid" ] && error "parent FID not present"
15229
15230         # Verify that the path for the parent FID is the same as the path for
15231         # the test directory
15232         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15233
15234         dir=$(dirname $1)
15235
15236         [[ "${pdir%/}" == "$dir" ]] ||
15237                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15238 }
15239
15240 test_160l() {
15241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15242
15243         remote_mds_nodsh && skip "remote MDS with nodsh"
15244         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15245                 skip "Need MDS version at least 2.13.55"
15246
15247         local cl_user
15248
15249         changelog_register || error "changelog_register failed"
15250         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15251
15252         changelog_users $SINGLEMDS | grep -q $cl_user ||
15253                 error "User '$cl_user' not found in changelog_users"
15254
15255         # Clear some types so that MTIME changelogs are generated
15256         changelog_chmask "-CREAT"
15257         changelog_chmask "-CLOSE"
15258
15259         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15260
15261         # Test CL_MTIME during setattr
15262         touch $DIR/$tdir/$tfile
15263         compare_mtime_changelog $DIR/$tdir/$tfile
15264
15265         # Test CL_MTIME during close
15266         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15267         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15268 }
15269 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15270
15271 test_161a() {
15272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15273
15274         test_mkdir -c1 $DIR/$tdir
15275         cp /etc/hosts $DIR/$tdir/$tfile
15276         test_mkdir -c1 $DIR/$tdir/foo1
15277         test_mkdir -c1 $DIR/$tdir/foo2
15278         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15279         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15280         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15281         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15282         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15283         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15284                 $LFS fid2path $DIR $FID
15285                 error "bad link ea"
15286         fi
15287         # middle
15288         rm $DIR/$tdir/foo2/zachary
15289         # last
15290         rm $DIR/$tdir/foo2/thor
15291         # first
15292         rm $DIR/$tdir/$tfile
15293         # rename
15294         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15295         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15296                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15297         rm $DIR/$tdir/foo2/maggie
15298
15299         # overflow the EA
15300         local longname=$tfile.avg_len_is_thirty_two_
15301         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15302                 error_noexit 'failed to unlink many hardlinks'" EXIT
15303         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15304                 error "failed to hardlink many files"
15305         links=$($LFS fid2path $DIR $FID | wc -l)
15306         echo -n "${links}/1000 links in link EA"
15307         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15308 }
15309 run_test 161a "link ea sanity"
15310
15311 test_161b() {
15312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15313         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15314
15315         local MDTIDX=1
15316         local remote_dir=$DIR/$tdir/remote_dir
15317
15318         mkdir -p $DIR/$tdir
15319         $LFS mkdir -i $MDTIDX $remote_dir ||
15320                 error "create remote directory failed"
15321
15322         cp /etc/hosts $remote_dir/$tfile
15323         mkdir -p $remote_dir/foo1
15324         mkdir -p $remote_dir/foo2
15325         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15326         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15327         ln $remote_dir/$tfile $remote_dir/foo1/luna
15328         ln $remote_dir/$tfile $remote_dir/foo2/thor
15329
15330         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15331                      tr -d ']')
15332         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15333                 $LFS fid2path $DIR $FID
15334                 error "bad link ea"
15335         fi
15336         # middle
15337         rm $remote_dir/foo2/zachary
15338         # last
15339         rm $remote_dir/foo2/thor
15340         # first
15341         rm $remote_dir/$tfile
15342         # rename
15343         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15344         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15345         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15346                 $LFS fid2path $DIR $FID
15347                 error "bad link rename"
15348         fi
15349         rm $remote_dir/foo2/maggie
15350
15351         # overflow the EA
15352         local longname=filename_avg_len_is_thirty_two_
15353         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15354                 error "failed to hardlink many files"
15355         links=$($LFS fid2path $DIR $FID | wc -l)
15356         echo -n "${links}/1000 links in link EA"
15357         [[ ${links} -gt 60 ]] ||
15358                 error "expected at least 60 links in link EA"
15359         unlinkmany $remote_dir/foo2/$longname 1000 ||
15360         error "failed to unlink many hardlinks"
15361 }
15362 run_test 161b "link ea sanity under remote directory"
15363
15364 test_161c() {
15365         remote_mds_nodsh && skip "remote MDS with nodsh"
15366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15367         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15368                 skip "Need MDS version at least 2.1.5"
15369
15370         # define CLF_RENAME_LAST 0x0001
15371         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15372         changelog_register || error "changelog_register failed"
15373
15374         rm -rf $DIR/$tdir
15375         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15376         touch $DIR/$tdir/foo_161c
15377         touch $DIR/$tdir/bar_161c
15378         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15379         changelog_dump | grep RENME | tail -n 5
15380         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15381         changelog_clear 0 || error "changelog_clear failed"
15382         if [ x$flags != "x0x1" ]; then
15383                 error "flag $flags is not 0x1"
15384         fi
15385
15386         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15387         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15388         touch $DIR/$tdir/foo_161c
15389         touch $DIR/$tdir/bar_161c
15390         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15391         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15392         changelog_dump | grep RENME | tail -n 5
15393         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15394         changelog_clear 0 || error "changelog_clear failed"
15395         if [ x$flags != "x0x0" ]; then
15396                 error "flag $flags is not 0x0"
15397         fi
15398         echo "rename overwrite a target having nlink > 1," \
15399                 "changelog record has flags of $flags"
15400
15401         # rename doesn't overwrite a target (changelog flag 0x0)
15402         touch $DIR/$tdir/foo_161c
15403         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15404         changelog_dump | grep RENME | tail -n 5
15405         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15406         changelog_clear 0 || error "changelog_clear failed"
15407         if [ x$flags != "x0x0" ]; then
15408                 error "flag $flags is not 0x0"
15409         fi
15410         echo "rename doesn't overwrite a target," \
15411                 "changelog record has flags of $flags"
15412
15413         # define CLF_UNLINK_LAST 0x0001
15414         # unlink a file having nlink = 1 (changelog flag 0x1)
15415         rm -f $DIR/$tdir/foo2_161c
15416         changelog_dump | grep UNLNK | tail -n 5
15417         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15418         changelog_clear 0 || error "changelog_clear failed"
15419         if [ x$flags != "x0x1" ]; then
15420                 error "flag $flags is not 0x1"
15421         fi
15422         echo "unlink a file having nlink = 1," \
15423                 "changelog record has flags of $flags"
15424
15425         # unlink a file having nlink > 1 (changelog flag 0x0)
15426         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15427         rm -f $DIR/$tdir/foobar_161c
15428         changelog_dump | grep UNLNK | tail -n 5
15429         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15430         changelog_clear 0 || error "changelog_clear failed"
15431         if [ x$flags != "x0x0" ]; then
15432                 error "flag $flags is not 0x0"
15433         fi
15434         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15435 }
15436 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15437
15438 test_161d() {
15439         remote_mds_nodsh && skip "remote MDS with nodsh"
15440         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15441
15442         local pid
15443         local fid
15444
15445         changelog_register || error "changelog_register failed"
15446
15447         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15448         # interfer with $MOUNT/.lustre/fid/ access
15449         mkdir $DIR/$tdir
15450         [[ $? -eq 0 ]] || error "mkdir failed"
15451
15452         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15453         $LCTL set_param fail_loc=0x8000140c
15454         # 5s pause
15455         $LCTL set_param fail_val=5
15456
15457         # create file
15458         echo foofoo > $DIR/$tdir/$tfile &
15459         pid=$!
15460
15461         # wait for create to be delayed
15462         sleep 2
15463
15464         ps -p $pid
15465         [[ $? -eq 0 ]] || error "create should be blocked"
15466
15467         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15468         stack_trap "rm -f $tempfile"
15469         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15470         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15471         # some delay may occur during ChangeLog publishing and file read just
15472         # above, that could allow file write to happen finally
15473         [[ -s $tempfile ]] && echo "file should be empty"
15474
15475         $LCTL set_param fail_loc=0
15476
15477         wait $pid
15478         [[ $? -eq 0 ]] || error "create failed"
15479 }
15480 run_test 161d "create with concurrent .lustre/fid access"
15481
15482 check_path() {
15483         local expected="$1"
15484         shift
15485         local fid="$2"
15486
15487         local path
15488         path=$($LFS fid2path "$@")
15489         local rc=$?
15490
15491         if [ $rc -ne 0 ]; then
15492                 error "path looked up of '$expected' failed: rc=$rc"
15493         elif [ "$path" != "$expected" ]; then
15494                 error "path looked up '$path' instead of '$expected'"
15495         else
15496                 echo "FID '$fid' resolves to path '$path' as expected"
15497         fi
15498 }
15499
15500 test_162a() { # was test_162
15501         test_mkdir -p -c1 $DIR/$tdir/d2
15502         touch $DIR/$tdir/d2/$tfile
15503         touch $DIR/$tdir/d2/x1
15504         touch $DIR/$tdir/d2/x2
15505         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15506         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15507         # regular file
15508         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15509         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15510
15511         # softlink
15512         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15513         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15514         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15515
15516         # softlink to wrong file
15517         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15518         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15519         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15520
15521         # hardlink
15522         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15523         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15524         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15525         # fid2path dir/fsname should both work
15526         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15527         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15528
15529         # hardlink count: check that there are 2 links
15530         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15531         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15532
15533         # hardlink indexing: remove the first link
15534         rm $DIR/$tdir/d2/p/q/r/hlink
15535         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15536 }
15537 run_test 162a "path lookup sanity"
15538
15539 test_162b() {
15540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15542
15543         mkdir $DIR/$tdir
15544         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15545                                 error "create striped dir failed"
15546
15547         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15548                                         tail -n 1 | awk '{print $2}')
15549         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15550
15551         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15552         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15553
15554         # regular file
15555         for ((i=0;i<5;i++)); do
15556                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15557                         error "get fid for f$i failed"
15558                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15559
15560                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15561                         error "get fid for d$i failed"
15562                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15563         done
15564
15565         return 0
15566 }
15567 run_test 162b "striped directory path lookup sanity"
15568
15569 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15570 test_162c() {
15571         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15572                 skip "Need MDS version at least 2.7.51"
15573
15574         local lpath=$tdir.local
15575         local rpath=$tdir.remote
15576
15577         test_mkdir $DIR/$lpath
15578         test_mkdir $DIR/$rpath
15579
15580         for ((i = 0; i <= 101; i++)); do
15581                 lpath="$lpath/$i"
15582                 mkdir $DIR/$lpath
15583                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15584                         error "get fid for local directory $DIR/$lpath failed"
15585                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15586
15587                 rpath="$rpath/$i"
15588                 test_mkdir $DIR/$rpath
15589                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15590                         error "get fid for remote directory $DIR/$rpath failed"
15591                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15592         done
15593
15594         return 0
15595 }
15596 run_test 162c "fid2path works with paths 100 or more directories deep"
15597
15598 oalr_event_count() {
15599         local event="${1}"
15600         local trace="${2}"
15601
15602         awk -v name="${FSNAME}-OST0000" \
15603             -v event="${event}" \
15604             '$1 == "TRACE" && $2 == event && $3 == name' \
15605             "${trace}" |
15606         wc -l
15607 }
15608
15609 oalr_expect_event_count() {
15610         local event="${1}"
15611         local trace="${2}"
15612         local expect="${3}"
15613         local count
15614
15615         count=$(oalr_event_count "${event}" "${trace}")
15616         if ((count == expect)); then
15617                 return 0
15618         fi
15619
15620         error_noexit "${event} event count was '${count}', expected ${expect}"
15621         cat "${trace}" >&2
15622         exit 1
15623 }
15624
15625 cleanup_165() {
15626         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15627         stop ost1
15628         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15629 }
15630
15631 setup_165() {
15632         sync # Flush previous IOs so we can count log entries.
15633         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15634         stack_trap cleanup_165 EXIT
15635 }
15636
15637 test_165a() {
15638         local trace="/tmp/${tfile}.trace"
15639         local rc
15640         local count
15641
15642         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15643                 skip "OFD access log unsupported"
15644
15645         setup_165
15646         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15647         sleep 5
15648
15649         do_facet ost1 ofd_access_log_reader --list
15650         stop ost1
15651
15652         do_facet ost1 killall -TERM ofd_access_log_reader
15653         wait
15654         rc=$?
15655
15656         if ((rc != 0)); then
15657                 error "ofd_access_log_reader exited with rc = '${rc}'"
15658         fi
15659
15660         # Parse trace file for discovery events:
15661         oalr_expect_event_count alr_log_add "${trace}" 1
15662         oalr_expect_event_count alr_log_eof "${trace}" 1
15663         oalr_expect_event_count alr_log_free "${trace}" 1
15664 }
15665 run_test 165a "ofd access log discovery"
15666
15667 test_165b() {
15668         local trace="/tmp/${tfile}.trace"
15669         local file="${DIR}/${tfile}"
15670         local pfid1
15671         local pfid2
15672         local -a entry
15673         local rc
15674         local count
15675         local size
15676         local flags
15677
15678         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15679                 skip "OFD access log unsupported"
15680
15681         setup_165
15682         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15683         sleep 5
15684
15685         do_facet ost1 ofd_access_log_reader --list
15686
15687         lfs setstripe -c 1 -i 0 "${file}"
15688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15689                 error "cannot create '${file}'"
15690
15691         sleep 5
15692         do_facet ost1 killall -TERM ofd_access_log_reader
15693         wait
15694         rc=$?
15695
15696         if ((rc != 0)); then
15697                 error "ofd_access_log_reader exited with rc = '${rc}'"
15698         fi
15699
15700         oalr_expect_event_count alr_log_entry "${trace}" 1
15701
15702         pfid1=$($LFS path2fid "${file}")
15703
15704         # 1     2             3   4    5     6   7    8    9     10
15705         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15706         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15707
15708         echo "entry = '${entry[*]}'" >&2
15709
15710         pfid2=${entry[4]}
15711         if [[ "${pfid1}" != "${pfid2}" ]]; then
15712                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15713         fi
15714
15715         size=${entry[8]}
15716         if ((size != 1048576)); then
15717                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15718         fi
15719
15720         flags=${entry[10]}
15721         if [[ "${flags}" != "w" ]]; then
15722                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15723         fi
15724
15725         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15726         sleep 5
15727
15728         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15729                 error "cannot read '${file}'"
15730         sleep 5
15731
15732         do_facet ost1 killall -TERM ofd_access_log_reader
15733         wait
15734         rc=$?
15735
15736         if ((rc != 0)); then
15737                 error "ofd_access_log_reader exited with rc = '${rc}'"
15738         fi
15739
15740         oalr_expect_event_count alr_log_entry "${trace}" 1
15741
15742         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15743         echo "entry = '${entry[*]}'" >&2
15744
15745         pfid2=${entry[4]}
15746         if [[ "${pfid1}" != "${pfid2}" ]]; then
15747                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15748         fi
15749
15750         size=${entry[8]}
15751         if ((size != 524288)); then
15752                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15753         fi
15754
15755         flags=${entry[10]}
15756         if [[ "${flags}" != "r" ]]; then
15757                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15758         fi
15759 }
15760 run_test 165b "ofd access log entries are produced and consumed"
15761
15762 test_165c() {
15763         local trace="/tmp/${tfile}.trace"
15764         local file="${DIR}/${tdir}/${tfile}"
15765
15766         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15767                 skip "OFD access log unsupported"
15768
15769         test_mkdir "${DIR}/${tdir}"
15770
15771         setup_165
15772         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15773         sleep 5
15774
15775         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15776
15777         # 4096 / 64 = 64. Create twice as many entries.
15778         for ((i = 0; i < 128; i++)); do
15779                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15780                         error "cannot create file"
15781         done
15782
15783         sync
15784
15785         do_facet ost1 killall -TERM ofd_access_log_reader
15786         wait
15787         rc=$?
15788         if ((rc != 0)); then
15789                 error "ofd_access_log_reader exited with rc = '${rc}'"
15790         fi
15791
15792         unlinkmany  "${file}-%d" 128
15793 }
15794 run_test 165c "full ofd access logs do not block IOs"
15795
15796 oal_get_read_count() {
15797         local stats="$1"
15798
15799         # STATS lustre-OST0001 alr_read_count 1
15800
15801         do_facet ost1 cat "${stats}" |
15802         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15803              END { print count; }'
15804 }
15805
15806 oal_expect_read_count() {
15807         local stats="$1"
15808         local count
15809         local expect="$2"
15810
15811         # Ask ofd_access_log_reader to write stats.
15812         do_facet ost1 killall -USR1 ofd_access_log_reader
15813
15814         # Allow some time for things to happen.
15815         sleep 1
15816
15817         count=$(oal_get_read_count "${stats}")
15818         if ((count == expect)); then
15819                 return 0
15820         fi
15821
15822         error_noexit "bad read count, got ${count}, expected ${expect}"
15823         do_facet ost1 cat "${stats}" >&2
15824         exit 1
15825 }
15826
15827 test_165d() {
15828         local stats="/tmp/${tfile}.stats"
15829         local file="${DIR}/${tdir}/${tfile}"
15830         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15831
15832         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15833                 skip "OFD access log unsupported"
15834
15835         test_mkdir "${DIR}/${tdir}"
15836
15837         setup_165
15838         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15839         sleep 5
15840
15841         lfs setstripe -c 1 -i 0 "${file}"
15842
15843         do_facet ost1 lctl set_param "${param}=rw"
15844         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15845                 error "cannot create '${file}'"
15846         oal_expect_read_count "${stats}" 1
15847
15848         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15849                 error "cannot read '${file}'"
15850         oal_expect_read_count "${stats}" 2
15851
15852         do_facet ost1 lctl set_param "${param}=r"
15853         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15854                 error "cannot create '${file}'"
15855         oal_expect_read_count "${stats}" 2
15856
15857         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15858                 error "cannot read '${file}'"
15859         oal_expect_read_count "${stats}" 3
15860
15861         do_facet ost1 lctl set_param "${param}=w"
15862         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15863                 error "cannot create '${file}'"
15864         oal_expect_read_count "${stats}" 4
15865
15866         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15867                 error "cannot read '${file}'"
15868         oal_expect_read_count "${stats}" 4
15869
15870         do_facet ost1 lctl set_param "${param}=0"
15871         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15872                 error "cannot create '${file}'"
15873         oal_expect_read_count "${stats}" 4
15874
15875         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15876                 error "cannot read '${file}'"
15877         oal_expect_read_count "${stats}" 4
15878
15879         do_facet ost1 killall -TERM ofd_access_log_reader
15880         wait
15881         rc=$?
15882         if ((rc != 0)); then
15883                 error "ofd_access_log_reader exited with rc = '${rc}'"
15884         fi
15885 }
15886 run_test 165d "ofd_access_log mask works"
15887
15888 test_165e() {
15889         local stats="/tmp/${tfile}.stats"
15890         local file0="${DIR}/${tdir}-0/${tfile}"
15891         local file1="${DIR}/${tdir}-1/${tfile}"
15892
15893         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15894                 skip "OFD access log unsupported"
15895
15896         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15897
15898         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15899         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15900
15901         lfs setstripe -c 1 -i 0 "${file0}"
15902         lfs setstripe -c 1 -i 0 "${file1}"
15903
15904         setup_165
15905         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15906         sleep 5
15907
15908         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15909                 error "cannot create '${file0}'"
15910         sync
15911         oal_expect_read_count "${stats}" 0
15912
15913         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15914                 error "cannot create '${file1}'"
15915         sync
15916         oal_expect_read_count "${stats}" 1
15917
15918         do_facet ost1 killall -TERM ofd_access_log_reader
15919         wait
15920         rc=$?
15921         if ((rc != 0)); then
15922                 error "ofd_access_log_reader exited with rc = '${rc}'"
15923         fi
15924 }
15925 run_test 165e "ofd_access_log MDT index filter works"
15926
15927 test_165f() {
15928         local trace="/tmp/${tfile}.trace"
15929         local rc
15930         local count
15931
15932         setup_165
15933         do_facet ost1 timeout 60 ofd_access_log_reader \
15934                 --exit-on-close --debug=- --trace=- > "${trace}" &
15935         sleep 5
15936         stop ost1
15937
15938         wait
15939         rc=$?
15940
15941         if ((rc != 0)); then
15942                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15943                 cat "${trace}"
15944                 exit 1
15945         fi
15946 }
15947 run_test 165f "ofd_access_log_reader --exit-on-close works"
15948
15949 test_169() {
15950         # do directio so as not to populate the page cache
15951         log "creating a 10 Mb file"
15952         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15953                 error "multiop failed while creating a file"
15954         log "starting reads"
15955         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15956         log "truncating the file"
15957         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15958                 error "multiop failed while truncating the file"
15959         log "killing dd"
15960         kill %+ || true # reads might have finished
15961         echo "wait until dd is finished"
15962         wait
15963         log "removing the temporary file"
15964         rm -rf $DIR/$tfile || error "tmp file removal failed"
15965 }
15966 run_test 169 "parallel read and truncate should not deadlock"
15967
15968 test_170() {
15969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15970
15971         $LCTL clear     # bug 18514
15972         $LCTL debug_daemon start $TMP/${tfile}_log_good
15973         touch $DIR/$tfile
15974         $LCTL debug_daemon stop
15975         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15976                 error "sed failed to read log_good"
15977
15978         $LCTL debug_daemon start $TMP/${tfile}_log_good
15979         rm -rf $DIR/$tfile
15980         $LCTL debug_daemon stop
15981
15982         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15983                error "lctl df log_bad failed"
15984
15985         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15986         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15987
15988         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15989         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15990
15991         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15992                 error "bad_line good_line1 good_line2 are empty"
15993
15994         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15995         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15996         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15997
15998         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15999         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16000         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16001
16002         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16003                 error "bad_line_new good_line_new are empty"
16004
16005         local expected_good=$((good_line1 + good_line2*2))
16006
16007         rm -f $TMP/${tfile}*
16008         # LU-231, short malformed line may not be counted into bad lines
16009         if [ $bad_line -ne $bad_line_new ] &&
16010                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16011                 error "expected $bad_line bad lines, but got $bad_line_new"
16012                 return 1
16013         fi
16014
16015         if [ $expected_good -ne $good_line_new ]; then
16016                 error "expected $expected_good good lines, but got $good_line_new"
16017                 return 2
16018         fi
16019         true
16020 }
16021 run_test 170 "test lctl df to handle corrupted log ====================="
16022
16023 test_171() { # bug20592
16024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16025
16026         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16027         $LCTL set_param fail_loc=0x50e
16028         $LCTL set_param fail_val=3000
16029         multiop_bg_pause $DIR/$tfile O_s || true
16030         local MULTIPID=$!
16031         kill -USR1 $MULTIPID
16032         # cause log dump
16033         sleep 3
16034         wait $MULTIPID
16035         if dmesg | grep "recursive fault"; then
16036                 error "caught a recursive fault"
16037         fi
16038         $LCTL set_param fail_loc=0
16039         true
16040 }
16041 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16042
16043 # it would be good to share it with obdfilter-survey/iokit-libecho code
16044 setup_obdecho_osc () {
16045         local rc=0
16046         local ost_nid=$1
16047         local obdfilter_name=$2
16048         echo "Creating new osc for $obdfilter_name on $ost_nid"
16049         # make sure we can find loopback nid
16050         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16051
16052         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16053                            ${obdfilter_name}_osc_UUID || rc=2; }
16054         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16055                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16056         return $rc
16057 }
16058
16059 cleanup_obdecho_osc () {
16060         local obdfilter_name=$1
16061         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16062         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16063         return 0
16064 }
16065
16066 obdecho_test() {
16067         local OBD=$1
16068         local node=$2
16069         local pages=${3:-64}
16070         local rc=0
16071         local id
16072
16073         local count=10
16074         local obd_size=$(get_obd_size $node $OBD)
16075         local page_size=$(get_page_size $node)
16076         if [[ -n "$obd_size" ]]; then
16077                 local new_count=$((obd_size / (pages * page_size / 1024)))
16078                 [[ $new_count -ge $count ]] || count=$new_count
16079         fi
16080
16081         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16082         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16083                            rc=2; }
16084         if [ $rc -eq 0 ]; then
16085             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16086             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16087         fi
16088         echo "New object id is $id"
16089         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16090                            rc=4; }
16091         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16092                            "test_brw $count w v $pages $id" || rc=4; }
16093         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16094                            rc=4; }
16095         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16096                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16097         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16098                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16099         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16100         return $rc
16101 }
16102
16103 test_180a() {
16104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16105
16106         if ! [ -d /sys/fs/lustre/echo_client ] &&
16107            ! module_loaded obdecho; then
16108                 load_module obdecho/obdecho &&
16109                         stack_trap "rmmod obdecho" EXIT ||
16110                         error "unable to load obdecho on client"
16111         fi
16112
16113         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16114         local host=$($LCTL get_param -n osc.$osc.import |
16115                      awk '/current_connection:/ { print $2 }' )
16116         local target=$($LCTL get_param -n osc.$osc.import |
16117                        awk '/target:/ { print $2 }' )
16118         target=${target%_UUID}
16119
16120         if [ -n "$target" ]; then
16121                 setup_obdecho_osc $host $target &&
16122                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16123                         { error "obdecho setup failed with $?"; return; }
16124
16125                 obdecho_test ${target}_osc client ||
16126                         error "obdecho_test failed on ${target}_osc"
16127         else
16128                 $LCTL get_param osc.$osc.import
16129                 error "there is no osc.$osc.import target"
16130         fi
16131 }
16132 run_test 180a "test obdecho on osc"
16133
16134 test_180b() {
16135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16136         remote_ost_nodsh && skip "remote OST with nodsh"
16137
16138         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16139                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16140                 error "failed to load module obdecho"
16141
16142         local target=$(do_facet ost1 $LCTL dl |
16143                        awk '/obdfilter/ { print $4; exit; }')
16144
16145         if [ -n "$target" ]; then
16146                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16147         else
16148                 do_facet ost1 $LCTL dl
16149                 error "there is no obdfilter target on ost1"
16150         fi
16151 }
16152 run_test 180b "test obdecho directly on obdfilter"
16153
16154 test_180c() { # LU-2598
16155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16156         remote_ost_nodsh && skip "remote OST with nodsh"
16157         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16158                 skip "Need MDS version at least 2.4.0"
16159
16160         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16161                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16162                 error "failed to load module obdecho"
16163
16164         local target=$(do_facet ost1 $LCTL dl |
16165                        awk '/obdfilter/ { print $4; exit; }')
16166
16167         if [ -n "$target" ]; then
16168                 local pages=16384 # 64MB bulk I/O RPC size
16169
16170                 obdecho_test "$target" ost1 "$pages" ||
16171                         error "obdecho_test with pages=$pages failed with $?"
16172         else
16173                 do_facet ost1 $LCTL dl
16174                 error "there is no obdfilter target on ost1"
16175         fi
16176 }
16177 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16178
16179 test_181() { # bug 22177
16180         test_mkdir $DIR/$tdir
16181         # create enough files to index the directory
16182         createmany -o $DIR/$tdir/foobar 4000
16183         # print attributes for debug purpose
16184         lsattr -d .
16185         # open dir
16186         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16187         MULTIPID=$!
16188         # remove the files & current working dir
16189         unlinkmany $DIR/$tdir/foobar 4000
16190         rmdir $DIR/$tdir
16191         kill -USR1 $MULTIPID
16192         wait $MULTIPID
16193         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16194         return 0
16195 }
16196 run_test 181 "Test open-unlinked dir ========================"
16197
16198 test_182() {
16199         local fcount=1000
16200         local tcount=10
16201
16202         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16203
16204         $LCTL set_param mdc.*.rpc_stats=clear
16205
16206         for (( i = 0; i < $tcount; i++ )) ; do
16207                 mkdir $DIR/$tdir/$i
16208         done
16209
16210         for (( i = 0; i < $tcount; i++ )) ; do
16211                 createmany -o $DIR/$tdir/$i/f- $fcount &
16212         done
16213         wait
16214
16215         for (( i = 0; i < $tcount; i++ )) ; do
16216                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16217         done
16218         wait
16219
16220         $LCTL get_param mdc.*.rpc_stats
16221
16222         rm -rf $DIR/$tdir
16223 }
16224 run_test 182 "Test parallel modify metadata operations ================"
16225
16226 test_183() { # LU-2275
16227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16228         remote_mds_nodsh && skip "remote MDS with nodsh"
16229         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16230                 skip "Need MDS version at least 2.3.56"
16231
16232         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16233         echo aaa > $DIR/$tdir/$tfile
16234
16235 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16236         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16237
16238         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16239         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16240
16241         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16242
16243         # Flush negative dentry cache
16244         touch $DIR/$tdir/$tfile
16245
16246         # We are not checking for any leaked references here, they'll
16247         # become evident next time we do cleanup with module unload.
16248         rm -rf $DIR/$tdir
16249 }
16250 run_test 183 "No crash or request leak in case of strange dispositions ========"
16251
16252 # test suite 184 is for LU-2016, LU-2017
16253 test_184a() {
16254         check_swap_layouts_support
16255
16256         dir0=$DIR/$tdir/$testnum
16257         test_mkdir -p -c1 $dir0
16258         ref1=/etc/passwd
16259         ref2=/etc/group
16260         file1=$dir0/f1
16261         file2=$dir0/f2
16262         $LFS setstripe -c1 $file1
16263         cp $ref1 $file1
16264         $LFS setstripe -c2 $file2
16265         cp $ref2 $file2
16266         gen1=$($LFS getstripe -g $file1)
16267         gen2=$($LFS getstripe -g $file2)
16268
16269         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16270         gen=$($LFS getstripe -g $file1)
16271         [[ $gen1 != $gen ]] ||
16272                 "Layout generation on $file1 does not change"
16273         gen=$($LFS getstripe -g $file2)
16274         [[ $gen2 != $gen ]] ||
16275                 "Layout generation on $file2 does not change"
16276
16277         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16278         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16279
16280         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16281 }
16282 run_test 184a "Basic layout swap"
16283
16284 test_184b() {
16285         check_swap_layouts_support
16286
16287         dir0=$DIR/$tdir/$testnum
16288         mkdir -p $dir0 || error "creating dir $dir0"
16289         file1=$dir0/f1
16290         file2=$dir0/f2
16291         file3=$dir0/f3
16292         dir1=$dir0/d1
16293         dir2=$dir0/d2
16294         mkdir $dir1 $dir2
16295         $LFS setstripe -c1 $file1
16296         $LFS setstripe -c2 $file2
16297         $LFS setstripe -c1 $file3
16298         chown $RUNAS_ID $file3
16299         gen1=$($LFS getstripe -g $file1)
16300         gen2=$($LFS getstripe -g $file2)
16301
16302         $LFS swap_layouts $dir1 $dir2 &&
16303                 error "swap of directories layouts should fail"
16304         $LFS swap_layouts $dir1 $file1 &&
16305                 error "swap of directory and file layouts should fail"
16306         $RUNAS $LFS swap_layouts $file1 $file2 &&
16307                 error "swap of file we cannot write should fail"
16308         $LFS swap_layouts $file1 $file3 &&
16309                 error "swap of file with different owner should fail"
16310         /bin/true # to clear error code
16311 }
16312 run_test 184b "Forbidden layout swap (will generate errors)"
16313
16314 test_184c() {
16315         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16316         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16317         check_swap_layouts_support
16318         check_swap_layout_no_dom $DIR
16319
16320         local dir0=$DIR/$tdir/$testnum
16321         mkdir -p $dir0 || error "creating dir $dir0"
16322
16323         local ref1=$dir0/ref1
16324         local ref2=$dir0/ref2
16325         local file1=$dir0/file1
16326         local file2=$dir0/file2
16327         # create a file large enough for the concurrent test
16328         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16329         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16330         echo "ref file size: ref1($(stat -c %s $ref1))," \
16331              "ref2($(stat -c %s $ref2))"
16332
16333         cp $ref2 $file2
16334         dd if=$ref1 of=$file1 bs=16k &
16335         local DD_PID=$!
16336
16337         # Make sure dd starts to copy file, but wait at most 5 seconds
16338         local loops=0
16339         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16340
16341         $LFS swap_layouts $file1 $file2
16342         local rc=$?
16343         wait $DD_PID
16344         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16345         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16346
16347         # how many bytes copied before swapping layout
16348         local copied=$(stat -c %s $file2)
16349         local remaining=$(stat -c %s $ref1)
16350         remaining=$((remaining - copied))
16351         echo "Copied $copied bytes before swapping layout..."
16352
16353         cmp -n $copied $file1 $ref2 | grep differ &&
16354                 error "Content mismatch [0, $copied) of ref2 and file1"
16355         cmp -n $copied $file2 $ref1 ||
16356                 error "Content mismatch [0, $copied) of ref1 and file2"
16357         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16358                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16359
16360         # clean up
16361         rm -f $ref1 $ref2 $file1 $file2
16362 }
16363 run_test 184c "Concurrent write and layout swap"
16364
16365 test_184d() {
16366         check_swap_layouts_support
16367         check_swap_layout_no_dom $DIR
16368         [ -z "$(which getfattr 2>/dev/null)" ] &&
16369                 skip_env "no getfattr command"
16370
16371         local file1=$DIR/$tdir/$tfile-1
16372         local file2=$DIR/$tdir/$tfile-2
16373         local file3=$DIR/$tdir/$tfile-3
16374         local lovea1
16375         local lovea2
16376
16377         mkdir -p $DIR/$tdir
16378         touch $file1 || error "create $file1 failed"
16379         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16380                 error "create $file2 failed"
16381         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16382                 error "create $file3 failed"
16383         lovea1=$(get_layout_param $file1)
16384
16385         $LFS swap_layouts $file2 $file3 ||
16386                 error "swap $file2 $file3 layouts failed"
16387         $LFS swap_layouts $file1 $file2 ||
16388                 error "swap $file1 $file2 layouts failed"
16389
16390         lovea2=$(get_layout_param $file2)
16391         echo "$lovea1"
16392         echo "$lovea2"
16393         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16394
16395         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16396         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16397 }
16398 run_test 184d "allow stripeless layouts swap"
16399
16400 test_184e() {
16401         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16402                 skip "Need MDS version at least 2.6.94"
16403         check_swap_layouts_support
16404         check_swap_layout_no_dom $DIR
16405         [ -z "$(which getfattr 2>/dev/null)" ] &&
16406                 skip_env "no getfattr command"
16407
16408         local file1=$DIR/$tdir/$tfile-1
16409         local file2=$DIR/$tdir/$tfile-2
16410         local file3=$DIR/$tdir/$tfile-3
16411         local lovea
16412
16413         mkdir -p $DIR/$tdir
16414         touch $file1 || error "create $file1 failed"
16415         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16416                 error "create $file2 failed"
16417         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16418                 error "create $file3 failed"
16419
16420         $LFS swap_layouts $file1 $file2 ||
16421                 error "swap $file1 $file2 layouts failed"
16422
16423         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16424         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16425
16426         echo 123 > $file1 || error "Should be able to write into $file1"
16427
16428         $LFS swap_layouts $file1 $file3 ||
16429                 error "swap $file1 $file3 layouts failed"
16430
16431         echo 123 > $file1 || error "Should be able to write into $file1"
16432
16433         rm -rf $file1 $file2 $file3
16434 }
16435 run_test 184e "Recreate layout after stripeless layout swaps"
16436
16437 test_184f() {
16438         # Create a file with name longer than sizeof(struct stat) ==
16439         # 144 to see if we can get chars from the file name to appear
16440         # in the returned striping. Note that 'f' == 0x66.
16441         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16442
16443         mkdir -p $DIR/$tdir
16444         mcreate $DIR/$tdir/$file
16445         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16446                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16447         fi
16448 }
16449 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16450
16451 test_185() { # LU-2441
16452         # LU-3553 - no volatile file support in old servers
16453         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16454                 skip "Need MDS version at least 2.3.60"
16455
16456         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16457         touch $DIR/$tdir/spoo
16458         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16459         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16460                 error "cannot create/write a volatile file"
16461         [ "$FILESET" == "" ] &&
16462         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16463                 error "FID is still valid after close"
16464
16465         multiop_bg_pause $DIR/$tdir vVw4096_c
16466         local multi_pid=$!
16467
16468         local OLD_IFS=$IFS
16469         IFS=":"
16470         local fidv=($fid)
16471         IFS=$OLD_IFS
16472         # assume that the next FID for this client is sequential, since stdout
16473         # is unfortunately eaten by multiop_bg_pause
16474         local n=$((${fidv[1]} + 1))
16475         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16476         if [ "$FILESET" == "" ]; then
16477                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16478                         error "FID is missing before close"
16479         fi
16480         kill -USR1 $multi_pid
16481         # 1 second delay, so if mtime change we will see it
16482         sleep 1
16483         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16484         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16485 }
16486 run_test 185 "Volatile file support"
16487
16488 function create_check_volatile() {
16489         local idx=$1
16490         local tgt
16491
16492         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16493         local PID=$!
16494         sleep 1
16495         local FID=$(cat /tmp/${tfile}.fid)
16496         [ "$FID" == "" ] && error "can't get FID for volatile"
16497         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16498         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16499         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16500         kill -USR1 $PID
16501         wait
16502         sleep 1
16503         cancel_lru_locks mdc # flush opencache
16504         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16505         return 0
16506 }
16507
16508 test_185a(){
16509         # LU-12516 - volatile creation via .lustre
16510         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16511                 skip "Need MDS version at least 2.3.55"
16512
16513         create_check_volatile 0
16514         [ $MDSCOUNT -lt 2 ] && return 0
16515
16516         # DNE case
16517         create_check_volatile 1
16518
16519         return 0
16520 }
16521 run_test 185a "Volatile file creation in .lustre/fid/"
16522
16523 test_187a() {
16524         remote_mds_nodsh && skip "remote MDS with nodsh"
16525         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16526                 skip "Need MDS version at least 2.3.0"
16527
16528         local dir0=$DIR/$tdir/$testnum
16529         mkdir -p $dir0 || error "creating dir $dir0"
16530
16531         local file=$dir0/file1
16532         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16533         local dv1=$($LFS data_version $file)
16534         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16535         local dv2=$($LFS data_version $file)
16536         [[ $dv1 != $dv2 ]] ||
16537                 error "data version did not change on write $dv1 == $dv2"
16538
16539         # clean up
16540         rm -f $file1
16541 }
16542 run_test 187a "Test data version change"
16543
16544 test_187b() {
16545         remote_mds_nodsh && skip "remote MDS with nodsh"
16546         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16547                 skip "Need MDS version at least 2.3.0"
16548
16549         local dir0=$DIR/$tdir/$testnum
16550         mkdir -p $dir0 || error "creating dir $dir0"
16551
16552         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16553         [[ ${DV[0]} != ${DV[1]} ]] ||
16554                 error "data version did not change on write"\
16555                       " ${DV[0]} == ${DV[1]}"
16556
16557         # clean up
16558         rm -f $file1
16559 }
16560 run_test 187b "Test data version change on volatile file"
16561
16562 test_200() {
16563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16564         remote_mgs_nodsh && skip "remote MGS with nodsh"
16565         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16566
16567         local POOL=${POOL:-cea1}
16568         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16569         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16570         # Pool OST targets
16571         local first_ost=0
16572         local last_ost=$(($OSTCOUNT - 1))
16573         local ost_step=2
16574         local ost_list=$(seq $first_ost $ost_step $last_ost)
16575         local ost_range="$first_ost $last_ost $ost_step"
16576         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16577         local file_dir=$POOL_ROOT/file_tst
16578         local subdir=$test_path/subdir
16579         local rc=0
16580
16581         while : ; do
16582                 # former test_200a test_200b
16583                 pool_add $POOL                          || { rc=$? ; break; }
16584                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16585                 # former test_200c test_200d
16586                 mkdir -p $test_path
16587                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16588                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16589                 mkdir -p $subdir
16590                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16591                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16592                                                         || { rc=$? ; break; }
16593                 # former test_200e test_200f
16594                 local files=$((OSTCOUNT*3))
16595                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16596                                                         || { rc=$? ; break; }
16597                 pool_create_files $POOL $file_dir $files "$ost_list" \
16598                                                         || { rc=$? ; break; }
16599                 # former test_200g test_200h
16600                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16601                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16602
16603                 # former test_201a test_201b test_201c
16604                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16605
16606                 local f=$test_path/$tfile
16607                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16608                 pool_remove $POOL $f                    || { rc=$? ; break; }
16609                 break
16610         done
16611
16612         destroy_test_pools
16613
16614         return $rc
16615 }
16616 run_test 200 "OST pools"
16617
16618 # usage: default_attr <count | size | offset>
16619 default_attr() {
16620         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16621 }
16622
16623 # usage: check_default_stripe_attr
16624 check_default_stripe_attr() {
16625         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16626         case $1 in
16627         --stripe-count|-c)
16628                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16629         --stripe-size|-S)
16630                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16631         --stripe-index|-i)
16632                 EXPECTED=-1;;
16633         *)
16634                 error "unknown getstripe attr '$1'"
16635         esac
16636
16637         [ $ACTUAL == $EXPECTED ] ||
16638                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16639 }
16640
16641 test_204a() {
16642         test_mkdir $DIR/$tdir
16643         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16644
16645         check_default_stripe_attr --stripe-count
16646         check_default_stripe_attr --stripe-size
16647         check_default_stripe_attr --stripe-index
16648 }
16649 run_test 204a "Print default stripe attributes"
16650
16651 test_204b() {
16652         test_mkdir $DIR/$tdir
16653         $LFS setstripe --stripe-count 1 $DIR/$tdir
16654
16655         check_default_stripe_attr --stripe-size
16656         check_default_stripe_attr --stripe-index
16657 }
16658 run_test 204b "Print default stripe size and offset"
16659
16660 test_204c() {
16661         test_mkdir $DIR/$tdir
16662         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16663
16664         check_default_stripe_attr --stripe-count
16665         check_default_stripe_attr --stripe-index
16666 }
16667 run_test 204c "Print default stripe count and offset"
16668
16669 test_204d() {
16670         test_mkdir $DIR/$tdir
16671         $LFS setstripe --stripe-index 0 $DIR/$tdir
16672
16673         check_default_stripe_attr --stripe-count
16674         check_default_stripe_attr --stripe-size
16675 }
16676 run_test 204d "Print default stripe count and size"
16677
16678 test_204e() {
16679         test_mkdir $DIR/$tdir
16680         $LFS setstripe -d $DIR/$tdir
16681
16682         check_default_stripe_attr --stripe-count --raw
16683         check_default_stripe_attr --stripe-size --raw
16684         check_default_stripe_attr --stripe-index --raw
16685 }
16686 run_test 204e "Print raw stripe attributes"
16687
16688 test_204f() {
16689         test_mkdir $DIR/$tdir
16690         $LFS setstripe --stripe-count 1 $DIR/$tdir
16691
16692         check_default_stripe_attr --stripe-size --raw
16693         check_default_stripe_attr --stripe-index --raw
16694 }
16695 run_test 204f "Print raw stripe size and offset"
16696
16697 test_204g() {
16698         test_mkdir $DIR/$tdir
16699         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16700
16701         check_default_stripe_attr --stripe-count --raw
16702         check_default_stripe_attr --stripe-index --raw
16703 }
16704 run_test 204g "Print raw stripe count and offset"
16705
16706 test_204h() {
16707         test_mkdir $DIR/$tdir
16708         $LFS setstripe --stripe-index 0 $DIR/$tdir
16709
16710         check_default_stripe_attr --stripe-count --raw
16711         check_default_stripe_attr --stripe-size --raw
16712 }
16713 run_test 204h "Print raw stripe count and size"
16714
16715 # Figure out which job scheduler is being used, if any,
16716 # or use a fake one
16717 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16718         JOBENV=SLURM_JOB_ID
16719 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16720         JOBENV=LSB_JOBID
16721 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16722         JOBENV=PBS_JOBID
16723 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16724         JOBENV=LOADL_STEP_ID
16725 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16726         JOBENV=JOB_ID
16727 else
16728         $LCTL list_param jobid_name > /dev/null 2>&1
16729         if [ $? -eq 0 ]; then
16730                 JOBENV=nodelocal
16731         else
16732                 JOBENV=FAKE_JOBID
16733         fi
16734 fi
16735 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16736
16737 verify_jobstats() {
16738         local cmd=($1)
16739         shift
16740         local facets="$@"
16741
16742 # we don't really need to clear the stats for this test to work, since each
16743 # command has a unique jobid, but it makes debugging easier if needed.
16744 #       for facet in $facets; do
16745 #               local dev=$(convert_facet2label $facet)
16746 #               # clear old jobstats
16747 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16748 #       done
16749
16750         # use a new JobID for each test, or we might see an old one
16751         [ "$JOBENV" = "FAKE_JOBID" ] &&
16752                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16753
16754         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16755
16756         [ "$JOBENV" = "nodelocal" ] && {
16757                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16758                 $LCTL set_param jobid_name=$FAKE_JOBID
16759                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16760         }
16761
16762         log "Test: ${cmd[*]}"
16763         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16764
16765         if [ $JOBENV = "FAKE_JOBID" ]; then
16766                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16767         else
16768                 ${cmd[*]}
16769         fi
16770
16771         # all files are created on OST0000
16772         for facet in $facets; do
16773                 local stats="*.$(convert_facet2label $facet).job_stats"
16774
16775                 # strip out libtool wrappers for in-tree executables
16776                 if [ $(do_facet $facet lctl get_param $stats |
16777                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16778                         do_facet $facet lctl get_param $stats
16779                         error "No jobstats for $JOBVAL found on $facet::$stats"
16780                 fi
16781         done
16782 }
16783
16784 jobstats_set() {
16785         local new_jobenv=$1
16786
16787         set_persistent_param_and_check client "jobid_var" \
16788                 "$FSNAME.sys.jobid_var" $new_jobenv
16789 }
16790
16791 test_205a() { # Job stats
16792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16793         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16794                 skip "Need MDS version with at least 2.7.1"
16795         remote_mgs_nodsh && skip "remote MGS with nodsh"
16796         remote_mds_nodsh && skip "remote MDS with nodsh"
16797         remote_ost_nodsh && skip "remote OST with nodsh"
16798         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16799                 skip "Server doesn't support jobstats"
16800         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16801
16802         local old_jobenv=$($LCTL get_param -n jobid_var)
16803         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16804
16805         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16806                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16807         else
16808                 stack_trap "do_facet mgs $PERM_CMD \
16809                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16810         fi
16811         changelog_register
16812
16813         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16814                                 mdt.*.job_cleanup_interval | head -n 1)
16815         local new_interval=5
16816         do_facet $SINGLEMDS \
16817                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16818         stack_trap "do_facet $SINGLEMDS \
16819                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16820         local start=$SECONDS
16821
16822         local cmd
16823         # mkdir
16824         cmd="mkdir $DIR/$tdir"
16825         verify_jobstats "$cmd" "$SINGLEMDS"
16826         # rmdir
16827         cmd="rmdir $DIR/$tdir"
16828         verify_jobstats "$cmd" "$SINGLEMDS"
16829         # mkdir on secondary MDT
16830         if [ $MDSCOUNT -gt 1 ]; then
16831                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16832                 verify_jobstats "$cmd" "mds2"
16833         fi
16834         # mknod
16835         cmd="mknod $DIR/$tfile c 1 3"
16836         verify_jobstats "$cmd" "$SINGLEMDS"
16837         # unlink
16838         cmd="rm -f $DIR/$tfile"
16839         verify_jobstats "$cmd" "$SINGLEMDS"
16840         # create all files on OST0000 so verify_jobstats can find OST stats
16841         # open & close
16842         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16843         verify_jobstats "$cmd" "$SINGLEMDS"
16844         # setattr
16845         cmd="touch $DIR/$tfile"
16846         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16847         # write
16848         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16849         verify_jobstats "$cmd" "ost1"
16850         # read
16851         cancel_lru_locks osc
16852         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16853         verify_jobstats "$cmd" "ost1"
16854         # truncate
16855         cmd="$TRUNCATE $DIR/$tfile 0"
16856         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16857         # rename
16858         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16859         verify_jobstats "$cmd" "$SINGLEMDS"
16860         # jobstats expiry - sleep until old stats should be expired
16861         local left=$((new_interval + 5 - (SECONDS - start)))
16862         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16863                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16864                         "0" $left
16865         cmd="mkdir $DIR/$tdir.expire"
16866         verify_jobstats "$cmd" "$SINGLEMDS"
16867         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16868             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16869
16870         # Ensure that jobid are present in changelog (if supported by MDS)
16871         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16872                 changelog_dump | tail -10
16873                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16874                 [ $jobids -eq 9 ] ||
16875                         error "Wrong changelog jobid count $jobids != 9"
16876
16877                 # LU-5862
16878                 JOBENV="disable"
16879                 jobstats_set $JOBENV
16880                 touch $DIR/$tfile
16881                 changelog_dump | grep $tfile
16882                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16883                 [ $jobids -eq 0 ] ||
16884                         error "Unexpected jobids when jobid_var=$JOBENV"
16885         fi
16886
16887         # test '%j' access to environment variable - if supported
16888         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16889                 JOBENV="JOBCOMPLEX"
16890                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16891
16892                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16893         fi
16894
16895         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
16896                 JOBENV="JOBCOMPLEX"
16897                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
16898
16899                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16900         fi
16901
16902         # test '%j' access to per-session jobid - if supported
16903         if lctl list_param jobid_this_session > /dev/null 2>&1
16904         then
16905                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16906                 lctl set_param jobid_this_session=$USER
16907
16908                 JOBENV="JOBCOMPLEX"
16909                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16910
16911                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16912         fi
16913 }
16914 run_test 205a "Verify job stats"
16915
16916 # LU-13117, LU-13597
16917 test_205b() {
16918         job_stats="mdt.*.job_stats"
16919         $LCTL set_param $job_stats=clear
16920         # Setting jobid_var to USER might not be supported
16921         $LCTL set_param jobid_var=USER || true
16922         $LCTL set_param jobid_name="%e.%u"
16923         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16924         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16925                 grep "job_id:.*foolish" &&
16926                         error "Unexpected jobid found"
16927         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16928                 grep "open:.*min.*max.*sum" ||
16929                         error "wrong job_stats format found"
16930 }
16931 run_test 205b "Verify job stats jobid and output format"
16932
16933 # LU-13733
16934 test_205c() {
16935         $LCTL set_param llite.*.stats=0
16936         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16937         $LCTL get_param llite.*.stats
16938         $LCTL get_param llite.*.stats | grep \
16939                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16940                         error "wrong client stats format found"
16941 }
16942 run_test 205c "Verify client stats format"
16943
16944 # LU-1480, LU-1773 and LU-1657
16945 test_206() {
16946         mkdir -p $DIR/$tdir
16947         $LFS setstripe -c -1 $DIR/$tdir
16948 #define OBD_FAIL_LOV_INIT 0x1403
16949         $LCTL set_param fail_loc=0xa0001403
16950         $LCTL set_param fail_val=1
16951         touch $DIR/$tdir/$tfile || true
16952 }
16953 run_test 206 "fail lov_init_raid0() doesn't lbug"
16954
16955 test_207a() {
16956         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16957         local fsz=`stat -c %s $DIR/$tfile`
16958         cancel_lru_locks mdc
16959
16960         # do not return layout in getattr intent
16961 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16962         $LCTL set_param fail_loc=0x170
16963         local sz=`stat -c %s $DIR/$tfile`
16964
16965         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16966
16967         rm -rf $DIR/$tfile
16968 }
16969 run_test 207a "can refresh layout at glimpse"
16970
16971 test_207b() {
16972         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16973         local cksum=`md5sum $DIR/$tfile`
16974         local fsz=`stat -c %s $DIR/$tfile`
16975         cancel_lru_locks mdc
16976         cancel_lru_locks osc
16977
16978         # do not return layout in getattr intent
16979 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16980         $LCTL set_param fail_loc=0x171
16981
16982         # it will refresh layout after the file is opened but before read issues
16983         echo checksum is "$cksum"
16984         echo "$cksum" |md5sum -c --quiet || error "file differs"
16985
16986         rm -rf $DIR/$tfile
16987 }
16988 run_test 207b "can refresh layout at open"
16989
16990 test_208() {
16991         # FIXME: in this test suite, only RD lease is used. This is okay
16992         # for now as only exclusive open is supported. After generic lease
16993         # is done, this test suite should be revised. - Jinshan
16994
16995         remote_mds_nodsh && skip "remote MDS with nodsh"
16996         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16997                 skip "Need MDS version at least 2.4.52"
16998
16999         echo "==== test 1: verify get lease work"
17000         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17001
17002         echo "==== test 2: verify lease can be broken by upcoming open"
17003         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17004         local PID=$!
17005         sleep 1
17006
17007         $MULTIOP $DIR/$tfile oO_RDONLY:c
17008         kill -USR1 $PID && wait $PID || error "break lease error"
17009
17010         echo "==== test 3: verify lease can't be granted if an open already exists"
17011         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17012         local PID=$!
17013         sleep 1
17014
17015         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17016         kill -USR1 $PID && wait $PID || error "open file error"
17017
17018         echo "==== test 4: lease can sustain over recovery"
17019         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17020         PID=$!
17021         sleep 1
17022
17023         fail mds1
17024
17025         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17026
17027         echo "==== test 5: lease broken can't be regained by replay"
17028         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17029         PID=$!
17030         sleep 1
17031
17032         # open file to break lease and then recovery
17033         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17034         fail mds1
17035
17036         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17037
17038         rm -f $DIR/$tfile
17039 }
17040 run_test 208 "Exclusive open"
17041
17042 test_209() {
17043         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17044                 skip_env "must have disp_stripe"
17045
17046         touch $DIR/$tfile
17047         sync; sleep 5; sync;
17048
17049         echo 3 > /proc/sys/vm/drop_caches
17050         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17051                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17052         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17053
17054         # open/close 500 times
17055         for i in $(seq 500); do
17056                 cat $DIR/$tfile
17057         done
17058
17059         echo 3 > /proc/sys/vm/drop_caches
17060         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17061                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17062         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17063
17064         echo "before: $req_before, after: $req_after"
17065         [ $((req_after - req_before)) -ge 300 ] &&
17066                 error "open/close requests are not freed"
17067         return 0
17068 }
17069 run_test 209 "read-only open/close requests should be freed promptly"
17070
17071 test_210() {
17072         local pid
17073
17074         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17075         pid=$!
17076         sleep 1
17077
17078         $LFS getstripe $DIR/$tfile
17079         kill -USR1 $pid
17080         wait $pid || error "multiop failed"
17081
17082         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17083         pid=$!
17084         sleep 1
17085
17086         $LFS getstripe $DIR/$tfile
17087         kill -USR1 $pid
17088         wait $pid || error "multiop failed"
17089 }
17090 run_test 210 "lfs getstripe does not break leases"
17091
17092 test_212() {
17093         size=`date +%s`
17094         size=$((size % 8192 + 1))
17095         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17096         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17097         rm -f $DIR/f212 $DIR/f212.xyz
17098 }
17099 run_test 212 "Sendfile test ============================================"
17100
17101 test_213() {
17102         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17103         cancel_lru_locks osc
17104         lctl set_param fail_loc=0x8000040f
17105         # generate a read lock
17106         cat $DIR/$tfile > /dev/null
17107         # write to the file, it will try to cancel the above read lock.
17108         cat /etc/hosts >> $DIR/$tfile
17109 }
17110 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17111
17112 test_214() { # for bug 20133
17113         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17114         for (( i=0; i < 340; i++ )) ; do
17115                 touch $DIR/$tdir/d214c/a$i
17116         done
17117
17118         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17119         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17120         ls $DIR/d214c || error "ls $DIR/d214c failed"
17121         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17122         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17123 }
17124 run_test 214 "hash-indexed directory test - bug 20133"
17125
17126 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17127 create_lnet_proc_files() {
17128         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17129 }
17130
17131 # counterpart of create_lnet_proc_files
17132 remove_lnet_proc_files() {
17133         rm -f $TMP/lnet_$1.sys
17134 }
17135
17136 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17137 # 3rd arg as regexp for body
17138 check_lnet_proc_stats() {
17139         local l=$(cat "$TMP/lnet_$1" |wc -l)
17140         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17141
17142         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17143 }
17144
17145 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17146 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17147 # optional and can be regexp for 2nd line (lnet.routes case)
17148 check_lnet_proc_entry() {
17149         local blp=2          # blp stands for 'position of 1st line of body'
17150         [ -z "$5" ] || blp=3 # lnet.routes case
17151
17152         local l=$(cat "$TMP/lnet_$1" |wc -l)
17153         # subtracting one from $blp because the body can be empty
17154         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17155
17156         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17157                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17158
17159         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17160                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17161
17162         # bail out if any unexpected line happened
17163         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17164         [ "$?" != 0 ] || error "$2 misformatted"
17165 }
17166
17167 test_215() { # for bugs 18102, 21079, 21517
17168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17169
17170         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17171         local P='[1-9][0-9]*'           # positive numeric
17172         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17173         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17174         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17175         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17176
17177         local L1 # regexp for 1st line
17178         local L2 # regexp for 2nd line (optional)
17179         local BR # regexp for the rest (body)
17180
17181         # lnet.stats should look as 11 space-separated non-negative numerics
17182         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17183         create_lnet_proc_files "stats"
17184         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17185         remove_lnet_proc_files "stats"
17186
17187         # lnet.routes should look like this:
17188         # Routing disabled/enabled
17189         # net hops priority state router
17190         # where net is a string like tcp0, hops > 0, priority >= 0,
17191         # state is up/down,
17192         # router is a string like 192.168.1.1@tcp2
17193         L1="^Routing (disabled|enabled)$"
17194         L2="^net +hops +priority +state +router$"
17195         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17196         create_lnet_proc_files "routes"
17197         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17198         remove_lnet_proc_files "routes"
17199
17200         # lnet.routers should look like this:
17201         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17202         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17203         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17204         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17205         L1="^ref +rtr_ref +alive +router$"
17206         BR="^$P +$P +(up|down) +$NID$"
17207         create_lnet_proc_files "routers"
17208         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17209         remove_lnet_proc_files "routers"
17210
17211         # lnet.peers should look like this:
17212         # nid refs state last max rtr min tx min queue
17213         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17214         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17215         # numeric (0 or >0 or <0), queue >= 0.
17216         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17217         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17218         create_lnet_proc_files "peers"
17219         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17220         remove_lnet_proc_files "peers"
17221
17222         # lnet.buffers  should look like this:
17223         # pages count credits min
17224         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17225         L1="^pages +count +credits +min$"
17226         BR="^ +$N +$N +$I +$I$"
17227         create_lnet_proc_files "buffers"
17228         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17229         remove_lnet_proc_files "buffers"
17230
17231         # lnet.nis should look like this:
17232         # nid status alive refs peer rtr max tx min
17233         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17234         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17235         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17236         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17237         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17238         create_lnet_proc_files "nis"
17239         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17240         remove_lnet_proc_files "nis"
17241
17242         # can we successfully write to lnet.stats?
17243         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17244 }
17245 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17246
17247 test_216() { # bug 20317
17248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17249         remote_ost_nodsh && skip "remote OST with nodsh"
17250
17251         local node
17252         local facets=$(get_facets OST)
17253         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17254
17255         save_lustre_params client "osc.*.contention_seconds" > $p
17256         save_lustre_params $facets \
17257                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17258         save_lustre_params $facets \
17259                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17260         save_lustre_params $facets \
17261                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17262         clear_stats osc.*.osc_stats
17263
17264         # agressive lockless i/o settings
17265         do_nodes $(comma_list $(osts_nodes)) \
17266                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17267                         ldlm.namespaces.filter-*.contended_locks=0 \
17268                         ldlm.namespaces.filter-*.contention_seconds=60"
17269         lctl set_param -n osc.*.contention_seconds=60
17270
17271         $DIRECTIO write $DIR/$tfile 0 10 4096
17272         $CHECKSTAT -s 40960 $DIR/$tfile
17273
17274         # disable lockless i/o
17275         do_nodes $(comma_list $(osts_nodes)) \
17276                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17277                         ldlm.namespaces.filter-*.contended_locks=32 \
17278                         ldlm.namespaces.filter-*.contention_seconds=0"
17279         lctl set_param -n osc.*.contention_seconds=0
17280         clear_stats osc.*.osc_stats
17281
17282         dd if=/dev/zero of=$DIR/$tfile count=0
17283         $CHECKSTAT -s 0 $DIR/$tfile
17284
17285         restore_lustre_params <$p
17286         rm -f $p
17287         rm $DIR/$tfile
17288 }
17289 run_test 216 "check lockless direct write updates file size and kms correctly"
17290
17291 test_217() { # bug 22430
17292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17293
17294         local node
17295         local nid
17296
17297         for node in $(nodes_list); do
17298                 nid=$(host_nids_address $node $NETTYPE)
17299                 if [[ $nid = *-* ]] ; then
17300                         echo "lctl ping $(h2nettype $nid)"
17301                         lctl ping $(h2nettype $nid)
17302                 else
17303                         echo "skipping $node (no hyphen detected)"
17304                 fi
17305         done
17306 }
17307 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17308
17309 test_218() {
17310        # do directio so as not to populate the page cache
17311        log "creating a 10 Mb file"
17312        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17313        log "starting reads"
17314        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17315        log "truncating the file"
17316        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17317        log "killing dd"
17318        kill %+ || true # reads might have finished
17319        echo "wait until dd is finished"
17320        wait
17321        log "removing the temporary file"
17322        rm -rf $DIR/$tfile || error "tmp file removal failed"
17323 }
17324 run_test 218 "parallel read and truncate should not deadlock"
17325
17326 test_219() {
17327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17328
17329         # write one partial page
17330         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17331         # set no grant so vvp_io_commit_write will do sync write
17332         $LCTL set_param fail_loc=0x411
17333         # write a full page at the end of file
17334         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17335
17336         $LCTL set_param fail_loc=0
17337         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17338         $LCTL set_param fail_loc=0x411
17339         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17340
17341         # LU-4201
17342         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17343         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17344 }
17345 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17346
17347 test_220() { #LU-325
17348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17349         remote_ost_nodsh && skip "remote OST with nodsh"
17350         remote_mds_nodsh && skip "remote MDS with nodsh"
17351         remote_mgs_nodsh && skip "remote MGS with nodsh"
17352
17353         local OSTIDX=0
17354
17355         # create on MDT0000 so the last_id and next_id are correct
17356         mkdir $DIR/$tdir
17357         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17358         OST=${OST%_UUID}
17359
17360         # on the mdt's osc
17361         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17362         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17363                         osp.$mdtosc_proc1.prealloc_last_id)
17364         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17365                         osp.$mdtosc_proc1.prealloc_next_id)
17366
17367         $LFS df -i
17368
17369         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17370         #define OBD_FAIL_OST_ENOINO              0x229
17371         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17372         create_pool $FSNAME.$TESTNAME || return 1
17373         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17374
17375         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17376
17377         MDSOBJS=$((last_id - next_id))
17378         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17379
17380         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17381         echo "OST still has $count kbytes free"
17382
17383         echo "create $MDSOBJS files @next_id..."
17384         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17385
17386         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17387                         osp.$mdtosc_proc1.prealloc_last_id)
17388         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17389                         osp.$mdtosc_proc1.prealloc_next_id)
17390
17391         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17392         $LFS df -i
17393
17394         echo "cleanup..."
17395
17396         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17397         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17398
17399         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17400                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17401         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17402                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17403         echo "unlink $MDSOBJS files @$next_id..."
17404         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17405 }
17406 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17407
17408 test_221() {
17409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17410
17411         dd if=`which date` of=$MOUNT/date oflag=sync
17412         chmod +x $MOUNT/date
17413
17414         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17415         $LCTL set_param fail_loc=0x80001401
17416
17417         $MOUNT/date > /dev/null
17418         rm -f $MOUNT/date
17419 }
17420 run_test 221 "make sure fault and truncate race to not cause OOM"
17421
17422 test_222a () {
17423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17424
17425         rm -rf $DIR/$tdir
17426         test_mkdir $DIR/$tdir
17427         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17428         createmany -o $DIR/$tdir/$tfile 10
17429         cancel_lru_locks mdc
17430         cancel_lru_locks osc
17431         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17432         $LCTL set_param fail_loc=0x31a
17433         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17434         $LCTL set_param fail_loc=0
17435         rm -r $DIR/$tdir
17436 }
17437 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17438
17439 test_222b () {
17440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17441
17442         rm -rf $DIR/$tdir
17443         test_mkdir $DIR/$tdir
17444         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17445         createmany -o $DIR/$tdir/$tfile 10
17446         cancel_lru_locks mdc
17447         cancel_lru_locks osc
17448         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17449         $LCTL set_param fail_loc=0x31a
17450         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17451         $LCTL set_param fail_loc=0
17452 }
17453 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17454
17455 test_223 () {
17456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17457
17458         rm -rf $DIR/$tdir
17459         test_mkdir $DIR/$tdir
17460         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17461         createmany -o $DIR/$tdir/$tfile 10
17462         cancel_lru_locks mdc
17463         cancel_lru_locks osc
17464         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17465         $LCTL set_param fail_loc=0x31b
17466         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17467         $LCTL set_param fail_loc=0
17468         rm -r $DIR/$tdir
17469 }
17470 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17471
17472 test_224a() { # LU-1039, MRP-303
17473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17474
17475         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17476         $LCTL set_param fail_loc=0x508
17477         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17478         $LCTL set_param fail_loc=0
17479         df $DIR
17480 }
17481 run_test 224a "Don't panic on bulk IO failure"
17482
17483 test_224b() { # LU-1039, MRP-303
17484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17485
17486         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17487         cancel_lru_locks osc
17488         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17489         $LCTL set_param fail_loc=0x515
17490         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17491         $LCTL set_param fail_loc=0
17492         df $DIR
17493 }
17494 run_test 224b "Don't panic on bulk IO failure"
17495
17496 test_224c() { # LU-6441
17497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17498         remote_mds_nodsh && skip "remote MDS with nodsh"
17499
17500         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17501         save_writethrough $p
17502         set_cache writethrough on
17503
17504         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17505         local at_max=$($LCTL get_param -n at_max)
17506         local timeout=$($LCTL get_param -n timeout)
17507         local test_at="at_max"
17508         local param_at="$FSNAME.sys.at_max"
17509         local test_timeout="timeout"
17510         local param_timeout="$FSNAME.sys.timeout"
17511
17512         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17513
17514         set_persistent_param_and_check client "$test_at" "$param_at" 0
17515         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17516
17517         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17518         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17519         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17520         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17521         sync
17522         do_facet ost1 "$LCTL set_param fail_loc=0"
17523
17524         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17525         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17526                 $timeout
17527
17528         $LCTL set_param -n $pages_per_rpc
17529         restore_lustre_params < $p
17530         rm -f $p
17531 }
17532 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17533
17534 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17535 test_225a () {
17536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17537         if [ -z ${MDSSURVEY} ]; then
17538                 skip_env "mds-survey not found"
17539         fi
17540         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17541                 skip "Need MDS version at least 2.2.51"
17542
17543         local mds=$(facet_host $SINGLEMDS)
17544         local target=$(do_nodes $mds 'lctl dl' |
17545                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17546
17547         local cmd1="file_count=1000 thrhi=4"
17548         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17549         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17550         local cmd="$cmd1 $cmd2 $cmd3"
17551
17552         rm -f ${TMP}/mds_survey*
17553         echo + $cmd
17554         eval $cmd || error "mds-survey with zero-stripe failed"
17555         cat ${TMP}/mds_survey*
17556         rm -f ${TMP}/mds_survey*
17557 }
17558 run_test 225a "Metadata survey sanity with zero-stripe"
17559
17560 test_225b () {
17561         if [ -z ${MDSSURVEY} ]; then
17562                 skip_env "mds-survey not found"
17563         fi
17564         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17565                 skip "Need MDS version at least 2.2.51"
17566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17567         remote_mds_nodsh && skip "remote MDS with nodsh"
17568         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17569                 skip_env "Need to mount OST to test"
17570         fi
17571
17572         local mds=$(facet_host $SINGLEMDS)
17573         local target=$(do_nodes $mds 'lctl dl' |
17574                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17575
17576         local cmd1="file_count=1000 thrhi=4"
17577         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17578         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17579         local cmd="$cmd1 $cmd2 $cmd3"
17580
17581         rm -f ${TMP}/mds_survey*
17582         echo + $cmd
17583         eval $cmd || error "mds-survey with stripe_count failed"
17584         cat ${TMP}/mds_survey*
17585         rm -f ${TMP}/mds_survey*
17586 }
17587 run_test 225b "Metadata survey sanity with stripe_count = 1"
17588
17589 mcreate_path2fid () {
17590         local mode=$1
17591         local major=$2
17592         local minor=$3
17593         local name=$4
17594         local desc=$5
17595         local path=$DIR/$tdir/$name
17596         local fid
17597         local rc
17598         local fid_path
17599
17600         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17601                 error "cannot create $desc"
17602
17603         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17604         rc=$?
17605         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17606
17607         fid_path=$($LFS fid2path $MOUNT $fid)
17608         rc=$?
17609         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17610
17611         [ "$path" == "$fid_path" ] ||
17612                 error "fid2path returned $fid_path, expected $path"
17613
17614         echo "pass with $path and $fid"
17615 }
17616
17617 test_226a () {
17618         rm -rf $DIR/$tdir
17619         mkdir -p $DIR/$tdir
17620
17621         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17622         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17623         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17624         mcreate_path2fid 0040666 0 0 dir "directory"
17625         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17626         mcreate_path2fid 0100666 0 0 file "regular file"
17627         mcreate_path2fid 0120666 0 0 link "symbolic link"
17628         mcreate_path2fid 0140666 0 0 sock "socket"
17629 }
17630 run_test 226a "call path2fid and fid2path on files of all type"
17631
17632 test_226b () {
17633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17634
17635         local MDTIDX=1
17636
17637         rm -rf $DIR/$tdir
17638         mkdir -p $DIR/$tdir
17639         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17640                 error "create remote directory failed"
17641         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17642         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17643                                 "character special file (null)"
17644         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17645                                 "character special file (no device)"
17646         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17647         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17648                                 "block special file (loop)"
17649         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17650         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17651         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17652 }
17653 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17654
17655 test_226c () {
17656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17657         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17658                 skip "Need MDS version at least 2.13.55"
17659
17660         local submnt=/mnt/submnt
17661         local srcfile=/etc/passwd
17662         local dstfile=$submnt/passwd
17663         local path
17664         local fid
17665
17666         rm -rf $DIR/$tdir
17667         rm -rf $submnt
17668         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17669                 error "create remote directory failed"
17670         mkdir -p $submnt || error "create $submnt failed"
17671         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17672                 error "mount $submnt failed"
17673         stack_trap "umount $submnt" EXIT
17674
17675         cp $srcfile $dstfile
17676         fid=$($LFS path2fid $dstfile)
17677         path=$($LFS fid2path $submnt "$fid")
17678         [ "$path" = "$dstfile" ] ||
17679                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17680 }
17681 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17682
17683 # LU-1299 Executing or running ldd on a truncated executable does not
17684 # cause an out-of-memory condition.
17685 test_227() {
17686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17687         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17688
17689         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17690         chmod +x $MOUNT/date
17691
17692         $MOUNT/date > /dev/null
17693         ldd $MOUNT/date > /dev/null
17694         rm -f $MOUNT/date
17695 }
17696 run_test 227 "running truncated executable does not cause OOM"
17697
17698 # LU-1512 try to reuse idle OI blocks
17699 test_228a() {
17700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17701         remote_mds_nodsh && skip "remote MDS with nodsh"
17702         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17703
17704         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17705         local myDIR=$DIR/$tdir
17706
17707         mkdir -p $myDIR
17708         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17709         $LCTL set_param fail_loc=0x80001002
17710         createmany -o $myDIR/t- 10000
17711         $LCTL set_param fail_loc=0
17712         # The guard is current the largest FID holder
17713         touch $myDIR/guard
17714         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17715                     tr -d '[')
17716         local IDX=$(($SEQ % 64))
17717
17718         do_facet $SINGLEMDS sync
17719         # Make sure journal flushed.
17720         sleep 6
17721         local blk1=$(do_facet $SINGLEMDS \
17722                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17723                      grep Blockcount | awk '{print $4}')
17724
17725         # Remove old files, some OI blocks will become idle.
17726         unlinkmany $myDIR/t- 10000
17727         # Create new files, idle OI blocks should be reused.
17728         createmany -o $myDIR/t- 2000
17729         do_facet $SINGLEMDS sync
17730         # Make sure journal flushed.
17731         sleep 6
17732         local blk2=$(do_facet $SINGLEMDS \
17733                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17734                      grep Blockcount | awk '{print $4}')
17735
17736         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17737 }
17738 run_test 228a "try to reuse idle OI blocks"
17739
17740 test_228b() {
17741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17742         remote_mds_nodsh && skip "remote MDS with nodsh"
17743         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17744
17745         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17746         local myDIR=$DIR/$tdir
17747
17748         mkdir -p $myDIR
17749         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17750         $LCTL set_param fail_loc=0x80001002
17751         createmany -o $myDIR/t- 10000
17752         $LCTL set_param fail_loc=0
17753         # The guard is current the largest FID holder
17754         touch $myDIR/guard
17755         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17756                     tr -d '[')
17757         local IDX=$(($SEQ % 64))
17758
17759         do_facet $SINGLEMDS sync
17760         # Make sure journal flushed.
17761         sleep 6
17762         local blk1=$(do_facet $SINGLEMDS \
17763                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17764                      grep Blockcount | awk '{print $4}')
17765
17766         # Remove old files, some OI blocks will become idle.
17767         unlinkmany $myDIR/t- 10000
17768
17769         # stop the MDT
17770         stop $SINGLEMDS || error "Fail to stop MDT."
17771         # remount the MDT
17772         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17773
17774         df $MOUNT || error "Fail to df."
17775         # Create new files, idle OI blocks should be reused.
17776         createmany -o $myDIR/t- 2000
17777         do_facet $SINGLEMDS sync
17778         # Make sure journal flushed.
17779         sleep 6
17780         local blk2=$(do_facet $SINGLEMDS \
17781                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17782                      grep Blockcount | awk '{print $4}')
17783
17784         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17785 }
17786 run_test 228b "idle OI blocks can be reused after MDT restart"
17787
17788 #LU-1881
17789 test_228c() {
17790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17791         remote_mds_nodsh && skip "remote MDS with nodsh"
17792         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17793
17794         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17795         local myDIR=$DIR/$tdir
17796
17797         mkdir -p $myDIR
17798         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17799         $LCTL set_param fail_loc=0x80001002
17800         # 20000 files can guarantee there are index nodes in the OI file
17801         createmany -o $myDIR/t- 20000
17802         $LCTL set_param fail_loc=0
17803         # The guard is current the largest FID holder
17804         touch $myDIR/guard
17805         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17806                     tr -d '[')
17807         local IDX=$(($SEQ % 64))
17808
17809         do_facet $SINGLEMDS sync
17810         # Make sure journal flushed.
17811         sleep 6
17812         local blk1=$(do_facet $SINGLEMDS \
17813                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17814                      grep Blockcount | awk '{print $4}')
17815
17816         # Remove old files, some OI blocks will become idle.
17817         unlinkmany $myDIR/t- 20000
17818         rm -f $myDIR/guard
17819         # The OI file should become empty now
17820
17821         # Create new files, idle OI blocks should be reused.
17822         createmany -o $myDIR/t- 2000
17823         do_facet $SINGLEMDS sync
17824         # Make sure journal flushed.
17825         sleep 6
17826         local blk2=$(do_facet $SINGLEMDS \
17827                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17828                      grep Blockcount | awk '{print $4}')
17829
17830         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17831 }
17832 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17833
17834 test_229() { # LU-2482, LU-3448
17835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17836         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17837         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17838                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17839
17840         rm -f $DIR/$tfile
17841
17842         # Create a file with a released layout and stripe count 2.
17843         $MULTIOP $DIR/$tfile H2c ||
17844                 error "failed to create file with released layout"
17845
17846         $LFS getstripe -v $DIR/$tfile
17847
17848         local pattern=$($LFS getstripe -L $DIR/$tfile)
17849         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17850
17851         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17852                 error "getstripe"
17853         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17854         stat $DIR/$tfile || error "failed to stat released file"
17855
17856         chown $RUNAS_ID $DIR/$tfile ||
17857                 error "chown $RUNAS_ID $DIR/$tfile failed"
17858
17859         chgrp $RUNAS_ID $DIR/$tfile ||
17860                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17861
17862         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17863         rm $DIR/$tfile || error "failed to remove released file"
17864 }
17865 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17866
17867 test_230a() {
17868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17870         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17871                 skip "Need MDS version at least 2.11.52"
17872
17873         local MDTIDX=1
17874
17875         test_mkdir $DIR/$tdir
17876         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17877         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17878         [ $mdt_idx -ne 0 ] &&
17879                 error "create local directory on wrong MDT $mdt_idx"
17880
17881         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17882                         error "create remote directory failed"
17883         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17884         [ $mdt_idx -ne $MDTIDX ] &&
17885                 error "create remote directory on wrong MDT $mdt_idx"
17886
17887         createmany -o $DIR/$tdir/test_230/t- 10 ||
17888                 error "create files on remote directory failed"
17889         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17890         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17891         rm -r $DIR/$tdir || error "unlink remote directory failed"
17892 }
17893 run_test 230a "Create remote directory and files under the remote directory"
17894
17895 test_230b() {
17896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17897         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17898         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17899                 skip "Need MDS version at least 2.11.52"
17900
17901         local MDTIDX=1
17902         local mdt_index
17903         local i
17904         local file
17905         local pid
17906         local stripe_count
17907         local migrate_dir=$DIR/$tdir/migrate_dir
17908         local other_dir=$DIR/$tdir/other_dir
17909
17910         test_mkdir $DIR/$tdir
17911         test_mkdir -i0 -c1 $migrate_dir
17912         test_mkdir -i0 -c1 $other_dir
17913         for ((i=0; i<10; i++)); do
17914                 mkdir -p $migrate_dir/dir_${i}
17915                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17916                         error "create files under remote dir failed $i"
17917         done
17918
17919         cp /etc/passwd $migrate_dir/$tfile
17920         cp /etc/passwd $other_dir/$tfile
17921         chattr +SAD $migrate_dir
17922         chattr +SAD $migrate_dir/$tfile
17923
17924         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17925         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17926         local old_dir_mode=$(stat -c%f $migrate_dir)
17927         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17928
17929         mkdir -p $migrate_dir/dir_default_stripe2
17930         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17931         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17932
17933         mkdir -p $other_dir
17934         ln $migrate_dir/$tfile $other_dir/luna
17935         ln $migrate_dir/$tfile $migrate_dir/sofia
17936         ln $other_dir/$tfile $migrate_dir/david
17937         ln -s $migrate_dir/$tfile $other_dir/zachary
17938         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17939         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17940
17941         local len
17942         local lnktgt
17943
17944         # inline symlink
17945         for len in 58 59 60; do
17946                 lnktgt=$(str_repeat 'l' $len)
17947                 touch $migrate_dir/$lnktgt
17948                 ln -s $lnktgt $migrate_dir/${len}char_ln
17949         done
17950
17951         # PATH_MAX
17952         for len in 4094 4095; do
17953                 lnktgt=$(str_repeat 'l' $len)
17954                 ln -s $lnktgt $migrate_dir/${len}char_ln
17955         done
17956
17957         # NAME_MAX
17958         for len in 254 255; do
17959                 touch $migrate_dir/$(str_repeat 'l' $len)
17960         done
17961
17962         $LFS migrate -m $MDTIDX $migrate_dir ||
17963                 error "fails on migrating remote dir to MDT1"
17964
17965         echo "migratate to MDT1, then checking.."
17966         for ((i = 0; i < 10; i++)); do
17967                 for file in $(find $migrate_dir/dir_${i}); do
17968                         mdt_index=$($LFS getstripe -m $file)
17969                         # broken symlink getstripe will fail
17970                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17971                                 error "$file is not on MDT${MDTIDX}"
17972                 done
17973         done
17974
17975         # the multiple link file should still in MDT0
17976         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17977         [ $mdt_index == 0 ] ||
17978                 error "$file is not on MDT${MDTIDX}"
17979
17980         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17981         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17982                 error " expect $old_dir_flag get $new_dir_flag"
17983
17984         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17985         [ "$old_file_flag" = "$new_file_flag" ] ||
17986                 error " expect $old_file_flag get $new_file_flag"
17987
17988         local new_dir_mode=$(stat -c%f $migrate_dir)
17989         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17990                 error "expect mode $old_dir_mode get $new_dir_mode"
17991
17992         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17993         [ "$old_file_mode" = "$new_file_mode" ] ||
17994                 error "expect mode $old_file_mode get $new_file_mode"
17995
17996         diff /etc/passwd $migrate_dir/$tfile ||
17997                 error "$tfile different after migration"
17998
17999         diff /etc/passwd $other_dir/luna ||
18000                 error "luna different after migration"
18001
18002         diff /etc/passwd $migrate_dir/sofia ||
18003                 error "sofia different after migration"
18004
18005         diff /etc/passwd $migrate_dir/david ||
18006                 error "david different after migration"
18007
18008         diff /etc/passwd $other_dir/zachary ||
18009                 error "zachary different after migration"
18010
18011         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18012                 error "${tfile}_ln different after migration"
18013
18014         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18015                 error "${tfile}_ln_other different after migration"
18016
18017         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18018         [ $stripe_count = 2 ] ||
18019                 error "dir strpe_count $d != 2 after migration."
18020
18021         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18022         [ $stripe_count = 2 ] ||
18023                 error "file strpe_count $d != 2 after migration."
18024
18025         #migrate back to MDT0
18026         MDTIDX=0
18027
18028         $LFS migrate -m $MDTIDX $migrate_dir ||
18029                 error "fails on migrating remote dir to MDT0"
18030
18031         echo "migrate back to MDT0, checking.."
18032         for file in $(find $migrate_dir); do
18033                 mdt_index=$($LFS getstripe -m $file)
18034                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18035                         error "$file is not on MDT${MDTIDX}"
18036         done
18037
18038         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18039         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18040                 error " expect $old_dir_flag get $new_dir_flag"
18041
18042         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18043         [ "$old_file_flag" = "$new_file_flag" ] ||
18044                 error " expect $old_file_flag get $new_file_flag"
18045
18046         local new_dir_mode=$(stat -c%f $migrate_dir)
18047         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18048                 error "expect mode $old_dir_mode get $new_dir_mode"
18049
18050         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18051         [ "$old_file_mode" = "$new_file_mode" ] ||
18052                 error "expect mode $old_file_mode get $new_file_mode"
18053
18054         diff /etc/passwd ${migrate_dir}/$tfile ||
18055                 error "$tfile different after migration"
18056
18057         diff /etc/passwd ${other_dir}/luna ||
18058                 error "luna different after migration"
18059
18060         diff /etc/passwd ${migrate_dir}/sofia ||
18061                 error "sofia different after migration"
18062
18063         diff /etc/passwd ${other_dir}/zachary ||
18064                 error "zachary different after migration"
18065
18066         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18067                 error "${tfile}_ln different after migration"
18068
18069         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18070                 error "${tfile}_ln_other different after migration"
18071
18072         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18073         [ $stripe_count = 2 ] ||
18074                 error "dir strpe_count $d != 2 after migration."
18075
18076         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18077         [ $stripe_count = 2 ] ||
18078                 error "file strpe_count $d != 2 after migration."
18079
18080         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18081 }
18082 run_test 230b "migrate directory"
18083
18084 test_230c() {
18085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18086         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18087         remote_mds_nodsh && skip "remote MDS with nodsh"
18088         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18089                 skip "Need MDS version at least 2.11.52"
18090
18091         local MDTIDX=1
18092         local total=3
18093         local mdt_index
18094         local file
18095         local migrate_dir=$DIR/$tdir/migrate_dir
18096
18097         #If migrating directory fails in the middle, all entries of
18098         #the directory is still accessiable.
18099         test_mkdir $DIR/$tdir
18100         test_mkdir -i0 -c1 $migrate_dir
18101         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18102         stat $migrate_dir
18103         createmany -o $migrate_dir/f $total ||
18104                 error "create files under ${migrate_dir} failed"
18105
18106         # fail after migrating top dir, and this will fail only once, so the
18107         # first sub file migration will fail (currently f3), others succeed.
18108         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18109         do_facet mds1 lctl set_param fail_loc=0x1801
18110         local t=$(ls $migrate_dir | wc -l)
18111         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18112                 error "migrate should fail"
18113         local u=$(ls $migrate_dir | wc -l)
18114         [ "$u" == "$t" ] || error "$u != $t during migration"
18115
18116         # add new dir/file should succeed
18117         mkdir $migrate_dir/dir ||
18118                 error "mkdir failed under migrating directory"
18119         touch $migrate_dir/file ||
18120                 error "create file failed under migrating directory"
18121
18122         # add file with existing name should fail
18123         for file in $migrate_dir/f*; do
18124                 stat $file > /dev/null || error "stat $file failed"
18125                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18126                         error "open(O_CREAT|O_EXCL) $file should fail"
18127                 $MULTIOP $file m && error "create $file should fail"
18128                 touch $DIR/$tdir/remote_dir/$tfile ||
18129                         error "touch $tfile failed"
18130                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18131                         error "link $file should fail"
18132                 mdt_index=$($LFS getstripe -m $file)
18133                 if [ $mdt_index == 0 ]; then
18134                         # file failed to migrate is not allowed to rename to
18135                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18136                                 error "rename to $file should fail"
18137                 else
18138                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18139                                 error "rename to $file failed"
18140                 fi
18141                 echo hello >> $file || error "write $file failed"
18142         done
18143
18144         # resume migration with different options should fail
18145         $LFS migrate -m 0 $migrate_dir &&
18146                 error "migrate -m 0 $migrate_dir should fail"
18147
18148         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18149                 error "migrate -c 2 $migrate_dir should fail"
18150
18151         # resume migration should succeed
18152         $LFS migrate -m $MDTIDX $migrate_dir ||
18153                 error "migrate $migrate_dir failed"
18154
18155         echo "Finish migration, then checking.."
18156         for file in $(find $migrate_dir); do
18157                 mdt_index=$($LFS getstripe -m $file)
18158                 [ $mdt_index == $MDTIDX ] ||
18159                         error "$file is not on MDT${MDTIDX}"
18160         done
18161
18162         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18163 }
18164 run_test 230c "check directory accessiblity if migration failed"
18165
18166 test_230d() {
18167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18168         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18169         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18170                 skip "Need MDS version at least 2.11.52"
18171         # LU-11235
18172         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18173
18174         local migrate_dir=$DIR/$tdir/migrate_dir
18175         local old_index
18176         local new_index
18177         local old_count
18178         local new_count
18179         local new_hash
18180         local mdt_index
18181         local i
18182         local j
18183
18184         old_index=$((RANDOM % MDSCOUNT))
18185         old_count=$((MDSCOUNT - old_index))
18186         new_index=$((RANDOM % MDSCOUNT))
18187         new_count=$((MDSCOUNT - new_index))
18188         new_hash=1 # for all_char
18189
18190         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18191         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18192
18193         test_mkdir $DIR/$tdir
18194         test_mkdir -i $old_index -c $old_count $migrate_dir
18195
18196         for ((i=0; i<100; i++)); do
18197                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18198                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18199                         error "create files under remote dir failed $i"
18200         done
18201
18202         echo -n "Migrate from MDT$old_index "
18203         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18204         echo -n "to MDT$new_index"
18205         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18206         echo
18207
18208         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18209         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18210                 error "migrate remote dir error"
18211
18212         echo "Finish migration, then checking.."
18213         for file in $(find $migrate_dir); do
18214                 mdt_index=$($LFS getstripe -m $file)
18215                 if [ $mdt_index -lt $new_index ] ||
18216                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18217                         error "$file is on MDT$mdt_index"
18218                 fi
18219         done
18220
18221         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18222 }
18223 run_test 230d "check migrate big directory"
18224
18225 test_230e() {
18226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18227         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18228         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18229                 skip "Need MDS version at least 2.11.52"
18230
18231         local i
18232         local j
18233         local a_fid
18234         local b_fid
18235
18236         mkdir -p $DIR/$tdir
18237         mkdir $DIR/$tdir/migrate_dir
18238         mkdir $DIR/$tdir/other_dir
18239         touch $DIR/$tdir/migrate_dir/a
18240         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18241         ls $DIR/$tdir/other_dir
18242
18243         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18244                 error "migrate dir fails"
18245
18246         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18247         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18248
18249         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18250         [ $mdt_index == 0 ] || error "a is not on MDT0"
18251
18252         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18253                 error "migrate dir fails"
18254
18255         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18256         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18257
18258         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18259         [ $mdt_index == 1 ] || error "a is not on MDT1"
18260
18261         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18262         [ $mdt_index == 1 ] || error "b is not on MDT1"
18263
18264         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18265         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18266
18267         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18268
18269         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18270 }
18271 run_test 230e "migrate mulitple local link files"
18272
18273 test_230f() {
18274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18276         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18277                 skip "Need MDS version at least 2.11.52"
18278
18279         local a_fid
18280         local ln_fid
18281
18282         mkdir -p $DIR/$tdir
18283         mkdir $DIR/$tdir/migrate_dir
18284         $LFS mkdir -i1 $DIR/$tdir/other_dir
18285         touch $DIR/$tdir/migrate_dir/a
18286         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18287         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18288         ls $DIR/$tdir/other_dir
18289
18290         # a should be migrated to MDT1, since no other links on MDT0
18291         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18292                 error "#1 migrate dir fails"
18293         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18294         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18295         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18296         [ $mdt_index == 1 ] || error "a is not on MDT1"
18297
18298         # a should stay on MDT1, because it is a mulitple link file
18299         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18300                 error "#2 migrate dir fails"
18301         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18302         [ $mdt_index == 1 ] || error "a is not on MDT1"
18303
18304         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18305                 error "#3 migrate dir fails"
18306
18307         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18308         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18309         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18310
18311         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18312         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18313
18314         # a should be migrated to MDT0, since no other links on MDT1
18315         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18316                 error "#4 migrate dir fails"
18317         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18318         [ $mdt_index == 0 ] || error "a is not on MDT0"
18319
18320         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18321 }
18322 run_test 230f "migrate mulitple remote link files"
18323
18324 test_230g() {
18325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18327         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18328                 skip "Need MDS version at least 2.11.52"
18329
18330         mkdir -p $DIR/$tdir/migrate_dir
18331
18332         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18333                 error "migrating dir to non-exist MDT succeeds"
18334         true
18335 }
18336 run_test 230g "migrate dir to non-exist MDT"
18337
18338 test_230h() {
18339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18341         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18342                 skip "Need MDS version at least 2.11.52"
18343
18344         local mdt_index
18345
18346         mkdir -p $DIR/$tdir/migrate_dir
18347
18348         $LFS migrate -m1 $DIR &&
18349                 error "migrating mountpoint1 should fail"
18350
18351         $LFS migrate -m1 $DIR/$tdir/.. &&
18352                 error "migrating mountpoint2 should fail"
18353
18354         # same as mv
18355         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18356                 error "migrating $tdir/migrate_dir/.. should fail"
18357
18358         true
18359 }
18360 run_test 230h "migrate .. and root"
18361
18362 test_230i() {
18363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18365         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18366                 skip "Need MDS version at least 2.11.52"
18367
18368         mkdir -p $DIR/$tdir/migrate_dir
18369
18370         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18371                 error "migration fails with a tailing slash"
18372
18373         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18374                 error "migration fails with two tailing slashes"
18375 }
18376 run_test 230i "lfs migrate -m tolerates trailing slashes"
18377
18378 test_230j() {
18379         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18380         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18381                 skip "Need MDS version at least 2.11.52"
18382
18383         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18384         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18385                 error "create $tfile failed"
18386         cat /etc/passwd > $DIR/$tdir/$tfile
18387
18388         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18389
18390         cmp /etc/passwd $DIR/$tdir/$tfile ||
18391                 error "DoM file mismatch after migration"
18392 }
18393 run_test 230j "DoM file data not changed after dir migration"
18394
18395 test_230k() {
18396         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18397         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18398                 skip "Need MDS version at least 2.11.56"
18399
18400         local total=20
18401         local files_on_starting_mdt=0
18402
18403         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18404         $LFS getdirstripe $DIR/$tdir
18405         for i in $(seq $total); do
18406                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18407                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18408                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18409         done
18410
18411         echo "$files_on_starting_mdt files on MDT0"
18412
18413         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18414         $LFS getdirstripe $DIR/$tdir
18415
18416         files_on_starting_mdt=0
18417         for i in $(seq $total); do
18418                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18419                         error "file $tfile.$i mismatch after migration"
18420                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18421                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18422         done
18423
18424         echo "$files_on_starting_mdt files on MDT1 after migration"
18425         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18426
18427         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18428         $LFS getdirstripe $DIR/$tdir
18429
18430         files_on_starting_mdt=0
18431         for i in $(seq $total); do
18432                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18433                         error "file $tfile.$i mismatch after 2nd migration"
18434                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18435                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18436         done
18437
18438         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18439         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18440
18441         true
18442 }
18443 run_test 230k "file data not changed after dir migration"
18444
18445 test_230l() {
18446         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18447         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18448                 skip "Need MDS version at least 2.11.56"
18449
18450         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18451         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18452                 error "create files under remote dir failed $i"
18453         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18454 }
18455 run_test 230l "readdir between MDTs won't crash"
18456
18457 test_230m() {
18458         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18459         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18460                 skip "Need MDS version at least 2.11.56"
18461
18462         local MDTIDX=1
18463         local mig_dir=$DIR/$tdir/migrate_dir
18464         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18465         local shortstr="b"
18466         local val
18467
18468         echo "Creating files and dirs with xattrs"
18469         test_mkdir $DIR/$tdir
18470         test_mkdir -i0 -c1 $mig_dir
18471         mkdir $mig_dir/dir
18472         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18473                 error "cannot set xattr attr1 on dir"
18474         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18475                 error "cannot set xattr attr2 on dir"
18476         touch $mig_dir/dir/f0
18477         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18478                 error "cannot set xattr attr1 on file"
18479         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18480                 error "cannot set xattr attr2 on file"
18481         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18482         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18483         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18484         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18485         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18486         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18487         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18488         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18489         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18490
18491         echo "Migrating to MDT1"
18492         $LFS migrate -m $MDTIDX $mig_dir ||
18493                 error "fails on migrating dir to MDT1"
18494
18495         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18496         echo "Checking xattrs"
18497         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18498         [ "$val" = $longstr ] ||
18499                 error "expecting xattr1 $longstr on dir, found $val"
18500         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18501         [ "$val" = $shortstr ] ||
18502                 error "expecting xattr2 $shortstr on dir, found $val"
18503         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18504         [ "$val" = $longstr ] ||
18505                 error "expecting xattr1 $longstr on file, found $val"
18506         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18507         [ "$val" = $shortstr ] ||
18508                 error "expecting xattr2 $shortstr on file, found $val"
18509 }
18510 run_test 230m "xattrs not changed after dir migration"
18511
18512 test_230n() {
18513         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18514         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18515                 skip "Need MDS version at least 2.13.53"
18516
18517         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18518         cat /etc/hosts > $DIR/$tdir/$tfile
18519         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18520         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18521
18522         cmp /etc/hosts $DIR/$tdir/$tfile ||
18523                 error "File data mismatch after migration"
18524 }
18525 run_test 230n "Dir migration with mirrored file"
18526
18527 test_230o() {
18528         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18529         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18530                 skip "Need MDS version at least 2.13.52"
18531
18532         local mdts=$(comma_list $(mdts_nodes))
18533         local timeout=100
18534
18535         local restripe_status
18536         local delta
18537         local i
18538         local j
18539
18540         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18541
18542         # in case "crush" hash type is not set
18543         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18544
18545         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18546                            mdt.*MDT0000.enable_dir_restripe)
18547         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18548         stack_trap "do_nodes $mdts $LCTL set_param \
18549                     mdt.*.enable_dir_restripe=$restripe_status"
18550
18551         mkdir $DIR/$tdir
18552         createmany -m $DIR/$tdir/f 100 ||
18553                 error "create files under remote dir failed $i"
18554         createmany -d $DIR/$tdir/d 100 ||
18555                 error "create dirs under remote dir failed $i"
18556
18557         for i in $(seq 2 $MDSCOUNT); do
18558                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18559                 $LFS setdirstripe -c $i $DIR/$tdir ||
18560                         error "split -c $i $tdir failed"
18561                 wait_update $HOSTNAME \
18562                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18563                         error "dir split not finished"
18564                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18565                         awk '/migrate/ {sum += $2} END { print sum }')
18566                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18567                 # delta is around total_files/stripe_count
18568                 [ $delta -lt $((200 /(i - 1))) ] ||
18569                         error "$delta files migrated"
18570         done
18571 }
18572 run_test 230o "dir split"
18573
18574 test_230p() {
18575         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18576         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18577                 skip "Need MDS version at least 2.13.52"
18578
18579         local mdts=$(comma_list $(mdts_nodes))
18580         local timeout=100
18581
18582         local restripe_status
18583         local delta
18584         local i
18585         local j
18586
18587         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18588
18589         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18590
18591         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18592                            mdt.*MDT0000.enable_dir_restripe)
18593         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18594         stack_trap "do_nodes $mdts $LCTL set_param \
18595                     mdt.*.enable_dir_restripe=$restripe_status"
18596
18597         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18598         createmany -m $DIR/$tdir/f 100 ||
18599                 error "create files under remote dir failed $i"
18600         createmany -d $DIR/$tdir/d 100 ||
18601                 error "create dirs under remote dir failed $i"
18602
18603         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18604                 local mdt_hash="crush"
18605
18606                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18607                 $LFS setdirstripe -c $i $DIR/$tdir ||
18608                         error "split -c $i $tdir failed"
18609                 [ $i -eq 1 ] && mdt_hash="none"
18610                 wait_update $HOSTNAME \
18611                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18612                         error "dir merge not finished"
18613                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18614                         awk '/migrate/ {sum += $2} END { print sum }')
18615                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18616                 # delta is around total_files/stripe_count
18617                 [ $delta -lt $((200 / i)) ] ||
18618                         error "$delta files migrated"
18619         done
18620 }
18621 run_test 230p "dir merge"
18622
18623 test_230q() {
18624         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18625         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18626                 skip "Need MDS version at least 2.13.52"
18627
18628         local mdts=$(comma_list $(mdts_nodes))
18629         local saved_threshold=$(do_facet mds1 \
18630                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18631         local saved_delta=$(do_facet mds1 \
18632                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18633         local threshold=100
18634         local delta=2
18635         local total=0
18636         local stripe_count=0
18637         local stripe_index
18638         local nr_files
18639
18640         # test with fewer files on ZFS
18641         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18642
18643         stack_trap "do_nodes $mdts $LCTL set_param \
18644                     mdt.*.dir_split_count=$saved_threshold"
18645         stack_trap "do_nodes $mdts $LCTL set_param \
18646                     mdt.*.dir_split_delta=$saved_delta"
18647         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18648         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18649         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18650         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18651         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18652         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18653
18654         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18655         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18656
18657         while [ $stripe_count -lt $MDSCOUNT ]; do
18658                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18659                         error "create sub files failed"
18660                 stat $DIR/$tdir > /dev/null
18661                 total=$((total + threshold * 3 / 2))
18662                 stripe_count=$((stripe_count + delta))
18663                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18664
18665                 wait_update $HOSTNAME \
18666                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18667                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18668
18669                 wait_update $HOSTNAME \
18670                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18671                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18672
18673                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18674                            grep -w $stripe_index | wc -l)
18675                 echo "$nr_files files on MDT$stripe_index after split"
18676                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18677                         error "$nr_files files on MDT$stripe_index after split"
18678
18679                 nr_files=$(ls $DIR/$tdir | wc -w)
18680                 [ $nr_files -eq $total ] ||
18681                         error "total sub files $nr_files != $total"
18682         done
18683 }
18684 run_test 230q "dir auto split"
18685
18686 test_230r() {
18687         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18688         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18689         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18690                 skip "Need MDS version at least 2.13.54"
18691
18692         # maximum amount of local locks:
18693         # parent striped dir - 2 locks
18694         # new stripe in parent to migrate to - 1 lock
18695         # source and target - 2 locks
18696         # Total 5 locks for regular file
18697         mkdir -p $DIR/$tdir
18698         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18699         touch $DIR/$tdir/dir1/eee
18700
18701         # create 4 hardlink for 4 more locks
18702         # Total: 9 locks > RS_MAX_LOCKS (8)
18703         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18704         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18705         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18706         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18707         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18708         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18709         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18710         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18711
18712         cancel_lru_locks mdc
18713
18714         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18715                 error "migrate dir fails"
18716
18717         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18718 }
18719 run_test 230r "migrate with too many local locks"
18720
18721 test_231a()
18722 {
18723         # For simplicity this test assumes that max_pages_per_rpc
18724         # is the same across all OSCs
18725         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18726         local bulk_size=$((max_pages * PAGE_SIZE))
18727         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18728                                        head -n 1)
18729
18730         mkdir -p $DIR/$tdir
18731         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18732                 error "failed to set stripe with -S ${brw_size}M option"
18733
18734         # clear the OSC stats
18735         $LCTL set_param osc.*.stats=0 &>/dev/null
18736         stop_writeback
18737
18738         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18739         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18740                 oflag=direct &>/dev/null || error "dd failed"
18741
18742         sync; sleep 1; sync # just to be safe
18743         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18744         if [ x$nrpcs != "x1" ]; then
18745                 $LCTL get_param osc.*.stats
18746                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18747         fi
18748
18749         start_writeback
18750         # Drop the OSC cache, otherwise we will read from it
18751         cancel_lru_locks osc
18752
18753         # clear the OSC stats
18754         $LCTL set_param osc.*.stats=0 &>/dev/null
18755
18756         # Client reads $bulk_size.
18757         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18758                 iflag=direct &>/dev/null || error "dd failed"
18759
18760         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18761         if [ x$nrpcs != "x1" ]; then
18762                 $LCTL get_param osc.*.stats
18763                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18764         fi
18765 }
18766 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18767
18768 test_231b() {
18769         mkdir -p $DIR/$tdir
18770         local i
18771         for i in {0..1023}; do
18772                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18773                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18774                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18775         done
18776         sync
18777 }
18778 run_test 231b "must not assert on fully utilized OST request buffer"
18779
18780 test_232a() {
18781         mkdir -p $DIR/$tdir
18782         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18783
18784         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18785         do_facet ost1 $LCTL set_param fail_loc=0x31c
18786
18787         # ignore dd failure
18788         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18789
18790         do_facet ost1 $LCTL set_param fail_loc=0
18791         umount_client $MOUNT || error "umount failed"
18792         mount_client $MOUNT || error "mount failed"
18793         stop ost1 || error "cannot stop ost1"
18794         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18795 }
18796 run_test 232a "failed lock should not block umount"
18797
18798 test_232b() {
18799         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18800                 skip "Need MDS version at least 2.10.58"
18801
18802         mkdir -p $DIR/$tdir
18803         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18804         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18805         sync
18806         cancel_lru_locks osc
18807
18808         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18809         do_facet ost1 $LCTL set_param fail_loc=0x31c
18810
18811         # ignore failure
18812         $LFS data_version $DIR/$tdir/$tfile || true
18813
18814         do_facet ost1 $LCTL set_param fail_loc=0
18815         umount_client $MOUNT || error "umount failed"
18816         mount_client $MOUNT || error "mount failed"
18817         stop ost1 || error "cannot stop ost1"
18818         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18819 }
18820 run_test 232b "failed data version lock should not block umount"
18821
18822 test_233a() {
18823         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18824                 skip "Need MDS version at least 2.3.64"
18825         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18826
18827         local fid=$($LFS path2fid $MOUNT)
18828
18829         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18830                 error "cannot access $MOUNT using its FID '$fid'"
18831 }
18832 run_test 233a "checking that OBF of the FS root succeeds"
18833
18834 test_233b() {
18835         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18836                 skip "Need MDS version at least 2.5.90"
18837         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18838
18839         local fid=$($LFS path2fid $MOUNT/.lustre)
18840
18841         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18842                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18843
18844         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18845         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18846                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18847 }
18848 run_test 233b "checking that OBF of the FS .lustre succeeds"
18849
18850 test_234() {
18851         local p="$TMP/sanityN-$TESTNAME.parameters"
18852         save_lustre_params client "llite.*.xattr_cache" > $p
18853         lctl set_param llite.*.xattr_cache 1 ||
18854                 skip_env "xattr cache is not supported"
18855
18856         mkdir -p $DIR/$tdir || error "mkdir failed"
18857         touch $DIR/$tdir/$tfile || error "touch failed"
18858         # OBD_FAIL_LLITE_XATTR_ENOMEM
18859         $LCTL set_param fail_loc=0x1405
18860         getfattr -n user.attr $DIR/$tdir/$tfile &&
18861                 error "getfattr should have failed with ENOMEM"
18862         $LCTL set_param fail_loc=0x0
18863         rm -rf $DIR/$tdir
18864
18865         restore_lustre_params < $p
18866         rm -f $p
18867 }
18868 run_test 234 "xattr cache should not crash on ENOMEM"
18869
18870 test_235() {
18871         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18872                 skip "Need MDS version at least 2.4.52"
18873
18874         flock_deadlock $DIR/$tfile
18875         local RC=$?
18876         case $RC in
18877                 0)
18878                 ;;
18879                 124) error "process hangs on a deadlock"
18880                 ;;
18881                 *) error "error executing flock_deadlock $DIR/$tfile"
18882                 ;;
18883         esac
18884 }
18885 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18886
18887 #LU-2935
18888 test_236() {
18889         check_swap_layouts_support
18890
18891         local ref1=/etc/passwd
18892         local ref2=/etc/group
18893         local file1=$DIR/$tdir/f1
18894         local file2=$DIR/$tdir/f2
18895
18896         test_mkdir -c1 $DIR/$tdir
18897         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18898         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18899         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18900         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18901         local fd=$(free_fd)
18902         local cmd="exec $fd<>$file2"
18903         eval $cmd
18904         rm $file2
18905         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18906                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18907         cmd="exec $fd>&-"
18908         eval $cmd
18909         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18910
18911         #cleanup
18912         rm -rf $DIR/$tdir
18913 }
18914 run_test 236 "Layout swap on open unlinked file"
18915
18916 # LU-4659 linkea consistency
18917 test_238() {
18918         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18919                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18920                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18921                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18922
18923         touch $DIR/$tfile
18924         ln $DIR/$tfile $DIR/$tfile.lnk
18925         touch $DIR/$tfile.new
18926         mv $DIR/$tfile.new $DIR/$tfile
18927         local fid1=$($LFS path2fid $DIR/$tfile)
18928         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18929         local path1=$($LFS fid2path $FSNAME "$fid1")
18930         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18931         local path2=$($LFS fid2path $FSNAME "$fid2")
18932         [ $tfile.lnk == $path2 ] ||
18933                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18934         rm -f $DIR/$tfile*
18935 }
18936 run_test 238 "Verify linkea consistency"
18937
18938 test_239A() { # was test_239
18939         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18940                 skip "Need MDS version at least 2.5.60"
18941
18942         local list=$(comma_list $(mdts_nodes))
18943
18944         mkdir -p $DIR/$tdir
18945         createmany -o $DIR/$tdir/f- 5000
18946         unlinkmany $DIR/$tdir/f- 5000
18947         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18948                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18949         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18950                         osp.*MDT*.sync_in_flight" | calc_sum)
18951         [ "$changes" -eq 0 ] || error "$changes not synced"
18952 }
18953 run_test 239A "osp_sync test"
18954
18955 test_239a() { #LU-5297
18956         remote_mds_nodsh && skip "remote MDS with nodsh"
18957
18958         touch $DIR/$tfile
18959         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18960         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18961         chgrp $RUNAS_GID $DIR/$tfile
18962         wait_delete_completed
18963 }
18964 run_test 239a "process invalid osp sync record correctly"
18965
18966 test_239b() { #LU-5297
18967         remote_mds_nodsh && skip "remote MDS with nodsh"
18968
18969         touch $DIR/$tfile1
18970         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18971         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18972         chgrp $RUNAS_GID $DIR/$tfile1
18973         wait_delete_completed
18974         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18975         touch $DIR/$tfile2
18976         chgrp $RUNAS_GID $DIR/$tfile2
18977         wait_delete_completed
18978 }
18979 run_test 239b "process osp sync record with ENOMEM error correctly"
18980
18981 test_240() {
18982         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18983         remote_mds_nodsh && skip "remote MDS with nodsh"
18984
18985         mkdir -p $DIR/$tdir
18986
18987         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18988                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18989         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18990                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18991
18992         umount_client $MOUNT || error "umount failed"
18993         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18994         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18995         mount_client $MOUNT || error "failed to mount client"
18996
18997         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18998         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18999 }
19000 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19001
19002 test_241_bio() {
19003         local count=$1
19004         local bsize=$2
19005
19006         for LOOP in $(seq $count); do
19007                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19008                 cancel_lru_locks $OSC || true
19009         done
19010 }
19011
19012 test_241_dio() {
19013         local count=$1
19014         local bsize=$2
19015
19016         for LOOP in $(seq $1); do
19017                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19018                         2>/dev/null
19019         done
19020 }
19021
19022 test_241a() { # was test_241
19023         local bsize=$PAGE_SIZE
19024
19025         (( bsize < 40960 )) && bsize=40960
19026         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19027         ls -la $DIR/$tfile
19028         cancel_lru_locks $OSC
19029         test_241_bio 1000 $bsize &
19030         PID=$!
19031         test_241_dio 1000 $bsize
19032         wait $PID
19033 }
19034 run_test 241a "bio vs dio"
19035
19036 test_241b() {
19037         local bsize=$PAGE_SIZE
19038
19039         (( bsize < 40960 )) && bsize=40960
19040         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19041         ls -la $DIR/$tfile
19042         test_241_dio 1000 $bsize &
19043         PID=$!
19044         test_241_dio 1000 $bsize
19045         wait $PID
19046 }
19047 run_test 241b "dio vs dio"
19048
19049 test_242() {
19050         remote_mds_nodsh && skip "remote MDS with nodsh"
19051
19052         mkdir -p $DIR/$tdir
19053         touch $DIR/$tdir/$tfile
19054
19055         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19056         do_facet mds1 lctl set_param fail_loc=0x105
19057         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19058
19059         do_facet mds1 lctl set_param fail_loc=0
19060         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19061 }
19062 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19063
19064 test_243()
19065 {
19066         test_mkdir $DIR/$tdir
19067         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19068 }
19069 run_test 243 "various group lock tests"
19070
19071 test_244a()
19072 {
19073         test_mkdir $DIR/$tdir
19074         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19075         sendfile_grouplock $DIR/$tdir/$tfile || \
19076                 error "sendfile+grouplock failed"
19077         rm -rf $DIR/$tdir
19078 }
19079 run_test 244a "sendfile with group lock tests"
19080
19081 test_244b()
19082 {
19083         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19084
19085         local threads=50
19086         local size=$((1024*1024))
19087
19088         test_mkdir $DIR/$tdir
19089         for i in $(seq 1 $threads); do
19090                 local file=$DIR/$tdir/file_$((i / 10))
19091                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19092                 local pids[$i]=$!
19093         done
19094         for i in $(seq 1 $threads); do
19095                 wait ${pids[$i]}
19096         done
19097 }
19098 run_test 244b "multi-threaded write with group lock"
19099
19100 test_245() {
19101         local flagname="multi_mod_rpcs"
19102         local connect_data_name="max_mod_rpcs"
19103         local out
19104
19105         # check if multiple modify RPCs flag is set
19106         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19107                 grep "connect_flags:")
19108         echo "$out"
19109
19110         echo "$out" | grep -qw $flagname
19111         if [ $? -ne 0 ]; then
19112                 echo "connect flag $flagname is not set"
19113                 return
19114         fi
19115
19116         # check if multiple modify RPCs data is set
19117         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19118         echo "$out"
19119
19120         echo "$out" | grep -qw $connect_data_name ||
19121                 error "import should have connect data $connect_data_name"
19122 }
19123 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19124
19125 cleanup_247() {
19126         local submount=$1
19127
19128         trap 0
19129         umount_client $submount
19130         rmdir $submount
19131 }
19132
19133 test_247a() {
19134         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19135                 grep -q subtree ||
19136                 skip_env "Fileset feature is not supported"
19137
19138         local submount=${MOUNT}_$tdir
19139
19140         mkdir $MOUNT/$tdir
19141         mkdir -p $submount || error "mkdir $submount failed"
19142         FILESET="$FILESET/$tdir" mount_client $submount ||
19143                 error "mount $submount failed"
19144         trap "cleanup_247 $submount" EXIT
19145         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19146         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19147                 error "read $MOUNT/$tdir/$tfile failed"
19148         cleanup_247 $submount
19149 }
19150 run_test 247a "mount subdir as fileset"
19151
19152 test_247b() {
19153         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19154                 skip_env "Fileset feature is not supported"
19155
19156         local submount=${MOUNT}_$tdir
19157
19158         rm -rf $MOUNT/$tdir
19159         mkdir -p $submount || error "mkdir $submount failed"
19160         SKIP_FILESET=1
19161         FILESET="$FILESET/$tdir" mount_client $submount &&
19162                 error "mount $submount should fail"
19163         rmdir $submount
19164 }
19165 run_test 247b "mount subdir that dose not exist"
19166
19167 test_247c() {
19168         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19169                 skip_env "Fileset feature is not supported"
19170
19171         local submount=${MOUNT}_$tdir
19172
19173         mkdir -p $MOUNT/$tdir/dir1
19174         mkdir -p $submount || error "mkdir $submount failed"
19175         trap "cleanup_247 $submount" EXIT
19176         FILESET="$FILESET/$tdir" mount_client $submount ||
19177                 error "mount $submount failed"
19178         local fid=$($LFS path2fid $MOUNT/)
19179         $LFS fid2path $submount $fid && error "fid2path should fail"
19180         cleanup_247 $submount
19181 }
19182 run_test 247c "running fid2path outside subdirectory root"
19183
19184 test_247d() {
19185         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19186                 skip "Fileset feature is not supported"
19187
19188         local submount=${MOUNT}_$tdir
19189
19190         mkdir -p $MOUNT/$tdir/dir1
19191         mkdir -p $submount || error "mkdir $submount failed"
19192         FILESET="$FILESET/$tdir" mount_client $submount ||
19193                 error "mount $submount failed"
19194         trap "cleanup_247 $submount" EXIT
19195
19196         local td=$submount/dir1
19197         local fid=$($LFS path2fid $td)
19198         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19199
19200         # check that we get the same pathname back
19201         local rootpath
19202         local found
19203         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19204                 echo "$rootpath $fid"
19205                 found=$($LFS fid2path $rootpath "$fid")
19206                 [ -n "found" ] || error "fid2path should succeed"
19207                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19208         done
19209         # check wrong root path format
19210         rootpath=$submount"_wrong"
19211         found=$($LFS fid2path $rootpath "$fid")
19212         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19213
19214         cleanup_247 $submount
19215 }
19216 run_test 247d "running fid2path inside subdirectory root"
19217
19218 # LU-8037
19219 test_247e() {
19220         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19221                 grep -q subtree ||
19222                 skip "Fileset feature is not supported"
19223
19224         local submount=${MOUNT}_$tdir
19225
19226         mkdir $MOUNT/$tdir
19227         mkdir -p $submount || error "mkdir $submount failed"
19228         FILESET="$FILESET/.." mount_client $submount &&
19229                 error "mount $submount should fail"
19230         rmdir $submount
19231 }
19232 run_test 247e "mount .. as fileset"
19233
19234 test_247f() {
19235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19236         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19237                 skip "Need at least version 2.13.52"
19238         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19239                 grep -q subtree ||
19240                 skip "Fileset feature is not supported"
19241
19242         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19243         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19244                 error "mkdir remote failed"
19245         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19246         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19247                 error "mkdir striped failed"
19248         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19249
19250         local submount=${MOUNT}_$tdir
19251
19252         mkdir -p $submount || error "mkdir $submount failed"
19253
19254         local dir
19255         local fileset=$FILESET
19256
19257         for dir in $tdir/remote $tdir/remote/subdir \
19258                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19259                 FILESET="$fileset/$dir" mount_client $submount ||
19260                         error "mount $dir failed"
19261                 umount_client $submount
19262         done
19263 }
19264 run_test 247f "mount striped or remote directory as fileset"
19265
19266 test_248a() {
19267         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19268         [ -z "$fast_read_sav" ] && skip "no fast read support"
19269
19270         # create a large file for fast read verification
19271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19272
19273         # make sure the file is created correctly
19274         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19275                 { rm -f $DIR/$tfile; skip "file creation error"; }
19276
19277         echo "Test 1: verify that fast read is 4 times faster on cache read"
19278
19279         # small read with fast read enabled
19280         $LCTL set_param -n llite.*.fast_read=1
19281         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19282                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19283                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19284         # small read with fast read disabled
19285         $LCTL set_param -n llite.*.fast_read=0
19286         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19287                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19288                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19289
19290         # verify that fast read is 4 times faster for cache read
19291         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19292                 error_not_in_vm "fast read was not 4 times faster: " \
19293                            "$t_fast vs $t_slow"
19294
19295         echo "Test 2: verify the performance between big and small read"
19296         $LCTL set_param -n llite.*.fast_read=1
19297
19298         # 1k non-cache read
19299         cancel_lru_locks osc
19300         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19301                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19302                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19303
19304         # 1M non-cache read
19305         cancel_lru_locks osc
19306         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19307                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19308                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19309
19310         # verify that big IO is not 4 times faster than small IO
19311         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19312                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19313
19314         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19315         rm -f $DIR/$tfile
19316 }
19317 run_test 248a "fast read verification"
19318
19319 test_248b() {
19320         # Default short_io_bytes=16384, try both smaller and larger sizes.
19321         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19322         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19323         echo "bs=53248 count=113 normal buffered write"
19324         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19325                 error "dd of initial data file failed"
19326         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19327
19328         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19329         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19330                 error "dd with sync normal writes failed"
19331         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19332
19333         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19334         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19335                 error "dd with sync small writes failed"
19336         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19337
19338         cancel_lru_locks osc
19339
19340         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19341         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19342         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19343         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19344                 iflag=direct || error "dd with O_DIRECT small read failed"
19345         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19346         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19347                 error "compare $TMP/$tfile.1 failed"
19348
19349         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19350         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19351
19352         # just to see what the maximum tunable value is, and test parsing
19353         echo "test invalid parameter 2MB"
19354         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19355                 error "too-large short_io_bytes allowed"
19356         echo "test maximum parameter 512KB"
19357         # if we can set a larger short_io_bytes, run test regardless of version
19358         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19359                 # older clients may not allow setting it this large, that's OK
19360                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19361                         skip "Need at least client version 2.13.50"
19362                 error "medium short_io_bytes failed"
19363         fi
19364         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19365         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19366
19367         echo "test large parameter 64KB"
19368         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19369         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19370
19371         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19372         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19373                 error "dd with sync large writes failed"
19374         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19375
19376         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19377         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19378         num=$((113 * 4096 / PAGE_SIZE))
19379         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19380         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19381                 error "dd with O_DIRECT large writes failed"
19382         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19383                 error "compare $DIR/$tfile.3 failed"
19384
19385         cancel_lru_locks osc
19386
19387         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19388         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19389                 error "dd with O_DIRECT large read failed"
19390         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19391                 error "compare $TMP/$tfile.2 failed"
19392
19393         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19394         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19395                 error "dd with O_DIRECT large read failed"
19396         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19397                 error "compare $TMP/$tfile.3 failed"
19398 }
19399 run_test 248b "test short_io read and write for both small and large sizes"
19400
19401 test_249() { # LU-7890
19402         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19403                 skip "Need at least version 2.8.54"
19404
19405         rm -f $DIR/$tfile
19406         $LFS setstripe -c 1 $DIR/$tfile
19407         # Offset 2T == 4k * 512M
19408         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19409                 error "dd to 2T offset failed"
19410 }
19411 run_test 249 "Write above 2T file size"
19412
19413 test_250() {
19414         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19415          && skip "no 16TB file size limit on ZFS"
19416
19417         $LFS setstripe -c 1 $DIR/$tfile
19418         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19419         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19420         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19421         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19422                 conv=notrunc,fsync && error "append succeeded"
19423         return 0
19424 }
19425 run_test 250 "Write above 16T limit"
19426
19427 test_251() {
19428         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19429
19430         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19431         #Skip once - writing the first stripe will succeed
19432         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19433         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19434                 error "short write happened"
19435
19436         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19437         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19438                 error "short read happened"
19439
19440         rm -f $DIR/$tfile
19441 }
19442 run_test 251 "Handling short read and write correctly"
19443
19444 test_252() {
19445         remote_mds_nodsh && skip "remote MDS with nodsh"
19446         remote_ost_nodsh && skip "remote OST with nodsh"
19447         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19448                 skip_env "ldiskfs only test"
19449         fi
19450
19451         local tgt
19452         local dev
19453         local out
19454         local uuid
19455         local num
19456         local gen
19457
19458         # check lr_reader on OST0000
19459         tgt=ost1
19460         dev=$(facet_device $tgt)
19461         out=$(do_facet $tgt $LR_READER $dev)
19462         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19463         echo "$out"
19464         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19465         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19466                 error "Invalid uuid returned by $LR_READER on target $tgt"
19467         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19468
19469         # check lr_reader -c on MDT0000
19470         tgt=mds1
19471         dev=$(facet_device $tgt)
19472         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19473                 skip "$LR_READER does not support additional options"
19474         fi
19475         out=$(do_facet $tgt $LR_READER -c $dev)
19476         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19477         echo "$out"
19478         num=$(echo "$out" | grep -c "mdtlov")
19479         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19480                 error "Invalid number of mdtlov clients returned by $LR_READER"
19481         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19482
19483         # check lr_reader -cr on MDT0000
19484         out=$(do_facet $tgt $LR_READER -cr $dev)
19485         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19486         echo "$out"
19487         echo "$out" | grep -q "^reply_data:$" ||
19488                 error "$LR_READER should have returned 'reply_data' section"
19489         num=$(echo "$out" | grep -c "client_generation")
19490         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19491 }
19492 run_test 252 "check lr_reader tool"
19493
19494 test_253() {
19495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19496         remote_mds_nodsh && skip "remote MDS with nodsh"
19497         remote_mgs_nodsh && skip "remote MGS with nodsh"
19498
19499         local ostidx=0
19500         local rc=0
19501         local ost_name=$(ostname_from_index $ostidx)
19502
19503         # on the mdt's osc
19504         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19505         do_facet $SINGLEMDS $LCTL get_param -n \
19506                 osp.$mdtosc_proc1.reserved_mb_high ||
19507                 skip  "remote MDS does not support reserved_mb_high"
19508
19509         rm -rf $DIR/$tdir
19510         wait_mds_ost_sync
19511         wait_delete_completed
19512         mkdir $DIR/$tdir
19513
19514         pool_add $TESTNAME || error "Pool creation failed"
19515         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19516
19517         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19518                 error "Setstripe failed"
19519
19520         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19521
19522         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19523                     grep "watermarks")
19524         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19525
19526         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19527                         osp.$mdtosc_proc1.prealloc_status)
19528         echo "prealloc_status $oa_status"
19529
19530         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19531                 error "File creation should fail"
19532
19533         #object allocation was stopped, but we still able to append files
19534         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19535                 oflag=append || error "Append failed"
19536
19537         rm -f $DIR/$tdir/$tfile.0
19538
19539         # For this test, we want to delete the files we created to go out of
19540         # space but leave the watermark, so we remain nearly out of space
19541         ost_watermarks_enospc_delete_files $tfile $ostidx
19542
19543         wait_delete_completed
19544
19545         sleep_maxage
19546
19547         for i in $(seq 10 12); do
19548                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19549                         2>/dev/null || error "File creation failed after rm"
19550         done
19551
19552         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19553                         osp.$mdtosc_proc1.prealloc_status)
19554         echo "prealloc_status $oa_status"
19555
19556         if (( oa_status != 0 )); then
19557                 error "Object allocation still disable after rm"
19558         fi
19559 }
19560 run_test 253 "Check object allocation limit"
19561
19562 test_254() {
19563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19564         remote_mds_nodsh && skip "remote MDS with nodsh"
19565         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19566                 skip "MDS does not support changelog_size"
19567
19568         local cl_user
19569         local MDT0=$(facet_svc $SINGLEMDS)
19570
19571         changelog_register || error "changelog_register failed"
19572
19573         changelog_clear 0 || error "changelog_clear failed"
19574
19575         local size1=$(do_facet $SINGLEMDS \
19576                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19577         echo "Changelog size $size1"
19578
19579         rm -rf $DIR/$tdir
19580         $LFS mkdir -i 0 $DIR/$tdir
19581         # change something
19582         mkdir -p $DIR/$tdir/pics/2008/zachy
19583         touch $DIR/$tdir/pics/2008/zachy/timestamp
19584         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19585         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19586         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19587         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19588         rm $DIR/$tdir/pics/desktop.jpg
19589
19590         local size2=$(do_facet $SINGLEMDS \
19591                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19592         echo "Changelog size after work $size2"
19593
19594         (( $size2 > $size1 )) ||
19595                 error "new Changelog size=$size2 less than old size=$size1"
19596 }
19597 run_test 254 "Check changelog size"
19598
19599 ladvise_no_type()
19600 {
19601         local type=$1
19602         local file=$2
19603
19604         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19605                 awk -F: '{print $2}' | grep $type > /dev/null
19606         if [ $? -ne 0 ]; then
19607                 return 0
19608         fi
19609         return 1
19610 }
19611
19612 ladvise_no_ioctl()
19613 {
19614         local file=$1
19615
19616         lfs ladvise -a willread $file > /dev/null 2>&1
19617         if [ $? -eq 0 ]; then
19618                 return 1
19619         fi
19620
19621         lfs ladvise -a willread $file 2>&1 |
19622                 grep "Inappropriate ioctl for device" > /dev/null
19623         if [ $? -eq 0 ]; then
19624                 return 0
19625         fi
19626         return 1
19627 }
19628
19629 percent() {
19630         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19631 }
19632
19633 # run a random read IO workload
19634 # usage: random_read_iops <filename> <filesize> <iosize>
19635 random_read_iops() {
19636         local file=$1
19637         local fsize=$2
19638         local iosize=${3:-4096}
19639
19640         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19641                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19642 }
19643
19644 drop_file_oss_cache() {
19645         local file="$1"
19646         local nodes="$2"
19647
19648         $LFS ladvise -a dontneed $file 2>/dev/null ||
19649                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19650 }
19651
19652 ladvise_willread_performance()
19653 {
19654         local repeat=10
19655         local average_origin=0
19656         local average_cache=0
19657         local average_ladvise=0
19658
19659         for ((i = 1; i <= $repeat; i++)); do
19660                 echo "Iter $i/$repeat: reading without willread hint"
19661                 cancel_lru_locks osc
19662                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19663                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19664                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19665                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19666
19667                 cancel_lru_locks osc
19668                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19669                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19670                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19671
19672                 cancel_lru_locks osc
19673                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19674                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19675                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19676                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19677                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19678         done
19679         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19680         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19681         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19682
19683         speedup_cache=$(percent $average_cache $average_origin)
19684         speedup_ladvise=$(percent $average_ladvise $average_origin)
19685
19686         echo "Average uncached read: $average_origin"
19687         echo "Average speedup with OSS cached read: " \
19688                 "$average_cache = +$speedup_cache%"
19689         echo "Average speedup with ladvise willread: " \
19690                 "$average_ladvise = +$speedup_ladvise%"
19691
19692         local lowest_speedup=20
19693         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19694                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19695                         "got $average_cache%. Skipping ladvise willread check."
19696                 return 0
19697         fi
19698
19699         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19700         # it is still good to run until then to exercise 'ladvise willread'
19701         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19702                 [ "$ost1_FSTYPE" = "zfs" ] &&
19703                 echo "osd-zfs does not support dontneed or drop_caches" &&
19704                 return 0
19705
19706         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19707         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19708                 error_not_in_vm "Speedup with willread is less than " \
19709                         "$lowest_speedup%, got $average_ladvise%"
19710 }
19711
19712 test_255a() {
19713         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19714                 skip "lustre < 2.8.54 does not support ladvise "
19715         remote_ost_nodsh && skip "remote OST with nodsh"
19716
19717         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19718
19719         ladvise_no_type willread $DIR/$tfile &&
19720                 skip "willread ladvise is not supported"
19721
19722         ladvise_no_ioctl $DIR/$tfile &&
19723                 skip "ladvise ioctl is not supported"
19724
19725         local size_mb=100
19726         local size=$((size_mb * 1048576))
19727         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19728                 error "dd to $DIR/$tfile failed"
19729
19730         lfs ladvise -a willread $DIR/$tfile ||
19731                 error "Ladvise failed with no range argument"
19732
19733         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19734                 error "Ladvise failed with no -l or -e argument"
19735
19736         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19737                 error "Ladvise failed with only -e argument"
19738
19739         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19740                 error "Ladvise failed with only -l argument"
19741
19742         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19743                 error "End offset should not be smaller than start offset"
19744
19745         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19746                 error "End offset should not be equal to start offset"
19747
19748         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19749                 error "Ladvise failed with overflowing -s argument"
19750
19751         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19752                 error "Ladvise failed with overflowing -e argument"
19753
19754         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19755                 error "Ladvise failed with overflowing -l argument"
19756
19757         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19758                 error "Ladvise succeeded with conflicting -l and -e arguments"
19759
19760         echo "Synchronous ladvise should wait"
19761         local delay=4
19762 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19763         do_nodes $(comma_list $(osts_nodes)) \
19764                 $LCTL set_param fail_val=$delay fail_loc=0x237
19765
19766         local start_ts=$SECONDS
19767         lfs ladvise -a willread $DIR/$tfile ||
19768                 error "Ladvise failed with no range argument"
19769         local end_ts=$SECONDS
19770         local inteval_ts=$((end_ts - start_ts))
19771
19772         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19773                 error "Synchronous advice didn't wait reply"
19774         fi
19775
19776         echo "Asynchronous ladvise shouldn't wait"
19777         local start_ts=$SECONDS
19778         lfs ladvise -a willread -b $DIR/$tfile ||
19779                 error "Ladvise failed with no range argument"
19780         local end_ts=$SECONDS
19781         local inteval_ts=$((end_ts - start_ts))
19782
19783         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19784                 error "Asynchronous advice blocked"
19785         fi
19786
19787         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19788         ladvise_willread_performance
19789 }
19790 run_test 255a "check 'lfs ladvise -a willread'"
19791
19792 facet_meminfo() {
19793         local facet=$1
19794         local info=$2
19795
19796         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19797 }
19798
19799 test_255b() {
19800         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19801                 skip "lustre < 2.8.54 does not support ladvise "
19802         remote_ost_nodsh && skip "remote OST with nodsh"
19803
19804         lfs setstripe -c 1 -i 0 $DIR/$tfile
19805
19806         ladvise_no_type dontneed $DIR/$tfile &&
19807                 skip "dontneed ladvise is not supported"
19808
19809         ladvise_no_ioctl $DIR/$tfile &&
19810                 skip "ladvise ioctl is not supported"
19811
19812         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19813                 [ "$ost1_FSTYPE" = "zfs" ] &&
19814                 skip "zfs-osd does not support 'ladvise dontneed'"
19815
19816         local size_mb=100
19817         local size=$((size_mb * 1048576))
19818         # In order to prevent disturbance of other processes, only check 3/4
19819         # of the memory usage
19820         local kibibytes=$((size_mb * 1024 * 3 / 4))
19821
19822         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19823                 error "dd to $DIR/$tfile failed"
19824
19825         #force write to complete before dropping OST cache & checking memory
19826         sync
19827
19828         local total=$(facet_meminfo ost1 MemTotal)
19829         echo "Total memory: $total KiB"
19830
19831         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19832         local before_read=$(facet_meminfo ost1 Cached)
19833         echo "Cache used before read: $before_read KiB"
19834
19835         lfs ladvise -a willread $DIR/$tfile ||
19836                 error "Ladvise willread failed"
19837         local after_read=$(facet_meminfo ost1 Cached)
19838         echo "Cache used after read: $after_read KiB"
19839
19840         lfs ladvise -a dontneed $DIR/$tfile ||
19841                 error "Ladvise dontneed again failed"
19842         local no_read=$(facet_meminfo ost1 Cached)
19843         echo "Cache used after dontneed ladvise: $no_read KiB"
19844
19845         if [ $total -lt $((before_read + kibibytes)) ]; then
19846                 echo "Memory is too small, abort checking"
19847                 return 0
19848         fi
19849
19850         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19851                 error "Ladvise willread should use more memory" \
19852                         "than $kibibytes KiB"
19853         fi
19854
19855         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19856                 error "Ladvise dontneed should release more memory" \
19857                         "than $kibibytes KiB"
19858         fi
19859 }
19860 run_test 255b "check 'lfs ladvise -a dontneed'"
19861
19862 test_255c() {
19863         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19864                 skip "lustre < 2.10.50 does not support lockahead"
19865
19866         local count
19867         local new_count
19868         local difference
19869         local i
19870         local rc
19871
19872         test_mkdir -p $DIR/$tdir
19873         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19874
19875         #test 10 returns only success/failure
19876         i=10
19877         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19878         rc=$?
19879         if [ $rc -eq 255 ]; then
19880                 error "Ladvise test${i} failed, ${rc}"
19881         fi
19882
19883         #test 11 counts lock enqueue requests, all others count new locks
19884         i=11
19885         count=$(do_facet ost1 \
19886                 $LCTL get_param -n ost.OSS.ost.stats)
19887         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19888
19889         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19890         rc=$?
19891         if [ $rc -eq 255 ]; then
19892                 error "Ladvise test${i} failed, ${rc}"
19893         fi
19894
19895         new_count=$(do_facet ost1 \
19896                 $LCTL get_param -n ost.OSS.ost.stats)
19897         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19898                    awk '{ print $2 }')
19899
19900         difference="$((new_count - count))"
19901         if [ $difference -ne $rc ]; then
19902                 error "Ladvise test${i}, bad enqueue count, returned " \
19903                       "${rc}, actual ${difference}"
19904         fi
19905
19906         for i in $(seq 12 21); do
19907                 # If we do not do this, we run the risk of having too many
19908                 # locks and starting lock cancellation while we are checking
19909                 # lock counts.
19910                 cancel_lru_locks osc
19911
19912                 count=$($LCTL get_param -n \
19913                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19914
19915                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19916                 rc=$?
19917                 if [ $rc -eq 255 ]; then
19918                         error "Ladvise test ${i} failed, ${rc}"
19919                 fi
19920
19921                 new_count=$($LCTL get_param -n \
19922                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19923                 difference="$((new_count - count))"
19924
19925                 # Test 15 output is divided by 100 to map down to valid return
19926                 if [ $i -eq 15 ]; then
19927                         rc="$((rc * 100))"
19928                 fi
19929
19930                 if [ $difference -ne $rc ]; then
19931                         error "Ladvise test ${i}, bad lock count, returned " \
19932                               "${rc}, actual ${difference}"
19933                 fi
19934         done
19935
19936         #test 22 returns only success/failure
19937         i=22
19938         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19939         rc=$?
19940         if [ $rc -eq 255 ]; then
19941                 error "Ladvise test${i} failed, ${rc}"
19942         fi
19943 }
19944 run_test 255c "suite of ladvise lockahead tests"
19945
19946 test_256() {
19947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19948         remote_mds_nodsh && skip "remote MDS with nodsh"
19949         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19950         changelog_users $SINGLEMDS | grep "^cl" &&
19951                 skip "active changelog user"
19952
19953         local cl_user
19954         local cat_sl
19955         local mdt_dev
19956
19957         mdt_dev=$(mdsdevname 1)
19958         echo $mdt_dev
19959
19960         changelog_register || error "changelog_register failed"
19961
19962         rm -rf $DIR/$tdir
19963         mkdir -p $DIR/$tdir
19964
19965         changelog_clear 0 || error "changelog_clear failed"
19966
19967         # change something
19968         touch $DIR/$tdir/{1..10}
19969
19970         # stop the MDT
19971         stop $SINGLEMDS || error "Fail to stop MDT"
19972
19973         # remount the MDT
19974
19975         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19976
19977         #after mount new plainllog is used
19978         touch $DIR/$tdir/{11..19}
19979         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19980         stack_trap "rm -f $tmpfile"
19981         cat_sl=$(do_facet $SINGLEMDS "sync; \
19982                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19983                  llog_reader $tmpfile | grep -c type=1064553b")
19984         do_facet $SINGLEMDS llog_reader $tmpfile
19985
19986         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19987
19988         changelog_clear 0 || error "changelog_clear failed"
19989
19990         cat_sl=$(do_facet $SINGLEMDS "sync; \
19991                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19992                  llog_reader $tmpfile | grep -c type=1064553b")
19993
19994         if (( cat_sl == 2 )); then
19995                 error "Empty plain llog was not deleted from changelog catalog"
19996         elif (( cat_sl != 1 )); then
19997                 error "Active plain llog shouldn't be deleted from catalog"
19998         fi
19999 }
20000 run_test 256 "Check llog delete for empty and not full state"
20001
20002 test_257() {
20003         remote_mds_nodsh && skip "remote MDS with nodsh"
20004         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20005                 skip "Need MDS version at least 2.8.55"
20006
20007         test_mkdir $DIR/$tdir
20008
20009         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20010                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20011         stat $DIR/$tdir
20012
20013 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20014         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20015         local facet=mds$((mdtidx + 1))
20016         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20017         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20018
20019         stop $facet || error "stop MDS failed"
20020         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20021                 error "start MDS fail"
20022         wait_recovery_complete $facet
20023 }
20024 run_test 257 "xattr locks are not lost"
20025
20026 # Verify we take the i_mutex when security requires it
20027 test_258a() {
20028 #define OBD_FAIL_IMUTEX_SEC 0x141c
20029         $LCTL set_param fail_loc=0x141c
20030         touch $DIR/$tfile
20031         chmod u+s $DIR/$tfile
20032         chmod a+rwx $DIR/$tfile
20033         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20034         RC=$?
20035         if [ $RC -ne 0 ]; then
20036                 error "error, failed to take i_mutex, rc=$?"
20037         fi
20038         rm -f $DIR/$tfile
20039 }
20040 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20041
20042 # Verify we do NOT take the i_mutex in the normal case
20043 test_258b() {
20044 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20045         $LCTL set_param fail_loc=0x141d
20046         touch $DIR/$tfile
20047         chmod a+rwx $DIR
20048         chmod a+rw $DIR/$tfile
20049         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20050         RC=$?
20051         if [ $RC -ne 0 ]; then
20052                 error "error, took i_mutex unnecessarily, rc=$?"
20053         fi
20054         rm -f $DIR/$tfile
20055
20056 }
20057 run_test 258b "verify i_mutex security behavior"
20058
20059 test_259() {
20060         local file=$DIR/$tfile
20061         local before
20062         local after
20063
20064         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20065
20066         stack_trap "rm -f $file" EXIT
20067
20068         wait_delete_completed
20069         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20070         echo "before: $before"
20071
20072         $LFS setstripe -i 0 -c 1 $file
20073         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20074         sync_all_data
20075         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20076         echo "after write: $after"
20077
20078 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20079         do_facet ost1 $LCTL set_param fail_loc=0x2301
20080         $TRUNCATE $file 0
20081         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20082         echo "after truncate: $after"
20083
20084         stop ost1
20085         do_facet ost1 $LCTL set_param fail_loc=0
20086         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20087         sleep 2
20088         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20089         echo "after restart: $after"
20090         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20091                 error "missing truncate?"
20092
20093         return 0
20094 }
20095 run_test 259 "crash at delayed truncate"
20096
20097 test_260() {
20098 #define OBD_FAIL_MDC_CLOSE               0x806
20099         $LCTL set_param fail_loc=0x80000806
20100         touch $DIR/$tfile
20101
20102 }
20103 run_test 260 "Check mdc_close fail"
20104
20105 ### Data-on-MDT sanity tests ###
20106 test_270a() {
20107         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20108                 skip "Need MDS version at least 2.10.55 for DoM"
20109
20110         # create DoM file
20111         local dom=$DIR/$tdir/dom_file
20112         local tmp=$DIR/$tdir/tmp_file
20113
20114         mkdir -p $DIR/$tdir
20115
20116         # basic checks for DoM component creation
20117         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20118                 error "Can set MDT layout to non-first entry"
20119
20120         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20121                 error "Can define multiple entries as MDT layout"
20122
20123         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20124
20125         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20126         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20127         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20128
20129         local mdtidx=$($LFS getstripe -m $dom)
20130         local mdtname=MDT$(printf %04x $mdtidx)
20131         local facet=mds$((mdtidx + 1))
20132         local space_check=1
20133
20134         # Skip free space checks with ZFS
20135         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20136
20137         # write
20138         sync
20139         local size_tmp=$((65536 * 3))
20140         local mdtfree1=$(do_facet $facet \
20141                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20142
20143         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20144         # check also direct IO along write
20145         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20146         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20147         sync
20148         cmp $tmp $dom || error "file data is different"
20149         [ $(stat -c%s $dom) == $size_tmp ] ||
20150                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20151         if [ $space_check == 1 ]; then
20152                 local mdtfree2=$(do_facet $facet \
20153                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20154
20155                 # increase in usage from by $size_tmp
20156                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20157                         error "MDT free space wrong after write: " \
20158                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20159         fi
20160
20161         # truncate
20162         local size_dom=10000
20163
20164         $TRUNCATE $dom $size_dom
20165         [ $(stat -c%s $dom) == $size_dom ] ||
20166                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20167         if [ $space_check == 1 ]; then
20168                 mdtfree1=$(do_facet $facet \
20169                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20170                 # decrease in usage from $size_tmp to new $size_dom
20171                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20172                   $(((size_tmp - size_dom) / 1024)) ] ||
20173                         error "MDT free space is wrong after truncate: " \
20174                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20175         fi
20176
20177         # append
20178         cat $tmp >> $dom
20179         sync
20180         size_dom=$((size_dom + size_tmp))
20181         [ $(stat -c%s $dom) == $size_dom ] ||
20182                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20183         if [ $space_check == 1 ]; then
20184                 mdtfree2=$(do_facet $facet \
20185                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20186                 # increase in usage by $size_tmp from previous
20187                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20188                         error "MDT free space is wrong after append: " \
20189                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20190         fi
20191
20192         # delete
20193         rm $dom
20194         if [ $space_check == 1 ]; then
20195                 mdtfree1=$(do_facet $facet \
20196                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20197                 # decrease in usage by $size_dom from previous
20198                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20199                         error "MDT free space is wrong after removal: " \
20200                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20201         fi
20202
20203         # combined striping
20204         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20205                 error "Can't create DoM + OST striping"
20206
20207         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20208         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20209         # check also direct IO along write
20210         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20211         sync
20212         cmp $tmp $dom || error "file data is different"
20213         [ $(stat -c%s $dom) == $size_tmp ] ||
20214                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20215         rm $dom $tmp
20216
20217         return 0
20218 }
20219 run_test 270a "DoM: basic functionality tests"
20220
20221 test_270b() {
20222         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20223                 skip "Need MDS version at least 2.10.55"
20224
20225         local dom=$DIR/$tdir/dom_file
20226         local max_size=1048576
20227
20228         mkdir -p $DIR/$tdir
20229         $LFS setstripe -E $max_size -L mdt $dom
20230
20231         # truncate over the limit
20232         $TRUNCATE $dom $(($max_size + 1)) &&
20233                 error "successful truncate over the maximum size"
20234         # write over the limit
20235         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20236                 error "successful write over the maximum size"
20237         # append over the limit
20238         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20239         echo "12345" >> $dom && error "successful append over the maximum size"
20240         rm $dom
20241
20242         return 0
20243 }
20244 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20245
20246 test_270c() {
20247         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20248                 skip "Need MDS version at least 2.10.55"
20249
20250         mkdir -p $DIR/$tdir
20251         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20252
20253         # check files inherit DoM EA
20254         touch $DIR/$tdir/first
20255         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20256                 error "bad pattern"
20257         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20258                 error "bad stripe count"
20259         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20260                 error "bad stripe size"
20261
20262         # check directory inherits DoM EA and uses it as default
20263         mkdir $DIR/$tdir/subdir
20264         touch $DIR/$tdir/subdir/second
20265         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20266                 error "bad pattern in sub-directory"
20267         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20268                 error "bad stripe count in sub-directory"
20269         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20270                 error "bad stripe size in sub-directory"
20271         return 0
20272 }
20273 run_test 270c "DoM: DoM EA inheritance tests"
20274
20275 test_270d() {
20276         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20277                 skip "Need MDS version at least 2.10.55"
20278
20279         mkdir -p $DIR/$tdir
20280         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20281
20282         # inherit default DoM striping
20283         mkdir $DIR/$tdir/subdir
20284         touch $DIR/$tdir/subdir/f1
20285
20286         # change default directory striping
20287         $LFS setstripe -c 1 $DIR/$tdir/subdir
20288         touch $DIR/$tdir/subdir/f2
20289         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20290                 error "wrong default striping in file 2"
20291         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20292                 error "bad pattern in file 2"
20293         return 0
20294 }
20295 run_test 270d "DoM: change striping from DoM to RAID0"
20296
20297 test_270e() {
20298         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20299                 skip "Need MDS version at least 2.10.55"
20300
20301         mkdir -p $DIR/$tdir/dom
20302         mkdir -p $DIR/$tdir/norm
20303         DOMFILES=20
20304         NORMFILES=10
20305         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20306         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20307
20308         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20309         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20310
20311         # find DoM files by layout
20312         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20313         [ $NUM -eq  $DOMFILES ] ||
20314                 error "lfs find -L: found $NUM, expected $DOMFILES"
20315         echo "Test 1: lfs find 20 DOM files by layout: OK"
20316
20317         # there should be 1 dir with default DOM striping
20318         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20319         [ $NUM -eq  1 ] ||
20320                 error "lfs find -L: found $NUM, expected 1 dir"
20321         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20322
20323         # find DoM files by stripe size
20324         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20325         [ $NUM -eq  $DOMFILES ] ||
20326                 error "lfs find -S: found $NUM, expected $DOMFILES"
20327         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20328
20329         # find files by stripe offset except DoM files
20330         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20331         [ $NUM -eq  $NORMFILES ] ||
20332                 error "lfs find -i: found $NUM, expected $NORMFILES"
20333         echo "Test 5: lfs find no DOM files by stripe index: OK"
20334         return 0
20335 }
20336 run_test 270e "DoM: lfs find with DoM files test"
20337
20338 test_270f() {
20339         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20340                 skip "Need MDS version at least 2.10.55"
20341
20342         local mdtname=${FSNAME}-MDT0000-mdtlov
20343         local dom=$DIR/$tdir/dom_file
20344         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20345                                                 lod.$mdtname.dom_stripesize)
20346         local dom_limit=131072
20347
20348         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20349         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20350                                                 lod.$mdtname.dom_stripesize)
20351         [ ${dom_limit} -eq ${dom_current} ] ||
20352                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20353
20354         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20355         $LFS setstripe -d $DIR/$tdir
20356         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20357                 error "Can't set directory default striping"
20358
20359         # exceed maximum stripe size
20360         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20361                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20362         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20363                 error "Able to create DoM component size more than LOD limit"
20364
20365         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20366         dom_current=$(do_facet mds1 $LCTL get_param -n \
20367                                                 lod.$mdtname.dom_stripesize)
20368         [ 0 -eq ${dom_current} ] ||
20369                 error "Can't set zero DoM stripe limit"
20370         rm $dom
20371
20372         # attempt to create DoM file on server with disabled DoM should
20373         # remove DoM entry from layout and be succeed
20374         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20375                 error "Can't create DoM file (DoM is disabled)"
20376         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20377                 error "File has DoM component while DoM is disabled"
20378         rm $dom
20379
20380         # attempt to create DoM file with only DoM stripe should return error
20381         $LFS setstripe -E $dom_limit -L mdt $dom &&
20382                 error "Able to create DoM-only file while DoM is disabled"
20383
20384         # too low values to be aligned with smallest stripe size 64K
20385         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20386         dom_current=$(do_facet mds1 $LCTL get_param -n \
20387                                                 lod.$mdtname.dom_stripesize)
20388         [ 30000 -eq ${dom_current} ] &&
20389                 error "Can set too small DoM stripe limit"
20390
20391         # 64K is a minimal stripe size in Lustre, expect limit of that size
20392         [ 65536 -eq ${dom_current} ] ||
20393                 error "Limit is not set to 64K but ${dom_current}"
20394
20395         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20396         dom_current=$(do_facet mds1 $LCTL get_param -n \
20397                                                 lod.$mdtname.dom_stripesize)
20398         echo $dom_current
20399         [ 2147483648 -eq ${dom_current} ] &&
20400                 error "Can set too large DoM stripe limit"
20401
20402         do_facet mds1 $LCTL set_param -n \
20403                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20404         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20405                 error "Can't create DoM component size after limit change"
20406         do_facet mds1 $LCTL set_param -n \
20407                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20408         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20409                 error "Can't create DoM file after limit decrease"
20410         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20411                 error "Can create big DoM component after limit decrease"
20412         touch ${dom}_def ||
20413                 error "Can't create file with old default layout"
20414
20415         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20416         return 0
20417 }
20418 run_test 270f "DoM: maximum DoM stripe size checks"
20419
20420 test_270g() {
20421         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20422                 skip "Need MDS version at least 2.13.52"
20423         local dom=$DIR/$tdir/$tfile
20424
20425         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20426         local lodname=${FSNAME}-MDT0000-mdtlov
20427
20428         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20429         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20430         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20431         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20432
20433         local dom_limit=1024
20434         local dom_threshold="50%"
20435
20436         $LFS setstripe -d $DIR/$tdir
20437         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20438                 error "Can't set directory default striping"
20439
20440         do_facet mds1 $LCTL set_param -n \
20441                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20442         # set 0 threshold and create DOM file to change tunable stripesize
20443         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20444         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20445                 error "Failed to create $dom file"
20446         # now tunable dom_cur_stripesize should reach maximum
20447         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20448                                         lod.${lodname}.dom_stripesize_cur_kb)
20449         [[ $dom_current == $dom_limit ]] ||
20450                 error "Current DOM stripesize is not maximum"
20451         rm $dom
20452
20453         # set threshold for further tests
20454         do_facet mds1 $LCTL set_param -n \
20455                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20456         echo "DOM threshold is $dom_threshold free space"
20457         local dom_def
20458         local dom_set
20459         # Spoof bfree to exceed threshold
20460         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20461         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20462         for spfree in 40 20 0 15 30 55; do
20463                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20464                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20465                         error "Failed to create $dom file"
20466                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20467                                         lod.${lodname}.dom_stripesize_cur_kb)
20468                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20469                 [[ $dom_def != $dom_current ]] ||
20470                         error "Default stripe size was not changed"
20471                 if [[ $spfree > 0 ]] ; then
20472                         dom_set=$($LFS getstripe -S $dom)
20473                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20474                                 error "DOM component size is still old"
20475                 else
20476                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20477                                 error "DoM component is set with no free space"
20478                 fi
20479                 rm $dom
20480                 dom_current=$dom_def
20481         done
20482 }
20483 run_test 270g "DoM: default DoM stripe size depends on free space"
20484
20485 test_270h() {
20486         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20487                 skip "Need MDS version at least 2.13.53"
20488
20489         local mdtname=${FSNAME}-MDT0000-mdtlov
20490         local dom=$DIR/$tdir/$tfile
20491         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20492
20493         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20494         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20495
20496         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20497         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20498                 error "can't create OST file"
20499         # mirrored file with DOM entry in the second mirror
20500         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20501                 error "can't create mirror with DoM component"
20502
20503         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20504
20505         # DOM component in the middle and has other enries in the same mirror,
20506         # should succeed but lost DoM component
20507         $LFS setstripe --copy=${dom}_1 $dom ||
20508                 error "Can't create file from OST|DOM mirror layout"
20509         # check new file has no DoM layout after all
20510         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20511                 error "File has DoM component while DoM is disabled"
20512 }
20513 run_test 270h "DoM: DoM stripe removal when disabled on server"
20514
20515 test_271a() {
20516         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20517                 skip "Need MDS version at least 2.10.55"
20518
20519         local dom=$DIR/$tdir/dom
20520
20521         mkdir -p $DIR/$tdir
20522
20523         $LFS setstripe -E 1024K -L mdt $dom
20524
20525         lctl set_param -n mdc.*.stats=clear
20526         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20527         cat $dom > /dev/null
20528         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20529         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20530         ls $dom
20531         rm -f $dom
20532 }
20533 run_test 271a "DoM: data is cached for read after write"
20534
20535 test_271b() {
20536         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20537                 skip "Need MDS version at least 2.10.55"
20538
20539         local dom=$DIR/$tdir/dom
20540
20541         mkdir -p $DIR/$tdir
20542
20543         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20544
20545         lctl set_param -n mdc.*.stats=clear
20546         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20547         cancel_lru_locks mdc
20548         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20549         # second stat to check size is cached on client
20550         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20551         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20552         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20553         rm -f $dom
20554 }
20555 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20556
20557 test_271ba() {
20558         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20559                 skip "Need MDS version at least 2.10.55"
20560
20561         local dom=$DIR/$tdir/dom
20562
20563         mkdir -p $DIR/$tdir
20564
20565         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20566
20567         lctl set_param -n mdc.*.stats=clear
20568         lctl set_param -n osc.*.stats=clear
20569         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20570         cancel_lru_locks mdc
20571         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20572         # second stat to check size is cached on client
20573         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20574         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20575         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20576         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20577         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20578         rm -f $dom
20579 }
20580 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20581
20582
20583 get_mdc_stats() {
20584         local mdtidx=$1
20585         local param=$2
20586         local mdt=MDT$(printf %04x $mdtidx)
20587
20588         if [ -z $param ]; then
20589                 lctl get_param -n mdc.*$mdt*.stats
20590         else
20591                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20592         fi
20593 }
20594
20595 test_271c() {
20596         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20597                 skip "Need MDS version at least 2.10.55"
20598
20599         local dom=$DIR/$tdir/dom
20600
20601         mkdir -p $DIR/$tdir
20602
20603         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20604
20605         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20606         local facet=mds$((mdtidx + 1))
20607
20608         cancel_lru_locks mdc
20609         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20610         createmany -o $dom 1000
20611         lctl set_param -n mdc.*.stats=clear
20612         smalliomany -w $dom 1000 200
20613         get_mdc_stats $mdtidx
20614         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20615         # Each file has 1 open, 1 IO enqueues, total 2000
20616         # but now we have also +1 getxattr for security.capability, total 3000
20617         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20618         unlinkmany $dom 1000
20619
20620         cancel_lru_locks mdc
20621         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20622         createmany -o $dom 1000
20623         lctl set_param -n mdc.*.stats=clear
20624         smalliomany -w $dom 1000 200
20625         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20626         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20627         # for OPEN and IO lock.
20628         [ $((enq - enq_2)) -ge 1000 ] ||
20629                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20630         unlinkmany $dom 1000
20631         return 0
20632 }
20633 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20634
20635 cleanup_271def_tests() {
20636         trap 0
20637         rm -f $1
20638 }
20639
20640 test_271d() {
20641         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20642                 skip "Need MDS version at least 2.10.57"
20643
20644         local dom=$DIR/$tdir/dom
20645         local tmp=$TMP/$tfile
20646         trap "cleanup_271def_tests $tmp" EXIT
20647
20648         mkdir -p $DIR/$tdir
20649
20650         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20651
20652         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20653
20654         cancel_lru_locks mdc
20655         dd if=/dev/urandom of=$tmp bs=1000 count=1
20656         dd if=$tmp of=$dom bs=1000 count=1
20657         cancel_lru_locks mdc
20658
20659         cat /etc/hosts >> $tmp
20660         lctl set_param -n mdc.*.stats=clear
20661
20662         # append data to the same file it should update local page
20663         echo "Append to the same page"
20664         cat /etc/hosts >> $dom
20665         local num=$(get_mdc_stats $mdtidx ost_read)
20666         local ra=$(get_mdc_stats $mdtidx req_active)
20667         local rw=$(get_mdc_stats $mdtidx req_waittime)
20668
20669         [ -z $num ] || error "$num READ RPC occured"
20670         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20671         echo "... DONE"
20672
20673         # compare content
20674         cmp $tmp $dom || error "file miscompare"
20675
20676         cancel_lru_locks mdc
20677         lctl set_param -n mdc.*.stats=clear
20678
20679         echo "Open and read file"
20680         cat $dom > /dev/null
20681         local num=$(get_mdc_stats $mdtidx ost_read)
20682         local ra=$(get_mdc_stats $mdtidx req_active)
20683         local rw=$(get_mdc_stats $mdtidx req_waittime)
20684
20685         [ -z $num ] || error "$num READ RPC occured"
20686         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20687         echo "... DONE"
20688
20689         # compare content
20690         cmp $tmp $dom || error "file miscompare"
20691
20692         return 0
20693 }
20694 run_test 271d "DoM: read on open (1K file in reply buffer)"
20695
20696 test_271f() {
20697         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20698                 skip "Need MDS version at least 2.10.57"
20699
20700         local dom=$DIR/$tdir/dom
20701         local tmp=$TMP/$tfile
20702         trap "cleanup_271def_tests $tmp" EXIT
20703
20704         mkdir -p $DIR/$tdir
20705
20706         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20707
20708         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20709
20710         cancel_lru_locks mdc
20711         dd if=/dev/urandom of=$tmp bs=265000 count=1
20712         dd if=$tmp of=$dom bs=265000 count=1
20713         cancel_lru_locks mdc
20714         cat /etc/hosts >> $tmp
20715         lctl set_param -n mdc.*.stats=clear
20716
20717         echo "Append to the same page"
20718         cat /etc/hosts >> $dom
20719         local num=$(get_mdc_stats $mdtidx ost_read)
20720         local ra=$(get_mdc_stats $mdtidx req_active)
20721         local rw=$(get_mdc_stats $mdtidx req_waittime)
20722
20723         [ -z $num ] || error "$num READ RPC occured"
20724         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20725         echo "... DONE"
20726
20727         # compare content
20728         cmp $tmp $dom || error "file miscompare"
20729
20730         cancel_lru_locks mdc
20731         lctl set_param -n mdc.*.stats=clear
20732
20733         echo "Open and read file"
20734         cat $dom > /dev/null
20735         local num=$(get_mdc_stats $mdtidx ost_read)
20736         local ra=$(get_mdc_stats $mdtidx req_active)
20737         local rw=$(get_mdc_stats $mdtidx req_waittime)
20738
20739         [ -z $num ] && num=0
20740         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20741         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20742         echo "... DONE"
20743
20744         # compare content
20745         cmp $tmp $dom || error "file miscompare"
20746
20747         return 0
20748 }
20749 run_test 271f "DoM: read on open (200K file and read tail)"
20750
20751 test_271g() {
20752         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20753                 skip "Skipping due to old client or server version"
20754
20755         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20756         # to get layout
20757         $CHECKSTAT -t file $DIR1/$tfile
20758
20759         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20760         MULTIOP_PID=$!
20761         sleep 1
20762         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20763         $LCTL set_param fail_loc=0x80000314
20764         rm $DIR1/$tfile || error "Unlink fails"
20765         RC=$?
20766         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20767         [ $RC -eq 0 ] || error "Failed write to stale object"
20768 }
20769 run_test 271g "Discard DoM data vs client flush race"
20770
20771 test_272a() {
20772         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20773                 skip "Need MDS version at least 2.11.50"
20774
20775         local dom=$DIR/$tdir/dom
20776         mkdir -p $DIR/$tdir
20777
20778         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20779         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20780                 error "failed to write data into $dom"
20781         local old_md5=$(md5sum $dom)
20782
20783         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20784                 error "failed to migrate to the same DoM component"
20785
20786         local new_md5=$(md5sum $dom)
20787
20788         [ "$old_md5" == "$new_md5" ] ||
20789                 error "md5sum differ: $old_md5, $new_md5"
20790
20791         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20792                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20793 }
20794 run_test 272a "DoM migration: new layout with the same DOM component"
20795
20796 test_272b() {
20797         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20798                 skip "Need MDS version at least 2.11.50"
20799
20800         local dom=$DIR/$tdir/dom
20801         mkdir -p $DIR/$tdir
20802         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20803
20804         local mdtidx=$($LFS getstripe -m $dom)
20805         local mdtname=MDT$(printf %04x $mdtidx)
20806         local facet=mds$((mdtidx + 1))
20807
20808         local mdtfree1=$(do_facet $facet \
20809                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20810         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20811                 error "failed to write data into $dom"
20812         local old_md5=$(md5sum $dom)
20813         cancel_lru_locks mdc
20814         local mdtfree1=$(do_facet $facet \
20815                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20816
20817         $LFS migrate -c2 $dom ||
20818                 error "failed to migrate to the new composite layout"
20819         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20820                 error "MDT stripe was not removed"
20821
20822         cancel_lru_locks mdc
20823         local new_md5=$(md5sum $dom)
20824         [ "$old_md5" == "$new_md5" ] ||
20825                 error "$old_md5 != $new_md5"
20826
20827         # Skip free space checks with ZFS
20828         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20829                 local mdtfree2=$(do_facet $facet \
20830                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20831                 [ $mdtfree2 -gt $mdtfree1 ] ||
20832                         error "MDT space is not freed after migration"
20833         fi
20834         return 0
20835 }
20836 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20837
20838 test_272c() {
20839         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20840                 skip "Need MDS version at least 2.11.50"
20841
20842         local dom=$DIR/$tdir/$tfile
20843         mkdir -p $DIR/$tdir
20844         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20845
20846         local mdtidx=$($LFS getstripe -m $dom)
20847         local mdtname=MDT$(printf %04x $mdtidx)
20848         local facet=mds$((mdtidx + 1))
20849
20850         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20851                 error "failed to write data into $dom"
20852         local old_md5=$(md5sum $dom)
20853         cancel_lru_locks mdc
20854         local mdtfree1=$(do_facet $facet \
20855                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20856
20857         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20858                 error "failed to migrate to the new composite layout"
20859         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20860                 error "MDT stripe was not removed"
20861
20862         cancel_lru_locks mdc
20863         local new_md5=$(md5sum $dom)
20864         [ "$old_md5" == "$new_md5" ] ||
20865                 error "$old_md5 != $new_md5"
20866
20867         # Skip free space checks with ZFS
20868         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20869                 local mdtfree2=$(do_facet $facet \
20870                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20871                 [ $mdtfree2 -gt $mdtfree1 ] ||
20872                         error "MDS space is not freed after migration"
20873         fi
20874         return 0
20875 }
20876 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20877
20878 test_272d() {
20879         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20880                 skip "Need MDS version at least 2.12.55"
20881
20882         local dom=$DIR/$tdir/$tfile
20883         mkdir -p $DIR/$tdir
20884         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20885
20886         local mdtidx=$($LFS getstripe -m $dom)
20887         local mdtname=MDT$(printf %04x $mdtidx)
20888         local facet=mds$((mdtidx + 1))
20889
20890         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20891                 error "failed to write data into $dom"
20892         local old_md5=$(md5sum $dom)
20893         cancel_lru_locks mdc
20894         local mdtfree1=$(do_facet $facet \
20895                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20896
20897         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20898                 error "failed mirroring to the new composite layout"
20899         $LFS mirror resync $dom ||
20900                 error "failed mirror resync"
20901         $LFS mirror split --mirror-id 1 -d $dom ||
20902                 error "failed mirror split"
20903
20904         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20905                 error "MDT stripe was not removed"
20906
20907         cancel_lru_locks mdc
20908         local new_md5=$(md5sum $dom)
20909         [ "$old_md5" == "$new_md5" ] ||
20910                 error "$old_md5 != $new_md5"
20911
20912         # Skip free space checks with ZFS
20913         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20914                 local mdtfree2=$(do_facet $facet \
20915                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20916                 [ $mdtfree2 -gt $mdtfree1 ] ||
20917                         error "MDS space is not freed after DOM mirror deletion"
20918         fi
20919         return 0
20920 }
20921 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20922
20923 test_272e() {
20924         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20925                 skip "Need MDS version at least 2.12.55"
20926
20927         local dom=$DIR/$tdir/$tfile
20928         mkdir -p $DIR/$tdir
20929         $LFS setstripe -c 2 $dom
20930
20931         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20932                 error "failed to write data into $dom"
20933         local old_md5=$(md5sum $dom)
20934         cancel_lru_locks mdc
20935
20936         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20937                 error "failed mirroring to the DOM layout"
20938         $LFS mirror resync $dom ||
20939                 error "failed mirror resync"
20940         $LFS mirror split --mirror-id 1 -d $dom ||
20941                 error "failed mirror split"
20942
20943         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20944                 error "MDT stripe was not removed"
20945
20946         cancel_lru_locks mdc
20947         local new_md5=$(md5sum $dom)
20948         [ "$old_md5" == "$new_md5" ] ||
20949                 error "$old_md5 != $new_md5"
20950
20951         return 0
20952 }
20953 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20954
20955 test_272f() {
20956         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20957                 skip "Need MDS version at least 2.12.55"
20958
20959         local dom=$DIR/$tdir/$tfile
20960         mkdir -p $DIR/$tdir
20961         $LFS setstripe -c 2 $dom
20962
20963         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20964                 error "failed to write data into $dom"
20965         local old_md5=$(md5sum $dom)
20966         cancel_lru_locks mdc
20967
20968         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20969                 error "failed migrating to the DOM file"
20970
20971         cancel_lru_locks mdc
20972         local new_md5=$(md5sum $dom)
20973         [ "$old_md5" != "$new_md5" ] &&
20974                 error "$old_md5 != $new_md5"
20975
20976         return 0
20977 }
20978 run_test 272f "DoM migration: OST-striped file to DOM file"
20979
20980 test_273a() {
20981         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20982                 skip "Need MDS version at least 2.11.50"
20983
20984         # Layout swap cannot be done if either file has DOM component,
20985         # this will never be supported, migration should be used instead
20986
20987         local dom=$DIR/$tdir/$tfile
20988         mkdir -p $DIR/$tdir
20989
20990         $LFS setstripe -c2 ${dom}_plain
20991         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20992         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20993                 error "can swap layout with DoM component"
20994         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20995                 error "can swap layout with DoM component"
20996
20997         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20998         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20999                 error "can swap layout with DoM component"
21000         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21001                 error "can swap layout with DoM component"
21002         return 0
21003 }
21004 run_test 273a "DoM: layout swapping should fail with DOM"
21005
21006 test_275() {
21007         remote_ost_nodsh && skip "remote OST with nodsh"
21008         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21009                 skip "Need OST version >= 2.10.57"
21010
21011         local file=$DIR/$tfile
21012         local oss
21013
21014         oss=$(comma_list $(osts_nodes))
21015
21016         dd if=/dev/urandom of=$file bs=1M count=2 ||
21017                 error "failed to create a file"
21018         cancel_lru_locks osc
21019
21020         #lock 1
21021         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21022                 error "failed to read a file"
21023
21024 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21025         $LCTL set_param fail_loc=0x8000031f
21026
21027         cancel_lru_locks osc &
21028         sleep 1
21029
21030 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21031         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21032         #IO takes another lock, but matches the PENDING one
21033         #and places it to the IO RPC
21034         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21035                 error "failed to read a file with PENDING lock"
21036 }
21037 run_test 275 "Read on a canceled duplicate lock"
21038
21039 test_276() {
21040         remote_ost_nodsh && skip "remote OST with nodsh"
21041         local pid
21042
21043         do_facet ost1 "(while true; do \
21044                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21045                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21046         pid=$!
21047
21048         for LOOP in $(seq 20); do
21049                 stop ost1
21050                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21051         done
21052         kill -9 $pid
21053         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21054                 rm $TMP/sanity_276_pid"
21055 }
21056 run_test 276 "Race between mount and obd_statfs"
21057
21058 test_277() {
21059         $LCTL set_param ldlm.namespaces.*.lru_size=0
21060         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21061         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21062                         grep ^used_mb | awk '{print $2}')
21063         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21064         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21065                 oflag=direct conv=notrunc
21066         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21067                         grep ^used_mb | awk '{print $2}')
21068         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21069 }
21070 run_test 277 "Direct IO shall drop page cache"
21071
21072 test_278() {
21073         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21074         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21075         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21076                 skip "needs the same host for mdt1 mdt2" && return
21077
21078         local pid1
21079         local pid2
21080
21081 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21082         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21083         stop mds2 &
21084         pid2=$!
21085
21086         stop mds1
21087
21088         echo "Starting MDTs"
21089         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21090         wait $pid2
21091 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21092 #will return NULL
21093         do_facet mds2 $LCTL set_param fail_loc=0
21094
21095         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21096         wait_recovery_complete mds2
21097 }
21098 run_test 278 "Race starting MDS between MDTs stop/start"
21099
21100 test_280() {
21101         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21102                 skip "Need MGS version at least 2.13.52"
21103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21104         combined_mgs_mds || skip "needs combined MGS/MDT"
21105
21106         umount_client $MOUNT
21107 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21108         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21109
21110         mount_client $MOUNT &
21111         sleep 1
21112         stop mgs || error "stop mgs failed"
21113         #for a race mgs would crash
21114         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21115         mount_client $MOUNT || error "mount client failed"
21116 }
21117 run_test 280 "Race between MGS umount and client llog processing"
21118
21119 cleanup_test_300() {
21120         trap 0
21121         umask $SAVE_UMASK
21122 }
21123 test_striped_dir() {
21124         local mdt_index=$1
21125         local stripe_count
21126         local stripe_index
21127
21128         mkdir -p $DIR/$tdir
21129
21130         SAVE_UMASK=$(umask)
21131         trap cleanup_test_300 RETURN EXIT
21132
21133         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21134                                                 $DIR/$tdir/striped_dir ||
21135                 error "set striped dir error"
21136
21137         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21138         [ "$mode" = "755" ] || error "expect 755 got $mode"
21139
21140         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21141                 error "getdirstripe failed"
21142         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21143         if [ "$stripe_count" != "2" ]; then
21144                 error "1:stripe_count is $stripe_count, expect 2"
21145         fi
21146         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21147         if [ "$stripe_count" != "2" ]; then
21148                 error "2:stripe_count is $stripe_count, expect 2"
21149         fi
21150
21151         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21152         if [ "$stripe_index" != "$mdt_index" ]; then
21153                 error "stripe_index is $stripe_index, expect $mdt_index"
21154         fi
21155
21156         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21157                 error "nlink error after create striped dir"
21158
21159         mkdir $DIR/$tdir/striped_dir/a
21160         mkdir $DIR/$tdir/striped_dir/b
21161
21162         stat $DIR/$tdir/striped_dir/a ||
21163                 error "create dir under striped dir failed"
21164         stat $DIR/$tdir/striped_dir/b ||
21165                 error "create dir under striped dir failed"
21166
21167         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21168                 error "nlink error after mkdir"
21169
21170         rmdir $DIR/$tdir/striped_dir/a
21171         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21172                 error "nlink error after rmdir"
21173
21174         rmdir $DIR/$tdir/striped_dir/b
21175         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21176                 error "nlink error after rmdir"
21177
21178         chattr +i $DIR/$tdir/striped_dir
21179         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21180                 error "immutable flags not working under striped dir!"
21181         chattr -i $DIR/$tdir/striped_dir
21182
21183         rmdir $DIR/$tdir/striped_dir ||
21184                 error "rmdir striped dir error"
21185
21186         cleanup_test_300
21187
21188         true
21189 }
21190
21191 test_300a() {
21192         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21193                 skip "skipped for lustre < 2.7.0"
21194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21196
21197         test_striped_dir 0 || error "failed on striped dir on MDT0"
21198         test_striped_dir 1 || error "failed on striped dir on MDT0"
21199 }
21200 run_test 300a "basic striped dir sanity test"
21201
21202 test_300b() {
21203         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21204                 skip "skipped for lustre < 2.7.0"
21205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21207
21208         local i
21209         local mtime1
21210         local mtime2
21211         local mtime3
21212
21213         test_mkdir $DIR/$tdir || error "mkdir fail"
21214         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21215                 error "set striped dir error"
21216         for i in {0..9}; do
21217                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21218                 sleep 1
21219                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21220                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21221                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21222                 sleep 1
21223                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21224                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21225                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21226         done
21227         true
21228 }
21229 run_test 300b "check ctime/mtime for striped dir"
21230
21231 test_300c() {
21232         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21233                 skip "skipped for lustre < 2.7.0"
21234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21236
21237         local file_count
21238
21239         mkdir -p $DIR/$tdir
21240         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21241                 error "set striped dir error"
21242
21243         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21244                 error "chown striped dir failed"
21245
21246         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21247                 error "create 5k files failed"
21248
21249         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21250
21251         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21252
21253         rm -rf $DIR/$tdir
21254 }
21255 run_test 300c "chown && check ls under striped directory"
21256
21257 test_300d() {
21258         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21259                 skip "skipped for lustre < 2.7.0"
21260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21262
21263         local stripe_count
21264         local file
21265
21266         mkdir -p $DIR/$tdir
21267         $LFS setstripe -c 2 $DIR/$tdir
21268
21269         #local striped directory
21270         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21271                 error "set striped dir error"
21272         #look at the directories for debug purposes
21273         ls -l $DIR/$tdir
21274         $LFS getdirstripe $DIR/$tdir
21275         ls -l $DIR/$tdir/striped_dir
21276         $LFS getdirstripe $DIR/$tdir/striped_dir
21277         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21278                 error "create 10 files failed"
21279
21280         #remote striped directory
21281         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21282                 error "set striped dir error"
21283         #look at the directories for debug purposes
21284         ls -l $DIR/$tdir
21285         $LFS getdirstripe $DIR/$tdir
21286         ls -l $DIR/$tdir/remote_striped_dir
21287         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21288         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21289                 error "create 10 files failed"
21290
21291         for file in $(find $DIR/$tdir); do
21292                 stripe_count=$($LFS getstripe -c $file)
21293                 [ $stripe_count -eq 2 ] ||
21294                         error "wrong stripe $stripe_count for $file"
21295         done
21296
21297         rm -rf $DIR/$tdir
21298 }
21299 run_test 300d "check default stripe under striped directory"
21300
21301 test_300e() {
21302         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21303                 skip "Need MDS version at least 2.7.55"
21304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21306
21307         local stripe_count
21308         local file
21309
21310         mkdir -p $DIR/$tdir
21311
21312         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21313                 error "set striped dir error"
21314
21315         touch $DIR/$tdir/striped_dir/a
21316         touch $DIR/$tdir/striped_dir/b
21317         touch $DIR/$tdir/striped_dir/c
21318
21319         mkdir $DIR/$tdir/striped_dir/dir_a
21320         mkdir $DIR/$tdir/striped_dir/dir_b
21321         mkdir $DIR/$tdir/striped_dir/dir_c
21322
21323         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21324                 error "set striped adir under striped dir error"
21325
21326         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21327                 error "set striped bdir under striped dir error"
21328
21329         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21330                 error "set striped cdir under striped dir error"
21331
21332         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21333                 error "rename dir under striped dir fails"
21334
21335         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21336                 error "rename dir under different stripes fails"
21337
21338         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21339                 error "rename file under striped dir should succeed"
21340
21341         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21342                 error "rename dir under striped dir should succeed"
21343
21344         rm -rf $DIR/$tdir
21345 }
21346 run_test 300e "check rename under striped directory"
21347
21348 test_300f() {
21349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21351         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21352                 skip "Need MDS version at least 2.7.55"
21353
21354         local stripe_count
21355         local file
21356
21357         rm -rf $DIR/$tdir
21358         mkdir -p $DIR/$tdir
21359
21360         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21361                 error "set striped dir error"
21362
21363         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21364                 error "set striped dir error"
21365
21366         touch $DIR/$tdir/striped_dir/a
21367         mkdir $DIR/$tdir/striped_dir/dir_a
21368         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21369                 error "create striped dir under striped dir fails"
21370
21371         touch $DIR/$tdir/striped_dir1/b
21372         mkdir $DIR/$tdir/striped_dir1/dir_b
21373         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21374                 error "create striped dir under striped dir fails"
21375
21376         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21377                 error "rename dir under different striped dir should fail"
21378
21379         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21380                 error "rename striped dir under diff striped dir should fail"
21381
21382         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21383                 error "rename file under diff striped dirs fails"
21384
21385         rm -rf $DIR/$tdir
21386 }
21387 run_test 300f "check rename cross striped directory"
21388
21389 test_300_check_default_striped_dir()
21390 {
21391         local dirname=$1
21392         local default_count=$2
21393         local default_index=$3
21394         local stripe_count
21395         local stripe_index
21396         local dir_stripe_index
21397         local dir
21398
21399         echo "checking $dirname $default_count $default_index"
21400         $LFS setdirstripe -D -c $default_count -i $default_index \
21401                                 -t all_char $DIR/$tdir/$dirname ||
21402                 error "set default stripe on striped dir error"
21403         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21404         [ $stripe_count -eq $default_count ] ||
21405                 error "expect $default_count get $stripe_count for $dirname"
21406
21407         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21408         [ $stripe_index -eq $default_index ] ||
21409                 error "expect $default_index get $stripe_index for $dirname"
21410
21411         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21412                                                 error "create dirs failed"
21413
21414         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21415         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21416         for dir in $(find $DIR/$tdir/$dirname/*); do
21417                 stripe_count=$($LFS getdirstripe -c $dir)
21418                 [ $stripe_count -eq $default_count ] ||
21419                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21420                 error "stripe count $default_count != $stripe_count for $dir"
21421
21422                 stripe_index=$($LFS getdirstripe -i $dir)
21423                 [ $default_index -eq -1 ] ||
21424                         [ $stripe_index -eq $default_index ] ||
21425                         error "$stripe_index != $default_index for $dir"
21426
21427                 #check default stripe
21428                 stripe_count=$($LFS getdirstripe -D -c $dir)
21429                 [ $stripe_count -eq $default_count ] ||
21430                 error "default count $default_count != $stripe_count for $dir"
21431
21432                 stripe_index=$($LFS getdirstripe -D -i $dir)
21433                 [ $stripe_index -eq $default_index ] ||
21434                 error "default index $default_index != $stripe_index for $dir"
21435         done
21436         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21437 }
21438
21439 test_300g() {
21440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21441         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21442                 skip "Need MDS version at least 2.7.55"
21443
21444         local dir
21445         local stripe_count
21446         local stripe_index
21447
21448         mkdir $DIR/$tdir
21449         mkdir $DIR/$tdir/normal_dir
21450
21451         #Checking when client cache stripe index
21452         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21453         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21454                 error "create striped_dir failed"
21455
21456         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21457                 error "create dir0 fails"
21458         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21459         [ $stripe_index -eq 0 ] ||
21460                 error "dir0 expect index 0 got $stripe_index"
21461
21462         mkdir $DIR/$tdir/striped_dir/dir1 ||
21463                 error "create dir1 fails"
21464         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21465         [ $stripe_index -eq 1 ] ||
21466                 error "dir1 expect index 1 got $stripe_index"
21467
21468         #check default stripe count/stripe index
21469         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21470         test_300_check_default_striped_dir normal_dir 1 0
21471         test_300_check_default_striped_dir normal_dir 2 1
21472         test_300_check_default_striped_dir normal_dir 2 -1
21473
21474         #delete default stripe information
21475         echo "delete default stripeEA"
21476         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21477                 error "set default stripe on striped dir error"
21478
21479         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21480         for dir in $(find $DIR/$tdir/normal_dir/*); do
21481                 stripe_count=$($LFS getdirstripe -c $dir)
21482                 [ $stripe_count -eq 0 ] ||
21483                         error "expect 1 get $stripe_count for $dir"
21484                 stripe_index=$($LFS getdirstripe -i $dir)
21485                 [ $stripe_index -eq 0 ] ||
21486                         error "expect 0 get $stripe_index for $dir"
21487         done
21488 }
21489 run_test 300g "check default striped directory for normal directory"
21490
21491 test_300h() {
21492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21493         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21494                 skip "Need MDS version at least 2.7.55"
21495
21496         local dir
21497         local stripe_count
21498
21499         mkdir $DIR/$tdir
21500         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21501                 error "set striped dir error"
21502
21503         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21504         test_300_check_default_striped_dir striped_dir 1 0
21505         test_300_check_default_striped_dir striped_dir 2 1
21506         test_300_check_default_striped_dir striped_dir 2 -1
21507
21508         #delete default stripe information
21509         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21510                 error "set default stripe on striped dir error"
21511
21512         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21513         for dir in $(find $DIR/$tdir/striped_dir/*); do
21514                 stripe_count=$($LFS getdirstripe -c $dir)
21515                 [ $stripe_count -eq 0 ] ||
21516                         error "expect 1 get $stripe_count for $dir"
21517         done
21518 }
21519 run_test 300h "check default striped directory for striped directory"
21520
21521 test_300i() {
21522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21525                 skip "Need MDS version at least 2.7.55"
21526
21527         local stripe_count
21528         local file
21529
21530         mkdir $DIR/$tdir
21531
21532         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21533                 error "set striped dir error"
21534
21535         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21536                 error "create files under striped dir failed"
21537
21538         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21539                 error "set striped hashdir error"
21540
21541         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21542                 error "create dir0 under hash dir failed"
21543         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21544                 error "create dir1 under hash dir failed"
21545
21546         # unfortunately, we need to umount to clear dir layout cache for now
21547         # once we fully implement dir layout, we can drop this
21548         umount_client $MOUNT || error "umount failed"
21549         mount_client $MOUNT || error "mount failed"
21550
21551         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21552         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21553         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21554
21555         #set the stripe to be unknown hash type
21556         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21557         $LCTL set_param fail_loc=0x1901
21558         for ((i = 0; i < 10; i++)); do
21559                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21560                         error "stat f-$i failed"
21561                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21562         done
21563
21564         touch $DIR/$tdir/striped_dir/f0 &&
21565                 error "create under striped dir with unknown hash should fail"
21566
21567         $LCTL set_param fail_loc=0
21568
21569         umount_client $MOUNT || error "umount failed"
21570         mount_client $MOUNT || error "mount failed"
21571
21572         return 0
21573 }
21574 run_test 300i "client handle unknown hash type striped directory"
21575
21576 test_300j() {
21577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21579         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21580                 skip "Need MDS version at least 2.7.55"
21581
21582         local stripe_count
21583         local file
21584
21585         mkdir $DIR/$tdir
21586
21587         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21588         $LCTL set_param fail_loc=0x1702
21589         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21590                 error "set striped dir error"
21591
21592         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21593                 error "create files under striped dir failed"
21594
21595         $LCTL set_param fail_loc=0
21596
21597         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21598
21599         return 0
21600 }
21601 run_test 300j "test large update record"
21602
21603 test_300k() {
21604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21606         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21607                 skip "Need MDS version at least 2.7.55"
21608
21609         # this test needs a huge transaction
21610         local kb
21611         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21612              osd*.$FSNAME-MDT0000.kbytestotal")
21613         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21614
21615         local stripe_count
21616         local file
21617
21618         mkdir $DIR/$tdir
21619
21620         #define OBD_FAIL_LARGE_STRIPE   0x1703
21621         $LCTL set_param fail_loc=0x1703
21622         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21623                 error "set striped dir error"
21624         $LCTL set_param fail_loc=0
21625
21626         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21627                 error "getstripeddir fails"
21628         rm -rf $DIR/$tdir/striped_dir ||
21629                 error "unlink striped dir fails"
21630
21631         return 0
21632 }
21633 run_test 300k "test large striped directory"
21634
21635 test_300l() {
21636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21638         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21639                 skip "Need MDS version at least 2.7.55"
21640
21641         local stripe_index
21642
21643         test_mkdir -p $DIR/$tdir/striped_dir
21644         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21645                         error "chown $RUNAS_ID failed"
21646         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21647                 error "set default striped dir failed"
21648
21649         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21650         $LCTL set_param fail_loc=0x80000158
21651         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21652
21653         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21654         [ $stripe_index -eq 1 ] ||
21655                 error "expect 1 get $stripe_index for $dir"
21656 }
21657 run_test 300l "non-root user to create dir under striped dir with stale layout"
21658
21659 test_300m() {
21660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21661         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21662         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21663                 skip "Need MDS version at least 2.7.55"
21664
21665         mkdir -p $DIR/$tdir/striped_dir
21666         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21667                 error "set default stripes dir error"
21668
21669         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21670
21671         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21672         [ $stripe_count -eq 0 ] ||
21673                         error "expect 0 get $stripe_count for a"
21674
21675         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21676                 error "set default stripes dir error"
21677
21678         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21679
21680         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21681         [ $stripe_count -eq 0 ] ||
21682                         error "expect 0 get $stripe_count for b"
21683
21684         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21685                 error "set default stripes dir error"
21686
21687         mkdir $DIR/$tdir/striped_dir/c &&
21688                 error "default stripe_index is invalid, mkdir c should fails"
21689
21690         rm -rf $DIR/$tdir || error "rmdir fails"
21691 }
21692 run_test 300m "setstriped directory on single MDT FS"
21693
21694 cleanup_300n() {
21695         local list=$(comma_list $(mdts_nodes))
21696
21697         trap 0
21698         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21699 }
21700
21701 test_300n() {
21702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21704         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21705                 skip "Need MDS version at least 2.7.55"
21706         remote_mds_nodsh && skip "remote MDS with nodsh"
21707
21708         local stripe_index
21709         local list=$(comma_list $(mdts_nodes))
21710
21711         trap cleanup_300n RETURN EXIT
21712         mkdir -p $DIR/$tdir
21713         chmod 777 $DIR/$tdir
21714         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21715                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21716                 error "create striped dir succeeds with gid=0"
21717
21718         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21719         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21720                 error "create striped dir fails with gid=-1"
21721
21722         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21723         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21724                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21725                 error "set default striped dir succeeds with gid=0"
21726
21727
21728         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21729         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21730                 error "set default striped dir fails with gid=-1"
21731
21732
21733         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21734         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21735                                         error "create test_dir fails"
21736         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21737                                         error "create test_dir1 fails"
21738         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21739                                         error "create test_dir2 fails"
21740         cleanup_300n
21741 }
21742 run_test 300n "non-root user to create dir under striped dir with default EA"
21743
21744 test_300o() {
21745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21747         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21748                 skip "Need MDS version at least 2.7.55"
21749
21750         local numfree1
21751         local numfree2
21752
21753         mkdir -p $DIR/$tdir
21754
21755         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21756         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21757         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21758                 skip "not enough free inodes $numfree1 $numfree2"
21759         fi
21760
21761         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21762         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21763         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21764                 skip "not enough free space $numfree1 $numfree2"
21765         fi
21766
21767         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21768                 error "setdirstripe fails"
21769
21770         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21771                 error "create dirs fails"
21772
21773         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21774         ls $DIR/$tdir/striped_dir > /dev/null ||
21775                 error "ls striped dir fails"
21776         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21777                 error "unlink big striped dir fails"
21778 }
21779 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21780
21781 test_300p() {
21782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21784         remote_mds_nodsh && skip "remote MDS with nodsh"
21785
21786         mkdir -p $DIR/$tdir
21787
21788         #define OBD_FAIL_OUT_ENOSPC     0x1704
21789         do_facet mds2 lctl set_param fail_loc=0x80001704
21790         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21791                  && error "create striped directory should fail"
21792
21793         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21794
21795         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21796         true
21797 }
21798 run_test 300p "create striped directory without space"
21799
21800 test_300q() {
21801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21803
21804         local fd=$(free_fd)
21805         local cmd="exec $fd<$tdir"
21806         cd $DIR
21807         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21808         eval $cmd
21809         cmd="exec $fd<&-"
21810         trap "eval $cmd" EXIT
21811         cd $tdir || error "cd $tdir fails"
21812         rmdir  ../$tdir || error "rmdir $tdir fails"
21813         mkdir local_dir && error "create dir succeeds"
21814         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21815         eval $cmd
21816         return 0
21817 }
21818 run_test 300q "create remote directory under orphan directory"
21819
21820 test_300r() {
21821         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21822                 skip "Need MDS version at least 2.7.55" && return
21823         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21824
21825         mkdir $DIR/$tdir
21826
21827         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21828                 error "set striped dir error"
21829
21830         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21831                 error "getstripeddir fails"
21832
21833         local stripe_count
21834         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21835                       awk '/lmv_stripe_count:/ { print $2 }')
21836
21837         [ $MDSCOUNT -ne $stripe_count ] &&
21838                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21839
21840         rm -rf $DIR/$tdir/striped_dir ||
21841                 error "unlink striped dir fails"
21842 }
21843 run_test 300r "test -1 striped directory"
21844
21845 test_300s_helper() {
21846         local count=$1
21847
21848         local stripe_dir=$DIR/$tdir/striped_dir.$count
21849
21850         $LFS mkdir -c $count $stripe_dir ||
21851                 error "lfs mkdir -c error"
21852
21853         $LFS getdirstripe $stripe_dir ||
21854                 error "lfs getdirstripe fails"
21855
21856         local stripe_count
21857         stripe_count=$($LFS getdirstripe $stripe_dir |
21858                       awk '/lmv_stripe_count:/ { print $2 }')
21859
21860         [ $count -ne $stripe_count ] &&
21861                 error_noexit "bad stripe count $stripe_count expected $count"
21862
21863         local dupe_stripes
21864         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21865                 awk '/0x/ {count[$1] += 1}; END {
21866                         for (idx in count) {
21867                                 if (count[idx]>1) {
21868                                         print "index " idx " count " count[idx]
21869                                 }
21870                         }
21871                 }')
21872
21873         if [[ -n "$dupe_stripes" ]] ; then
21874                 lfs getdirstripe $stripe_dir
21875                 error_noexit "Dupe MDT above: $dupe_stripes "
21876         fi
21877
21878         rm -rf $stripe_dir ||
21879                 error_noexit "unlink $stripe_dir fails"
21880 }
21881
21882 test_300s() {
21883         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21884                 skip "Need MDS version at least 2.7.55" && return
21885         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21886
21887         mkdir $DIR/$tdir
21888         for count in $(seq 2 $MDSCOUNT); do
21889                 test_300s_helper $count
21890         done
21891 }
21892 run_test 300s "test lfs mkdir -c without -i"
21893
21894
21895 prepare_remote_file() {
21896         mkdir $DIR/$tdir/src_dir ||
21897                 error "create remote source failed"
21898
21899         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21900                  error "cp to remote source failed"
21901         touch $DIR/$tdir/src_dir/a
21902
21903         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21904                 error "create remote target dir failed"
21905
21906         touch $DIR/$tdir/tgt_dir/b
21907
21908         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21909                 error "rename dir cross MDT failed!"
21910
21911         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21912                 error "src_child still exists after rename"
21913
21914         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21915                 error "missing file(a) after rename"
21916
21917         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21918                 error "diff after rename"
21919 }
21920
21921 test_310a() {
21922         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21924
21925         local remote_file=$DIR/$tdir/tgt_dir/b
21926
21927         mkdir -p $DIR/$tdir
21928
21929         prepare_remote_file || error "prepare remote file failed"
21930
21931         #open-unlink file
21932         $OPENUNLINK $remote_file $remote_file ||
21933                 error "openunlink $remote_file failed"
21934         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21935 }
21936 run_test 310a "open unlink remote file"
21937
21938 test_310b() {
21939         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21941
21942         local remote_file=$DIR/$tdir/tgt_dir/b
21943
21944         mkdir -p $DIR/$tdir
21945
21946         prepare_remote_file || error "prepare remote file failed"
21947
21948         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21949         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21950         $CHECKSTAT -t file $remote_file || error "check file failed"
21951 }
21952 run_test 310b "unlink remote file with multiple links while open"
21953
21954 test_310c() {
21955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21956         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21957
21958         local remote_file=$DIR/$tdir/tgt_dir/b
21959
21960         mkdir -p $DIR/$tdir
21961
21962         prepare_remote_file || error "prepare remote file failed"
21963
21964         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21965         multiop_bg_pause $remote_file O_uc ||
21966                         error "mulitop failed for remote file"
21967         MULTIPID=$!
21968         $MULTIOP $DIR/$tfile Ouc
21969         kill -USR1 $MULTIPID
21970         wait $MULTIPID
21971 }
21972 run_test 310c "open-unlink remote file with multiple links"
21973
21974 #LU-4825
21975 test_311() {
21976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21977         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21978         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21979                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21980         remote_mds_nodsh && skip "remote MDS with nodsh"
21981
21982         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21983         local mdts=$(comma_list $(mdts_nodes))
21984
21985         mkdir -p $DIR/$tdir
21986         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21987         createmany -o $DIR/$tdir/$tfile. 1000
21988
21989         # statfs data is not real time, let's just calculate it
21990         old_iused=$((old_iused + 1000))
21991
21992         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21993                         osp.*OST0000*MDT0000.create_count")
21994         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21995                                 osp.*OST0000*MDT0000.max_create_count")
21996         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21997
21998         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21999         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22000         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22001
22002         unlinkmany $DIR/$tdir/$tfile. 1000
22003
22004         do_nodes $mdts "$LCTL set_param -n \
22005                         osp.*OST0000*.max_create_count=$max_count"
22006         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22007                 do_nodes $mdts "$LCTL set_param -n \
22008                                 osp.*OST0000*.create_count=$count"
22009         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22010                         grep "=0" && error "create_count is zero"
22011
22012         local new_iused
22013         for i in $(seq 120); do
22014                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22015                 # system may be too busy to destroy all objs in time, use
22016                 # a somewhat small value to not fail autotest
22017                 [ $((old_iused - new_iused)) -gt 400 ] && break
22018                 sleep 1
22019         done
22020
22021         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22022         [ $((old_iused - new_iused)) -gt 400 ] ||
22023                 error "objs not destroyed after unlink"
22024 }
22025 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22026
22027 zfs_oid_to_objid()
22028 {
22029         local ost=$1
22030         local objid=$2
22031
22032         local vdevdir=$(dirname $(facet_vdevice $ost))
22033         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22034         local zfs_zapid=$(do_facet $ost $cmd |
22035                           grep -w "/O/0/d$((objid%32))" -C 5 |
22036                           awk '/Object/{getline; print $1}')
22037         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22038                           awk "/$objid = /"'{printf $3}')
22039
22040         echo $zfs_objid
22041 }
22042
22043 zfs_object_blksz() {
22044         local ost=$1
22045         local objid=$2
22046
22047         local vdevdir=$(dirname $(facet_vdevice $ost))
22048         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22049         local blksz=$(do_facet $ost $cmd $objid |
22050                       awk '/dblk/{getline; printf $4}')
22051
22052         case "${blksz: -1}" in
22053                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22054                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22055                 *) ;;
22056         esac
22057
22058         echo $blksz
22059 }
22060
22061 test_312() { # LU-4856
22062         remote_ost_nodsh && skip "remote OST with nodsh"
22063         [ "$ost1_FSTYPE" = "zfs" ] ||
22064                 skip_env "the test only applies to zfs"
22065
22066         local max_blksz=$(do_facet ost1 \
22067                           $ZFS get -p recordsize $(facet_device ost1) |
22068                           awk '!/VALUE/{print $3}')
22069
22070         # to make life a little bit easier
22071         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22072         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22073
22074         local tf=$DIR/$tdir/$tfile
22075         touch $tf
22076         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22077
22078         # Get ZFS object id
22079         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22080         # block size change by sequential overwrite
22081         local bs
22082
22083         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22084                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22085
22086                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22087                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22088         done
22089         rm -f $tf
22090
22091         # block size change by sequential append write
22092         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22093         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22094         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22095         local count
22096
22097         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22098                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22099                         oflag=sync conv=notrunc
22100
22101                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22102                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22103                         error "blksz error, actual $blksz, " \
22104                                 "expected: 2 * $count * $PAGE_SIZE"
22105         done
22106         rm -f $tf
22107
22108         # random write
22109         touch $tf
22110         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22111         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22112
22113         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22114         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22115         [ $blksz -eq $PAGE_SIZE ] ||
22116                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22117
22118         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22119         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22120         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22121
22122         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22123         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22124         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22125 }
22126 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22127
22128 test_313() {
22129         remote_ost_nodsh && skip "remote OST with nodsh"
22130
22131         local file=$DIR/$tfile
22132
22133         rm -f $file
22134         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22135
22136         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22137         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22138         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22139                 error "write should failed"
22140         do_facet ost1 "$LCTL set_param fail_loc=0"
22141         rm -f $file
22142 }
22143 run_test 313 "io should fail after last_rcvd update fail"
22144
22145 test_314() {
22146         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22147
22148         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22149         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22150         rm -f $DIR/$tfile
22151         wait_delete_completed
22152         do_facet ost1 "$LCTL set_param fail_loc=0"
22153 }
22154 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22155
22156 test_315() { # LU-618
22157         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22158
22159         local file=$DIR/$tfile
22160         rm -f $file
22161
22162         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22163                 error "multiop file write failed"
22164         $MULTIOP $file oO_RDONLY:r4063232_c &
22165         PID=$!
22166
22167         sleep 2
22168
22169         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22170         kill -USR1 $PID
22171
22172         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22173         rm -f $file
22174 }
22175 run_test 315 "read should be accounted"
22176
22177 test_316() {
22178         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22179         large_xattr_enabled || skip_env "ea_inode feature disabled"
22180
22181         rm -rf $DIR/$tdir/d
22182         mkdir -p $DIR/$tdir/d
22183         chown nobody $DIR/$tdir/d
22184         touch $DIR/$tdir/d/file
22185
22186         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22187 }
22188 run_test 316 "lfs mv"
22189
22190 test_317() {
22191         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22192                 skip "Need MDS version at least 2.11.53"
22193         if [ "$ost1_FSTYPE" == "zfs" ]; then
22194                 skip "LU-10370: no implementation for ZFS"
22195         fi
22196
22197         local trunc_sz
22198         local grant_blk_size
22199
22200         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22201                         awk '/grant_block_size:/ { print $2; exit; }')
22202         #
22203         # Create File of size 5M. Truncate it to below size's and verify
22204         # blocks count.
22205         #
22206         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22207                 error "Create file $DIR/$tfile failed"
22208         stack_trap "rm -f $DIR/$tfile" EXIT
22209
22210         for trunc_sz in 2097152 4097 4000 509 0; do
22211                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22212                         error "truncate $tfile to $trunc_sz failed"
22213                 local sz=$(stat --format=%s $DIR/$tfile)
22214                 local blk=$(stat --format=%b $DIR/$tfile)
22215                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22216                                      grant_blk_size) * 8))
22217
22218                 if [[ $blk -ne $trunc_blk ]]; then
22219                         $(which stat) $DIR/$tfile
22220                         error "Expected Block $trunc_blk got $blk for $tfile"
22221                 fi
22222
22223                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22224                         error "Expected Size $trunc_sz got $sz for $tfile"
22225         done
22226
22227         #
22228         # sparse file test
22229         # Create file with a hole and write actual two blocks. Block count
22230         # must be 16.
22231         #
22232         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22233                 conv=fsync || error "Create file : $DIR/$tfile"
22234
22235         # Calculate the final truncate size.
22236         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22237
22238         #
22239         # truncate to size $trunc_sz bytes. Strip the last block
22240         # The block count must drop to 8
22241         #
22242         $TRUNCATE $DIR/$tfile $trunc_sz ||
22243                 error "truncate $tfile to $trunc_sz failed"
22244
22245         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22246         sz=$(stat --format=%s $DIR/$tfile)
22247         blk=$(stat --format=%b $DIR/$tfile)
22248
22249         if [[ $blk -ne $trunc_bsz ]]; then
22250                 $(which stat) $DIR/$tfile
22251                 error "Expected Block $trunc_bsz got $blk for $tfile"
22252         fi
22253
22254         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22255                 error "Expected Size $trunc_sz got $sz for $tfile"
22256 }
22257 run_test 317 "Verify blocks get correctly update after truncate"
22258
22259 test_318() {
22260         local old_max_active=$($LCTL get_param -n \
22261                             llite.*.max_read_ahead_async_active 2>/dev/null)
22262
22263         $LCTL set_param llite.*.max_read_ahead_async_active=256
22264         local max_active=$($LCTL get_param -n \
22265                            llite.*.max_read_ahead_async_active 2>/dev/null)
22266         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22267
22268         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22269                 error "set max_read_ahead_async_active should succeed"
22270
22271         $LCTL set_param llite.*.max_read_ahead_async_active=512
22272         max_active=$($LCTL get_param -n \
22273                      llite.*.max_read_ahead_async_active 2>/dev/null)
22274         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22275
22276         # restore @max_active
22277         [ $old_max_active -ne 0 ] && $LCTL set_param \
22278                 llite.*.max_read_ahead_async_active=$old_max_active
22279
22280         local old_threshold=$($LCTL get_param -n \
22281                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22282         local max_per_file_mb=$($LCTL get_param -n \
22283                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22284
22285         local invalid=$(($max_per_file_mb + 1))
22286         $LCTL set_param \
22287                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22288                         && error "set $invalid should fail"
22289
22290         local valid=$(($invalid - 1))
22291         $LCTL set_param \
22292                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22293                         error "set $valid should succeed"
22294         local threshold=$($LCTL get_param -n \
22295                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22296         [ $threshold -eq $valid ] || error \
22297                 "expect threshold $valid got $threshold"
22298         $LCTL set_param \
22299                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22300 }
22301 run_test 318 "Verify async readahead tunables"
22302
22303 test_319() {
22304         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22305
22306         local before=$(date +%s)
22307         local evict
22308         local mdir=$DIR/$tdir
22309         local file=$mdir/xxx
22310
22311         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22312         touch $file
22313
22314 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22315         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22316         $LFS mv -m1 $file &
22317
22318         sleep 1
22319         dd if=$file of=/dev/null
22320         wait
22321         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22322           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22323
22324         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22325 }
22326 run_test 319 "lost lease lock on migrate error"
22327
22328 test_398a() { # LU-4198
22329         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22330         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22331
22332         # request a new lock on client
22333         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22334
22335         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22336         local lock_count=$($LCTL get_param -n \
22337                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22338         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22339
22340         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22341
22342         # no lock cached, should use lockless IO and not enqueue new lock
22343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22344         lock_count=$($LCTL get_param -n \
22345                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22346         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22347 }
22348 run_test 398a "direct IO should cancel lock otherwise lockless"
22349
22350 test_398b() { # LU-4198
22351         which fio || skip_env "no fio installed"
22352         $LFS setstripe -c -1 $DIR/$tfile
22353
22354         local size=12
22355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22356
22357         local njobs=4
22358         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22359         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22360                 --numjobs=$njobs --fallocate=none \
22361                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22362                 --filename=$DIR/$tfile &
22363         bg_pid=$!
22364
22365         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22366         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22367                 --numjobs=$njobs --fallocate=none \
22368                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22369                 --filename=$DIR/$tfile || true
22370         wait $bg_pid
22371
22372         rm -rf $DIR/$tfile
22373 }
22374 run_test 398b "DIO and buffer IO race"
22375
22376 test_398c() { # LU-4198
22377         which fio || skip_env "no fio installed"
22378
22379         saved_debug=$($LCTL get_param -n debug)
22380         $LCTL set_param debug=0
22381
22382         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22383         ((size /= 1024)) # by megabytes
22384         ((size /= 2)) # write half of the OST at most
22385         [ $size -gt 40 ] && size=40 #reduce test time anyway
22386
22387         $LFS setstripe -c 1 $DIR/$tfile
22388
22389         # it seems like ldiskfs reserves more space than necessary if the
22390         # writing blocks are not mapped, so it extends the file firstly
22391         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22392         cancel_lru_locks osc
22393
22394         # clear and verify rpc_stats later
22395         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22396
22397         local njobs=4
22398         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22399         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22400                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22401                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22402                 --filename=$DIR/$tfile
22403         [ $? -eq 0 ] || error "fio write error"
22404
22405         [ $($LCTL get_param -n \
22406          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22407                 error "Locks were requested while doing AIO"
22408
22409         # get the percentage of 1-page I/O
22410         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22411                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22412                 awk '{print $7}')
22413         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22414
22415         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22416         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22417                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22418                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22419                 --filename=$DIR/$tfile
22420         [ $? -eq 0 ] || error "fio mixed read write error"
22421
22422         echo "AIO with large block size ${size}M"
22423         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22424                 --numjobs=1 --fallocate=none --ioengine=libaio \
22425                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22426                 --filename=$DIR/$tfile
22427         [ $? -eq 0 ] || error "fio large block size failed"
22428
22429         rm -rf $DIR/$tfile
22430         $LCTL set_param debug="$saved_debug"
22431 }
22432 run_test 398c "run fio to test AIO"
22433
22434 test_398d() { #  LU-13846
22435         test -f aiocp || skip_env "no aiocp installed"
22436         local aio_file=$DIR/aio_file
22437
22438         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22439
22440         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22441         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22442
22443         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22444
22445         # make sure we don't crash and fail properly
22446         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22447                 error "aio not aligned with PAGE SIZE should fail"
22448
22449         rm -rf $DIR/$tfile $aio_file
22450 }
22451 run_test 398d "run aiocp to verify block size > stripe size"
22452
22453 test_398e() {
22454         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22455         touch $DIR/$tfile.new
22456         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22457 }
22458 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22459
22460 test_fake_rw() {
22461         local read_write=$1
22462         if [ "$read_write" = "write" ]; then
22463                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22464         elif [ "$read_write" = "read" ]; then
22465                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22466         else
22467                 error "argument error"
22468         fi
22469
22470         # turn off debug for performance testing
22471         local saved_debug=$($LCTL get_param -n debug)
22472         $LCTL set_param debug=0
22473
22474         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22475
22476         # get ost1 size - $FSNAME-OST0000
22477         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22478         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22479         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22480
22481         if [ "$read_write" = "read" ]; then
22482                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22483         fi
22484
22485         local start_time=$(date +%s.%N)
22486         $dd_cmd bs=1M count=$blocks oflag=sync ||
22487                 error "real dd $read_write error"
22488         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22489
22490         if [ "$read_write" = "write" ]; then
22491                 rm -f $DIR/$tfile
22492         fi
22493
22494         # define OBD_FAIL_OST_FAKE_RW           0x238
22495         do_facet ost1 $LCTL set_param fail_loc=0x238
22496
22497         local start_time=$(date +%s.%N)
22498         $dd_cmd bs=1M count=$blocks oflag=sync ||
22499                 error "fake dd $read_write error"
22500         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22501
22502         if [ "$read_write" = "write" ]; then
22503                 # verify file size
22504                 cancel_lru_locks osc
22505                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22506                         error "$tfile size not $blocks MB"
22507         fi
22508         do_facet ost1 $LCTL set_param fail_loc=0
22509
22510         echo "fake $read_write $duration_fake vs. normal $read_write" \
22511                 "$duration in seconds"
22512         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22513                 error_not_in_vm "fake write is slower"
22514
22515         $LCTL set_param -n debug="$saved_debug"
22516         rm -f $DIR/$tfile
22517 }
22518 test_399a() { # LU-7655 for OST fake write
22519         remote_ost_nodsh && skip "remote OST with nodsh"
22520
22521         test_fake_rw write
22522 }
22523 run_test 399a "fake write should not be slower than normal write"
22524
22525 test_399b() { # LU-8726 for OST fake read
22526         remote_ost_nodsh && skip "remote OST with nodsh"
22527         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22528                 skip_env "ldiskfs only test"
22529         fi
22530
22531         test_fake_rw read
22532 }
22533 run_test 399b "fake read should not be slower than normal read"
22534
22535 test_400a() { # LU-1606, was conf-sanity test_74
22536         if ! which $CC > /dev/null 2>&1; then
22537                 skip_env "$CC is not installed"
22538         fi
22539
22540         local extra_flags=''
22541         local out=$TMP/$tfile
22542         local prefix=/usr/include/lustre
22543         local prog
22544
22545         # Oleg removes c files in his test rig so test if any c files exist
22546         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22547                 skip_env "Needed c test files are missing"
22548
22549         if ! [[ -d $prefix ]]; then
22550                 # Assume we're running in tree and fixup the include path.
22551                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22552                 extra_flags+=" -L$LUSTRE/utils/.lib"
22553         fi
22554
22555         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22556                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22557                         error "client api broken"
22558         done
22559         rm -f $out
22560 }
22561 run_test 400a "Lustre client api program can compile and link"
22562
22563 test_400b() { # LU-1606, LU-5011
22564         local header
22565         local out=$TMP/$tfile
22566         local prefix=/usr/include/linux/lustre
22567
22568         # We use a hard coded prefix so that this test will not fail
22569         # when run in tree. There are headers in lustre/include/lustre/
22570         # that are not packaged (like lustre_idl.h) and have more
22571         # complicated include dependencies (like config.h and lnet/types.h).
22572         # Since this test about correct packaging we just skip them when
22573         # they don't exist (see below) rather than try to fixup cppflags.
22574
22575         if ! which $CC > /dev/null 2>&1; then
22576                 skip_env "$CC is not installed"
22577         fi
22578
22579         for header in $prefix/*.h; do
22580                 if ! [[ -f "$header" ]]; then
22581                         continue
22582                 fi
22583
22584                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22585                         continue # lustre_ioctl.h is internal header
22586                 fi
22587
22588                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22589                         error "cannot compile '$header'"
22590         done
22591         rm -f $out
22592 }
22593 run_test 400b "packaged headers can be compiled"
22594
22595 test_401a() { #LU-7437
22596         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22597         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22598
22599         #count the number of parameters by "list_param -R"
22600         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22601         #count the number of parameters by listing proc files
22602         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22603         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22604         echo "proc_dirs='$proc_dirs'"
22605         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22606         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22607                       sort -u | wc -l)
22608
22609         [ $params -eq $procs ] ||
22610                 error "found $params parameters vs. $procs proc files"
22611
22612         # test the list_param -D option only returns directories
22613         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22614         #count the number of parameters by listing proc directories
22615         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22616                 sort -u | wc -l)
22617
22618         [ $params -eq $procs ] ||
22619                 error "found $params parameters vs. $procs proc files"
22620 }
22621 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22622
22623 test_401b() {
22624         # jobid_var may not allow arbitrary values, so use jobid_name
22625         # if available
22626         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22627                 local testname=jobid_name tmp='testing%p'
22628         else
22629                 local testname=jobid_var tmp=testing
22630         fi
22631
22632         local save=$($LCTL get_param -n $testname)
22633
22634         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22635                 error "no error returned when setting bad parameters"
22636
22637         local jobid_new=$($LCTL get_param -n foe $testname baz)
22638         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22639
22640         $LCTL set_param -n fog=bam $testname=$save bat=fog
22641         local jobid_old=$($LCTL get_param -n foe $testname bag)
22642         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22643 }
22644 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22645
22646 test_401c() {
22647         # jobid_var may not allow arbitrary values, so use jobid_name
22648         # if available
22649         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22650                 local testname=jobid_name
22651         else
22652                 local testname=jobid_var
22653         fi
22654
22655         local jobid_var_old=$($LCTL get_param -n $testname)
22656         local jobid_var_new
22657
22658         $LCTL set_param $testname= &&
22659                 error "no error returned for 'set_param a='"
22660
22661         jobid_var_new=$($LCTL get_param -n $testname)
22662         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22663                 error "$testname was changed by setting without value"
22664
22665         $LCTL set_param $testname &&
22666                 error "no error returned for 'set_param a'"
22667
22668         jobid_var_new=$($LCTL get_param -n $testname)
22669         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22670                 error "$testname was changed by setting without value"
22671 }
22672 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22673
22674 test_401d() {
22675         # jobid_var may not allow arbitrary values, so use jobid_name
22676         # if available
22677         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22678                 local testname=jobid_name new_value='foo=bar%p'
22679         else
22680                 local testname=jobid_var new_valuie=foo=bar
22681         fi
22682
22683         local jobid_var_old=$($LCTL get_param -n $testname)
22684         local jobid_var_new
22685
22686         $LCTL set_param $testname=$new_value ||
22687                 error "'set_param a=b' did not accept a value containing '='"
22688
22689         jobid_var_new=$($LCTL get_param -n $testname)
22690         [[ "$jobid_var_new" == "$new_value" ]] ||
22691                 error "'set_param a=b' failed on a value containing '='"
22692
22693         # Reset the $testname to test the other format
22694         $LCTL set_param $testname=$jobid_var_old
22695         jobid_var_new=$($LCTL get_param -n $testname)
22696         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22697                 error "failed to reset $testname"
22698
22699         $LCTL set_param $testname $new_value ||
22700                 error "'set_param a b' did not accept a value containing '='"
22701
22702         jobid_var_new=$($LCTL get_param -n $testname)
22703         [[ "$jobid_var_new" == "$new_value" ]] ||
22704                 error "'set_param a b' failed on a value containing '='"
22705
22706         $LCTL set_param $testname $jobid_var_old
22707         jobid_var_new=$($LCTL get_param -n $testname)
22708         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22709                 error "failed to reset $testname"
22710 }
22711 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22712
22713 test_402() {
22714         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22715         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22716                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22717         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22718                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22719                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22720         remote_mds_nodsh && skip "remote MDS with nodsh"
22721
22722         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22723 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22724         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22725         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22726                 echo "Touch failed - OK"
22727 }
22728 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22729
22730 test_403() {
22731         local file1=$DIR/$tfile.1
22732         local file2=$DIR/$tfile.2
22733         local tfile=$TMP/$tfile
22734
22735         rm -f $file1 $file2 $tfile
22736
22737         touch $file1
22738         ln $file1 $file2
22739
22740         # 30 sec OBD_TIMEOUT in ll_getattr()
22741         # right before populating st_nlink
22742         $LCTL set_param fail_loc=0x80001409
22743         stat -c %h $file1 > $tfile &
22744
22745         # create an alias, drop all locks and reclaim the dentry
22746         < $file2
22747         cancel_lru_locks mdc
22748         cancel_lru_locks osc
22749         sysctl -w vm.drop_caches=2
22750
22751         wait
22752
22753         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22754
22755         rm -f $tfile $file1 $file2
22756 }
22757 run_test 403 "i_nlink should not drop to zero due to aliasing"
22758
22759 test_404() { # LU-6601
22760         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22761                 skip "Need server version newer than 2.8.52"
22762         remote_mds_nodsh && skip "remote MDS with nodsh"
22763
22764         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22765                 awk '/osp .*-osc-MDT/ { print $4}')
22766
22767         local osp
22768         for osp in $mosps; do
22769                 echo "Deactivate: " $osp
22770                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22771                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22772                         awk -vp=$osp '$4 == p { print $2 }')
22773                 [ $stat = IN ] || {
22774                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22775                         error "deactivate error"
22776                 }
22777                 echo "Activate: " $osp
22778                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22779                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22780                         awk -vp=$osp '$4 == p { print $2 }')
22781                 [ $stat = UP ] || {
22782                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22783                         error "activate error"
22784                 }
22785         done
22786 }
22787 run_test 404 "validate manual {de}activated works properly for OSPs"
22788
22789 test_405() {
22790         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22791         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22792                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22793                         skip "Layout swap lock is not supported"
22794
22795         check_swap_layouts_support
22796         check_swap_layout_no_dom $DIR
22797
22798         test_mkdir $DIR/$tdir
22799         swap_lock_test -d $DIR/$tdir ||
22800                 error "One layout swap locked test failed"
22801 }
22802 run_test 405 "Various layout swap lock tests"
22803
22804 test_406() {
22805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22806         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22807         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22809         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22810                 skip "Need MDS version at least 2.8.50"
22811
22812         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22813         local test_pool=$TESTNAME
22814
22815         pool_add $test_pool || error "pool_add failed"
22816         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22817                 error "pool_add_targets failed"
22818
22819         save_layout_restore_at_exit $MOUNT
22820
22821         # parent set default stripe count only, child will stripe from both
22822         # parent and fs default
22823         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22824                 error "setstripe $MOUNT failed"
22825         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22826         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22827         for i in $(seq 10); do
22828                 local f=$DIR/$tdir/$tfile.$i
22829                 touch $f || error "touch failed"
22830                 local count=$($LFS getstripe -c $f)
22831                 [ $count -eq $OSTCOUNT ] ||
22832                         error "$f stripe count $count != $OSTCOUNT"
22833                 local offset=$($LFS getstripe -i $f)
22834                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22835                 local size=$($LFS getstripe -S $f)
22836                 [ $size -eq $((def_stripe_size * 2)) ] ||
22837                         error "$f stripe size $size != $((def_stripe_size * 2))"
22838                 local pool=$($LFS getstripe -p $f)
22839                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22840         done
22841
22842         # change fs default striping, delete parent default striping, now child
22843         # will stripe from new fs default striping only
22844         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22845                 error "change $MOUNT default stripe failed"
22846         $LFS setstripe -c 0 $DIR/$tdir ||
22847                 error "delete $tdir default stripe failed"
22848         for i in $(seq 11 20); do
22849                 local f=$DIR/$tdir/$tfile.$i
22850                 touch $f || error "touch $f failed"
22851                 local count=$($LFS getstripe -c $f)
22852                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22853                 local offset=$($LFS getstripe -i $f)
22854                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22855                 local size=$($LFS getstripe -S $f)
22856                 [ $size -eq $def_stripe_size ] ||
22857                         error "$f stripe size $size != $def_stripe_size"
22858                 local pool=$($LFS getstripe -p $f)
22859                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22860         done
22861
22862         unlinkmany $DIR/$tdir/$tfile. 1 20
22863
22864         local f=$DIR/$tdir/$tfile
22865         pool_remove_all_targets $test_pool $f
22866         pool_remove $test_pool $f
22867 }
22868 run_test 406 "DNE support fs default striping"
22869
22870 test_407() {
22871         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22872         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22873                 skip "Need MDS version at least 2.8.55"
22874         remote_mds_nodsh && skip "remote MDS with nodsh"
22875
22876         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22877                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22878         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22879                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22880         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22881
22882         #define OBD_FAIL_DT_TXN_STOP    0x2019
22883         for idx in $(seq $MDSCOUNT); do
22884                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22885         done
22886         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22887         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22888                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22889         true
22890 }
22891 run_test 407 "transaction fail should cause operation fail"
22892
22893 test_408() {
22894         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22895
22896         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22897         lctl set_param fail_loc=0x8000040a
22898         # let ll_prepare_partial_page() fail
22899         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22900
22901         rm -f $DIR/$tfile
22902
22903         # create at least 100 unused inodes so that
22904         # shrink_icache_memory(0) should not return 0
22905         touch $DIR/$tfile-{0..100}
22906         rm -f $DIR/$tfile-{0..100}
22907         sync
22908
22909         echo 2 > /proc/sys/vm/drop_caches
22910 }
22911 run_test 408 "drop_caches should not hang due to page leaks"
22912
22913 test_409()
22914 {
22915         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22916
22917         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22918         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22919         touch $DIR/$tdir/guard || error "(2) Fail to create"
22920
22921         local PREFIX=$(str_repeat 'A' 128)
22922         echo "Create 1K hard links start at $(date)"
22923         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22924                 error "(3) Fail to hard link"
22925
22926         echo "Links count should be right although linkEA overflow"
22927         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22928         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22929         [ $linkcount -eq 1001 ] ||
22930                 error "(5) Unexpected hard links count: $linkcount"
22931
22932         echo "List all links start at $(date)"
22933         ls -l $DIR/$tdir/foo > /dev/null ||
22934                 error "(6) Fail to list $DIR/$tdir/foo"
22935
22936         echo "Unlink hard links start at $(date)"
22937         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22938                 error "(7) Fail to unlink"
22939         echo "Unlink hard links finished at $(date)"
22940 }
22941 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22942
22943 test_410()
22944 {
22945         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22946                 skip "Need client version at least 2.9.59"
22947         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22948                 skip "Need MODULES build"
22949
22950         # Create a file, and stat it from the kernel
22951         local testfile=$DIR/$tfile
22952         touch $testfile
22953
22954         local run_id=$RANDOM
22955         local my_ino=$(stat --format "%i" $testfile)
22956
22957         # Try to insert the module. This will always fail as the
22958         # module is designed to not be inserted.
22959         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22960             &> /dev/null
22961
22962         # Anything but success is a test failure
22963         dmesg | grep -q \
22964             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22965             error "no inode match"
22966 }
22967 run_test 410 "Test inode number returned from kernel thread"
22968
22969 cleanup_test411_cgroup() {
22970         trap 0
22971         rmdir "$1"
22972 }
22973
22974 test_411() {
22975         local cg_basedir=/sys/fs/cgroup/memory
22976         # LU-9966
22977         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22978                 skip "no setup for cgroup"
22979
22980         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22981                 error "test file creation failed"
22982         cancel_lru_locks osc
22983
22984         # Create a very small memory cgroup to force a slab allocation error
22985         local cgdir=$cg_basedir/osc_slab_alloc
22986         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22987         trap "cleanup_test411_cgroup $cgdir" EXIT
22988         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22989         echo 1M > $cgdir/memory.limit_in_bytes
22990
22991         # Should not LBUG, just be killed by oom-killer
22992         # dd will return 0 even allocation failure in some environment.
22993         # So don't check return value
22994         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22995         cleanup_test411_cgroup $cgdir
22996
22997         return 0
22998 }
22999 run_test 411 "Slab allocation error with cgroup does not LBUG"
23000
23001 test_412() {
23002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23003         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23004                 skip "Need server version at least 2.10.55"
23005         fi
23006
23007         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23008                 error "mkdir failed"
23009         $LFS getdirstripe $DIR/$tdir
23010         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23011         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23012                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23013         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23014         [ $stripe_count -eq 2 ] ||
23015                 error "expect 2 get $stripe_count"
23016 }
23017 run_test 412 "mkdir on specific MDTs"
23018
23019 test_qos_mkdir() {
23020         local mkdir_cmd=$1
23021         local stripe_count=$2
23022         local mdts=$(comma_list $(mdts_nodes))
23023
23024         local testdir
23025         local lmv_qos_prio_free
23026         local lmv_qos_threshold_rr
23027         local lmv_qos_maxage
23028         local lod_qos_prio_free
23029         local lod_qos_threshold_rr
23030         local lod_qos_maxage
23031         local count
23032         local i
23033
23034         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23035         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23036         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23037                 head -n1)
23038         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23039         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23040         stack_trap "$LCTL set_param \
23041                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23042         stack_trap "$LCTL set_param \
23043                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23044         stack_trap "$LCTL set_param \
23045                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23046
23047         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23048                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23049         lod_qos_prio_free=${lod_qos_prio_free%%%}
23050         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23051                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23052         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23053         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23054                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23055         stack_trap "do_nodes $mdts $LCTL set_param \
23056                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23057         stack_trap "do_nodes $mdts $LCTL set_param \
23058                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23059                 EXIT
23060         stack_trap "do_nodes $mdts $LCTL set_param \
23061                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23062
23063         echo
23064         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23065
23066         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23067         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23068
23069         testdir=$DIR/$tdir-s$stripe_count/rr
23070
23071         for i in $(seq $((100 * MDSCOUNT))); do
23072                 eval $mkdir_cmd $testdir/subdir$i ||
23073                         error "$mkdir_cmd subdir$i failed"
23074         done
23075
23076         for i in $(seq $MDSCOUNT); do
23077                 count=$($LFS getdirstripe -i $testdir/* |
23078                                 grep ^$((i - 1))$ | wc -l)
23079                 echo "$count directories created on MDT$((i - 1))"
23080                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23081
23082                 if [ $stripe_count -gt 1 ]; then
23083                         count=$($LFS getdirstripe $testdir/* |
23084                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23085                         echo "$count stripes created on MDT$((i - 1))"
23086                         # deviation should < 5% of average
23087                         [ $count -lt $((95 * stripe_count)) ] ||
23088                         [ $count -gt $((105 * stripe_count)) ] &&
23089                                 error "stripes are not evenly distributed"
23090                 fi
23091         done
23092
23093         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23094         do_nodes $mdts $LCTL set_param \
23095                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23096
23097         echo
23098         echo "Check for uneven MDTs: "
23099
23100         local ffree
23101         local bavail
23102         local max
23103         local min
23104         local max_index
23105         local min_index
23106         local tmp
23107
23108         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23109         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23110         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23111
23112         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23113         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23114         max_index=0
23115         min_index=0
23116         for ((i = 1; i < ${#ffree[@]}; i++)); do
23117                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23118                 if [ $tmp -gt $max ]; then
23119                         max=$tmp
23120                         max_index=$i
23121                 fi
23122                 if [ $tmp -lt $min ]; then
23123                         min=$tmp
23124                         min_index=$i
23125                 fi
23126         done
23127
23128         [ ${ffree[min_index]} -eq 0 ] &&
23129                 skip "no free files in MDT$min_index"
23130         [ ${ffree[min_index]} -gt 100000000 ] &&
23131                 skip "too much free files in MDT$min_index"
23132
23133         # Check if we need to generate uneven MDTs
23134         local threshold=50
23135         local diff=$(((max - min) * 100 / min))
23136         local value="$(generate_string 1024)"
23137
23138         while [ $diff -lt $threshold ]; do
23139                 # generate uneven MDTs, create till $threshold% diff
23140                 echo -n "weight diff=$diff% must be > $threshold% ..."
23141                 count=$((${ffree[min_index]} / 10))
23142                 # 50 sec per 10000 files in vm
23143                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23144                         skip "$count files to create"
23145                 echo "Fill MDT$min_index with $count files"
23146                 [ -d $DIR/$tdir-MDT$min_index ] ||
23147                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23148                         error "mkdir $tdir-MDT$min_index failed"
23149                 for i in $(seq $count); do
23150                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23151                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23152                                 error "create f$j_$i failed"
23153                         setfattr -n user.413b -v $value \
23154                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23155                                 error "setfattr f$j_$i failed"
23156                 done
23157
23158                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23159                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23160                 max=$(((${ffree[max_index]} >> 8) * \
23161                         (${bavail[max_index]} * bsize >> 16)))
23162                 min=$(((${ffree[min_index]} >> 8) * \
23163                         (${bavail[min_index]} * bsize >> 16)))
23164                 diff=$(((max - min) * 100 / min))
23165         done
23166
23167         echo "MDT filesfree available: ${ffree[@]}"
23168         echo "MDT blocks available: ${bavail[@]}"
23169         echo "weight diff=$diff%"
23170
23171         echo
23172         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23173
23174         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23175         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23176         # decrease statfs age, so that it can be updated in time
23177         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23178         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23179
23180         sleep 1
23181
23182         testdir=$DIR/$tdir-s$stripe_count/qos
23183
23184         for i in $(seq $((100 * MDSCOUNT))); do
23185                 eval $mkdir_cmd $testdir/subdir$i ||
23186                         error "$mkdir_cmd subdir$i failed"
23187         done
23188
23189         for i in $(seq $MDSCOUNT); do
23190                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23191                         wc -l)
23192                 echo "$count directories created on MDT$((i - 1))"
23193
23194                 if [ $stripe_count -gt 1 ]; then
23195                         count=$($LFS getdirstripe $testdir/* |
23196                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23197                         echo "$count stripes created on MDT$((i - 1))"
23198                 fi
23199         done
23200
23201         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23202         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23203
23204         # D-value should > 10% of averge
23205         [ $((max - min)) -lt 10 ] &&
23206                 error "subdirs shouldn't be evenly distributed"
23207
23208         # ditto
23209         if [ $stripe_count -gt 1 ]; then
23210                 max=$($LFS getdirstripe $testdir/* |
23211                         grep -P "^\s+$max_index\t" | wc -l)
23212                 min=$($LFS getdirstripe $testdir/* |
23213                         grep -P "^\s+$min_index\t" | wc -l)
23214                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23215                         error "stripes shouldn't be evenly distributed"|| true
23216         fi
23217 }
23218
23219 test_413a() {
23220         [ $MDSCOUNT -lt 2 ] &&
23221                 skip "We need at least 2 MDTs for this test"
23222
23223         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23224                 skip "Need server version at least 2.12.52"
23225
23226         local stripe_count
23227
23228         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23229                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23230                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23231                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23232                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23233         done
23234 }
23235 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23236
23237 test_413b() {
23238         [ $MDSCOUNT -lt 2 ] &&
23239                 skip "We need at least 2 MDTs for this test"
23240
23241         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23242                 skip "Need server version at least 2.12.52"
23243
23244         local stripe_count
23245
23246         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23247                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23248                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23249                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23250                 $LFS setdirstripe -D -c $stripe_count \
23251                         $DIR/$tdir-s$stripe_count/rr ||
23252                         error "setdirstripe failed"
23253                 $LFS setdirstripe -D -c $stripe_count \
23254                         $DIR/$tdir-s$stripe_count/qos ||
23255                         error "setdirstripe failed"
23256                 test_qos_mkdir "mkdir" $stripe_count
23257         done
23258 }
23259 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23260
23261 test_414() {
23262 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23263         $LCTL set_param fail_loc=0x80000521
23264         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23265         rm -f $DIR/$tfile
23266 }
23267 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23268
23269 test_415() {
23270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23271         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23272                 skip "Need server version at least 2.11.52"
23273
23274         # LU-11102
23275         local total
23276         local setattr_pid
23277         local start_time
23278         local end_time
23279         local duration
23280
23281         total=500
23282         # this test may be slow on ZFS
23283         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23284
23285         # though this test is designed for striped directory, let's test normal
23286         # directory too since lock is always saved as CoS lock.
23287         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23288         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23289
23290         (
23291                 while true; do
23292                         touch $DIR/$tdir
23293                 done
23294         ) &
23295         setattr_pid=$!
23296
23297         start_time=$(date +%s)
23298         for i in $(seq $total); do
23299                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23300                         > /dev/null
23301         done
23302         end_time=$(date +%s)
23303         duration=$((end_time - start_time))
23304
23305         kill -9 $setattr_pid
23306
23307         echo "rename $total files took $duration sec"
23308         [ $duration -lt 100 ] || error "rename took $duration sec"
23309 }
23310 run_test 415 "lock revoke is not missing"
23311
23312 test_416() {
23313         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23314                 skip "Need server version at least 2.11.55"
23315
23316         # define OBD_FAIL_OSD_TXN_START    0x19a
23317         do_facet mds1 lctl set_param fail_loc=0x19a
23318
23319         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23320
23321         true
23322 }
23323 run_test 416 "transaction start failure won't cause system hung"
23324
23325 cleanup_417() {
23326         trap 0
23327         do_nodes $(comma_list $(mdts_nodes)) \
23328                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23329         do_nodes $(comma_list $(mdts_nodes)) \
23330                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23331         do_nodes $(comma_list $(mdts_nodes)) \
23332                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23333 }
23334
23335 test_417() {
23336         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23337         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23338                 skip "Need MDS version at least 2.11.56"
23339
23340         trap cleanup_417 RETURN EXIT
23341
23342         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23343         do_nodes $(comma_list $(mdts_nodes)) \
23344                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23345         $LFS migrate -m 0 $DIR/$tdir.1 &&
23346                 error "migrate dir $tdir.1 should fail"
23347
23348         do_nodes $(comma_list $(mdts_nodes)) \
23349                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23350         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23351                 error "create remote dir $tdir.2 should fail"
23352
23353         do_nodes $(comma_list $(mdts_nodes)) \
23354                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23355         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23356                 error "create striped dir $tdir.3 should fail"
23357         true
23358 }
23359 run_test 417 "disable remote dir, striped dir and dir migration"
23360
23361 # Checks that the outputs of df [-i] and lfs df [-i] match
23362 #
23363 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23364 check_lfs_df() {
23365         local dir=$2
23366         local inodes
23367         local df_out
23368         local lfs_df_out
23369         local count
23370         local passed=false
23371
23372         # blocks or inodes
23373         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23374
23375         for count in {1..100}; do
23376                 cancel_lru_locks
23377                 sync; sleep 0.2
23378
23379                 # read the lines of interest
23380                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23381                         error "df $inodes $dir | tail -n +2 failed"
23382                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23383                         error "lfs df $inodes $dir | grep summary: failed"
23384
23385                 # skip first substrings of each output as they are different
23386                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23387                 # compare the two outputs
23388                 passed=true
23389                 for i in {1..5}; do
23390                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23391                 done
23392                 $passed && break
23393         done
23394
23395         if ! $passed; then
23396                 df -P $inodes $dir
23397                 echo
23398                 lfs df $inodes $dir
23399                 error "df and lfs df $1 output mismatch: "      \
23400                       "df ${inodes}: ${df_out[*]}, "            \
23401                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23402         fi
23403 }
23404
23405 test_418() {
23406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23407
23408         local dir=$DIR/$tdir
23409         local numfiles=$((RANDOM % 4096 + 2))
23410         local numblocks=$((RANDOM % 256 + 1))
23411
23412         wait_delete_completed
23413         test_mkdir $dir
23414
23415         # check block output
23416         check_lfs_df blocks $dir
23417         # check inode output
23418         check_lfs_df inodes $dir
23419
23420         # create a single file and retest
23421         echo "Creating a single file and testing"
23422         createmany -o $dir/$tfile- 1 &>/dev/null ||
23423                 error "creating 1 file in $dir failed"
23424         check_lfs_df blocks $dir
23425         check_lfs_df inodes $dir
23426
23427         # create a random number of files
23428         echo "Creating $((numfiles - 1)) files and testing"
23429         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23430                 error "creating $((numfiles - 1)) files in $dir failed"
23431
23432         # write a random number of blocks to the first test file
23433         echo "Writing $numblocks 4K blocks and testing"
23434         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23435                 count=$numblocks &>/dev/null ||
23436                 error "dd to $dir/${tfile}-0 failed"
23437
23438         # retest
23439         check_lfs_df blocks $dir
23440         check_lfs_df inodes $dir
23441
23442         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23443                 error "unlinking $numfiles files in $dir failed"
23444 }
23445 run_test 418 "df and lfs df outputs match"
23446
23447 test_419()
23448 {
23449         local dir=$DIR/$tdir
23450
23451         mkdir -p $dir
23452         touch $dir/file
23453
23454         cancel_lru_locks mdc
23455
23456         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23457         $LCTL set_param fail_loc=0x1410
23458         cat $dir/file
23459         $LCTL set_param fail_loc=0
23460         rm -rf $dir
23461 }
23462 run_test 419 "Verify open file by name doesn't crash kernel"
23463
23464 test_420()
23465 {
23466         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23467                 skip "Need MDS version at least 2.12.53"
23468
23469         local SAVE_UMASK=$(umask)
23470         local dir=$DIR/$tdir
23471         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23472
23473         mkdir -p $dir
23474         umask 0000
23475         mkdir -m03777 $dir/testdir
23476         ls -dn $dir/testdir
23477         # Need to remove trailing '.' when SELinux is enabled
23478         local dirperms=$(ls -dn $dir/testdir |
23479                          awk '{ sub(/\.$/, "", $1); print $1}')
23480         [ $dirperms == "drwxrwsrwt" ] ||
23481                 error "incorrect perms on $dir/testdir"
23482
23483         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23484                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23485         ls -n $dir/testdir/testfile
23486         local fileperms=$(ls -n $dir/testdir/testfile |
23487                           awk '{ sub(/\.$/, "", $1); print $1}')
23488         [ $fileperms == "-rwxr-xr-x" ] ||
23489                 error "incorrect perms on $dir/testdir/testfile"
23490
23491         umask $SAVE_UMASK
23492 }
23493 run_test 420 "clear SGID bit on non-directories for non-members"
23494
23495 test_421a() {
23496         local cnt
23497         local fid1
23498         local fid2
23499
23500         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23501                 skip "Need MDS version at least 2.12.54"
23502
23503         test_mkdir $DIR/$tdir
23504         createmany -o $DIR/$tdir/f 3
23505         cnt=$(ls -1 $DIR/$tdir | wc -l)
23506         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23507
23508         fid1=$(lfs path2fid $DIR/$tdir/f1)
23509         fid2=$(lfs path2fid $DIR/$tdir/f2)
23510         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23511
23512         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23513         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23514
23515         cnt=$(ls -1 $DIR/$tdir | wc -l)
23516         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23517
23518         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23519         createmany -o $DIR/$tdir/f 3
23520         cnt=$(ls -1 $DIR/$tdir | wc -l)
23521         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23522
23523         fid1=$(lfs path2fid $DIR/$tdir/f1)
23524         fid2=$(lfs path2fid $DIR/$tdir/f2)
23525         echo "remove using fsname $FSNAME"
23526         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23527
23528         cnt=$(ls -1 $DIR/$tdir | wc -l)
23529         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23530 }
23531 run_test 421a "simple rm by fid"
23532
23533 test_421b() {
23534         local cnt
23535         local FID1
23536         local FID2
23537
23538         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23539                 skip "Need MDS version at least 2.12.54"
23540
23541         test_mkdir $DIR/$tdir
23542         createmany -o $DIR/$tdir/f 3
23543         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23544         MULTIPID=$!
23545
23546         FID1=$(lfs path2fid $DIR/$tdir/f1)
23547         FID2=$(lfs path2fid $DIR/$tdir/f2)
23548         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23549
23550         kill -USR1 $MULTIPID
23551         wait
23552
23553         cnt=$(ls $DIR/$tdir | wc -l)
23554         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23555 }
23556 run_test 421b "rm by fid on open file"
23557
23558 test_421c() {
23559         local cnt
23560         local FIDS
23561
23562         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23563                 skip "Need MDS version at least 2.12.54"
23564
23565         test_mkdir $DIR/$tdir
23566         createmany -o $DIR/$tdir/f 3
23567         touch $DIR/$tdir/$tfile
23568         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23569         cnt=$(ls -1 $DIR/$tdir | wc -l)
23570         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23571
23572         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23573         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23574
23575         cnt=$(ls $DIR/$tdir | wc -l)
23576         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23577 }
23578 run_test 421c "rm by fid against hardlinked files"
23579
23580 test_421d() {
23581         local cnt
23582         local FIDS
23583
23584         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23585                 skip "Need MDS version at least 2.12.54"
23586
23587         test_mkdir $DIR/$tdir
23588         createmany -o $DIR/$tdir/f 4097
23589         cnt=$(ls -1 $DIR/$tdir | wc -l)
23590         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23591
23592         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23593         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23594
23595         cnt=$(ls $DIR/$tdir | wc -l)
23596         rm -rf $DIR/$tdir
23597         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23598 }
23599 run_test 421d "rmfid en masse"
23600
23601 test_421e() {
23602         local cnt
23603         local FID
23604
23605         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23606         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23607                 skip "Need MDS version at least 2.12.54"
23608
23609         mkdir -p $DIR/$tdir
23610         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23611         createmany -o $DIR/$tdir/striped_dir/f 512
23612         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23613         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23614
23615         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23616                 sed "s/[/][^:]*://g")
23617         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23618
23619         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23620         rm -rf $DIR/$tdir
23621         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23622 }
23623 run_test 421e "rmfid in DNE"
23624
23625 test_421f() {
23626         local cnt
23627         local FID
23628
23629         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23630                 skip "Need MDS version at least 2.12.54"
23631
23632         test_mkdir $DIR/$tdir
23633         touch $DIR/$tdir/f
23634         cnt=$(ls -1 $DIR/$tdir | wc -l)
23635         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23636
23637         FID=$(lfs path2fid $DIR/$tdir/f)
23638         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23639         # rmfid should fail
23640         cnt=$(ls -1 $DIR/$tdir | wc -l)
23641         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23642
23643         chmod a+rw $DIR/$tdir
23644         ls -la $DIR/$tdir
23645         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23646         # rmfid should fail
23647         cnt=$(ls -1 $DIR/$tdir | wc -l)
23648         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23649
23650         rm -f $DIR/$tdir/f
23651         $RUNAS touch $DIR/$tdir/f
23652         FID=$(lfs path2fid $DIR/$tdir/f)
23653         echo "rmfid as root"
23654         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23655         cnt=$(ls -1 $DIR/$tdir | wc -l)
23656         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23657
23658         rm -f $DIR/$tdir/f
23659         $RUNAS touch $DIR/$tdir/f
23660         cnt=$(ls -1 $DIR/$tdir | wc -l)
23661         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23662         FID=$(lfs path2fid $DIR/$tdir/f)
23663         # rmfid w/o user_fid2path mount option should fail
23664         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23665         cnt=$(ls -1 $DIR/$tdir | wc -l)
23666         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23667
23668         umount_client $MOUNT || error "failed to umount client"
23669         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23670                 error "failed to mount client'"
23671
23672         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23673         # rmfid should succeed
23674         cnt=$(ls -1 $DIR/$tdir | wc -l)
23675         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23676
23677         # rmfid shouldn't allow to remove files due to dir's permission
23678         chmod a+rwx $DIR/$tdir
23679         touch $DIR/$tdir/f
23680         ls -la $DIR/$tdir
23681         FID=$(lfs path2fid $DIR/$tdir/f)
23682         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23683
23684         umount_client $MOUNT || error "failed to umount client"
23685         mount_client $MOUNT "$MOUNT_OPTS" ||
23686                 error "failed to mount client'"
23687
23688 }
23689 run_test 421f "rmfid checks permissions"
23690
23691 test_421g() {
23692         local cnt
23693         local FIDS
23694
23695         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23696         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23697                 skip "Need MDS version at least 2.12.54"
23698
23699         mkdir -p $DIR/$tdir
23700         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23701         createmany -o $DIR/$tdir/striped_dir/f 512
23702         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23703         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23704
23705         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23706                 sed "s/[/][^:]*://g")
23707
23708         rm -f $DIR/$tdir/striped_dir/f1*
23709         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23710         removed=$((512 - cnt))
23711
23712         # few files have been just removed, so we expect
23713         # rmfid to fail on their fids
23714         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23715         [ $removed != $errors ] && error "$errors != $removed"
23716
23717         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23718         rm -rf $DIR/$tdir
23719         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23720 }
23721 run_test 421g "rmfid to return errors properly"
23722
23723 test_422() {
23724         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23725         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23726         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23727         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23728         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23729
23730         local amc=$(at_max_get client)
23731         local amo=$(at_max_get mds1)
23732         local timeout=`lctl get_param -n timeout`
23733
23734         at_max_set 0 client
23735         at_max_set 0 mds1
23736
23737 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23738         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23739                         fail_val=$(((2*timeout + 10)*1000))
23740         touch $DIR/$tdir/d3/file &
23741         sleep 2
23742 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23743         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23744                         fail_val=$((2*timeout + 5))
23745         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23746         local pid=$!
23747         sleep 1
23748         kill -9 $pid
23749         sleep $((2 * timeout))
23750         echo kill $pid
23751         kill -9 $pid
23752         lctl mark touch
23753         touch $DIR/$tdir/d2/file3
23754         touch $DIR/$tdir/d2/file4
23755         touch $DIR/$tdir/d2/file5
23756
23757         wait
23758         at_max_set $amc client
23759         at_max_set $amo mds1
23760
23761         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23762         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23763                 error "Watchdog is always throttled"
23764 }
23765 run_test 422 "kill a process with RPC in progress"
23766
23767 stat_test() {
23768     df -h $MOUNT &
23769     df -h $MOUNT &
23770     df -h $MOUNT &
23771     df -h $MOUNT &
23772     df -h $MOUNT &
23773     df -h $MOUNT &
23774 }
23775
23776 test_423() {
23777     local _stats
23778     # ensure statfs cache is expired
23779     sleep 2;
23780
23781     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23782     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23783
23784     return 0
23785 }
23786 run_test 423 "statfs should return a right data"
23787
23788 test_424() {
23789 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23790         $LCTL set_param fail_loc=0x80000522
23791         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23792         rm -f $DIR/$tfile
23793 }
23794 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23795
23796 test_425() {
23797         test_mkdir -c -1 $DIR/$tdir
23798         $LFS setstripe -c -1 $DIR/$tdir
23799
23800         lru_resize_disable "" 100
23801         stack_trap "lru_resize_enable" EXIT
23802
23803         sleep 5
23804
23805         for i in $(seq $((MDSCOUNT * 125))); do
23806                 local t=$DIR/$tdir/$tfile_$i
23807
23808                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23809                         error_noexit "Create file $t"
23810         done
23811         stack_trap "rm -rf $DIR/$tdir" EXIT
23812
23813         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23814                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23815                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23816
23817                 [ $lock_count -le $lru_size ] ||
23818                         error "osc lock count $lock_count > lru size $lru_size"
23819         done
23820
23821         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23822                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23823                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23824
23825                 [ $lock_count -le $lru_size ] ||
23826                         error "mdc lock count $lock_count > lru size $lru_size"
23827         done
23828 }
23829 run_test 425 "lock count should not exceed lru size"
23830
23831 test_426() {
23832         splice-test -r $DIR/$tfile
23833         splice-test -rd $DIR/$tfile
23834         splice-test $DIR/$tfile
23835         splice-test -d $DIR/$tfile
23836 }
23837 run_test 426 "splice test on Lustre"
23838
23839 lseek_test_430() {
23840         local offset
23841         local file=$1
23842
23843         # data at [200K, 400K)
23844         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23845                 error "256K->512K dd fails"
23846         # data at [2M, 3M)
23847         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23848                 error "2M->3M dd fails"
23849         # data at [4M, 5M)
23850         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23851                 error "4M->5M dd fails"
23852         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23853         # start at first component hole #1
23854         printf "Seeking hole from 1000 ... "
23855         offset=$(lseek_test -l 1000 $file)
23856         echo $offset
23857         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23858         printf "Seeking data from 1000 ... "
23859         offset=$(lseek_test -d 1000 $file)
23860         echo $offset
23861         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23862
23863         # start at first component data block
23864         printf "Seeking hole from 300000 ... "
23865         offset=$(lseek_test -l 300000 $file)
23866         echo $offset
23867         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23868         printf "Seeking data from 300000 ... "
23869         offset=$(lseek_test -d 300000 $file)
23870         echo $offset
23871         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23872
23873         # start at the first component but beyond end of object size
23874         printf "Seeking hole from 1000000 ... "
23875         offset=$(lseek_test -l 1000000 $file)
23876         echo $offset
23877         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23878         printf "Seeking data from 1000000 ... "
23879         offset=$(lseek_test -d 1000000 $file)
23880         echo $offset
23881         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23882
23883         # start at second component stripe 2 (empty file)
23884         printf "Seeking hole from 1500000 ... "
23885         offset=$(lseek_test -l 1500000 $file)
23886         echo $offset
23887         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23888         printf "Seeking data from 1500000 ... "
23889         offset=$(lseek_test -d 1500000 $file)
23890         echo $offset
23891         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23892
23893         # start at second component stripe 1 (all data)
23894         printf "Seeking hole from 3000000 ... "
23895         offset=$(lseek_test -l 3000000 $file)
23896         echo $offset
23897         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23898         printf "Seeking data from 3000000 ... "
23899         offset=$(lseek_test -d 3000000 $file)
23900         echo $offset
23901         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23902
23903         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23904                 error "2nd dd fails"
23905         echo "Add data block at 640K...1280K"
23906
23907         # start at before new data block, in hole
23908         printf "Seeking hole from 600000 ... "
23909         offset=$(lseek_test -l 600000 $file)
23910         echo $offset
23911         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23912         printf "Seeking data from 600000 ... "
23913         offset=$(lseek_test -d 600000 $file)
23914         echo $offset
23915         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23916
23917         # start at the first component new data block
23918         printf "Seeking hole from 1000000 ... "
23919         offset=$(lseek_test -l 1000000 $file)
23920         echo $offset
23921         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23922         printf "Seeking data from 1000000 ... "
23923         offset=$(lseek_test -d 1000000 $file)
23924         echo $offset
23925         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23926
23927         # start at second component stripe 2, new data
23928         printf "Seeking hole from 1200000 ... "
23929         offset=$(lseek_test -l 1200000 $file)
23930         echo $offset
23931         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23932         printf "Seeking data from 1200000 ... "
23933         offset=$(lseek_test -d 1200000 $file)
23934         echo $offset
23935         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23936
23937         # start beyond file end
23938         printf "Using offset > filesize ... "
23939         lseek_test -l 4000000 $file && error "lseek should fail"
23940         printf "Using offset > filesize ... "
23941         lseek_test -d 4000000 $file && error "lseek should fail"
23942
23943         printf "Done\n\n"
23944 }
23945
23946 test_430a() {
23947         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23948                 skip "MDT does not support SEEK_HOLE"
23949
23950         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23951                 skip "OST does not support SEEK_HOLE"
23952
23953         local file=$DIR/$tdir/$tfile
23954
23955         mkdir -p $DIR/$tdir
23956
23957         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23958         # OST stripe #1 will have continuous data at [1M, 3M)
23959         # OST stripe #2 is empty
23960         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23961         lseek_test_430 $file
23962         rm $file
23963         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23964         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23965         lseek_test_430 $file
23966         rm $file
23967         $LFS setstripe -c2 -S 512K $file
23968         echo "Two stripes, stripe size 512K"
23969         lseek_test_430 $file
23970         rm $file
23971         # FLR with stale mirror
23972         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23973                        -N -c2 -S 1M $file
23974         echo "Mirrored file:"
23975         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23976         echo "Plain 2 stripes 1M"
23977         lseek_test_430 $file
23978         rm $file
23979 }
23980 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23981
23982 test_430b() {
23983         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23984                 skip "OST does not support SEEK_HOLE"
23985
23986         local offset
23987         local file=$DIR/$tdir/$tfile
23988
23989         mkdir -p $DIR/$tdir
23990         # Empty layout lseek should fail
23991         $MCREATE $file
23992         # seek from 0
23993         printf "Seeking hole from 0 ... "
23994         lseek_test -l 0 $file && error "lseek should fail"
23995         printf "Seeking data from 0 ... "
23996         lseek_test -d 0 $file && error "lseek should fail"
23997         rm $file
23998
23999         # 1M-hole file
24000         $LFS setstripe -E 1M -c2 -E eof $file
24001         $TRUNCATE $file 1048576
24002         printf "Seeking hole from 1000000 ... "
24003         offset=$(lseek_test -l 1000000 $file)
24004         echo $offset
24005         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24006         printf "Seeking data from 1000000 ... "
24007         lseek_test -d 1000000 $file && error "lseek should fail"
24008         rm $file
24009
24010         # full component followed by non-inited one
24011         $LFS setstripe -E 1M -c2 -E eof $file
24012         dd if=/dev/urandom of=$file bs=1M count=1
24013         printf "Seeking hole from 1000000 ... "
24014         offset=$(lseek_test -l 1000000 $file)
24015         echo $offset
24016         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24017         printf "Seeking hole from 1048576 ... "
24018         lseek_test -l 1048576 $file && error "lseek should fail"
24019         # init second component and truncate back
24020         echo "123" >> $file
24021         $TRUNCATE $file 1048576
24022         printf "Seeking hole from 1000000 ... "
24023         offset=$(lseek_test -l 1000000 $file)
24024         echo $offset
24025         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24026         printf "Seeking hole from 1048576 ... "
24027         lseek_test -l 1048576 $file && error "lseek should fail"
24028         # boundary checks for big values
24029         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24030         offset=$(lseek_test -d 0 $file.10g)
24031         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24032         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24033         offset=$(lseek_test -d 0 $file.100g)
24034         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24035         return 0
24036 }
24037 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24038
24039 test_430c() {
24040         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24041                 skip "OST does not support SEEK_HOLE"
24042
24043         local file=$DIR/$tdir/$tfile
24044         local start
24045
24046         mkdir -p $DIR/$tdir
24047         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24048
24049         # cp version 8.33+ prefers lseek over fiemap
24050         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24051                 start=$SECONDS
24052                 time cp $file /dev/null
24053                 (( SECONDS - start < 5 )) ||
24054                         error "cp: too long runtime $((SECONDS - start))"
24055
24056         fi
24057         # tar version 1.29+ supports SEEK_HOLE/DATA
24058         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24059                 start=$SECONDS
24060                 time tar cS $file - | cat > /dev/null
24061                 (( SECONDS - start < 5 )) ||
24062                         error "tar: too long runtime $((SECONDS - start))"
24063         fi
24064 }
24065 run_test 430c "lseek: external tools check"
24066
24067 test_431() { # LU-14187
24068         local file=$DIR/$tdir/$tfile
24069
24070         mkdir -p $DIR/$tdir
24071         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24072         dd if=/dev/urandom of=$file bs=4k count=1
24073         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24074         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24075         #define OBD_FAIL_OST_RESTART_IO 0x251
24076         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24077         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24078         cp $file $file.0
24079         cancel_lru_locks
24080         sync_all_data
24081         echo 3 > /proc/sys/vm/drop_caches
24082         diff  $file $file.0 || error "data diff"
24083 }
24084 run_test 431 "Restart transaction for IO"
24085
24086 prep_801() {
24087         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24088         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24089                 skip "Need server version at least 2.9.55"
24090
24091         start_full_debug_logging
24092 }
24093
24094 post_801() {
24095         stop_full_debug_logging
24096 }
24097
24098 barrier_stat() {
24099         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24100                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24101                            awk '/The barrier for/ { print $7 }')
24102                 echo $st
24103         else
24104                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24105                 echo \'$st\'
24106         fi
24107 }
24108
24109 barrier_expired() {
24110         local expired
24111
24112         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24113                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24114                           awk '/will be expired/ { print $7 }')
24115         else
24116                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24117         fi
24118
24119         echo $expired
24120 }
24121
24122 test_801a() {
24123         prep_801
24124
24125         echo "Start barrier_freeze at: $(date)"
24126         #define OBD_FAIL_BARRIER_DELAY          0x2202
24127         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24128         # Do not reduce barrier time - See LU-11873
24129         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24130
24131         sleep 2
24132         local b_status=$(barrier_stat)
24133         echo "Got barrier status at: $(date)"
24134         [ "$b_status" = "'freezing_p1'" ] ||
24135                 error "(1) unexpected barrier status $b_status"
24136
24137         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24138         wait
24139         b_status=$(barrier_stat)
24140         [ "$b_status" = "'frozen'" ] ||
24141                 error "(2) unexpected barrier status $b_status"
24142
24143         local expired=$(barrier_expired)
24144         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24145         sleep $((expired + 3))
24146
24147         b_status=$(barrier_stat)
24148         [ "$b_status" = "'expired'" ] ||
24149                 error "(3) unexpected barrier status $b_status"
24150
24151         # Do not reduce barrier time - See LU-11873
24152         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24153                 error "(4) fail to freeze barrier"
24154
24155         b_status=$(barrier_stat)
24156         [ "$b_status" = "'frozen'" ] ||
24157                 error "(5) unexpected barrier status $b_status"
24158
24159         echo "Start barrier_thaw at: $(date)"
24160         #define OBD_FAIL_BARRIER_DELAY          0x2202
24161         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24162         do_facet mgs $LCTL barrier_thaw $FSNAME &
24163
24164         sleep 2
24165         b_status=$(barrier_stat)
24166         echo "Got barrier status at: $(date)"
24167         [ "$b_status" = "'thawing'" ] ||
24168                 error "(6) unexpected barrier status $b_status"
24169
24170         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24171         wait
24172         b_status=$(barrier_stat)
24173         [ "$b_status" = "'thawed'" ] ||
24174                 error "(7) unexpected barrier status $b_status"
24175
24176         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24177         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24178         do_facet mgs $LCTL barrier_freeze $FSNAME
24179
24180         b_status=$(barrier_stat)
24181         [ "$b_status" = "'failed'" ] ||
24182                 error "(8) unexpected barrier status $b_status"
24183
24184         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24185         do_facet mgs $LCTL barrier_thaw $FSNAME
24186
24187         post_801
24188 }
24189 run_test 801a "write barrier user interfaces and stat machine"
24190
24191 test_801b() {
24192         prep_801
24193
24194         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24195         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24196         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24197         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24198         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24199
24200         cancel_lru_locks mdc
24201
24202         # 180 seconds should be long enough
24203         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24204
24205         local b_status=$(barrier_stat)
24206         [ "$b_status" = "'frozen'" ] ||
24207                 error "(6) unexpected barrier status $b_status"
24208
24209         mkdir $DIR/$tdir/d0/d10 &
24210         mkdir_pid=$!
24211
24212         touch $DIR/$tdir/d1/f13 &
24213         touch_pid=$!
24214
24215         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24216         ln_pid=$!
24217
24218         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24219         mv_pid=$!
24220
24221         rm -f $DIR/$tdir/d4/f12 &
24222         rm_pid=$!
24223
24224         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24225
24226         # To guarantee taht the 'stat' is not blocked
24227         b_status=$(barrier_stat)
24228         [ "$b_status" = "'frozen'" ] ||
24229                 error "(8) unexpected barrier status $b_status"
24230
24231         # let above commands to run at background
24232         sleep 5
24233
24234         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24235         ps -p $touch_pid || error "(10) touch should be blocked"
24236         ps -p $ln_pid || error "(11) link should be blocked"
24237         ps -p $mv_pid || error "(12) rename should be blocked"
24238         ps -p $rm_pid || error "(13) unlink should be blocked"
24239
24240         b_status=$(barrier_stat)
24241         [ "$b_status" = "'frozen'" ] ||
24242                 error "(14) unexpected barrier status $b_status"
24243
24244         do_facet mgs $LCTL barrier_thaw $FSNAME
24245         b_status=$(barrier_stat)
24246         [ "$b_status" = "'thawed'" ] ||
24247                 error "(15) unexpected barrier status $b_status"
24248
24249         wait $mkdir_pid || error "(16) mkdir should succeed"
24250         wait $touch_pid || error "(17) touch should succeed"
24251         wait $ln_pid || error "(18) link should succeed"
24252         wait $mv_pid || error "(19) rename should succeed"
24253         wait $rm_pid || error "(20) unlink should succeed"
24254
24255         post_801
24256 }
24257 run_test 801b "modification will be blocked by write barrier"
24258
24259 test_801c() {
24260         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24261
24262         prep_801
24263
24264         stop mds2 || error "(1) Fail to stop mds2"
24265
24266         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24267
24268         local b_status=$(barrier_stat)
24269         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24270                 do_facet mgs $LCTL barrier_thaw $FSNAME
24271                 error "(2) unexpected barrier status $b_status"
24272         }
24273
24274         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24275                 error "(3) Fail to rescan barrier bitmap"
24276
24277         # Do not reduce barrier time - See LU-11873
24278         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24279
24280         b_status=$(barrier_stat)
24281         [ "$b_status" = "'frozen'" ] ||
24282                 error "(4) unexpected barrier status $b_status"
24283
24284         do_facet mgs $LCTL barrier_thaw $FSNAME
24285         b_status=$(barrier_stat)
24286         [ "$b_status" = "'thawed'" ] ||
24287                 error "(5) unexpected barrier status $b_status"
24288
24289         local devname=$(mdsdevname 2)
24290
24291         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24292
24293         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24294                 error "(7) Fail to rescan barrier bitmap"
24295
24296         post_801
24297 }
24298 run_test 801c "rescan barrier bitmap"
24299
24300 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24301 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24302 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24303 saved_MOUNT_OPTS=$MOUNT_OPTS
24304
24305 cleanup_802a() {
24306         trap 0
24307
24308         stopall
24309         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24310         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24311         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24312         MOUNT_OPTS=$saved_MOUNT_OPTS
24313         setupall
24314 }
24315
24316 test_802a() {
24317         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24318         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24319         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24320                 skip "Need server version at least 2.9.55"
24321
24322         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24323
24324         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24325
24326         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24327                 error "(2) Fail to copy"
24328
24329         trap cleanup_802a EXIT
24330
24331         # sync by force before remount as readonly
24332         sync; sync_all_data; sleep 3; sync_all_data
24333
24334         stopall
24335
24336         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24337         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24338         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24339
24340         echo "Mount the server as read only"
24341         setupall server_only || error "(3) Fail to start servers"
24342
24343         echo "Mount client without ro should fail"
24344         mount_client $MOUNT &&
24345                 error "(4) Mount client without 'ro' should fail"
24346
24347         echo "Mount client with ro should succeed"
24348         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24349         mount_client $MOUNT ||
24350                 error "(5) Mount client with 'ro' should succeed"
24351
24352         echo "Modify should be refused"
24353         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24354
24355         echo "Read should be allowed"
24356         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24357                 error "(7) Read should succeed under ro mode"
24358
24359         cleanup_802a
24360 }
24361 run_test 802a "simulate readonly device"
24362
24363 test_802b() {
24364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24365         remote_mds_nodsh && skip "remote MDS with nodsh"
24366
24367         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24368                 skip "readonly option not available"
24369
24370         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24371
24372         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24373                 error "(2) Fail to copy"
24374
24375         # write back all cached data before setting MDT to readonly
24376         cancel_lru_locks
24377         sync_all_data
24378
24379         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24380         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24381
24382         echo "Modify should be refused"
24383         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24384
24385         echo "Read should be allowed"
24386         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24387                 error "(7) Read should succeed under ro mode"
24388
24389         # disable readonly
24390         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24391 }
24392 run_test 802b "be able to set MDTs to readonly"
24393
24394 test_803a() {
24395         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24396         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24397                 skip "MDS needs to be newer than 2.10.54"
24398
24399         mkdir -p $DIR/$tdir
24400         # Create some objects on all MDTs to trigger related logs objects
24401         for idx in $(seq $MDSCOUNT); do
24402                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24403                         $DIR/$tdir/dir${idx} ||
24404                         error "Fail to create $DIR/$tdir/dir${idx}"
24405         done
24406
24407         sync; sleep 3
24408         wait_delete_completed # ensure old test cleanups are finished
24409         echo "before create:"
24410         $LFS df -i $MOUNT
24411         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24412
24413         for i in {1..10}; do
24414                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24415                         error "Fail to create $DIR/$tdir/foo$i"
24416         done
24417
24418         sync; sleep 3
24419         echo "after create:"
24420         $LFS df -i $MOUNT
24421         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24422
24423         # allow for an llog to be cleaned up during the test
24424         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24425                 error "before ($before_used) + 10 > after ($after_used)"
24426
24427         for i in {1..10}; do
24428                 rm -rf $DIR/$tdir/foo$i ||
24429                         error "Fail to remove $DIR/$tdir/foo$i"
24430         done
24431
24432         sleep 3 # avoid MDT return cached statfs
24433         wait_delete_completed
24434         echo "after unlink:"
24435         $LFS df -i $MOUNT
24436         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24437
24438         # allow for an llog to be created during the test
24439         [ $after_used -le $((before_used + 1)) ] ||
24440                 error "after ($after_used) > before ($before_used) + 1"
24441 }
24442 run_test 803a "verify agent object for remote object"
24443
24444 test_803b() {
24445         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24446         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24447                 skip "MDS needs to be newer than 2.13.56"
24448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24449
24450         for i in $(seq 0 $((MDSCOUNT - 1))); do
24451                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24452         done
24453
24454         local before=0
24455         local after=0
24456
24457         local tmp
24458
24459         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24460         for i in $(seq 0 $((MDSCOUNT - 1))); do
24461                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24462                         awk '/getattr/ { print $2 }')
24463                 before=$((before + tmp))
24464         done
24465         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24466         for i in $(seq 0 $((MDSCOUNT - 1))); do
24467                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24468                         awk '/getattr/ { print $2 }')
24469                 after=$((after + tmp))
24470         done
24471
24472         [ $before -eq $after ] || error "getattr count $before != $after"
24473 }
24474 run_test 803b "remote object can getattr from cache"
24475
24476 test_804() {
24477         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24478         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24479                 skip "MDS needs to be newer than 2.10.54"
24480         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24481
24482         mkdir -p $DIR/$tdir
24483         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24484                 error "Fail to create $DIR/$tdir/dir0"
24485
24486         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24487         local dev=$(mdsdevname 2)
24488
24489         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24490                 grep ${fid} || error "NOT found agent entry for dir0"
24491
24492         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24493                 error "Fail to create $DIR/$tdir/dir1"
24494
24495         touch $DIR/$tdir/dir1/foo0 ||
24496                 error "Fail to create $DIR/$tdir/dir1/foo0"
24497         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24498         local rc=0
24499
24500         for idx in $(seq $MDSCOUNT); do
24501                 dev=$(mdsdevname $idx)
24502                 do_facet mds${idx} \
24503                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24504                         grep ${fid} && rc=$idx
24505         done
24506
24507         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24508                 error "Fail to rename foo0 to foo1"
24509         if [ $rc -eq 0 ]; then
24510                 for idx in $(seq $MDSCOUNT); do
24511                         dev=$(mdsdevname $idx)
24512                         do_facet mds${idx} \
24513                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24514                         grep ${fid} && rc=$idx
24515                 done
24516         fi
24517
24518         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24519                 error "Fail to rename foo1 to foo2"
24520         if [ $rc -eq 0 ]; then
24521                 for idx in $(seq $MDSCOUNT); do
24522                         dev=$(mdsdevname $idx)
24523                         do_facet mds${idx} \
24524                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24525                         grep ${fid} && rc=$idx
24526                 done
24527         fi
24528
24529         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24530
24531         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24532                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24533         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24534                 error "Fail to rename foo2 to foo0"
24535         unlink $DIR/$tdir/dir1/foo0 ||
24536                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24537         rm -rf $DIR/$tdir/dir0 ||
24538                 error "Fail to rm $DIR/$tdir/dir0"
24539
24540         for idx in $(seq $MDSCOUNT); do
24541                 dev=$(mdsdevname $idx)
24542                 rc=0
24543
24544                 stop mds${idx}
24545                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24546                         rc=$?
24547                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24548                         error "mount mds$idx failed"
24549                 df $MOUNT > /dev/null 2>&1
24550
24551                 # e2fsck should not return error
24552                 [ $rc -eq 0 ] ||
24553                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24554         done
24555 }
24556 run_test 804 "verify agent entry for remote entry"
24557
24558 cleanup_805() {
24559         do_facet $SINGLEMDS zfs set quota=$old $fsset
24560         unlinkmany $DIR/$tdir/f- 1000000
24561         trap 0
24562 }
24563
24564 test_805() {
24565         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24566         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24567         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24568                 skip "netfree not implemented before 0.7"
24569         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24570                 skip "Need MDS version at least 2.10.57"
24571
24572         local fsset
24573         local freekb
24574         local usedkb
24575         local old
24576         local quota
24577         local pref="osd-zfs.$FSNAME-MDT0000."
24578
24579         # limit available space on MDS dataset to meet nospace issue
24580         # quickly. then ZFS 0.7.2 can use reserved space if asked
24581         # properly (using netfree flag in osd_declare_destroy()
24582         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24583         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24584                 gawk '{print $3}')
24585         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24586         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24587         let "usedkb=usedkb-freekb"
24588         let "freekb=freekb/2"
24589         if let "freekb > 5000"; then
24590                 let "freekb=5000"
24591         fi
24592         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24593         trap cleanup_805 EXIT
24594         mkdir $DIR/$tdir
24595         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24596                 error "Can't set PFL layout"
24597         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24598         rm -rf $DIR/$tdir || error "not able to remove"
24599         do_facet $SINGLEMDS zfs set quota=$old $fsset
24600         trap 0
24601 }
24602 run_test 805 "ZFS can remove from full fs"
24603
24604 # Size-on-MDS test
24605 check_lsom_data()
24606 {
24607         local file=$1
24608         local size=$($LFS getsom -s $file)
24609         local expect=$(stat -c %s $file)
24610
24611         [[ $size == $expect ]] ||
24612                 error "$file expected size: $expect, got: $size"
24613
24614         local blocks=$($LFS getsom -b $file)
24615         expect=$(stat -c %b $file)
24616         [[ $blocks == $expect ]] ||
24617                 error "$file expected blocks: $expect, got: $blocks"
24618 }
24619
24620 check_lsom_size()
24621 {
24622         local size=$($LFS getsom -s $1)
24623         local expect=$2
24624
24625         [[ $size == $expect ]] ||
24626                 error "$file expected size: $expect, got: $size"
24627 }
24628
24629 test_806() {
24630         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24631                 skip "Need MDS version at least 2.11.52"
24632
24633         local bs=1048576
24634
24635         touch $DIR/$tfile || error "touch $tfile failed"
24636
24637         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24638         save_lustre_params client "llite.*.xattr_cache" > $save
24639         lctl set_param llite.*.xattr_cache=0
24640         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24641
24642         # single-threaded write
24643         echo "Test SOM for single-threaded write"
24644         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24645                 error "write $tfile failed"
24646         check_lsom_size $DIR/$tfile $bs
24647
24648         local num=32
24649         local size=$(($num * $bs))
24650         local offset=0
24651         local i
24652
24653         echo "Test SOM for single client multi-threaded($num) write"
24654         $TRUNCATE $DIR/$tfile 0
24655         for ((i = 0; i < $num; i++)); do
24656                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24657                 local pids[$i]=$!
24658                 offset=$((offset + $bs))
24659         done
24660         for (( i=0; i < $num; i++ )); do
24661                 wait ${pids[$i]}
24662         done
24663         check_lsom_size $DIR/$tfile $size
24664
24665         $TRUNCATE $DIR/$tfile 0
24666         for ((i = 0; i < $num; i++)); do
24667                 offset=$((offset - $bs))
24668                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24669                 local pids[$i]=$!
24670         done
24671         for (( i=0; i < $num; i++ )); do
24672                 wait ${pids[$i]}
24673         done
24674         check_lsom_size $DIR/$tfile $size
24675
24676         # multi-client writes
24677         num=$(get_node_count ${CLIENTS//,/ })
24678         size=$(($num * $bs))
24679         offset=0
24680         i=0
24681
24682         echo "Test SOM for multi-client ($num) writes"
24683         $TRUNCATE $DIR/$tfile 0
24684         for client in ${CLIENTS//,/ }; do
24685                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24686                 local pids[$i]=$!
24687                 i=$((i + 1))
24688                 offset=$((offset + $bs))
24689         done
24690         for (( i=0; i < $num; i++ )); do
24691                 wait ${pids[$i]}
24692         done
24693         check_lsom_size $DIR/$tfile $offset
24694
24695         i=0
24696         $TRUNCATE $DIR/$tfile 0
24697         for client in ${CLIENTS//,/ }; do
24698                 offset=$((offset - $bs))
24699                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24700                 local pids[$i]=$!
24701                 i=$((i + 1))
24702         done
24703         for (( i=0; i < $num; i++ )); do
24704                 wait ${pids[$i]}
24705         done
24706         check_lsom_size $DIR/$tfile $size
24707
24708         # verify truncate
24709         echo "Test SOM for truncate"
24710         $TRUNCATE $DIR/$tfile 1048576
24711         check_lsom_size $DIR/$tfile 1048576
24712         $TRUNCATE $DIR/$tfile 1234
24713         check_lsom_size $DIR/$tfile 1234
24714
24715         # verify SOM blocks count
24716         echo "Verify SOM block count"
24717         $TRUNCATE $DIR/$tfile 0
24718         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24719                 error "failed to write file $tfile"
24720         check_lsom_data $DIR/$tfile
24721 }
24722 run_test 806 "Verify Lazy Size on MDS"
24723
24724 test_807() {
24725         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24726         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24727                 skip "Need MDS version at least 2.11.52"
24728
24729         # Registration step
24730         changelog_register || error "changelog_register failed"
24731         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24732         changelog_users $SINGLEMDS | grep -q $cl_user ||
24733                 error "User $cl_user not found in changelog_users"
24734
24735         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24736         save_lustre_params client "llite.*.xattr_cache" > $save
24737         lctl set_param llite.*.xattr_cache=0
24738         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24739
24740         rm -rf $DIR/$tdir || error "rm $tdir failed"
24741         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24742         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24743         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24744         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24745                 error "truncate $tdir/trunc failed"
24746
24747         local bs=1048576
24748         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24749                 error "write $tfile failed"
24750
24751         # multi-client wirtes
24752         local num=$(get_node_count ${CLIENTS//,/ })
24753         local offset=0
24754         local i=0
24755
24756         echo "Test SOM for multi-client ($num) writes"
24757         touch $DIR/$tfile || error "touch $tfile failed"
24758         $TRUNCATE $DIR/$tfile 0
24759         for client in ${CLIENTS//,/ }; do
24760                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24761                 local pids[$i]=$!
24762                 i=$((i + 1))
24763                 offset=$((offset + $bs))
24764         done
24765         for (( i=0; i < $num; i++ )); do
24766                 wait ${pids[$i]}
24767         done
24768
24769         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24770         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24771         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24772         check_lsom_data $DIR/$tdir/trunc
24773         check_lsom_data $DIR/$tdir/single_dd
24774         check_lsom_data $DIR/$tfile
24775
24776         rm -rf $DIR/$tdir
24777         # Deregistration step
24778         changelog_deregister || error "changelog_deregister failed"
24779 }
24780 run_test 807 "verify LSOM syncing tool"
24781
24782 check_som_nologged()
24783 {
24784         local lines=$($LFS changelog $FSNAME-MDT0000 |
24785                 grep 'x=trusted.som' | wc -l)
24786         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24787 }
24788
24789 test_808() {
24790         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24791                 skip "Need MDS version at least 2.11.55"
24792
24793         # Registration step
24794         changelog_register || error "changelog_register failed"
24795
24796         touch $DIR/$tfile || error "touch $tfile failed"
24797         check_som_nologged
24798
24799         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24800                 error "write $tfile failed"
24801         check_som_nologged
24802
24803         $TRUNCATE $DIR/$tfile 1234
24804         check_som_nologged
24805
24806         $TRUNCATE $DIR/$tfile 1048576
24807         check_som_nologged
24808
24809         # Deregistration step
24810         changelog_deregister || error "changelog_deregister failed"
24811 }
24812 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24813
24814 check_som_nodata()
24815 {
24816         $LFS getsom $1
24817         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24818 }
24819
24820 test_809() {
24821         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24822                 skip "Need MDS version at least 2.11.56"
24823
24824         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24825                 error "failed to create DoM-only file $DIR/$tfile"
24826         touch $DIR/$tfile || error "touch $tfile failed"
24827         check_som_nodata $DIR/$tfile
24828
24829         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24830                 error "write $tfile failed"
24831         check_som_nodata $DIR/$tfile
24832
24833         $TRUNCATE $DIR/$tfile 1234
24834         check_som_nodata $DIR/$tfile
24835
24836         $TRUNCATE $DIR/$tfile 4097
24837         check_som_nodata $DIR/$file
24838 }
24839 run_test 809 "Verify no SOM xattr store for DoM-only files"
24840
24841 test_810() {
24842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24843         $GSS && skip_env "could not run with gss"
24844         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24845                 skip "OST < 2.12.58 doesn't align checksum"
24846
24847         set_checksums 1
24848         stack_trap "set_checksums $ORIG_CSUM" EXIT
24849         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24850
24851         local csum
24852         local before
24853         local after
24854         for csum in $CKSUM_TYPES; do
24855                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24856                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24857                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24858                         eval set -- $i
24859                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24860                         before=$(md5sum $DIR/$tfile)
24861                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24862                         after=$(md5sum $DIR/$tfile)
24863                         [ "$before" == "$after" ] ||
24864                                 error "$csum: $before != $after bs=$1 seek=$2"
24865                 done
24866         done
24867 }
24868 run_test 810 "partial page writes on ZFS (LU-11663)"
24869
24870 test_812a() {
24871         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24872                 skip "OST < 2.12.51 doesn't support this fail_loc"
24873
24874         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24875         # ensure ost1 is connected
24876         stat $DIR/$tfile >/dev/null || error "can't stat"
24877         wait_osc_import_state client ost1 FULL
24878         # no locks, no reqs to let the connection idle
24879         cancel_lru_locks osc
24880
24881         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24882 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24883         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24884         wait_osc_import_state client ost1 CONNECTING
24885         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24886
24887         stat $DIR/$tfile >/dev/null || error "can't stat file"
24888 }
24889 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24890
24891 test_812b() { # LU-12378
24892         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24893                 skip "OST < 2.12.51 doesn't support this fail_loc"
24894
24895         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24896         # ensure ost1 is connected
24897         stat $DIR/$tfile >/dev/null || error "can't stat"
24898         wait_osc_import_state client ost1 FULL
24899         # no locks, no reqs to let the connection idle
24900         cancel_lru_locks osc
24901
24902         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24903 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24904         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24905         wait_osc_import_state client ost1 CONNECTING
24906         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24907
24908         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24909         wait_osc_import_state client ost1 IDLE
24910 }
24911 run_test 812b "do not drop no resend request for idle connect"
24912
24913 test_813() {
24914         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24915         [ -z "$file_heat_sav" ] && skip "no file heat support"
24916
24917         local readsample
24918         local writesample
24919         local readbyte
24920         local writebyte
24921         local readsample1
24922         local writesample1
24923         local readbyte1
24924         local writebyte1
24925
24926         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24927         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24928
24929         $LCTL set_param -n llite.*.file_heat=1
24930         echo "Turn on file heat"
24931         echo "Period second: $period_second, Decay percentage: $decay_pct"
24932
24933         echo "QQQQ" > $DIR/$tfile
24934         echo "QQQQ" > $DIR/$tfile
24935         echo "QQQQ" > $DIR/$tfile
24936         cat $DIR/$tfile > /dev/null
24937         cat $DIR/$tfile > /dev/null
24938         cat $DIR/$tfile > /dev/null
24939         cat $DIR/$tfile > /dev/null
24940
24941         local out=$($LFS heat_get $DIR/$tfile)
24942
24943         $LFS heat_get $DIR/$tfile
24944         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24945         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24946         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24947         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24948
24949         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24950         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24951         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24952         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24953
24954         sleep $((period_second + 3))
24955         echo "Sleep $((period_second + 3)) seconds..."
24956         # The recursion formula to calculate the heat of the file f is as
24957         # follow:
24958         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24959         # Where Hi is the heat value in the period between time points i*I and
24960         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24961         # to the weight of Ci.
24962         out=$($LFS heat_get $DIR/$tfile)
24963         $LFS heat_get $DIR/$tfile
24964         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24965         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24966         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24967         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24968
24969         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24970                 error "read sample ($readsample) is wrong"
24971         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24972                 error "write sample ($writesample) is wrong"
24973         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24974                 error "read bytes ($readbyte) is wrong"
24975         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24976                 error "write bytes ($writebyte) is wrong"
24977
24978         echo "QQQQ" > $DIR/$tfile
24979         echo "QQQQ" > $DIR/$tfile
24980         echo "QQQQ" > $DIR/$tfile
24981         cat $DIR/$tfile > /dev/null
24982         cat $DIR/$tfile > /dev/null
24983         cat $DIR/$tfile > /dev/null
24984         cat $DIR/$tfile > /dev/null
24985
24986         sleep $((period_second + 3))
24987         echo "Sleep $((period_second + 3)) seconds..."
24988
24989         out=$($LFS heat_get $DIR/$tfile)
24990         $LFS heat_get $DIR/$tfile
24991         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24992         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24993         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24994         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24995
24996         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24997                 4 * $decay_pct) / 100") -eq 1 ] ||
24998                 error "read sample ($readsample1) is wrong"
24999         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25000                 3 * $decay_pct) / 100") -eq 1 ] ||
25001                 error "write sample ($writesample1) is wrong"
25002         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25003                 20 * $decay_pct) / 100") -eq 1 ] ||
25004                 error "read bytes ($readbyte1) is wrong"
25005         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25006                 15 * $decay_pct) / 100") -eq 1 ] ||
25007                 error "write bytes ($writebyte1) is wrong"
25008
25009         echo "Turn off file heat for the file $DIR/$tfile"
25010         $LFS heat_set -o $DIR/$tfile
25011
25012         echo "QQQQ" > $DIR/$tfile
25013         echo "QQQQ" > $DIR/$tfile
25014         echo "QQQQ" > $DIR/$tfile
25015         cat $DIR/$tfile > /dev/null
25016         cat $DIR/$tfile > /dev/null
25017         cat $DIR/$tfile > /dev/null
25018         cat $DIR/$tfile > /dev/null
25019
25020         out=$($LFS heat_get $DIR/$tfile)
25021         $LFS heat_get $DIR/$tfile
25022         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25023         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25024         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25025         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25026
25027         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25028         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25029         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25030         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25031
25032         echo "Trun on file heat for the file $DIR/$tfile"
25033         $LFS heat_set -O $DIR/$tfile
25034
25035         echo "QQQQ" > $DIR/$tfile
25036         echo "QQQQ" > $DIR/$tfile
25037         echo "QQQQ" > $DIR/$tfile
25038         cat $DIR/$tfile > /dev/null
25039         cat $DIR/$tfile > /dev/null
25040         cat $DIR/$tfile > /dev/null
25041         cat $DIR/$tfile > /dev/null
25042
25043         out=$($LFS heat_get $DIR/$tfile)
25044         $LFS heat_get $DIR/$tfile
25045         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25046         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25047         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25048         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25049
25050         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25051         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25052         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25053         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25054
25055         $LFS heat_set -c $DIR/$tfile
25056         $LCTL set_param -n llite.*.file_heat=0
25057         echo "Turn off file heat support for the Lustre filesystem"
25058
25059         echo "QQQQ" > $DIR/$tfile
25060         echo "QQQQ" > $DIR/$tfile
25061         echo "QQQQ" > $DIR/$tfile
25062         cat $DIR/$tfile > /dev/null
25063         cat $DIR/$tfile > /dev/null
25064         cat $DIR/$tfile > /dev/null
25065         cat $DIR/$tfile > /dev/null
25066
25067         out=$($LFS heat_get $DIR/$tfile)
25068         $LFS heat_get $DIR/$tfile
25069         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25070         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25071         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25072         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25073
25074         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25075         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25076         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25077         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25078
25079         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25080         rm -f $DIR/$tfile
25081 }
25082 run_test 813 "File heat verfication"
25083
25084 test_814()
25085 {
25086         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25087         echo -n y >> $DIR/$tfile
25088         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25089         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25090 }
25091 run_test 814 "sparse cp works as expected (LU-12361)"
25092
25093 test_815()
25094 {
25095         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25096         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25097 }
25098 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25099
25100 test_816() {
25101         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25102         # ensure ost1 is connected
25103         stat $DIR/$tfile >/dev/null || error "can't stat"
25104         wait_osc_import_state client ost1 FULL
25105         # no locks, no reqs to let the connection idle
25106         cancel_lru_locks osc
25107         lru_resize_disable osc
25108         local before
25109         local now
25110         before=$($LCTL get_param -n \
25111                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25112
25113         wait_osc_import_state client ost1 IDLE
25114         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25115         now=$($LCTL get_param -n \
25116               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25117         [ $before == $now ] || error "lru_size changed $before != $now"
25118 }
25119 run_test 816 "do not reset lru_resize on idle reconnect"
25120
25121 cleanup_817() {
25122         umount $tmpdir
25123         exportfs -u localhost:$DIR/nfsexp
25124         rm -rf $DIR/nfsexp
25125 }
25126
25127 test_817() {
25128         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25129
25130         mkdir -p $DIR/nfsexp
25131         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25132                 error "failed to export nfs"
25133
25134         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25135         stack_trap cleanup_817 EXIT
25136
25137         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25138                 error "failed to mount nfs to $tmpdir"
25139
25140         cp /bin/true $tmpdir
25141         $DIR/nfsexp/true || error "failed to execute 'true' command"
25142 }
25143 run_test 817 "nfsd won't cache write lock for exec file"
25144
25145 test_818() {
25146         mkdir $DIR/$tdir
25147         $LFS setstripe -c1 -i0 $DIR/$tfile
25148         $LFS setstripe -c1 -i1 $DIR/$tfile
25149         stop $SINGLEMDS
25150         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25151         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25152         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25153                 error "start $SINGLEMDS failed"
25154         rm -rf $DIR/$tdir
25155 }
25156 run_test 818 "unlink with failed llog"
25157
25158 test_819a() {
25159         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25160         cancel_lru_locks osc
25161         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25162         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25163         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25164         rm -f $TDIR/$tfile
25165 }
25166 run_test 819a "too big niobuf in read"
25167
25168 test_819b() {
25169         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25170         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25171         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25172         cancel_lru_locks osc
25173         sleep 1
25174         rm -f $TDIR/$tfile
25175 }
25176 run_test 819b "too big niobuf in write"
25177
25178
25179 function test_820_start_ost() {
25180         sleep 5
25181
25182         for num in $(seq $OSTCOUNT); do
25183                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25184         done
25185 }
25186
25187 test_820() {
25188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25189
25190         mkdir $DIR/$tdir
25191         umount_client $MOUNT || error "umount failed"
25192         for num in $(seq $OSTCOUNT); do
25193                 stop ost$num
25194         done
25195
25196         # mount client with no active OSTs
25197         # so that the client can't initialize max LOV EA size
25198         # from OSC notifications
25199         mount_client $MOUNT || error "mount failed"
25200         # delay OST starting to keep this 0 max EA size for a while
25201         test_820_start_ost &
25202
25203         # create a directory on MDS2
25204         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25205                 error "Failed to create directory"
25206         # open intent should update default EA size
25207         # see mdc_update_max_ea_from_body()
25208         # notice this is the very first RPC to MDS2
25209         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25210         ret=$?
25211         echo $out
25212         # With SSK, this situation can lead to -EPERM being returned.
25213         # In that case, simply retry.
25214         if [ $ret -ne 0 ] && $SHARED_KEY; then
25215                 if echo "$out" | grep -q "not permitted"; then
25216                         cp /etc/services $DIR/$tdir/mds2
25217                         ret=$?
25218                 fi
25219         fi
25220         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25221 }
25222 run_test 820 "update max EA from open intent"
25223
25224 #
25225 # tests that do cleanup/setup should be run at the end
25226 #
25227
25228 test_900() {
25229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25230         local ls
25231
25232         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25233         $LCTL set_param fail_loc=0x903
25234
25235         cancel_lru_locks MGC
25236
25237         FAIL_ON_ERROR=true cleanup
25238         FAIL_ON_ERROR=true setup
25239 }
25240 run_test 900 "umount should not race with any mgc requeue thread"
25241
25242 # LUS-6253/LU-11185
25243 test_901() {
25244         local oldc
25245         local newc
25246         local olds
25247         local news
25248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25249
25250         # some get_param have a bug to handle dot in param name
25251         cancel_lru_locks MGC
25252         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25253         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25254         umount_client $MOUNT || error "umount failed"
25255         mount_client $MOUNT || error "mount failed"
25256         cancel_lru_locks MGC
25257         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25258         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25259
25260         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25261         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25262
25263         return 0
25264 }
25265 run_test 901 "don't leak a mgc lock on client umount"
25266
25267 # LU-13377
25268 test_902() {
25269         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25270                 skip "client does not have LU-13377 fix"
25271         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25272         $LCTL set_param fail_loc=0x1415
25273         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25274         cancel_lru_locks osc
25275         rm -f $DIR/$tfile
25276 }
25277 run_test 902 "test short write doesn't hang lustre"
25278
25279 complete $SECONDS
25280 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25281 check_and_cleanup_lustre
25282 if [ "$I_MOUNTED" != "yes" ]; then
25283         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25284 fi
25285 exit_status