Whamcloud - gitweb
LU-12687 osc: consume grants for direct I/O
[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 LU-13314
45 ALWAYS_EXCEPT+=" 407     312    56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
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 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177 lctl set_param debug=-1 2> /dev/null || true
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare the value of client version
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $exp_client_version)
233         imp_val=$CLIENT_VERSION
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export client version '$exp_val' != '$imp_val'"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_1() {
240         test_mkdir $DIR/$tdir
241         test_mkdir $DIR/$tdir/d2
242         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
243         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
244         rmdir $DIR/$tdir/d2
245         rmdir $DIR/$tdir
246         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
247 }
248 run_test 1 "mkdir; remkdir; rmdir"
249
250 test_2() {
251         test_mkdir $DIR/$tdir
252         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
253         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
254         rm -r $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
256 }
257 run_test 2 "mkdir; touch; rmdir; check file"
258
259 test_3() {
260         test_mkdir $DIR/$tdir
261         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
262         touch $DIR/$tdir/$tfile
263         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
264         rm -r $DIR/$tdir
265         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
266 }
267 run_test 3 "mkdir; touch; rmdir; check dir"
268
269 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
270 test_4() {
271         test_mkdir -i 1 $DIR/$tdir
272
273         touch $DIR/$tdir/$tfile ||
274                 error "Create file under remote directory failed"
275
276         rmdir $DIR/$tdir &&
277                 error "Expect error removing in-use dir $DIR/$tdir"
278
279         test -d $DIR/$tdir || error "Remote directory disappeared"
280
281         rm -rf $DIR/$tdir || error "remove remote dir error"
282 }
283 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
284
285 test_5() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
289         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
290         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
291 }
292 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
293
294 test_6a() {
295         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
296         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
297         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
298                 error "$tfile does not have perm 0666 or UID $UID"
299         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
300         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
301                 error "$tfile should be 0666 and owned by UID $UID"
302 }
303 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
304
305 test_6c() {
306         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
307
308         touch $DIR/$tfile
309         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
310         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
311                 error "$tfile should be owned by UID $RUNAS_ID"
312         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
313         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
314                 error "$tfile should be owned by UID $RUNAS_ID"
315 }
316 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
317
318 test_6e() {
319         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
320
321         touch $DIR/$tfile
322         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
323         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
324                 error "$tfile should be owned by GID $UID"
325         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
326         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
327                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
328 }
329 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
330
331 test_6g() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         test_mkdir $DIR/$tdir
335         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
336         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
337         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
338         test_mkdir $DIR/$tdir/d/subdir
339         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
340                 error "$tdir/d/subdir should be GID $RUNAS_GID"
341         if [[ $MDSCOUNT -gt 1 ]]; then
342                 # check remote dir sgid inherite
343                 $LFS mkdir -i 0 $DIR/$tdir.local ||
344                         error "mkdir $tdir.local failed"
345                 chmod g+s $DIR/$tdir.local ||
346                         error "chmod $tdir.local failed"
347                 chgrp $RUNAS_GID $DIR/$tdir.local ||
348                         error "chgrp $tdir.local failed"
349                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
350                         error "mkdir $tdir.remote failed"
351                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
352                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
353                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
354                         error "$tdir.remote should be mode 02755"
355         fi
356 }
357 run_test 6g "verify new dir in sgid dir inherits group"
358
359 test_6h() { # bug 7331
360         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
361
362         touch $DIR/$tfile || error "touch failed"
363         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
364         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
365                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
366         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
367                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
368 }
369 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
370
371 test_7a() {
372         test_mkdir $DIR/$tdir
373         $MCREATE $DIR/$tdir/$tfile
374         chmod 0666 $DIR/$tdir/$tfile
375         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
376                 error "$tdir/$tfile should be mode 0666"
377 }
378 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
379
380 test_7b() {
381         if [ ! -d $DIR/$tdir ]; then
382                 test_mkdir $DIR/$tdir
383         fi
384         $MCREATE $DIR/$tdir/$tfile
385         echo -n foo > $DIR/$tdir/$tfile
386         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
387         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
388 }
389 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
390
391 test_8() {
392         test_mkdir $DIR/$tdir
393         touch $DIR/$tdir/$tfile
394         chmod 0666 $DIR/$tdir/$tfile
395         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
396                 error "$tfile mode not 0666"
397 }
398 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
399
400 test_9() {
401         test_mkdir $DIR/$tdir
402         test_mkdir $DIR/$tdir/d2
403         test_mkdir $DIR/$tdir/d2/d3
404         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
405 }
406 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
407
408 test_10() {
409         test_mkdir $DIR/$tdir
410         test_mkdir $DIR/$tdir/d2
411         touch $DIR/$tdir/d2/$tfile
412         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
413                 error "$tdir/d2/$tfile not a file"
414 }
415 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
416
417 test_11() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         chmod 0666 $DIR/$tdir/d2
421         chmod 0705 $DIR/$tdir/d2
422         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
423                 error "$tdir/d2 mode not 0705"
424 }
425 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
426
427 test_12() {
428         test_mkdir $DIR/$tdir
429         touch $DIR/$tdir/$tfile
430         chmod 0666 $DIR/$tdir/$tfile
431         chmod 0654 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
433                 error "$tdir/d2 mode not 0654"
434 }
435 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
436
437 test_13() {
438         test_mkdir $DIR/$tdir
439         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
440         >  $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
442                 error "$tdir/$tfile size not 0 after truncate"
443 }
444 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
445
446 test_14() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
453
454 test_15() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
458         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
459                 error "$tdir/${tfile_2} not a file after rename"
460         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
461 }
462 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
463
464 test_16() {
465         test_mkdir $DIR/$tdir
466         touch $DIR/$tdir/$tfile
467         rm -rf $DIR/$tdir/$tfile
468         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
469 }
470 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
471
472 test_17a() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
476         ls -l $DIR/$tdir
477         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
478                 error "$tdir/l-exist not a symlink"
479         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
480                 error "$tdir/l-exist not referencing a file"
481         rm -f $DIR/$tdir/l-exist
482         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
483 }
484 run_test 17a "symlinks: create, remove (real)"
485
486 test_17b() {
487         test_mkdir $DIR/$tdir
488         ln -s no-such-file $DIR/$tdir/l-dangle
489         ls -l $DIR/$tdir
490         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
491                 error "$tdir/l-dangle not referencing no-such-file"
492         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
493                 error "$tdir/l-dangle not referencing non-existent file"
494         rm -f $DIR/$tdir/l-dangle
495         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
496 }
497 run_test 17b "symlinks: create, remove (dangling)"
498
499 test_17c() { # bug 3440 - don't save failed open RPC for replay
500         test_mkdir $DIR/$tdir
501         ln -s foo $DIR/$tdir/$tfile
502         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
503 }
504 run_test 17c "symlinks: open dangling (should return error)"
505
506 test_17d() {
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         touch $DIR/$tdir/$tfile || error "creating to new symlink"
510 }
511 run_test 17d "symlinks: create dangling"
512
513 test_17e() {
514         test_mkdir $DIR/$tdir
515         local foo=$DIR/$tdir/$tfile
516         ln -s $foo $foo || error "create symlink failed"
517         ls -l $foo || error "ls -l failed"
518         ls $foo && error "ls not failed" || true
519 }
520 run_test 17e "symlinks: create recursive symlink (should return error)"
521
522 test_17f() {
523         test_mkdir $DIR/$tdir
524         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
529         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
530         ls -l  $DIR/$tdir
531 }
532 run_test 17f "symlinks: long and very long symlink name"
533
534 # str_repeat(S, N) generate a string that is string S repeated N times
535 str_repeat() {
536         local s=$1
537         local n=$2
538         local ret=''
539         while [ $((n -= 1)) -ge 0 ]; do
540                 ret=$ret$s
541         done
542         echo $ret
543 }
544
545 # Long symlinks and LU-2241
546 test_17g() {
547         test_mkdir $DIR/$tdir
548         local TESTS="59 60 61 4094 4095"
549
550         # Fix for inode size boundary in 2.1.4
551         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
552                 TESTS="4094 4095"
553
554         # Patch not applied to 2.2 or 2.3 branches
555         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
556         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
557                 TESTS="4094 4095"
558
559         for i in $TESTS; do
560                 local SYMNAME=$(str_repeat 'x' $i)
561                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
562                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
563         done
564 }
565 run_test 17g "symlinks: really long symlink name and inode boundaries"
566
567 test_17h() { #bug 17378
568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
569         remote_mds_nodsh && skip "remote MDS with nodsh"
570
571         local mdt_idx
572
573         test_mkdir $DIR/$tdir
574         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
575         $LFS setstripe -c -1 $DIR/$tdir
576         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
577         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
578         touch $DIR/$tdir/$tfile || true
579 }
580 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
581
582 test_17i() { #bug 20018
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local foo=$DIR/$tdir/$tfile
587         local mdt_idx
588
589         test_mkdir -c1 $DIR/$tdir
590         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
591         ln -s $foo $foo || error "create symlink failed"
592 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
593         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
594         ls -l $foo && error "error not detected"
595         return 0
596 }
597 run_test 17i "don't panic on short symlink (should return error)"
598
599 test_17k() { #bug 22301
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         [[ -z "$(which rsync 2>/dev/null)" ]] &&
602                 skip "no rsync command"
603         rsync --help | grep -q xattr ||
604                 skip_env "$(rsync --version | head -n1) does not support xattrs"
605         test_mkdir $DIR/$tdir
606         test_mkdir $DIR/$tdir.new
607         touch $DIR/$tdir/$tfile
608         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
609         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
610                 error "rsync failed with xattrs enabled"
611 }
612 run_test 17k "symlinks: rsync with xattrs enabled"
613
614 test_17l() { # LU-279
615         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
616                 skip "no getfattr command"
617
618         test_mkdir $DIR/$tdir
619         touch $DIR/$tdir/$tfile
620         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
621         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
622                 # -h to not follow symlinks. -m '' to list all the xattrs.
623                 # grep to remove first line: '# file: $path'.
624                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
625                 do
626                         lgetxattr_size_check $path $xattr ||
627                                 error "lgetxattr_size_check $path $xattr failed"
628                 done
629         done
630 }
631 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
632
633 # LU-1540
634 test_17m() {
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
637         remote_mds_nodsh && skip "remote MDS with nodsh"
638         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
639         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
640                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
641
642         local short_sym="0123456789"
643         local wdir=$DIR/$tdir
644         local i
645
646         test_mkdir $wdir
647         long_sym=$short_sym
648         # create a long symlink file
649         for ((i = 0; i < 4; ++i)); do
650                 long_sym=${long_sym}${long_sym}
651         done
652
653         echo "create 512 short and long symlink files under $wdir"
654         for ((i = 0; i < 256; ++i)); do
655                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
656                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
657         done
658
659         echo "erase them"
660         rm -f $wdir/*
661         sync
662         wait_delete_completed
663
664         echo "recreate the 512 symlink files with a shorter string"
665         for ((i = 0; i < 512; ++i)); do
666                 # rewrite the symlink file with a shorter string
667                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
668                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
669         done
670
671         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
672         local devname=$(mdsdevname $mds_index)
673
674         echo "stop and checking mds${mds_index}:"
675         # e2fsck should not return error
676         stop mds${mds_index}
677         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
678         rc=$?
679
680         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
681                 error "start mds${mds_index} failed"
682         df $MOUNT > /dev/null 2>&1
683         [ $rc -eq 0 ] ||
684                 error "e2fsck detected error for short/long symlink: rc=$rc"
685         rm -f $wdir/*
686 }
687 run_test 17m "run e2fsck against MDT which contains short/long symlink"
688
689 check_fs_consistency_17n() {
690         local mdt_index
691         local rc=0
692
693         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
694         # so it only check MDT1/MDT2 instead of all of MDTs.
695         for mdt_index in 1 2; do
696                 local devname=$(mdsdevname $mdt_index)
697                 # e2fsck should not return error
698                 stop mds${mdt_index}
699                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
700                         rc=$((rc + $?))
701
702                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
703                         error "mount mds$mdt_index failed"
704                 df $MOUNT > /dev/null 2>&1
705         done
706         return $rc
707 }
708
709 test_17n() {
710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
713         remote_mds_nodsh && skip "remote MDS with nodsh"
714         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
715         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
716                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
717
718         local i
719
720         test_mkdir $DIR/$tdir
721         for ((i=0; i<10; i++)); do
722                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
723                         error "create remote dir error $i"
724                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
725                         error "create files under remote dir failed $i"
726         done
727
728         check_fs_consistency_17n ||
729                 error "e2fsck report error after create files under remote dir"
730
731         for ((i = 0; i < 10; i++)); do
732                 rm -rf $DIR/$tdir/remote_dir_${i} ||
733                         error "destroy remote dir error $i"
734         done
735
736         check_fs_consistency_17n ||
737                 error "e2fsck report error after unlink files under remote dir"
738
739         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
740                 skip "lustre < 2.4.50 does not support migrate mv"
741
742         for ((i = 0; i < 10; i++)); do
743                 mkdir -p $DIR/$tdir/remote_dir_${i}
744                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
745                         error "create files under remote dir failed $i"
746                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
747                         error "migrate remote dir error $i"
748         done
749         check_fs_consistency_17n || error "e2fsck report error after migration"
750
751         for ((i = 0; i < 10; i++)); do
752                 rm -rf $DIR/$tdir/remote_dir_${i} ||
753                         error "destroy remote dir error $i"
754         done
755
756         check_fs_consistency_17n || error "e2fsck report error after unlink"
757 }
758 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
759
760 test_17o() {
761         remote_mds_nodsh && skip "remote MDS with nodsh"
762         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
763                 skip "Need MDS version at least 2.3.64"
764
765         local wdir=$DIR/${tdir}o
766         local mdt_index
767         local rc=0
768
769         test_mkdir $wdir
770         touch $wdir/$tfile
771         mdt_index=$($LFS getstripe -m $wdir/$tfile)
772         mdt_index=$((mdt_index + 1))
773
774         cancel_lru_locks mdc
775         #fail mds will wait the failover finish then set
776         #following fail_loc to avoid interfer the recovery process.
777         fail mds${mdt_index}
778
779         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
780         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
781         ls -l $wdir/$tfile && rc=1
782         do_facet mds${mdt_index} lctl set_param fail_loc=0
783         [[ $rc -eq 0 ]] || error "stat file should fail"
784 }
785 run_test 17o "stat file with incompat LMA feature"
786
787 test_18() {
788         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
789         ls $DIR || error "Failed to ls $DIR: $?"
790 }
791 run_test 18 "touch .../f ; ls ... =============================="
792
793 test_19a() {
794         touch $DIR/$tfile
795         ls -l $DIR
796         rm $DIR/$tfile
797         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
798 }
799 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
800
801 test_19b() {
802         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
803 }
804 run_test 19b "ls -l .../f19 (should return error) =============="
805
806 test_19c() {
807         [ $RUNAS_ID -eq $UID ] &&
808                 skip_env "RUNAS_ID = UID = $UID -- skipping"
809
810         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
811 }
812 run_test 19c "$RUNAS touch .../f19 (should return error) =="
813
814 test_19d() {
815         cat $DIR/f19 && error || true
816 }
817 run_test 19d "cat .../f19 (should return error) =============="
818
819 test_20() {
820         touch $DIR/$tfile
821         rm $DIR/$tfile
822         touch $DIR/$tfile
823         rm $DIR/$tfile
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 20 "touch .../f ; ls -l ..."
829
830 test_21() {
831         test_mkdir $DIR/$tdir
832         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
833         ln -s dangle $DIR/$tdir/link
834         echo foo >> $DIR/$tdir/link
835         cat $DIR/$tdir/dangle
836         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
837         $CHECKSTAT -f -t file $DIR/$tdir/link ||
838                 error "$tdir/link not linked to a file"
839 }
840 run_test 21 "write to dangling link"
841
842 test_22() {
843         local wdir=$DIR/$tdir
844         test_mkdir $wdir
845         chown $RUNAS_ID:$RUNAS_GID $wdir
846         (cd $wdir || error "cd $wdir failed";
847                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
848                 $RUNAS tar xf -)
849         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
850         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
851         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
852                 error "checkstat -u failed"
853 }
854 run_test 22 "unpack tar archive as non-root user"
855
856 # was test_23
857 test_23a() {
858         test_mkdir $DIR/$tdir
859         local file=$DIR/$tdir/$tfile
860
861         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
862         openfile -f O_CREAT:O_EXCL $file &&
863                 error "$file recreate succeeded" || true
864 }
865 run_test 23a "O_CREAT|O_EXCL in subdir"
866
867 test_23b() { # bug 18988
868         test_mkdir $DIR/$tdir
869         local file=$DIR/$tdir/$tfile
870
871         rm -f $file
872         echo foo > $file || error "write filed"
873         echo bar >> $file || error "append filed"
874         $CHECKSTAT -s 8 $file || error "wrong size"
875         rm $file
876 }
877 run_test 23b "O_APPEND check"
878
879 # LU-9409, size with O_APPEND and tiny writes
880 test_23c() {
881         local file=$DIR/$tfile
882
883         # single dd
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
885         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
886         rm -f $file
887
888         # racing tiny writes
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
891         wait
892         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
893         rm -f $file
894
895         #racing tiny & normal writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
898         wait
899         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
900         rm -f $file
901
902         #racing tiny & normal writes 2, ugly numbers
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
905         wait
906         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
907         rm -f $file
908 }
909 run_test 23c "O_APPEND size checks for tiny writes"
910
911 # LU-11069 file offset is correct after appending writes
912 test_23d() {
913         local file=$DIR/$tfile
914         local offset
915
916         echo CentaurHauls > $file
917         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
918         if ((offset != 26)); then
919                 error "wrong offset, expected 26, got '$offset'"
920         fi
921 }
922 run_test 23d "file offset is correct after appending writes"
923
924 # rename sanity
925 test_24a() {
926         echo '-- same directory rename'
927         test_mkdir $DIR/$tdir
928         touch $DIR/$tdir/$tfile.1
929         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
930         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
931 }
932 run_test 24a "rename file to non-existent target"
933
934 test_24b() {
935         test_mkdir $DIR/$tdir
936         touch $DIR/$tdir/$tfile.{1,2}
937         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
938         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24b "rename file to existing target"
942
943 test_24c() {
944         test_mkdir $DIR/$tdir
945         test_mkdir $DIR/$tdir/d$testnum.1
946         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
947         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
948         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
949 }
950 run_test 24c "rename directory to non-existent target"
951
952 test_24d() {
953         test_mkdir -c1 $DIR/$tdir
954         test_mkdir -c1 $DIR/$tdir/d$testnum.1
955         test_mkdir -c1 $DIR/$tdir/d$testnum.2
956         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
957         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
958         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
959 }
960 run_test 24d "rename directory to existing target"
961
962 test_24e() {
963         echo '-- cross directory renames --'
964         test_mkdir $DIR/R5a
965         test_mkdir $DIR/R5b
966         touch $DIR/R5a/f
967         mv $DIR/R5a/f $DIR/R5b/g
968         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
969         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
970 }
971 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
972
973 test_24f() {
974         test_mkdir $DIR/R6a
975         test_mkdir $DIR/R6b
976         touch $DIR/R6a/f $DIR/R6b/g
977         mv $DIR/R6a/f $DIR/R6b/g
978         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
979         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
980 }
981 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
982
983 test_24g() {
984         test_mkdir $DIR/R7a
985         test_mkdir $DIR/R7b
986         test_mkdir $DIR/R7a/d
987         mv $DIR/R7a/d $DIR/R7b/e
988         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
989         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
990 }
991 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
992
993 test_24h() {
994         test_mkdir -c1 $DIR/R8a
995         test_mkdir -c1 $DIR/R8b
996         test_mkdir -c1 $DIR/R8a/d
997         test_mkdir -c1 $DIR/R8b/e
998         mrename $DIR/R8a/d $DIR/R8b/e
999         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1000         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1001 }
1002 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1003
1004 test_24i() {
1005         echo "-- rename error cases"
1006         test_mkdir $DIR/R9
1007         test_mkdir $DIR/R9/a
1008         touch $DIR/R9/f
1009         mrename $DIR/R9/f $DIR/R9/a
1010         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1011         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1012         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1013 }
1014 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1015
1016 test_24j() {
1017         test_mkdir $DIR/R10
1018         mrename $DIR/R10/f $DIR/R10/g
1019         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1020         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1021         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1022 }
1023 run_test 24j "source does not exist ============================"
1024
1025 test_24k() {
1026         test_mkdir $DIR/R11a
1027         test_mkdir $DIR/R11a/d
1028         touch $DIR/R11a/f
1029         mv $DIR/R11a/f $DIR/R11a/d
1030         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1031         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1032 }
1033 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1034
1035 # bug 2429 - rename foo foo foo creates invalid file
1036 test_24l() {
1037         f="$DIR/f24l"
1038         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1039 }
1040 run_test 24l "Renaming a file to itself ========================"
1041
1042 test_24m() {
1043         f="$DIR/f24m"
1044         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1045         # on ext3 this does not remove either the source or target files
1046         # though the "expected" operation would be to remove the source
1047         $CHECKSTAT -t file ${f} || error "${f} missing"
1048         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1049 }
1050 run_test 24m "Renaming a file to a hard link to itself ========="
1051
1052 test_24n() {
1053     f="$DIR/f24n"
1054     # this stats the old file after it was renamed, so it should fail
1055     touch ${f}
1056     $CHECKSTAT ${f} || error "${f} missing"
1057     mv ${f} ${f}.rename
1058     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1059     $CHECKSTAT -a ${f} || error "${f} exists"
1060 }
1061 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1062
1063 test_24o() {
1064         test_mkdir $DIR/$tdir
1065         rename_many -s random -v -n 10 $DIR/$tdir
1066 }
1067 run_test 24o "rename of files during htree split"
1068
1069 test_24p() {
1070         test_mkdir $DIR/R12a
1071         test_mkdir $DIR/R12b
1072         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1073         mrename $DIR/R12a $DIR/R12b
1074         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1075         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1076         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1077         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1078 }
1079 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1080
1081 cleanup_multiop_pause() {
1082         trap 0
1083         kill -USR1 $MULTIPID
1084 }
1085
1086 test_24q() {
1087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1088
1089         test_mkdir $DIR/R13a
1090         test_mkdir $DIR/R13b
1091         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1092         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1093         MULTIPID=$!
1094
1095         trap cleanup_multiop_pause EXIT
1096         mrename $DIR/R13a $DIR/R13b
1097         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1098         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1099         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1100         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1101         cleanup_multiop_pause
1102         wait $MULTIPID || error "multiop close failed"
1103 }
1104 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1105
1106 test_24r() { #bug 3789
1107         test_mkdir $DIR/R14a
1108         test_mkdir $DIR/R14a/b
1109         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1110         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1111         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1112 }
1113 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1114
1115 test_24s() {
1116         test_mkdir $DIR/R15a
1117         test_mkdir $DIR/R15a/b
1118         test_mkdir $DIR/R15a/b/c
1119         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1120         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1121         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1122 }
1123 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1124 test_24t() {
1125         test_mkdir $DIR/R16a
1126         test_mkdir $DIR/R16a/b
1127         test_mkdir $DIR/R16a/b/c
1128         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1130         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1131 }
1132 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1133
1134 test_24u() { # bug12192
1135         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1136         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1137 }
1138 run_test 24u "create stripe file"
1139
1140 simple_cleanup_common() {
1141         local rc=0
1142         trap 0
1143         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1144
1145         local start=$SECONDS
1146         rm -rf $DIR/$tdir
1147         rc=$?
1148         wait_delete_completed
1149         echo "cleanup time $((SECONDS - start))"
1150         return $rc
1151 }
1152
1153 max_pages_per_rpc() {
1154         local mdtname="$(printf "MDT%04x" ${1:-0})"
1155         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1156 }
1157
1158 test_24v() {
1159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1160
1161         local nrfiles=${COUNT:-100000}
1162         local fname="$DIR/$tdir/$tfile"
1163
1164         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1165         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1166
1167         test_mkdir "$(dirname $fname)"
1168         # assume MDT0000 has the fewest inodes
1169         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1170         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1171         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1172
1173         trap simple_cleanup_common EXIT
1174
1175         createmany -m "$fname" $nrfiles
1176
1177         cancel_lru_locks mdc
1178         lctl set_param mdc.*.stats clear
1179
1180         # was previously test_24D: LU-6101
1181         # readdir() returns correct number of entries after cursor reload
1182         local num_ls=$(ls $DIR/$tdir | wc -l)
1183         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1184         local num_all=$(ls -a $DIR/$tdir | wc -l)
1185         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1186                 [ $num_all -ne $((nrfiles + 2)) ]; then
1187                         error "Expected $nrfiles files, got $num_ls " \
1188                                 "($num_uniq unique $num_all .&..)"
1189         fi
1190         # LU-5 large readdir
1191         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1192         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1193         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1194         # take into account of overhead in lu_dirpage header and end mark in
1195         # each page, plus one in rpc_num calculation.
1196         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1197         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1198         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1199         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1200         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1201         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1202         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1203         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1204                 error "large readdir doesn't take effect: " \
1205                       "$mds_readpage should be about $rpc_max"
1206
1207         simple_cleanup_common
1208 }
1209 run_test 24v "list large directory (test hash collision, b=17560)"
1210
1211 test_24w() { # bug21506
1212         SZ1=234852
1213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1214         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1215         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1216         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1217         [[ "$SZ1" -eq "$SZ2" ]] ||
1218                 error "Error reading at the end of the file $tfile"
1219 }
1220 run_test 24w "Reading a file larger than 4Gb"
1221
1222 test_24x() {
1223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1225         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1226                 skip "Need MDS version at least 2.7.56"
1227
1228         local MDTIDX=1
1229         local remote_dir=$DIR/$tdir/remote_dir
1230
1231         test_mkdir $DIR/$tdir
1232         $LFS mkdir -i $MDTIDX $remote_dir ||
1233                 error "create remote directory failed"
1234
1235         test_mkdir $DIR/$tdir/src_dir
1236         touch $DIR/$tdir/src_file
1237         test_mkdir $remote_dir/tgt_dir
1238         touch $remote_dir/tgt_file
1239
1240         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1241                 error "rename dir cross MDT failed!"
1242
1243         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1244                 error "rename file cross MDT failed!"
1245
1246         touch $DIR/$tdir/ln_file
1247         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1248                 error "ln file cross MDT failed"
1249
1250         rm -rf $DIR/$tdir || error "Can not delete directories"
1251 }
1252 run_test 24x "cross MDT rename/link"
1253
1254 test_24y() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257
1258         local remote_dir=$DIR/$tdir/remote_dir
1259         local mdtidx=1
1260
1261         test_mkdir $DIR/$tdir
1262         $LFS mkdir -i $mdtidx $remote_dir ||
1263                 error "create remote directory failed"
1264
1265         test_mkdir $remote_dir/src_dir
1266         touch $remote_dir/src_file
1267         test_mkdir $remote_dir/tgt_dir
1268         touch $remote_dir/tgt_file
1269
1270         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1271                 error "rename subdir in the same remote dir failed!"
1272
1273         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1274                 error "rename files in the same remote dir failed!"
1275
1276         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1277                 error "link files in the same remote dir failed!"
1278
1279         rm -rf $DIR/$tdir || error "Can not delete directories"
1280 }
1281 run_test 24y "rename/link on the same dir should succeed"
1282
1283 test_24z() {
1284         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1285         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1286                 skip "Need MDS version at least 2.12.51"
1287
1288         local index
1289
1290         for index in 0 1; do
1291                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1292                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1293         done
1294
1295         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1296
1297         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1298         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1299
1300         local mdts=$(comma_list $(mdts_nodes))
1301
1302         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1303         stack_trap "do_nodes $mdts $LCTL \
1304                 set_param mdt.*.enable_remote_rename=1" EXIT
1305
1306         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1307
1308         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1309         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1310 }
1311 run_test 24z "cross-MDT rename is done as cp"
1312
1313 test_24A() { # LU-3182
1314         local NFILES=5000
1315
1316         rm -rf $DIR/$tdir
1317         test_mkdir $DIR/$tdir
1318         trap simple_cleanup_common EXIT
1319         createmany -m $DIR/$tdir/$tfile $NFILES
1320         local t=$(ls $DIR/$tdir | wc -l)
1321         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1322         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1323         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1324            [ $v -ne $((NFILES + 2)) ] ; then
1325                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1326         fi
1327
1328         simple_cleanup_common || error "Can not delete directories"
1329 }
1330 run_test 24A "readdir() returns correct number of entries."
1331
1332 test_24B() { # LU-4805
1333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1334
1335         local count
1336
1337         test_mkdir $DIR/$tdir
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1342         [ $count -eq 2 ] || error "Expected 2, got $count"
1343
1344         touch $DIR/$tdir/striped_dir/a
1345
1346         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1347         [ $count -eq 3 ] || error "Expected 3, got $count"
1348
1349         touch $DIR/$tdir/striped_dir/.f
1350
1351         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1352         [ $count -eq 4 ] || error "Expected 4, got $count"
1353
1354         rm -rf $DIR/$tdir || error "Can not delete directories"
1355 }
1356 run_test 24B "readdir for striped dir return correct number of entries"
1357
1358 test_24C() {
1359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1360
1361         mkdir $DIR/$tdir
1362         mkdir $DIR/$tdir/d0
1363         mkdir $DIR/$tdir/d1
1364
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1366                 error "create striped dir failed"
1367
1368         cd $DIR/$tdir/d0/striped_dir
1369
1370         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1371         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1372         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1373
1374         [ "$d0_ino" = "$parent_ino" ] ||
1375                 error ".. wrong, expect $d0_ino, get $parent_ino"
1376
1377         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1378                 error "mv striped dir failed"
1379
1380         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1381
1382         [ "$d1_ino" = "$parent_ino" ] ||
1383                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1384 }
1385 run_test 24C "check .. in striped dir"
1386
1387 test_24E() {
1388         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1390
1391         mkdir -p $DIR/$tdir
1392         mkdir $DIR/$tdir/src_dir
1393         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1394                 error "create remote source failed"
1395
1396         touch $DIR/$tdir/src_dir/src_child/a
1397
1398         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1399                 error "create remote target dir failed"
1400
1401         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1402                 error "create remote target child failed"
1403
1404         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "rename dir cross MDT failed!"
1406
1407         find $DIR/$tdir
1408
1409         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1410                 error "src_child still exists after rename"
1411
1412         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1413                 error "missing file(a) after rename"
1414
1415         rm -rf $DIR/$tdir || error "Can not delete directories"
1416 }
1417 run_test 24E "cross MDT rename/link"
1418
1419 test_24F () {
1420         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1421
1422         local repeats=1000
1423         [ "$SLOW" = "no" ] && repeats=100
1424
1425         mkdir -p $DIR/$tdir
1426
1427         echo "$repeats repeats"
1428         for ((i = 0; i < repeats; i++)); do
1429                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1430                 touch $DIR/$tdir/test/a || error "touch fails"
1431                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1432                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1433         done
1434
1435         true
1436 }
1437 run_test 24F "hash order vs readdir (LU-11330)"
1438
1439 test_25a() {
1440         echo '== symlink sanity ============================================='
1441
1442         test_mkdir $DIR/d25
1443         ln -s d25 $DIR/s25
1444         touch $DIR/s25/foo ||
1445                 error "File creation in symlinked directory failed"
1446 }
1447 run_test 25a "create file in symlinked directory ==============="
1448
1449 test_25b() {
1450         [ ! -d $DIR/d25 ] && test_25a
1451         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1452 }
1453 run_test 25b "lookup file in symlinked directory ==============="
1454
1455 test_26a() {
1456         test_mkdir $DIR/d26
1457         test_mkdir $DIR/d26/d26-2
1458         ln -s d26/d26-2 $DIR/s26
1459         touch $DIR/s26/foo || error "File creation failed"
1460 }
1461 run_test 26a "multiple component symlink ======================="
1462
1463 test_26b() {
1464         test_mkdir -p $DIR/$tdir/d26-2
1465         ln -s $tdir/d26-2/foo $DIR/s26-2
1466         touch $DIR/s26-2 || error "File creation failed"
1467 }
1468 run_test 26b "multiple component symlink at end of lookup ======"
1469
1470 test_26c() {
1471         test_mkdir $DIR/d26.2
1472         touch $DIR/d26.2/foo
1473         ln -s d26.2 $DIR/s26.2-1
1474         ln -s s26.2-1 $DIR/s26.2-2
1475         ln -s s26.2-2 $DIR/s26.2-3
1476         chmod 0666 $DIR/s26.2-3/foo
1477 }
1478 run_test 26c "chain of symlinks"
1479
1480 # recursive symlinks (bug 439)
1481 test_26d() {
1482         ln -s d26-3/foo $DIR/d26-3
1483 }
1484 run_test 26d "create multiple component recursive symlink"
1485
1486 test_26e() {
1487         [ ! -h $DIR/d26-3 ] && test_26d
1488         rm $DIR/d26-3
1489 }
1490 run_test 26e "unlink multiple component recursive symlink"
1491
1492 # recursive symlinks (bug 7022)
1493 test_26f() {
1494         test_mkdir $DIR/$tdir
1495         test_mkdir $DIR/$tdir/$tfile
1496         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1497         test_mkdir -p lndir/bar1
1498         test_mkdir $DIR/$tdir/$tfile/$tfile
1499         cd $tfile                || error "cd $tfile failed"
1500         ln -s .. dotdot          || error "ln dotdot failed"
1501         ln -s dotdot/lndir lndir || error "ln lndir failed"
1502         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1503         output=`ls $tfile/$tfile/lndir/bar1`
1504         [ "$output" = bar1 ] && error "unexpected output"
1505         rm -r $tfile             || error "rm $tfile failed"
1506         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1507 }
1508 run_test 26f "rm -r of a directory which has recursive symlink"
1509
1510 test_27a() {
1511         test_mkdir $DIR/$tdir
1512         $LFS getstripe $DIR/$tdir
1513         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1514         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1515         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1516 }
1517 run_test 27a "one stripe file"
1518
1519 test_27b() {
1520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1521
1522         test_mkdir $DIR/$tdir
1523         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1524         $LFS getstripe -c $DIR/$tdir/$tfile
1525         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1526                 error "two-stripe file doesn't have two stripes"
1527
1528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1529 }
1530 run_test 27b "create and write to two stripe file"
1531
1532 # 27c family tests specific striping, setstripe -o
1533 test_27ca() {
1534         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1535         test_mkdir -p $DIR/$tdir
1536         local osts="1"
1537
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1539         $LFS getstripe -i $DIR/$tdir/$tfile
1540         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1541                 error "stripe not on specified OST"
1542
1543         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1544 }
1545 run_test 27ca "one stripe on specified OST"
1546
1547 test_27cb() {
1548         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1549         test_mkdir -p $DIR/$tdir
1550         local osts="1,0"
1551         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1552         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1553         echo "$getstripe"
1554
1555         # Strip getstripe output to a space separated list of OSTs
1556         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1557                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1558         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1559                 error "stripes not on specified OSTs"
1560
1561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1562 }
1563 run_test 27cb "two stripes on specified OSTs"
1564
1565 test_27cc() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1568                 skip "server does not support overstriping"
1569
1570         test_mkdir -p $DIR/$tdir
1571         local osts="0,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cc "two stripes on the same OST"
1585
1586 test_27cd() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590         test_mkdir -p $DIR/$tdir
1591         local osts="0,1,1,0"
1592         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1593         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1594         echo "$getstripe"
1595
1596         # Strip getstripe output to a space separated list of OSTs
1597         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1598                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1599         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1600                 error "stripes not on specified OSTs"
1601
1602         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1603 }
1604 run_test 27cd "four stripes on two OSTs"
1605
1606 test_27ce() {
1607         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1608                 skip_env "too many osts, skipping"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         # We do one more stripe than we have OSTs
1612         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1613                 skip_env "ea_inode feature disabled"
1614
1615         test_mkdir -p $DIR/$tdir
1616         local osts=""
1617         for i in $(seq 0 $OSTCOUNT);
1618         do
1619                 osts=$osts"0"
1620                 if [ $i -ne $OSTCOUNT ]; then
1621                         osts=$osts","
1622                 fi
1623         done
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 27ce "more stripes than OSTs with -o"
1637
1638 test_27cf() {
1639         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1640         local pid=0
1641
1642         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1643         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1644         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1645         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1646                 error "failed to set $osp_proc=0"
1647
1648         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1649         pid=$!
1650         sleep 1
1651         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1653                 error "failed to set $osp_proc=1"
1654         wait $pid
1655         [[ $pid -ne 0 ]] ||
1656                 error "should return error due to $osp_proc=0"
1657 }
1658 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1659
1660 test_27d() {
1661         test_mkdir $DIR/$tdir
1662         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1663                 error "setstripe failed"
1664         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1666 }
1667 run_test 27d "create file with default settings"
1668
1669 test_27e() {
1670         # LU-5839 adds check for existed layout before setting it
1671         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1672                 skip "Need MDS version at least 2.7.56"
1673
1674         test_mkdir $DIR/$tdir
1675         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1676         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1677         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1678 }
1679 run_test 27e "setstripe existing file (should return error)"
1680
1681 test_27f() {
1682         test_mkdir $DIR/$tdir
1683         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1684                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1685         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1686                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1688         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1689 }
1690 run_test 27f "setstripe with bad stripe size (should return error)"
1691
1692 test_27g() {
1693         test_mkdir $DIR/$tdir
1694         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1695         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1696                 error "$DIR/$tdir/$tfile has object"
1697 }
1698 run_test 27g "$LFS getstripe with no objects"
1699
1700 test_27ga() {
1701         test_mkdir $DIR/$tdir
1702         touch $DIR/$tdir/$tfile || error "touch failed"
1703         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1704         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1705         local rc=$?
1706         (( rc == 2 )) || error "getstripe did not return ENOENT"
1707 }
1708 run_test 27ga "$LFS getstripe with missing file (should return error)"
1709
1710 test_27i() {
1711         test_mkdir $DIR/$tdir
1712         touch $DIR/$tdir/$tfile || error "touch failed"
1713         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1714                 error "missing objects"
1715 }
1716 run_test 27i "$LFS getstripe with some objects"
1717
1718 test_27j() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1721                 error "setstripe failed" || true
1722 }
1723 run_test 27j "setstripe with bad stripe offset (should return error)"
1724
1725 test_27k() { # bug 2844
1726         test_mkdir $DIR/$tdir
1727         local file=$DIR/$tdir/$tfile
1728         local ll_max_blksize=$((4 * 1024 * 1024))
1729         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1730         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1731         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1732         dd if=/dev/zero of=$file bs=4k count=1
1733         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1734         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1735 }
1736 run_test 27k "limit i_blksize for broken user apps"
1737
1738 test_27l() {
1739         mcreate $DIR/$tfile || error "creating file"
1740         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1741                 error "setstripe should have failed" || true
1742 }
1743 run_test 27l "check setstripe permissions (should return error)"
1744
1745 test_27m() {
1746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1747
1748         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1749                 skip_env "multiple clients -- skipping"
1750
1751         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1752                    head -n1)
1753         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1754                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1755         fi
1756         trap simple_cleanup_common EXIT
1757         test_mkdir $DIR/$tdir
1758         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1759         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1760                 error "dd should fill OST0"
1761         i=2
1762         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1763                 i=$((i + 1))
1764                 [ $i -gt 256 ] && break
1765         done
1766         i=$((i + 1))
1767         touch $DIR/$tdir/$tfile.$i
1768         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1769             awk '{print $1}'| grep -w "0") ] &&
1770                 error "OST0 was full but new created file still use it"
1771         i=$((i + 1))
1772         touch $DIR/$tdir/$tfile.$i
1773         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1774             awk '{print $1}'| grep -w "0") ] &&
1775                 error "OST0 was full but new created file still use it"
1776         simple_cleanup_common
1777 }
1778 run_test 27m "create file while OST0 was full"
1779
1780 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1781 # if the OST isn't full anymore.
1782 reset_enospc() {
1783         local ostidx=${1:-""}
1784         local delay
1785         local ready
1786         local get_prealloc
1787
1788         local list=$(comma_list $(osts_nodes))
1789         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1790
1791         do_nodes $list lctl set_param fail_loc=0
1792         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1793         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1794                 awk '{print $1 * 2;exit;}')
1795         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1796                         grep -v \"^0$\""
1797         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1798 }
1799
1800 __exhaust_precreations() {
1801         local OSTIDX=$1
1802         local FAILLOC=$2
1803         local FAILIDX=${3:-$OSTIDX}
1804         local ofacet=ost$((OSTIDX + 1))
1805
1806         test_mkdir -p -c1 $DIR/$tdir
1807         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1808         local mfacet=mds$((mdtidx + 1))
1809         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1810
1811         local OST=$(ostname_from_index $OSTIDX)
1812
1813         # on the mdt's osc
1814         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1815         local last_id=$(do_facet $mfacet lctl get_param -n \
1816                         osp.$mdtosc_proc1.prealloc_last_id)
1817         local next_id=$(do_facet $mfacet lctl get_param -n \
1818                         osp.$mdtosc_proc1.prealloc_next_id)
1819
1820         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1821         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1822
1823         test_mkdir -p $DIR/$tdir/${OST}
1824         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1825 #define OBD_FAIL_OST_ENOSPC              0x215
1826         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1827         echo "Creating to objid $last_id on ost $OST..."
1828         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1829         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1830         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1831 }
1832
1833 exhaust_precreations() {
1834         __exhaust_precreations $1 $2 $3
1835         sleep_maxage
1836 }
1837
1838 exhaust_all_precreations() {
1839         local i
1840         for (( i=0; i < OSTCOUNT; i++ )) ; do
1841                 __exhaust_precreations $i $1 -1
1842         done
1843         sleep_maxage
1844 }
1845
1846 test_27n() {
1847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1849         remote_mds_nodsh && skip "remote MDS with nodsh"
1850         remote_ost_nodsh && skip "remote OST with nodsh"
1851
1852         reset_enospc
1853         rm -f $DIR/$tdir/$tfile
1854         exhaust_precreations 0 0x80000215
1855         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1856         touch $DIR/$tdir/$tfile || error "touch failed"
1857         $LFS getstripe $DIR/$tdir/$tfile
1858         reset_enospc
1859 }
1860 run_test 27n "create file with some full OSTs"
1861
1862 test_27o() {
1863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1865         remote_mds_nodsh && skip "remote MDS with nodsh"
1866         remote_ost_nodsh && skip "remote OST with nodsh"
1867
1868         reset_enospc
1869         rm -f $DIR/$tdir/$tfile
1870         exhaust_all_precreations 0x215
1871
1872         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1873
1874         reset_enospc
1875         rm -rf $DIR/$tdir/*
1876 }
1877 run_test 27o "create file with all full OSTs (should error)"
1878
1879 test_27p() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         test_mkdir $DIR/$tdir
1888
1889         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1890         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1891         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1892
1893         exhaust_precreations 0 0x80000215
1894         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1895         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1896         $LFS getstripe $DIR/$tdir/$tfile
1897
1898         reset_enospc
1899 }
1900 run_test 27p "append to a truncated file with some full OSTs"
1901
1902 test_27q() {
1903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1905         remote_mds_nodsh && skip "remote MDS with nodsh"
1906         remote_ost_nodsh && skip "remote OST with nodsh"
1907
1908         reset_enospc
1909         rm -f $DIR/$tdir/$tfile
1910
1911         test_mkdir $DIR/$tdir
1912         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1913         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1914                 error "truncate $DIR/$tdir/$tfile failed"
1915         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1916
1917         exhaust_all_precreations 0x215
1918
1919         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1920         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1921
1922         reset_enospc
1923 }
1924 run_test 27q "append to truncated file with all OSTs full (should error)"
1925
1926 test_27r() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_precreations 0 0x80000215
1935
1936         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1937
1938         reset_enospc
1939 }
1940 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1941
1942 test_27s() { # bug 10725
1943         test_mkdir $DIR/$tdir
1944         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1945         local stripe_count=0
1946         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1947         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1948                 error "stripe width >= 2^32 succeeded" || true
1949
1950 }
1951 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1952
1953 test_27t() { # bug 10864
1954         WDIR=$(pwd)
1955         WLFS=$(which lfs)
1956         cd $DIR
1957         touch $tfile
1958         $WLFS getstripe $tfile
1959         cd $WDIR
1960 }
1961 run_test 27t "check that utils parse path correctly"
1962
1963 test_27u() { # bug 4900
1964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966
1967         local index
1968         local list=$(comma_list $(mdts_nodes))
1969
1970 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1971         do_nodes $list $LCTL set_param fail_loc=0x139
1972         test_mkdir -p $DIR/$tdir
1973         trap simple_cleanup_common EXIT
1974         createmany -o $DIR/$tdir/t- 1000
1975         do_nodes $list $LCTL set_param fail_loc=0
1976
1977         TLOG=$TMP/$tfile.getstripe
1978         $LFS getstripe $DIR/$tdir > $TLOG
1979         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1980         unlinkmany $DIR/$tdir/t- 1000
1981         trap 0
1982         [[ $OBJS -gt 0 ]] &&
1983                 error "$OBJS objects created on OST-0. See $TLOG" ||
1984                 rm -f $TLOG
1985 }
1986 run_test 27u "skip object creation on OSC w/o objects"
1987
1988 test_27v() { # bug 4900
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         exhaust_all_precreations 0x215
1995         reset_enospc
1996
1997         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1998
1999         touch $DIR/$tdir/$tfile
2000         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2001         # all except ost1
2002         for (( i=1; i < OSTCOUNT; i++ )); do
2003                 do_facet ost$i lctl set_param fail_loc=0x705
2004         done
2005         local START=`date +%s`
2006         createmany -o $DIR/$tdir/$tfile 32
2007
2008         local FINISH=`date +%s`
2009         local TIMEOUT=`lctl get_param -n timeout`
2010         local PROCESS=$((FINISH - START))
2011         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2012                error "$FINISH - $START >= $TIMEOUT / 2"
2013         sleep $((TIMEOUT / 2 - PROCESS))
2014         reset_enospc
2015 }
2016 run_test 27v "skip object creation on slow OST"
2017
2018 test_27w() { # bug 10997
2019         test_mkdir $DIR/$tdir
2020         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2021         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2022                 error "stripe size $size != 65536" || true
2023         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2024                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2025 }
2026 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2027
2028 test_27wa() {
2029         [[ $OSTCOUNT -lt 2 ]] &&
2030                 skip_env "skipping multiple stripe count/offset test"
2031
2032         test_mkdir $DIR/$tdir
2033         for i in $(seq 1 $OSTCOUNT); do
2034                 offset=$((i - 1))
2035                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2036                         error "setstripe -c $i -i $offset failed"
2037                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2038                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2039                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2040                 [ $index -ne $offset ] &&
2041                         error "stripe offset $index != $offset" || true
2042         done
2043 }
2044 run_test 27wa "check $LFS setstripe -c -i options"
2045
2046 test_27x() {
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2050
2051         OFFSET=$(($OSTCOUNT - 1))
2052         OSTIDX=0
2053         local OST=$(ostname_from_index $OSTIDX)
2054
2055         test_mkdir $DIR/$tdir
2056         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2057         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2058         sleep_maxage
2059         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2060         for i in $(seq 0 $OFFSET); do
2061                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2062                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2063                 error "OST0 was degraded but new created file still use it"
2064         done
2065         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2066 }
2067 run_test 27x "create files while OST0 is degraded"
2068
2069 test_27y() {
2070         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2071         remote_mds_nodsh && skip "remote MDS with nodsh"
2072         remote_ost_nodsh && skip "remote OST with nodsh"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074
2075         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2076         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2077                 osp.$mdtosc.prealloc_last_id)
2078         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2079                 osp.$mdtosc.prealloc_next_id)
2080         local fcount=$((last_id - next_id))
2081         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2082         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2083
2084         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2085                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2086         local OST_DEACTIVE_IDX=-1
2087         local OSC
2088         local OSTIDX
2089         local OST
2090
2091         for OSC in $MDS_OSCS; do
2092                 OST=$(osc_to_ost $OSC)
2093                 OSTIDX=$(index_from_ostuuid $OST)
2094                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2095                         OST_DEACTIVE_IDX=$OSTIDX
2096                 fi
2097                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2098                         echo $OSC "is Deactivated:"
2099                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2100                 fi
2101         done
2102
2103         OSTIDX=$(index_from_ostuuid $OST)
2104         test_mkdir $DIR/$tdir
2105         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2106
2107         for OSC in $MDS_OSCS; do
2108                 OST=$(osc_to_ost $OSC)
2109                 OSTIDX=$(index_from_ostuuid $OST)
2110                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2111                         echo $OST "is degraded:"
2112                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2113                                                 obdfilter.$OST.degraded=1
2114                 fi
2115         done
2116
2117         sleep_maxage
2118         createmany -o $DIR/$tdir/$tfile $fcount
2119
2120         for OSC in $MDS_OSCS; do
2121                 OST=$(osc_to_ost $OSC)
2122                 OSTIDX=$(index_from_ostuuid $OST)
2123                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2124                         echo $OST "is recovered from degraded:"
2125                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2126                                                 obdfilter.$OST.degraded=0
2127                 else
2128                         do_facet $SINGLEMDS lctl --device %$OSC activate
2129                 fi
2130         done
2131
2132         # all osp devices get activated, hence -1 stripe count restored
2133         local stripe_count=0
2134
2135         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2136         # devices get activated.
2137         sleep_maxage
2138         $LFS setstripe -c -1 $DIR/$tfile
2139         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2140         rm -f $DIR/$tfile
2141         [ $stripe_count -ne $OSTCOUNT ] &&
2142                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2143         return 0
2144 }
2145 run_test 27y "create files while OST0 is degraded and the rest inactive"
2146
2147 check_seq_oid()
2148 {
2149         log "check file $1"
2150
2151         lmm_count=$($LFS getstripe -c $1)
2152         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2153         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2154
2155         local old_ifs="$IFS"
2156         IFS=$'[:]'
2157         fid=($($LFS path2fid $1))
2158         IFS="$old_ifs"
2159
2160         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2161         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2162
2163         # compare lmm_seq and lu_fid->f_seq
2164         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2165         # compare lmm_object_id and lu_fid->oid
2166         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2167
2168         # check the trusted.fid attribute of the OST objects of the file
2169         local have_obdidx=false
2170         local stripe_nr=0
2171         $LFS getstripe $1 | while read obdidx oid hex seq; do
2172                 # skip lines up to and including "obdidx"
2173                 [ -z "$obdidx" ] && break
2174                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2175                 $have_obdidx || continue
2176
2177                 local ost=$((obdidx + 1))
2178                 local dev=$(ostdevname $ost)
2179                 local oid_hex
2180
2181                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2182
2183                 seq=$(echo $seq | sed -e "s/^0x//g")
2184                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2185                         oid_hex=$(echo $oid)
2186                 else
2187                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2188                 fi
2189                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2190
2191                 local ff=""
2192                 #
2193                 # Don't unmount/remount the OSTs if we don't need to do that.
2194                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2195                 # update too, until that use mount/ll_decode_filter_fid/mount.
2196                 # Re-enable when debugfs will understand new filter_fid.
2197                 #
2198                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2199                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2200                                 $dev 2>/dev/null" | grep "parent=")
2201                 fi
2202                 if [ -z "$ff" ]; then
2203                         stop ost$ost
2204                         mount_fstype ost$ost
2205                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2206                                 $(facet_mntpt ost$ost)/$obj_file)
2207                         unmount_fstype ost$ost
2208                         start ost$ost $dev $OST_MOUNT_OPTS
2209                         clients_up
2210                 fi
2211
2212                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2213
2214                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2215
2216                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2217                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2218                 #
2219                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2220                 #       stripe_size=1048576 component_id=1 component_start=0 \
2221                 #       component_end=33554432
2222                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2223                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2224                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2225                 local ff_pstripe
2226                 if grep -q 'stripe=' <<<$ff; then
2227                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2228                 else
2229                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2230                         # into f_ver in this case.  See comment on ff_parent.
2231                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2232                 fi
2233
2234                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2235                 [ $ff_pseq = $lmm_seq ] ||
2236                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2237                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2238                 [ $ff_poid = $lmm_oid ] ||
2239                         error "FF parent OID $ff_poid != $lmm_oid"
2240                 (($ff_pstripe == $stripe_nr)) ||
2241                         error "FF stripe $ff_pstripe != $stripe_nr"
2242
2243                 stripe_nr=$((stripe_nr + 1))
2244                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2245                         continue
2246                 if grep -q 'stripe_count=' <<<$ff; then
2247                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2248                                             -e 's/ .*//' <<<$ff)
2249                         [ $lmm_count = $ff_scnt ] ||
2250                                 error "FF stripe count $lmm_count != $ff_scnt"
2251                 fi
2252         done
2253 }
2254
2255 test_27z() {
2256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2257         remote_ost_nodsh && skip "remote OST with nodsh"
2258
2259         test_mkdir $DIR/$tdir
2260         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2261                 { error "setstripe -c -1 failed"; return 1; }
2262         # We need to send a write to every object to get parent FID info set.
2263         # This _should_ also work for setattr, but does not currently.
2264         # touch $DIR/$tdir/$tfile-1 ||
2265         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2266                 { error "dd $tfile-1 failed"; return 2; }
2267         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2268                 { error "setstripe -c -1 failed"; return 3; }
2269         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2270                 { error "dd $tfile-2 failed"; return 4; }
2271
2272         # make sure write RPCs have been sent to OSTs
2273         sync; sleep 5; sync
2274
2275         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2276         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2277 }
2278 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2279
2280 test_27A() { # b=19102
2281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2282
2283         save_layout_restore_at_exit $MOUNT
2284         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2285         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2286                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2287         local default_size=$($LFS getstripe -S $MOUNT)
2288         local default_offset=$($LFS getstripe -i $MOUNT)
2289         local dsize=$(do_facet $SINGLEMDS \
2290                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2291         [ $default_size -eq $dsize ] ||
2292                 error "stripe size $default_size != $dsize"
2293         [ $default_offset -eq -1 ] ||
2294                 error "stripe offset $default_offset != -1"
2295 }
2296 run_test 27A "check filesystem-wide default LOV EA values"
2297
2298 test_27B() { # LU-2523
2299         test_mkdir $DIR/$tdir
2300         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2301         touch $DIR/$tdir/f0
2302         # open f1 with O_LOV_DELAY_CREATE
2303         # rename f0 onto f1
2304         # call setstripe ioctl on open file descriptor for f1
2305         # close
2306         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2307                 $DIR/$tdir/f0
2308
2309         rm -f $DIR/$tdir/f1
2310         # open f1 with O_LOV_DELAY_CREATE
2311         # unlink f1
2312         # call setstripe ioctl on open file descriptor for f1
2313         # close
2314         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2315
2316         # Allow multiop to fail in imitation of NFS's busted semantics.
2317         true
2318 }
2319 run_test 27B "call setstripe on open unlinked file/rename victim"
2320
2321 # 27C family tests full striping and overstriping
2322 test_27Ca() { #LU-2871
2323         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2324
2325         declare -a ost_idx
2326         local index
2327         local found
2328         local i
2329         local j
2330
2331         test_mkdir $DIR/$tdir
2332         cd $DIR/$tdir
2333         for i in $(seq 0 $((OSTCOUNT - 1))); do
2334                 # set stripe across all OSTs starting from OST$i
2335                 $LFS setstripe -i $i -c -1 $tfile$i
2336                 # get striping information
2337                 ost_idx=($($LFS getstripe $tfile$i |
2338                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2339                 echo ${ost_idx[@]}
2340
2341                 # check the layout
2342                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2343                         error "${#ost_idx[@]} != $OSTCOUNT"
2344
2345                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2346                         found=0
2347                         for j in $(echo ${ost_idx[@]}); do
2348                                 if [ $index -eq $j ]; then
2349                                         found=1
2350                                         break
2351                                 fi
2352                         done
2353                         [ $found = 1 ] ||
2354                                 error "Can not find $index in ${ost_idx[@]}"
2355                 done
2356         done
2357 }
2358 run_test 27Ca "check full striping across all OSTs"
2359
2360 test_27Cb() {
2361         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2362                 skip "server does not support overstriping"
2363         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2364                 skip_env "too many osts, skipping"
2365
2366         test_mkdir -p $DIR/$tdir
2367         local setcount=$(($OSTCOUNT * 2))
2368         [ $setcount -ge 160 ] || large_xattr_enabled ||
2369                 skip_env "ea_inode feature disabled"
2370
2371         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2372                 error "setstripe failed"
2373
2374         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2375         [ $count -eq $setcount ] ||
2376                 error "stripe count $count, should be $setcount"
2377
2378         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2379                 error "overstriped should be set in pattern"
2380
2381         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2382                 error "dd failed"
2383 }
2384 run_test 27Cb "more stripes than OSTs with -C"
2385
2386 test_27Cc() {
2387         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2388                 skip "server does not support overstriping"
2389         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2390
2391         test_mkdir -p $DIR/$tdir
2392         local setcount=$(($OSTCOUNT - 1))
2393
2394         [ $setcount -ge 160 ] || large_xattr_enabled ||
2395                 skip_env "ea_inode feature disabled"
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2405                 error "overstriped should not be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409 }
2410 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2411
2412 test_27Cd() {
2413         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2414                 skip "server does not support overstriping"
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2416         large_xattr_enabled || skip_env "ea_inode feature disabled"
2417
2418         test_mkdir -p $DIR/$tdir
2419         local setcount=$LOV_MAX_STRIPE_COUNT
2420
2421         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2422                 error "setstripe failed"
2423
2424         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2425         [ $count -eq $setcount ] ||
2426                 error "stripe count $count, should be $setcount"
2427
2428         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2429                 error "overstriped should be set in pattern"
2430
2431         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2432                 error "dd failed"
2433
2434         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2435 }
2436 run_test 27Cd "test maximum stripe count"
2437
2438 test_27Ce() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         test_mkdir -p $DIR/$tdir
2442
2443         pool_add $TESTNAME || error "Pool creation failed"
2444         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2445
2446         local setcount=8
2447
2448         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2449                 error "setstripe failed"
2450
2451         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2452         [ $count -eq $setcount ] ||
2453                 error "stripe count $count, should be $setcount"
2454
2455         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2456                 error "overstriped should be set in pattern"
2457
2458         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2459                 error "dd failed"
2460
2461         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2462 }
2463 run_test 27Ce "test pool with overstriping"
2464
2465 test_27Cf() {
2466         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2467                 skip "server does not support overstriping"
2468         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2469                 skip_env "too many osts, skipping"
2470
2471         test_mkdir -p $DIR/$tdir
2472
2473         local setcount=$(($OSTCOUNT * 2))
2474         [ $setcount -ge 160 ] || large_xattr_enabled ||
2475                 skip_env "ea_inode feature disabled"
2476
2477         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2478                 error "setstripe failed"
2479
2480         echo 1 > $DIR/$tdir/$tfile
2481
2482         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2483         [ $count -eq $setcount ] ||
2484                 error "stripe count $count, should be $setcount"
2485
2486         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2487                 error "overstriped should be set in pattern"
2488
2489         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2490                 error "dd failed"
2491
2492         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2493 }
2494 run_test 27Cf "test default inheritance with overstriping"
2495
2496 test_27D() {
2497         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2498         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2499         remote_mds_nodsh && skip "remote MDS with nodsh"
2500
2501         local POOL=${POOL:-testpool}
2502         local first_ost=0
2503         local last_ost=$(($OSTCOUNT - 1))
2504         local ost_step=1
2505         local ost_list=$(seq $first_ost $ost_step $last_ost)
2506         local ost_range="$first_ost $last_ost $ost_step"
2507
2508         test_mkdir $DIR/$tdir
2509         pool_add $POOL || error "pool_add failed"
2510         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2511
2512         local skip27D
2513         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2514                 skip27D+="-s 29"
2515         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2516                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2517                         skip27D+=" -s 30,31"
2518         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2519           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2520                 skip27D+=" -s 32,33"
2521         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2522                 skip27D+=" -s 34"
2523         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2524                 error "llapi_layout_test failed"
2525
2526         destroy_test_pools || error "destroy test pools failed"
2527 }
2528 run_test 27D "validate llapi_layout API"
2529
2530 # Verify that default_easize is increased from its initial value after
2531 # accessing a widely striped file.
2532 test_27E() {
2533         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2534         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2535                 skip "client does not have LU-3338 fix"
2536
2537         # 72 bytes is the minimum space required to store striping
2538         # information for a file striped across one OST:
2539         # (sizeof(struct lov_user_md_v3) +
2540         #  sizeof(struct lov_user_ost_data_v1))
2541         local min_easize=72
2542         $LCTL set_param -n llite.*.default_easize $min_easize ||
2543                 error "lctl set_param failed"
2544         local easize=$($LCTL get_param -n llite.*.default_easize)
2545
2546         [ $easize -eq $min_easize ] ||
2547                 error "failed to set default_easize"
2548
2549         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2550                 error "setstripe failed"
2551         # In order to ensure stat() call actually talks to MDS we need to
2552         # do something drastic to this file to shake off all lock, e.g.
2553         # rename it (kills lookup lock forcing cache cleaning)
2554         mv $DIR/$tfile $DIR/${tfile}-1
2555         ls -l $DIR/${tfile}-1
2556         rm $DIR/${tfile}-1
2557
2558         easize=$($LCTL get_param -n llite.*.default_easize)
2559
2560         [ $easize -gt $min_easize ] ||
2561                 error "default_easize not updated"
2562 }
2563 run_test 27E "check that default extended attribute size properly increases"
2564
2565 test_27F() { # LU-5346/LU-7975
2566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2567         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2568         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2569                 skip "Need MDS version at least 2.8.51"
2570         remote_ost_nodsh && skip "remote OST with nodsh"
2571
2572         test_mkdir $DIR/$tdir
2573         rm -f $DIR/$tdir/f0
2574         $LFS setstripe -c 2 $DIR/$tdir
2575
2576         # stop all OSTs to reproduce situation for LU-7975 ticket
2577         for num in $(seq $OSTCOUNT); do
2578                 stop ost$num
2579         done
2580
2581         # open/create f0 with O_LOV_DELAY_CREATE
2582         # truncate f0 to a non-0 size
2583         # close
2584         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2585
2586         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2587         # open/write it again to force delayed layout creation
2588         cat /etc/hosts > $DIR/$tdir/f0 &
2589         catpid=$!
2590
2591         # restart OSTs
2592         for num in $(seq $OSTCOUNT); do
2593                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2594                         error "ost$num failed to start"
2595         done
2596
2597         wait $catpid || error "cat failed"
2598
2599         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2600         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2601                 error "wrong stripecount"
2602
2603 }
2604 run_test 27F "Client resend delayed layout creation with non-zero size"
2605
2606 test_27G() { #LU-10629
2607         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2608                 skip "Need MDS version at least 2.11.51"
2609         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2610         remote_mds_nodsh && skip "remote MDS with nodsh"
2611         local POOL=${POOL:-testpool}
2612         local ostrange="0 0 1"
2613
2614         test_mkdir $DIR/$tdir
2615         touch $DIR/$tdir/$tfile.nopool
2616         pool_add $POOL || error "pool_add failed"
2617         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2618         $LFS setstripe -p $POOL $DIR/$tdir
2619
2620         local pool=$($LFS getstripe -p $DIR/$tdir)
2621
2622         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2623         touch $DIR/$tdir/$tfile.default
2624         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2625         $LFS find $DIR/$tdir -type f --pool $POOL
2626         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2627         [[ "$found" == "2" ]] ||
2628                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2629
2630         $LFS setstripe -d $DIR/$tdir
2631
2632         pool=$($LFS getstripe -p -d $DIR/$tdir)
2633
2634         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2635 }
2636 run_test 27G "Clear OST pool from stripe"
2637
2638 test_27H() {
2639         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2640                 skip "Need MDS version newer than 2.11.54"
2641         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2642         test_mkdir $DIR/$tdir
2643         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2644         touch $DIR/$tdir/$tfile
2645         $LFS getstripe -c $DIR/$tdir/$tfile
2646         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2647                 error "two-stripe file doesn't have two stripes"
2648
2649         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2650         $LFS getstripe -y $DIR/$tdir/$tfile
2651         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2652              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2653                 error "expected l_ost_idx: [02]$ not matched"
2654
2655         # make sure ost list has been cleared
2656         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2657         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2658                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2659         touch $DIR/$tdir/f3
2660         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2661 }
2662 run_test 27H "Set specific OSTs stripe"
2663
2664 test_27I() {
2665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2666         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2667         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2668                 skip "Need MDS version newer than 2.12.52"
2669         local pool=$TESTNAME
2670         local ostrange="1 1 1"
2671
2672         save_layout_restore_at_exit $MOUNT
2673         $LFS setstripe -c 2 -i 0 $MOUNT
2674         pool_add $pool || error "pool_add failed"
2675         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2676         test_mkdir $DIR/$tdir
2677         $LFS setstripe -p $pool $DIR/$tdir
2678         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2679         $LFS getstripe $DIR/$tdir/$tfile
2680 }
2681 run_test 27I "check that root dir striping does not break parent dir one"
2682
2683 test_27J() {
2684         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2685                 skip "Need MDS version newer than 2.12.51"
2686
2687         test_mkdir $DIR/$tdir
2688         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2689         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2690
2691         # create foreign file (raw way)
2692         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2693                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2694
2695         # verify foreign file (raw way)
2696         parse_foreign_file -f $DIR/$tdir/$tfile |
2697                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2698                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2699         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2700                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2701         parse_foreign_file -f $DIR/$tdir/$tfile |
2702                 grep "lov_foreign_size: 73" ||
2703                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2704         parse_foreign_file -f $DIR/$tdir/$tfile |
2705                 grep "lov_foreign_type: 1" ||
2706                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2707         parse_foreign_file -f $DIR/$tdir/$tfile |
2708                 grep "lov_foreign_flags: 0x0000DA08" ||
2709                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2710         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2711                 grep "lov_foreign_value: 0x" |
2712                 sed -e 's/lov_foreign_value: 0x//')
2713         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2714         [[ $lov = ${lov2// /} ]] ||
2715                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2716
2717         # create foreign file (lfs + API)
2718         $LFS setstripe --foreign=daos --flags 0xda08 \
2719                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2720                 error "$DIR/$tdir/${tfile}2: create failed"
2721
2722         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2723                 grep "lfm_magic:.*0x0BD70BD0" ||
2724                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2725         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2726         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2727                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2728         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2729                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2730         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2731                 grep "lfm_flags:.*0x0000DA08" ||
2732                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2733         $LFS getstripe $DIR/$tdir/${tfile}2 |
2734                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2735                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2736
2737         # modify striping should fail
2738         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2739                 error "$DIR/$tdir/$tfile: setstripe should fail"
2740         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2741                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2742
2743         # R/W should fail
2744         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2745         cat $DIR/$tdir/${tfile}2 &&
2746                 error "$DIR/$tdir/${tfile}2: read should fail"
2747         cat /etc/passwd > $DIR/$tdir/$tfile &&
2748                 error "$DIR/$tdir/$tfile: write should fail"
2749         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2750                 error "$DIR/$tdir/${tfile}2: write should fail"
2751
2752         # chmod should work
2753         chmod 222 $DIR/$tdir/$tfile ||
2754                 error "$DIR/$tdir/$tfile: chmod failed"
2755         chmod 222 $DIR/$tdir/${tfile}2 ||
2756                 error "$DIR/$tdir/${tfile}2: chmod failed"
2757
2758         # chown should work
2759         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2760                 error "$DIR/$tdir/$tfile: chown failed"
2761         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2762                 error "$DIR/$tdir/${tfile}2: chown failed"
2763
2764         # rename should work
2765         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2766                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2767         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2768                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2769
2770         #remove foreign file
2771         rm $DIR/$tdir/${tfile}.new ||
2772                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2773         rm $DIR/$tdir/${tfile}2.new ||
2774                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2775 }
2776 run_test 27J "basic ops on file with foreign LOV"
2777
2778 test_27K() {
2779         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2780                 skip "Need MDS version newer than 2.12.49"
2781
2782         test_mkdir $DIR/$tdir
2783         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2784         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2785
2786         # create foreign dir (raw way)
2787         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2788                 error "create_foreign_dir FAILED"
2789
2790         # verify foreign dir (raw way)
2791         parse_foreign_dir -d $DIR/$tdir/$tdir |
2792                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2794         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2795                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2796         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2797                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2798         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2799                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2800         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2801                 grep "lmv_foreign_value: 0x" |
2802                 sed 's/lmv_foreign_value: 0x//')
2803         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2804                 sed 's/ //g')
2805         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2806
2807         # create foreign dir (lfs + API)
2808         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2809                 $DIR/$tdir/${tdir}2 ||
2810                 error "$DIR/$tdir/${tdir}2: create failed"
2811
2812         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2813                 grep "lfm_magic:.*0x0CD50CD0" ||
2814                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2815         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         # - sizeof(lfm_type) - sizeof(lfm_flags)
2817         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2818                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2820                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2821         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2822                 grep "lfm_flags:.*0x0000DA05" ||
2823                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2824         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2825                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2826                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2827
2828         # file create in dir should fail
2829         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2830         touch $DIR/$tdir/${tdir}2/$tfile &&
2831                 "$DIR/${tdir}2: file create should fail"
2832
2833         # chmod should work
2834         chmod 777 $DIR/$tdir/$tdir ||
2835                 error "$DIR/$tdir: chmod failed"
2836         chmod 777 $DIR/$tdir/${tdir}2 ||
2837                 error "$DIR/${tdir}2: chmod failed"
2838
2839         # chown should work
2840         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2841                 error "$DIR/$tdir: chown failed"
2842         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2843                 error "$DIR/${tdir}2: chown failed"
2844
2845         # rename should work
2846         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2847                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2848         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2849                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2850
2851         #remove foreign dir
2852         rmdir $DIR/$tdir/${tdir}.new ||
2853                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2854         rmdir $DIR/$tdir/${tdir}2.new ||
2855                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2856 }
2857 run_test 27K "basic ops on dir with foreign LMV"
2858
2859 test_27L() {
2860         remote_mds_nodsh && skip "remote MDS with nodsh"
2861
2862         local POOL=${POOL:-$TESTNAME}
2863
2864         pool_add $POOL || error "pool_add failed"
2865
2866         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2867                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2868                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2869 }
2870 run_test 27L "lfs pool_list gives correct pool name"
2871
2872 test_27M() {
2873         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2874                 skip "Need MDS version >= than 2.12.57"
2875         remote_mds_nodsh && skip "remote MDS with nodsh"
2876         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2877
2878         test_mkdir $DIR/$tdir
2879
2880         # Set default striping on directory
2881         $LFS setstripe -C 4 $DIR/$tdir
2882
2883         echo 1 > $DIR/$tdir/${tfile}.1
2884         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2885         local setcount=4
2886         [ $count -eq $setcount ] ||
2887                 error "(1) stripe count $count, should be $setcount"
2888
2889         # Capture existing append_stripe_count setting for restore
2890         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2891         local mdts=$(comma_list $(mdts_nodes))
2892         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2893
2894         local appendcount=$orig_count
2895         echo 1 >> $DIR/$tdir/${tfile}.2_append
2896         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2897         [ $count -eq $appendcount ] ||
2898                 error "(2)stripe count $count, should be $appendcount for append"
2899
2900         # Disable O_APPEND striping, verify it works
2901         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2902
2903         # Should now get the default striping, which is 4
2904         setcount=4
2905         echo 1 >> $DIR/$tdir/${tfile}.3_append
2906         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2907         [ $count -eq $setcount ] ||
2908                 error "(3) stripe count $count, should be $setcount"
2909
2910         # Try changing the stripe count for append files
2911         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2912
2913         # Append striping is now 2 (directory default is still 4)
2914         appendcount=2
2915         echo 1 >> $DIR/$tdir/${tfile}.4_append
2916         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2917         [ $count -eq $appendcount ] ||
2918                 error "(4) stripe count $count, should be $appendcount for append"
2919
2920         # Test append stripe count of -1
2921         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2922         appendcount=$OSTCOUNT
2923         echo 1 >> $DIR/$tdir/${tfile}.5
2924         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2925         [ $count -eq $appendcount ] ||
2926                 error "(5) stripe count $count, should be $appendcount for append"
2927
2928         # Set append striping back to default of 1
2929         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2930
2931         # Try a new default striping, PFL + DOM
2932         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2933
2934         # Create normal DOM file, DOM returns stripe count == 0
2935         setcount=0
2936         touch $DIR/$tdir/${tfile}.6
2937         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2938         [ $count -eq $setcount ] ||
2939                 error "(6) stripe count $count, should be $setcount"
2940
2941         # Show
2942         appendcount=1
2943         echo 1 >> $DIR/$tdir/${tfile}.7_append
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2945         [ $count -eq $appendcount ] ||
2946                 error "(7) stripe count $count, should be $appendcount for append"
2947
2948         # Clean up DOM layout
2949         $LFS setstripe -d $DIR/$tdir
2950
2951         # Now test that append striping works when layout is from root
2952         $LFS setstripe -c 2 $MOUNT
2953         # Make a special directory for this
2954         mkdir $DIR/${tdir}/${tdir}.2
2955         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2956
2957         # Verify for normal file
2958         setcount=2
2959         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2960         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2961         [ $count -eq $setcount ] ||
2962                 error "(8) stripe count $count, should be $setcount"
2963
2964         appendcount=1
2965         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2966         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2967         [ $count -eq $appendcount ] ||
2968                 error "(9) stripe count $count, should be $appendcount for append"
2969
2970         # Now test O_APPEND striping with pools
2971         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2972         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2973
2974         # Create the pool
2975         pool_add $TESTNAME || error "pool creation failed"
2976         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2977
2978         echo 1 >> $DIR/$tdir/${tfile}.10_append
2979
2980         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2981         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2982
2983         # Check that count is still correct
2984         appendcount=1
2985         echo 1 >> $DIR/$tdir/${tfile}.11_append
2986         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2987         [ $count -eq $appendcount ] ||
2988                 error "(11) stripe count $count, should be $appendcount for append"
2989
2990         # Disable O_APPEND stripe count, verify pool works separately
2991         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2992
2993         echo 1 >> $DIR/$tdir/${tfile}.12_append
2994
2995         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2996         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2997
2998         # Remove pool setting, verify it's not applied
2999         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3000
3001         echo 1 >> $DIR/$tdir/${tfile}.13_append
3002
3003         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3004         [ "$pool" = "" ] || error "(13) pool found: $pool"
3005 }
3006 run_test 27M "test O_APPEND striping"
3007
3008 test_27N() {
3009         combined_mgs_mds && skip "needs separate MGS/MDT"
3010
3011         pool_add $TESTNAME || error "pool_add failed"
3012         do_facet mgs "$LCTL pool_list $FSNAME" |
3013                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3014                 error "lctl pool_list on MGS failed"
3015 }
3016 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3017
3018 # createtest also checks that device nodes are created and
3019 # then visible correctly (#2091)
3020 test_28() { # bug 2091
3021         test_mkdir $DIR/d28
3022         $CREATETEST $DIR/d28/ct || error "createtest failed"
3023 }
3024 run_test 28 "create/mknod/mkdir with bad file types ============"
3025
3026 test_29() {
3027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3028
3029         sync; sleep 1; sync # flush out any dirty pages from previous tests
3030         cancel_lru_locks
3031         test_mkdir $DIR/d29
3032         touch $DIR/d29/foo
3033         log 'first d29'
3034         ls -l $DIR/d29
3035
3036         declare -i LOCKCOUNTORIG=0
3037         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3038                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3039         done
3040         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3041
3042         declare -i LOCKUNUSEDCOUNTORIG=0
3043         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3044                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3045         done
3046
3047         log 'second d29'
3048         ls -l $DIR/d29
3049         log 'done'
3050
3051         declare -i LOCKCOUNTCURRENT=0
3052         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3053                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3054         done
3055
3056         declare -i LOCKUNUSEDCOUNTCURRENT=0
3057         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3058                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3059         done
3060
3061         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3062                 $LCTL set_param -n ldlm.dump_namespaces ""
3063                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3064                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3065                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3066                 return 2
3067         fi
3068         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3069                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3070                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3071                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3072                 return 3
3073         fi
3074 }
3075 run_test 29 "IT_GETATTR regression  ============================"
3076
3077 test_30a() { # was test_30
3078         cp $(which ls) $DIR || cp /bin/ls $DIR
3079         $DIR/ls / || error "Can't execute binary from lustre"
3080         rm $DIR/ls
3081 }
3082 run_test 30a "execute binary from Lustre (execve) =============="
3083
3084 test_30b() {
3085         cp `which ls` $DIR || cp /bin/ls $DIR
3086         chmod go+rx $DIR/ls
3087         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3088         rm $DIR/ls
3089 }
3090 run_test 30b "execute binary from Lustre as non-root ==========="
3091
3092 test_30c() { # b=22376
3093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3094
3095         cp $(which ls) $DIR || cp /bin/ls $DIR
3096         chmod a-rw $DIR/ls
3097         cancel_lru_locks mdc
3098         cancel_lru_locks osc
3099         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3100         rm -f $DIR/ls
3101 }
3102 run_test 30c "execute binary from Lustre without read perms ===="
3103
3104 test_30d() {
3105         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3106
3107         for i in {1..10}; do
3108                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3109                 local PID=$!
3110                 sleep 1
3111                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3112                 wait $PID || error "executing dd from Lustre failed"
3113                 rm -f $DIR/$tfile
3114         done
3115
3116         rm -f $DIR/dd
3117 }
3118 run_test 30d "execute binary from Lustre while clear locks"
3119
3120 test_31a() {
3121         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3122         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3123 }
3124 run_test 31a "open-unlink file =================================="
3125
3126 test_31b() {
3127         touch $DIR/f31 || error "touch $DIR/f31 failed"
3128         ln $DIR/f31 $DIR/f31b || error "ln failed"
3129         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3130         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3131 }
3132 run_test 31b "unlink file with multiple links while open ======="
3133
3134 test_31c() {
3135         touch $DIR/f31 || error "touch $DIR/f31 failed"
3136         ln $DIR/f31 $DIR/f31c || error "ln failed"
3137         multiop_bg_pause $DIR/f31 O_uc ||
3138                 error "multiop_bg_pause for $DIR/f31 failed"
3139         MULTIPID=$!
3140         $MULTIOP $DIR/f31c Ouc
3141         kill -USR1 $MULTIPID
3142         wait $MULTIPID
3143 }
3144 run_test 31c "open-unlink file with multiple links ============="
3145
3146 test_31d() {
3147         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3148         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3149 }
3150 run_test 31d "remove of open directory ========================="
3151
3152 test_31e() { # bug 2904
3153         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3154 }
3155 run_test 31e "remove of open non-empty directory ==============="
3156
3157 test_31f() { # bug 4554
3158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3159
3160         set -vx
3161         test_mkdir $DIR/d31f
3162         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3163         cp /etc/hosts $DIR/d31f
3164         ls -l $DIR/d31f
3165         $LFS getstripe $DIR/d31f/hosts
3166         multiop_bg_pause $DIR/d31f D_c || return 1
3167         MULTIPID=$!
3168
3169         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3170         test_mkdir $DIR/d31f
3171         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3172         cp /etc/hosts $DIR/d31f
3173         ls -l $DIR/d31f
3174         $LFS getstripe $DIR/d31f/hosts
3175         multiop_bg_pause $DIR/d31f D_c || return 1
3176         MULTIPID2=$!
3177
3178         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3179         wait $MULTIPID || error "first opendir $MULTIPID failed"
3180
3181         sleep 6
3182
3183         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3184         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3185         set +vx
3186 }
3187 run_test 31f "remove of open directory with open-unlink file ==="
3188
3189 test_31g() {
3190         echo "-- cross directory link --"
3191         test_mkdir -c1 $DIR/${tdir}ga
3192         test_mkdir -c1 $DIR/${tdir}gb
3193         touch $DIR/${tdir}ga/f
3194         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3195         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3196         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3197         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3198         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3199 }
3200 run_test 31g "cross directory link==============="
3201
3202 test_31h() {
3203         echo "-- cross directory link --"
3204         test_mkdir -c1 $DIR/${tdir}
3205         test_mkdir -c1 $DIR/${tdir}/dir
3206         touch $DIR/${tdir}/f
3207         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3208         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3209         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3210         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3211         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3212 }
3213 run_test 31h "cross directory link under child==============="
3214
3215 test_31i() {
3216         echo "-- cross directory link --"
3217         test_mkdir -c1 $DIR/$tdir
3218         test_mkdir -c1 $DIR/$tdir/dir
3219         touch $DIR/$tdir/dir/f
3220         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3221         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3222         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3223         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3224         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3225 }
3226 run_test 31i "cross directory link under parent==============="
3227
3228 test_31j() {
3229         test_mkdir -c1 -p $DIR/$tdir
3230         test_mkdir -c1 -p $DIR/$tdir/dir1
3231         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3232         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3233         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3234         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3235         return 0
3236 }
3237 run_test 31j "link for directory==============="
3238
3239 test_31k() {
3240         test_mkdir -c1 -p $DIR/$tdir
3241         touch $DIR/$tdir/s
3242         touch $DIR/$tdir/exist
3243         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3244         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3245         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3246         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3247         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3248         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3249         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3250         return 0
3251 }
3252 run_test 31k "link to file: the same, non-existing, dir==============="
3253
3254 test_31m() {
3255         mkdir $DIR/d31m
3256         touch $DIR/d31m/s
3257         mkdir $DIR/d31m2
3258         touch $DIR/d31m2/exist
3259         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3260         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3261         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3262         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3263         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3264         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3265         return 0
3266 }
3267 run_test 31m "link to file: the same, non-existing, dir==============="
3268
3269 test_31n() {
3270         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3271         nlink=$(stat --format=%h $DIR/$tfile)
3272         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3273         local fd=$(free_fd)
3274         local cmd="exec $fd<$DIR/$tfile"
3275         eval $cmd
3276         cmd="exec $fd<&-"
3277         trap "eval $cmd" EXIT
3278         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3281         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3282         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3283         eval $cmd
3284 }
3285 run_test 31n "check link count of unlinked file"
3286
3287 link_one() {
3288         local tempfile=$(mktemp $1_XXXXXX)
3289         mlink $tempfile $1 2> /dev/null &&
3290                 echo "$BASHPID: link $tempfile to $1 succeeded"
3291         munlink $tempfile
3292 }
3293
3294 test_31o() { # LU-2901
3295         test_mkdir $DIR/$tdir
3296         for LOOP in $(seq 100); do
3297                 rm -f $DIR/$tdir/$tfile*
3298                 for THREAD in $(seq 8); do
3299                         link_one $DIR/$tdir/$tfile.$LOOP &
3300                 done
3301                 wait
3302                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3303                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3304                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3305                         break || true
3306         done
3307 }
3308 run_test 31o "duplicate hard links with same filename"
3309
3310 test_31p() {
3311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3312
3313         test_mkdir $DIR/$tdir
3314         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3315         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3316
3317         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3318                 error "open unlink test1 failed"
3319         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3320                 error "open unlink test2 failed"
3321
3322         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3323                 error "test1 still exists"
3324         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3325                 error "test2 still exists"
3326 }
3327 run_test 31p "remove of open striped directory"
3328
3329 cleanup_test32_mount() {
3330         local rc=0
3331         trap 0
3332         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3333         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3334         losetup -d $loopdev || true
3335         rm -rf $DIR/$tdir
3336         return $rc
3337 }
3338
3339 test_32a() {
3340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3341
3342         echo "== more mountpoints and symlinks ================="
3343         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3344         trap cleanup_test32_mount EXIT
3345         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3346         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3347                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3348         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3349                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3350         cleanup_test32_mount
3351 }
3352 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3353
3354 test_32b() {
3355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3356
3357         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3358         trap cleanup_test32_mount EXIT
3359         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3360         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3361                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3362         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3363                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3364         cleanup_test32_mount
3365 }
3366 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3367
3368 test_32c() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3375                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3376         test_mkdir -p $DIR/$tdir/d2/test_dir
3377         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3378                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3379         cleanup_test32_mount
3380 }
3381 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3382
3383 test_32d() {
3384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3385
3386         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3387         trap cleanup_test32_mount EXIT
3388         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         test_mkdir -p $DIR/$tdir/d2/test_dir
3392         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3393                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3394         cleanup_test32_mount
3395 }
3396 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3397
3398 test_32e() {
3399         rm -fr $DIR/$tdir
3400         test_mkdir -p $DIR/$tdir/tmp
3401         local tmp_dir=$DIR/$tdir/tmp
3402         ln -s $DIR/$tdir $tmp_dir/symlink11
3403         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3404         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3405         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3406 }
3407 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3408
3409 test_32f() {
3410         rm -fr $DIR/$tdir
3411         test_mkdir -p $DIR/$tdir/tmp
3412         local tmp_dir=$DIR/$tdir/tmp
3413         ln -s $DIR/$tdir $tmp_dir/symlink11
3414         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3415         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3416         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3417 }
3418 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3419
3420 test_32g() {
3421         local tmp_dir=$DIR/$tdir/tmp
3422         test_mkdir -p $tmp_dir
3423         test_mkdir $DIR/${tdir}2
3424         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3425         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3426         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3427         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3428         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3429         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3430 }
3431 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3432
3433 test_32h() {
3434         rm -fr $DIR/$tdir $DIR/${tdir}2
3435         tmp_dir=$DIR/$tdir/tmp
3436         test_mkdir -p $tmp_dir
3437         test_mkdir $DIR/${tdir}2
3438         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3439         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3440         ls $tmp_dir/symlink12 || error "listing symlink12"
3441         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3442 }
3443 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3444
3445 test_32i() {
3446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3447
3448         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3449         trap cleanup_test32_mount EXIT
3450         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3451         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3452                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3453         touch $DIR/$tdir/test_file
3454         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3455                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3456         cleanup_test32_mount
3457 }
3458 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3459
3460 test_32j() {
3461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3462
3463         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3464         trap cleanup_test32_mount EXIT
3465         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3466         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3467                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3468         touch $DIR/$tdir/test_file
3469         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3470                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3471         cleanup_test32_mount
3472 }
3473 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3474
3475 test_32k() {
3476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3477
3478         rm -fr $DIR/$tdir
3479         trap cleanup_test32_mount EXIT
3480         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3481         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3482                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3483         test_mkdir -p $DIR/$tdir/d2
3484         touch $DIR/$tdir/d2/test_file || error "touch failed"
3485         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3486                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3487         cleanup_test32_mount
3488 }
3489 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3490
3491 test_32l() {
3492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3493
3494         rm -fr $DIR/$tdir
3495         trap cleanup_test32_mount EXIT
3496         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3497         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3498                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3499         test_mkdir -p $DIR/$tdir/d2
3500         touch $DIR/$tdir/d2/test_file || error "touch failed"
3501         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3502                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3503         cleanup_test32_mount
3504 }
3505 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3506
3507 test_32m() {
3508         rm -fr $DIR/d32m
3509         test_mkdir -p $DIR/d32m/tmp
3510         TMP_DIR=$DIR/d32m/tmp
3511         ln -s $DIR $TMP_DIR/symlink11
3512         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3513         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3514                 error "symlink11 not a link"
3515         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3516                 error "symlink01 not a link"
3517 }
3518 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3519
3520 test_32n() {
3521         rm -fr $DIR/d32n
3522         test_mkdir -p $DIR/d32n/tmp
3523         TMP_DIR=$DIR/d32n/tmp
3524         ln -s $DIR $TMP_DIR/symlink11
3525         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3526         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3527         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3528 }
3529 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3530
3531 test_32o() {
3532         touch $DIR/$tfile
3533         test_mkdir -p $DIR/d32o/tmp
3534         TMP_DIR=$DIR/d32o/tmp
3535         ln -s $DIR/$tfile $TMP_DIR/symlink12
3536         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3537         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3538                 error "symlink12 not a link"
3539         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3540         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3541                 error "$DIR/d32o/tmp/symlink12 not file type"
3542         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3543                 error "$DIR/d32o/symlink02 not file type"
3544 }
3545 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3546
3547 test_32p() {
3548         log 32p_1
3549         rm -fr $DIR/d32p
3550         log 32p_2
3551         rm -f $DIR/$tfile
3552         log 32p_3
3553         touch $DIR/$tfile
3554         log 32p_4
3555         test_mkdir -p $DIR/d32p/tmp
3556         log 32p_5
3557         TMP_DIR=$DIR/d32p/tmp
3558         log 32p_6
3559         ln -s $DIR/$tfile $TMP_DIR/symlink12
3560         log 32p_7
3561         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3562         log 32p_8
3563         cat $DIR/d32p/tmp/symlink12 ||
3564                 error "Can't open $DIR/d32p/tmp/symlink12"
3565         log 32p_9
3566         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3567         log 32p_10
3568 }
3569 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3570
3571 test_32q() {
3572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3573
3574         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3575         trap cleanup_test32_mount EXIT
3576         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3577         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3578         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3579                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3580         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3581         cleanup_test32_mount
3582 }
3583 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3584
3585 test_32r() {
3586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3587
3588         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3589         trap cleanup_test32_mount EXIT
3590         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3591         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3592         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3593                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3594         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3595         cleanup_test32_mount
3596 }
3597 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3598
3599 test_33aa() {
3600         rm -f $DIR/$tfile
3601         touch $DIR/$tfile
3602         chmod 444 $DIR/$tfile
3603         chown $RUNAS_ID $DIR/$tfile
3604         log 33_1
3605         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3606         log 33_2
3607 }
3608 run_test 33aa "write file with mode 444 (should return error)"
3609
3610 test_33a() {
3611         rm -fr $DIR/$tdir
3612         test_mkdir $DIR/$tdir
3613         chown $RUNAS_ID $DIR/$tdir
3614         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3615                 error "$RUNAS create $tdir/$tfile failed"
3616         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3617                 error "open RDWR" || true
3618 }
3619 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3620
3621 test_33b() {
3622         rm -fr $DIR/$tdir
3623         test_mkdir $DIR/$tdir
3624         chown $RUNAS_ID $DIR/$tdir
3625         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3626 }
3627 run_test 33b "test open file with malformed flags (No panic)"
3628
3629 test_33c() {
3630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3631         remote_ost_nodsh && skip "remote OST with nodsh"
3632
3633         local ostnum
3634         local ostname
3635         local write_bytes
3636         local all_zeros
3637
3638         all_zeros=:
3639         rm -fr $DIR/$tdir
3640         test_mkdir $DIR/$tdir
3641         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3642
3643         sync
3644         for ostnum in $(seq $OSTCOUNT); do
3645                 # test-framework's OST numbering is one-based, while Lustre's
3646                 # is zero-based
3647                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3648                 # Parsing llobdstat's output sucks; we could grep the /proc
3649                 # path, but that's likely to not be as portable as using the
3650                 # llobdstat utility.  So we parse lctl output instead.
3651                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3652                         obdfilter/$ostname/stats |
3653                         awk '/^write_bytes/ {print $7}' )
3654                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3655                 if (( ${write_bytes:-0} > 0 ))
3656                 then
3657                         all_zeros=false
3658                         break;
3659                 fi
3660         done
3661
3662         $all_zeros || return 0
3663
3664         # Write four bytes
3665         echo foo > $DIR/$tdir/bar
3666         # Really write them
3667         sync
3668
3669         # Total up write_bytes after writing.  We'd better find non-zeros.
3670         for ostnum in $(seq $OSTCOUNT); do
3671                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3672                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3673                         obdfilter/$ostname/stats |
3674                         awk '/^write_bytes/ {print $7}' )
3675                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3676                 if (( ${write_bytes:-0} > 0 ))
3677                 then
3678                         all_zeros=false
3679                         break;
3680                 fi
3681         done
3682
3683         if $all_zeros
3684         then
3685                 for ostnum in $(seq $OSTCOUNT); do
3686                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3687                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3688                         do_facet ost$ostnum lctl get_param -n \
3689                                 obdfilter/$ostname/stats
3690                 done
3691                 error "OST not keeping write_bytes stats (b22312)"
3692         fi
3693 }
3694 run_test 33c "test llobdstat and write_bytes"
3695
3696 test_33d() {
3697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3699
3700         local MDTIDX=1
3701         local remote_dir=$DIR/$tdir/remote_dir
3702
3703         test_mkdir $DIR/$tdir
3704         $LFS mkdir -i $MDTIDX $remote_dir ||
3705                 error "create remote directory failed"
3706
3707         touch $remote_dir/$tfile
3708         chmod 444 $remote_dir/$tfile
3709         chown $RUNAS_ID $remote_dir/$tfile
3710
3711         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3712
3713         chown $RUNAS_ID $remote_dir
3714         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3715                                         error "create" || true
3716         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3717                                     error "open RDWR" || true
3718         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3719 }
3720 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3721
3722 test_33e() {
3723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3724
3725         mkdir $DIR/$tdir
3726
3727         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3728         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3729         mkdir $DIR/$tdir/local_dir
3730
3731         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3732         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3733         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3734
3735         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3736                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3737
3738         rmdir $DIR/$tdir/* || error "rmdir failed"
3739
3740         umask 777
3741         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3742         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3743         mkdir $DIR/$tdir/local_dir
3744
3745         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3746         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3747         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3748
3749         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3750                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3751
3752         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3753
3754         umask 000
3755         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3756         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3757         mkdir $DIR/$tdir/local_dir
3758
3759         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3760         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3761         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3762
3763         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3764                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3765 }
3766 run_test 33e "mkdir and striped directory should have same mode"
3767
3768 cleanup_33f() {
3769         trap 0
3770         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3771 }
3772
3773 test_33f() {
3774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3775         remote_mds_nodsh && skip "remote MDS with nodsh"
3776
3777         mkdir $DIR/$tdir
3778         chmod go+rwx $DIR/$tdir
3779         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3780         trap cleanup_33f EXIT
3781
3782         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3783                 error "cannot create striped directory"
3784
3785         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3786                 error "cannot create files in striped directory"
3787
3788         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3789                 error "cannot remove files in striped directory"
3790
3791         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3792                 error "cannot remove striped directory"
3793
3794         cleanup_33f
3795 }
3796 run_test 33f "nonroot user can create, access, and remove a striped directory"
3797
3798 test_33g() {
3799         mkdir -p $DIR/$tdir/dir2
3800
3801         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3802         echo $err
3803         [[ $err =~ "exists" ]] || error "Not exists error"
3804 }
3805 run_test 33g "nonroot user create already existing root created file"
3806
3807 test_33h() {
3808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3809         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3810                 skip "Need MDS version at least 2.13.50"
3811
3812         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3813                 error "mkdir $tdir failed"
3814         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3815
3816         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3817         local index2
3818
3819         for fname in $DIR/$tdir/$tfile.bak \
3820                      $DIR/$tdir/$tfile.SAV \
3821                      $DIR/$tdir/$tfile.orig \
3822                      $DIR/$tdir/$tfile~; do
3823                 touch $fname  || error "touch $fname failed"
3824                 index2=$($LFS getstripe -m $fname)
3825                 [ $index -eq $index2 ] ||
3826                         error "$fname MDT index mismatch $index != $index2"
3827         done
3828
3829         local failed=0
3830         for i in {1..50}; do
3831                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3832                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3833                         touch $fname  || error "touch $fname failed"
3834                         index2=$($LFS getstripe -m $fname)
3835                         if [[ $index != $index2 ]]; then
3836                                 failed=$((failed + 1))
3837                                 echo "$fname MDT index mismatch $index != $index2"
3838                         fi
3839                 done
3840         done
3841         echo "$failed MDT index mismatches"
3842         (( failed < 4 )) || error "MDT index mismatch $failed times"
3843
3844 }
3845 run_test 33h "temp file is located on the same MDT as target"
3846
3847 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3848 test_34a() {
3849         rm -f $DIR/f34
3850         $MCREATE $DIR/f34 || error "mcreate failed"
3851         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3852                 error "getstripe failed"
3853         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3854         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3855                 error "getstripe failed"
3856         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3857                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3858 }
3859 run_test 34a "truncate file that has not been opened ==========="
3860
3861 test_34b() {
3862         [ ! -f $DIR/f34 ] && test_34a
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865         $OPENFILE -f O_RDONLY $DIR/f34
3866         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3867                 error "getstripe failed"
3868         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3869                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3870 }
3871 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3872
3873 test_34c() {
3874         [ ! -f $DIR/f34 ] && test_34a
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877         $OPENFILE -f O_RDWR $DIR/f34
3878         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3879                 error "$LFS getstripe failed"
3880         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3881                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3882 }
3883 run_test 34c "O_RDWR opening file-with-size works =============="
3884
3885 test_34d() {
3886         [ ! -f $DIR/f34 ] && test_34a
3887         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3888                 error "dd failed"
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891         rm $DIR/f34
3892 }
3893 run_test 34d "write to sparse file ============================="
3894
3895 test_34e() {
3896         rm -f $DIR/f34e
3897         $MCREATE $DIR/f34e || error "mcreate failed"
3898         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3899         $CHECKSTAT -s 1000 $DIR/f34e ||
3900                 error "Size of $DIR/f34e not equal to 1000 bytes"
3901         $OPENFILE -f O_RDWR $DIR/f34e
3902         $CHECKSTAT -s 1000 $DIR/f34e ||
3903                 error "Size of $DIR/f34e not equal to 1000 bytes"
3904 }
3905 run_test 34e "create objects, some with size and some without =="
3906
3907 test_34f() { # bug 6242, 6243
3908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3909
3910         SIZE34F=48000
3911         rm -f $DIR/f34f
3912         $MCREATE $DIR/f34f || error "mcreate failed"
3913         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3914         dd if=$DIR/f34f of=$TMP/f34f
3915         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3916         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3917         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3918         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3919         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3920 }
3921 run_test 34f "read from a file with no objects until EOF ======="
3922
3923 test_34g() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3927                 error "dd failed"
3928         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3929         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3930                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3931         cancel_lru_locks osc
3932         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3933                 error "wrong size after lock cancel"
3934
3935         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3936         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3937                 error "expanding truncate failed"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3940                 error "wrong expanded size after lock cancel"
3941 }
3942 run_test 34g "truncate long file ==============================="
3943
3944 test_34h() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         local gid=10
3948         local sz=1000
3949
3950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3951         sync # Flush the cache so that multiop below does not block on cache
3952              # flush when getting the group lock
3953         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3954         MULTIPID=$!
3955
3956         # Since just timed wait is not good enough, let's do a sync write
3957         # that way we are sure enough time for a roundtrip + processing
3958         # passed + 2 seconds of extra margin.
3959         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3960         rm $DIR/${tfile}-1
3961         sleep 2
3962
3963         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3964                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3965                 kill -9 $MULTIPID
3966         fi
3967         wait $MULTIPID
3968         local nsz=`stat -c %s $DIR/$tfile`
3969         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3970 }
3971 run_test 34h "ftruncate file under grouplock should not block"
3972
3973 test_35a() {
3974         cp /bin/sh $DIR/f35a
3975         chmod 444 $DIR/f35a
3976         chown $RUNAS_ID $DIR/f35a
3977         $RUNAS $DIR/f35a && error || true
3978         rm $DIR/f35a
3979 }
3980 run_test 35a "exec file with mode 444 (should return and not leak)"
3981
3982 test_36a() {
3983         rm -f $DIR/f36
3984         utime $DIR/f36 || error "utime failed for MDS"
3985 }
3986 run_test 36a "MDS utime check (mknod, utime)"
3987
3988 test_36b() {
3989         echo "" > $DIR/f36
3990         utime $DIR/f36 || error "utime failed for OST"
3991 }
3992 run_test 36b "OST utime check (open, utime)"
3993
3994 test_36c() {
3995         rm -f $DIR/d36/f36
3996         test_mkdir $DIR/d36
3997         chown $RUNAS_ID $DIR/d36
3998         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3999 }
4000 run_test 36c "non-root MDS utime check (mknod, utime)"
4001
4002 test_36d() {
4003         [ ! -d $DIR/d36 ] && test_36c
4004         echo "" > $DIR/d36/f36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4006 }
4007 run_test 36d "non-root OST utime check (open, utime)"
4008
4009 test_36e() {
4010         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4011
4012         test_mkdir $DIR/$tdir
4013         touch $DIR/$tdir/$tfile
4014         $RUNAS utime $DIR/$tdir/$tfile &&
4015                 error "utime worked, expected failure" || true
4016 }
4017 run_test 36e "utime on non-owned file (should return error)"
4018
4019 subr_36fh() {
4020         local fl="$1"
4021         local LANG_SAVE=$LANG
4022         local LC_LANG_SAVE=$LC_LANG
4023         export LANG=C LC_LANG=C # for date language
4024
4025         DATESTR="Dec 20  2000"
4026         test_mkdir $DIR/$tdir
4027         lctl set_param fail_loc=$fl
4028         date; date +%s
4029         cp /etc/hosts $DIR/$tdir/$tfile
4030         sync & # write RPC generated with "current" inode timestamp, but delayed
4031         sleep 1
4032         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4033         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4034         cancel_lru_locks $OSC
4035         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4036         date; date +%s
4037         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4038                 echo "BEFORE: $LS_BEFORE" && \
4039                 echo "AFTER : $LS_AFTER" && \
4040                 echo "WANT  : $DATESTR" && \
4041                 error "$DIR/$tdir/$tfile timestamps changed" || true
4042
4043         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4044 }
4045
4046 test_36f() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048
4049         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4050         subr_36fh "0x80000214"
4051 }
4052 run_test 36f "utime on file racing with OST BRW write =========="
4053
4054 test_36g() {
4055         remote_ost_nodsh && skip "remote OST with nodsh"
4056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4057         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4058                 skip "Need MDS version at least 2.12.51"
4059
4060         local fmd_max_age
4061         local fmd
4062         local facet="ost1"
4063         local tgt="obdfilter"
4064
4065         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4066
4067         test_mkdir $DIR/$tdir
4068         fmd_max_age=$(do_facet $facet \
4069                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4070                 head -n 1")
4071
4072         echo "FMD max age: ${fmd_max_age}s"
4073         touch $DIR/$tdir/$tfile
4074         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4075                 gawk '{cnt=cnt+$1}  END{print cnt}')
4076         echo "FMD before: $fmd"
4077         [[ $fmd == 0 ]] &&
4078                 error "FMD wasn't create by touch"
4079         sleep $((fmd_max_age + 12))
4080         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4081                 gawk '{cnt=cnt+$1}  END{print cnt}')
4082         echo "FMD after: $fmd"
4083         [[ $fmd == 0 ]] ||
4084                 error "FMD wasn't expired by ping"
4085 }
4086 run_test 36g "FMD cache expiry ====================="
4087
4088 test_36h() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4092         subr_36fh "0x80000227"
4093 }
4094 run_test 36h "utime on file racing with OST BRW write =========="
4095
4096 test_36i() {
4097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4098
4099         test_mkdir $DIR/$tdir
4100         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4101
4102         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4103         local new_mtime=$((mtime + 200))
4104
4105         #change Modify time of striped dir
4106         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4107                         error "change mtime failed"
4108
4109         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4110
4111         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4112 }
4113 run_test 36i "change mtime on striped directory"
4114
4115 # test_37 - duplicate with tests 32q 32r
4116
4117 test_38() {
4118         local file=$DIR/$tfile
4119         touch $file
4120         openfile -f O_DIRECTORY $file
4121         local RC=$?
4122         local ENOTDIR=20
4123         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4124         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4125 }
4126 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4127
4128 test_39a() { # was test_39
4129         touch $DIR/$tfile
4130         touch $DIR/${tfile}2
4131 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4132 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4133 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4134         sleep 2
4135         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4136         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4137                 echo "mtime"
4138                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4139                 echo "atime"
4140                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4141                 echo "ctime"
4142                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4143                 error "O_TRUNC didn't change timestamps"
4144         fi
4145 }
4146 run_test 39a "mtime changed on create"
4147
4148 test_39b() {
4149         test_mkdir -c1 $DIR/$tdir
4150         cp -p /etc/passwd $DIR/$tdir/fopen
4151         cp -p /etc/passwd $DIR/$tdir/flink
4152         cp -p /etc/passwd $DIR/$tdir/funlink
4153         cp -p /etc/passwd $DIR/$tdir/frename
4154         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4155
4156         sleep 1
4157         echo "aaaaaa" >> $DIR/$tdir/fopen
4158         echo "aaaaaa" >> $DIR/$tdir/flink
4159         echo "aaaaaa" >> $DIR/$tdir/funlink
4160         echo "aaaaaa" >> $DIR/$tdir/frename
4161
4162         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4163         local link_new=`stat -c %Y $DIR/$tdir/flink`
4164         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4165         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4166
4167         cat $DIR/$tdir/fopen > /dev/null
4168         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4169         rm -f $DIR/$tdir/funlink2
4170         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4171
4172         for (( i=0; i < 2; i++ )) ; do
4173                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4174                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4175                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4176                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4177
4178                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4179                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4180                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4181                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4182
4183                 cancel_lru_locks $OSC
4184                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4185         done
4186 }
4187 run_test 39b "mtime change on open, link, unlink, rename  ======"
4188
4189 # this should be set to past
4190 TEST_39_MTIME=`date -d "1 year ago" +%s`
4191
4192 # bug 11063
4193 test_39c() {
4194         touch $DIR1/$tfile
4195         sleep 2
4196         local mtime0=`stat -c %Y $DIR1/$tfile`
4197
4198         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4199         local mtime1=`stat -c %Y $DIR1/$tfile`
4200         [ "$mtime1" = $TEST_39_MTIME ] || \
4201                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4202
4203         local d1=`date +%s`
4204         echo hello >> $DIR1/$tfile
4205         local d2=`date +%s`
4206         local mtime2=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4208                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4209
4210         mv $DIR1/$tfile $DIR1/$tfile-1
4211
4212         for (( i=0; i < 2; i++ )) ; do
4213                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4214                 [ "$mtime2" = "$mtime3" ] || \
4215                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4216
4217                 cancel_lru_locks $OSC
4218                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4219         done
4220 }
4221 run_test 39c "mtime change on rename ==========================="
4222
4223 # bug 21114
4224 test_39d() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4229
4230         for (( i=0; i < 2; i++ )) ; do
4231                 local mtime=`stat -c %Y $DIR1/$tfile`
4232                 [ $mtime = $TEST_39_MTIME ] || \
4233                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4234
4235                 cancel_lru_locks $OSC
4236                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4237         done
4238 }
4239 run_test 39d "create, utime, stat =============================="
4240
4241 # bug 21114
4242 test_39e() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         touch $DIR1/$tfile
4246         local mtime1=`stat -c %Y $DIR1/$tfile`
4247
4248         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4249
4250         for (( i=0; i < 2; i++ )) ; do
4251                 local mtime2=`stat -c %Y $DIR1/$tfile`
4252                 [ $mtime2 = $TEST_39_MTIME ] || \
4253                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4254
4255                 cancel_lru_locks $OSC
4256                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4257         done
4258 }
4259 run_test 39e "create, stat, utime, stat ========================"
4260
4261 # bug 21114
4262 test_39f() {
4263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4264
4265         touch $DIR1/$tfile
4266         mtime1=`stat -c %Y $DIR1/$tfile`
4267
4268         sleep 2
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime2=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime2 = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39f "create, stat, sleep, utime, stat ================="
4281
4282 # bug 11063
4283 test_39g() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         echo hello >> $DIR1/$tfile
4287         local mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         sleep 2
4290         chmod o+r $DIR1/$tfile
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294                 [ "$mtime1" = "$mtime2" ] || \
4295                         error "lost mtime: $mtime2, should be $mtime1"
4296
4297                 cancel_lru_locks $OSC
4298                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4299         done
4300 }
4301 run_test 39g "write, chmod, stat ==============================="
4302
4303 # bug 11063
4304 test_39h() {
4305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4306
4307         touch $DIR1/$tfile
4308         sleep 1
4309
4310         local d1=`date`
4311         echo hello >> $DIR1/$tfile
4312         local mtime1=`stat -c %Y $DIR1/$tfile`
4313
4314         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4315         local d2=`date`
4316         if [ "$d1" != "$d2" ]; then
4317                 echo "write and touch not within one second"
4318         else
4319                 for (( i=0; i < 2; i++ )) ; do
4320                         local mtime2=`stat -c %Y $DIR1/$tfile`
4321                         [ "$mtime2" = $TEST_39_MTIME ] || \
4322                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4323
4324                         cancel_lru_locks $OSC
4325                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4326                 done
4327         fi
4328 }
4329 run_test 39h "write, utime within one second, stat ============="
4330
4331 test_39i() {
4332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4333
4334         touch $DIR1/$tfile
4335         sleep 1
4336
4337         echo hello >> $DIR1/$tfile
4338         local mtime1=`stat -c %Y $DIR1/$tfile`
4339
4340         mv $DIR1/$tfile $DIR1/$tfile-1
4341
4342         for (( i=0; i < 2; i++ )) ; do
4343                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4344
4345                 [ "$mtime1" = "$mtime2" ] || \
4346                         error "lost mtime: $mtime2, should be $mtime1"
4347
4348                 cancel_lru_locks $OSC
4349                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4350         done
4351 }
4352 run_test 39i "write, rename, stat =============================="
4353
4354 test_39j() {
4355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4356
4357         start_full_debug_logging
4358         touch $DIR1/$tfile
4359         sleep 1
4360
4361         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4362         lctl set_param fail_loc=0x80000412
4363         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4364                 error "multiop failed"
4365         local multipid=$!
4366         local mtime1=`stat -c %Y $DIR1/$tfile`
4367
4368         mv $DIR1/$tfile $DIR1/$tfile-1
4369
4370         kill -USR1 $multipid
4371         wait $multipid || error "multiop close failed"
4372
4373         for (( i=0; i < 2; i++ )) ; do
4374                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4375                 [ "$mtime1" = "$mtime2" ] ||
4376                         error "mtime is lost on close: $mtime2, " \
4377                               "should be $mtime1"
4378
4379                 cancel_lru_locks
4380                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4381         done
4382         lctl set_param fail_loc=0
4383         stop_full_debug_logging
4384 }
4385 run_test 39j "write, rename, close, stat ======================="
4386
4387 test_39k() {
4388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4389
4390         touch $DIR1/$tfile
4391         sleep 1
4392
4393         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4394         local multipid=$!
4395         local mtime1=`stat -c %Y $DIR1/$tfile`
4396
4397         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4398
4399         kill -USR1 $multipid
4400         wait $multipid || error "multiop close failed"
4401
4402         for (( i=0; i < 2; i++ )) ; do
4403                 local mtime2=`stat -c %Y $DIR1/$tfile`
4404
4405                 [ "$mtime2" = $TEST_39_MTIME ] || \
4406                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4407
4408                 cancel_lru_locks
4409                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4410         done
4411 }
4412 run_test 39k "write, utime, close, stat ========================"
4413
4414 # this should be set to future
4415 TEST_39_ATIME=`date -d "1 year" +%s`
4416
4417 test_39l() {
4418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4419         remote_mds_nodsh && skip "remote MDS with nodsh"
4420
4421         local atime_diff=$(do_facet $SINGLEMDS \
4422                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4423         rm -rf $DIR/$tdir
4424         mkdir -p $DIR/$tdir
4425
4426         # test setting directory atime to future
4427         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4428         local atime=$(stat -c %X $DIR/$tdir)
4429         [ "$atime" = $TEST_39_ATIME ] ||
4430                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4431
4432         # test setting directory atime from future to now
4433         local now=$(date +%s)
4434         touch -a -d @$now $DIR/$tdir
4435
4436         atime=$(stat -c %X $DIR/$tdir)
4437         [ "$atime" -eq "$now"  ] ||
4438                 error "atime is not updated from future: $atime, $now"
4439
4440         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4441         sleep 3
4442
4443         # test setting directory atime when now > dir atime + atime_diff
4444         local d1=$(date +%s)
4445         ls $DIR/$tdir
4446         local d2=$(date +%s)
4447         cancel_lru_locks mdc
4448         atime=$(stat -c %X $DIR/$tdir)
4449         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4450                 error "atime is not updated  : $atime, should be $d2"
4451
4452         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4453         sleep 3
4454
4455         # test not setting directory atime when now < dir atime + atime_diff
4456         ls $DIR/$tdir
4457         cancel_lru_locks mdc
4458         atime=$(stat -c %X $DIR/$tdir)
4459         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4460                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4461
4462         do_facet $SINGLEMDS \
4463                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4464 }
4465 run_test 39l "directory atime update ==========================="
4466
4467 test_39m() {
4468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4469
4470         touch $DIR1/$tfile
4471         sleep 2
4472         local far_past_mtime=$(date -d "May 29 1953" +%s)
4473         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4474
4475         touch -m -d @$far_past_mtime $DIR1/$tfile
4476         touch -a -d @$far_past_atime $DIR1/$tfile
4477
4478         for (( i=0; i < 2; i++ )) ; do
4479                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4480                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4481                         error "atime or mtime set incorrectly"
4482
4483                 cancel_lru_locks $OSC
4484                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4485         done
4486 }
4487 run_test 39m "test atime and mtime before 1970"
4488
4489 test_39n() { # LU-3832
4490         remote_mds_nodsh && skip "remote MDS with nodsh"
4491
4492         local atime_diff=$(do_facet $SINGLEMDS \
4493                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4494         local atime0
4495         local atime1
4496         local atime2
4497
4498         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4499
4500         rm -rf $DIR/$tfile
4501         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4502         atime0=$(stat -c %X $DIR/$tfile)
4503
4504         sleep 5
4505         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4506         atime1=$(stat -c %X $DIR/$tfile)
4507
4508         sleep 5
4509         cancel_lru_locks mdc
4510         cancel_lru_locks osc
4511         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4512         atime2=$(stat -c %X $DIR/$tfile)
4513
4514         do_facet $SINGLEMDS \
4515                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4516
4517         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4518         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4519 }
4520 run_test 39n "check that O_NOATIME is honored"
4521
4522 test_39o() {
4523         TESTDIR=$DIR/$tdir/$tfile
4524         [ -e $TESTDIR ] && rm -rf $TESTDIR
4525         mkdir -p $TESTDIR
4526         cd $TESTDIR
4527         links1=2
4528         ls
4529         mkdir a b
4530         ls
4531         links2=$(stat -c %h .)
4532         [ $(($links1 + 2)) != $links2 ] &&
4533                 error "wrong links count $(($links1 + 2)) != $links2"
4534         rmdir b
4535         links3=$(stat -c %h .)
4536         [ $(($links1 + 1)) != $links3 ] &&
4537                 error "wrong links count $links1 != $links3"
4538         return 0
4539 }
4540 run_test 39o "directory cached attributes updated after create"
4541
4542 test_39p() {
4543         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4544
4545         local MDTIDX=1
4546         TESTDIR=$DIR/$tdir/$tdir
4547         [ -e $TESTDIR ] && rm -rf $TESTDIR
4548         test_mkdir -p $TESTDIR
4549         cd $TESTDIR
4550         links1=2
4551         ls
4552         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4553         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4554         ls
4555         links2=$(stat -c %h .)
4556         [ $(($links1 + 2)) != $links2 ] &&
4557                 error "wrong links count $(($links1 + 2)) != $links2"
4558         rmdir remote_dir2
4559         links3=$(stat -c %h .)
4560         [ $(($links1 + 1)) != $links3 ] &&
4561                 error "wrong links count $links1 != $links3"
4562         return 0
4563 }
4564 run_test 39p "remote directory cached attributes updated after create ========"
4565
4566 test_39r() {
4567         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4568                 skip "no atime update on old OST"
4569         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4570                 skip_env "ldiskfs only test"
4571         fi
4572
4573         local saved_adiff
4574         saved_adiff=$(do_facet ost1 \
4575                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4576         stack_trap "do_facet ost1 \
4577                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4578
4579         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4580
4581         $LFS setstripe -i 0 $DIR/$tfile
4582         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4583                 error "can't write initial file"
4584         cancel_lru_locks osc
4585
4586         # exceed atime_diff and access file
4587         sleep 6
4588         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4589
4590         local atime_cli=$(stat -c %X $DIR/$tfile)
4591         echo "client atime: $atime_cli"
4592         # allow atime update to be written to device
4593         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4594         sleep 5
4595
4596         local ostdev=$(ostdevname 1)
4597         local fid=($(lfs getstripe -y $DIR/$tfile |
4598                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4599         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4600         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4601
4602         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4603         local atime_ost=$(do_facet ost1 "$cmd" |&
4604                           awk -F'[: ]' '/atime:/ { print $4 }')
4605         (( atime_cli == atime_ost )) ||
4606                 error "atime on client $atime_cli != ost $atime_ost"
4607 }
4608 run_test 39r "lazy atime update on OST"
4609
4610 test_39q() { # LU-8041
4611         local testdir=$DIR/$tdir
4612         mkdir -p $testdir
4613         multiop_bg_pause $testdir D_c || error "multiop failed"
4614         local multipid=$!
4615         cancel_lru_locks mdc
4616         kill -USR1 $multipid
4617         local atime=$(stat -c %X $testdir)
4618         [ "$atime" -ne 0 ] || error "atime is zero"
4619 }
4620 run_test 39q "close won't zero out atime"
4621
4622 test_40() {
4623         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4624         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4625                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4626         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4627                 error "$tfile is not 4096 bytes in size"
4628 }
4629 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4630
4631 test_41() {
4632         # bug 1553
4633         small_write $DIR/f41 18
4634 }
4635 run_test 41 "test small file write + fstat ====================="
4636
4637 count_ost_writes() {
4638         lctl get_param -n ${OSC}.*.stats |
4639                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4640                         END { printf("%0.0f", writes) }'
4641 }
4642
4643 # decent default
4644 WRITEBACK_SAVE=500
4645 DIRTY_RATIO_SAVE=40
4646 MAX_DIRTY_RATIO=50
4647 BG_DIRTY_RATIO_SAVE=10
4648 MAX_BG_DIRTY_RATIO=25
4649
4650 start_writeback() {
4651         trap 0
4652         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4653         # dirty_ratio, dirty_background_ratio
4654         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4655                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4656                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4657                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4658         else
4659                 # if file not here, we are a 2.4 kernel
4660                 kill -CONT `pidof kupdated`
4661         fi
4662 }
4663
4664 stop_writeback() {
4665         # setup the trap first, so someone cannot exit the test at the
4666         # exact wrong time and mess up a machine
4667         trap start_writeback EXIT
4668         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4669         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4670                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4671                 sysctl -w vm.dirty_writeback_centisecs=0
4672                 sysctl -w vm.dirty_writeback_centisecs=0
4673                 # save and increase /proc/sys/vm/dirty_ratio
4674                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4675                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4676                 # save and increase /proc/sys/vm/dirty_background_ratio
4677                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4678                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4679         else
4680                 # if file not here, we are a 2.4 kernel
4681                 kill -STOP `pidof kupdated`
4682         fi
4683 }
4684
4685 # ensure that all stripes have some grant before we test client-side cache
4686 setup_test42() {
4687         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4688                 dd if=/dev/zero of=$i bs=4k count=1
4689                 rm $i
4690         done
4691 }
4692
4693 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4694 # file truncation, and file removal.
4695 test_42a() {
4696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4697
4698         setup_test42
4699         cancel_lru_locks $OSC
4700         stop_writeback
4701         sync; sleep 1; sync # just to be safe
4702         BEFOREWRITES=`count_ost_writes`
4703         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4704         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4705         AFTERWRITES=`count_ost_writes`
4706         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4707                 error "$BEFOREWRITES < $AFTERWRITES"
4708         start_writeback
4709 }
4710 run_test 42a "ensure that we don't flush on close"
4711
4712 test_42b() {
4713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4714
4715         setup_test42
4716         cancel_lru_locks $OSC
4717         stop_writeback
4718         sync
4719         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4720         BEFOREWRITES=$(count_ost_writes)
4721         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4722         AFTERWRITES=$(count_ost_writes)
4723         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4724                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4725         fi
4726         BEFOREWRITES=$(count_ost_writes)
4727         sync || error "sync: $?"
4728         AFTERWRITES=$(count_ost_writes)
4729         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4730                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4731         fi
4732         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4733         start_writeback
4734         return 0
4735 }
4736 run_test 42b "test destroy of file with cached dirty data ======"
4737
4738 # if these tests just want to test the effect of truncation,
4739 # they have to be very careful.  consider:
4740 # - the first open gets a {0,EOF}PR lock
4741 # - the first write conflicts and gets a {0, count-1}PW
4742 # - the rest of the writes are under {count,EOF}PW
4743 # - the open for truncate tries to match a {0,EOF}PR
4744 #   for the filesize and cancels the PWs.
4745 # any number of fixes (don't get {0,EOF} on open, match
4746 # composite locks, do smarter file size management) fix
4747 # this, but for now we want these tests to verify that
4748 # the cancellation with truncate intent works, so we
4749 # start the file with a full-file pw lock to match against
4750 # until the truncate.
4751 trunc_test() {
4752         test=$1
4753         file=$DIR/$test
4754         offset=$2
4755         cancel_lru_locks $OSC
4756         stop_writeback
4757         # prime the file with 0,EOF PW to match
4758         touch $file
4759         $TRUNCATE $file 0
4760         sync; sync
4761         # now the real test..
4762         dd if=/dev/zero of=$file bs=1024 count=100
4763         BEFOREWRITES=`count_ost_writes`
4764         $TRUNCATE $file $offset
4765         cancel_lru_locks $OSC
4766         AFTERWRITES=`count_ost_writes`
4767         start_writeback
4768 }
4769
4770 test_42c() {
4771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4772
4773         trunc_test 42c 1024
4774         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4775                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4776         rm $file
4777 }
4778 run_test 42c "test partial truncate of file with cached dirty data"
4779
4780 test_42d() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         trunc_test 42d 0
4784         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4785                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4786         rm $file
4787 }
4788 run_test 42d "test complete truncate of file with cached dirty data"
4789
4790 test_42e() { # bug22074
4791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4792
4793         local TDIR=$DIR/${tdir}e
4794         local pages=16 # hardcoded 16 pages, don't change it.
4795         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4796         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4797         local max_dirty_mb
4798         local warmup_files
4799
4800         test_mkdir $DIR/${tdir}e
4801         $LFS setstripe -c 1 $TDIR
4802         createmany -o $TDIR/f $files
4803
4804         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4805
4806         # we assume that with $OSTCOUNT files, at least one of them will
4807         # be allocated on OST0.
4808         warmup_files=$((OSTCOUNT * max_dirty_mb))
4809         createmany -o $TDIR/w $warmup_files
4810
4811         # write a large amount of data into one file and sync, to get good
4812         # avail_grant number from OST.
4813         for ((i=0; i<$warmup_files; i++)); do
4814                 idx=$($LFS getstripe -i $TDIR/w$i)
4815                 [ $idx -ne 0 ] && continue
4816                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4817                 break
4818         done
4819         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4820         sync
4821         $LCTL get_param $proc_osc0/cur_dirty_bytes
4822         $LCTL get_param $proc_osc0/cur_grant_bytes
4823
4824         # create as much dirty pages as we can while not to trigger the actual
4825         # RPCs directly. but depends on the env, VFS may trigger flush during this
4826         # period, hopefully we are good.
4827         for ((i=0; i<$warmup_files; i++)); do
4828                 idx=$($LFS getstripe -i $TDIR/w$i)
4829                 [ $idx -ne 0 ] && continue
4830                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4831         done
4832         $LCTL get_param $proc_osc0/cur_dirty_bytes
4833         $LCTL get_param $proc_osc0/cur_grant_bytes
4834
4835         # perform the real test
4836         $LCTL set_param $proc_osc0/rpc_stats 0
4837         for ((;i<$files; i++)); do
4838                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4839                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4840         done
4841         sync
4842         $LCTL get_param $proc_osc0/rpc_stats
4843
4844         local percent=0
4845         local have_ppr=false
4846         $LCTL get_param $proc_osc0/rpc_stats |
4847                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4848                         # skip lines until we are at the RPC histogram data
4849                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4850                         $have_ppr || continue
4851
4852                         # we only want the percent stat for < 16 pages
4853                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4854
4855                         percent=$((percent + WPCT))
4856                         if [[ $percent -gt 15 ]]; then
4857                                 error "less than 16-pages write RPCs" \
4858                                       "$percent% > 15%"
4859                                 break
4860                         fi
4861                 done
4862         rm -rf $TDIR
4863 }
4864 run_test 42e "verify sub-RPC writes are not done synchronously"
4865
4866 test_43A() { # was test_43
4867         test_mkdir $DIR/$tdir
4868         cp -p /bin/ls $DIR/$tdir/$tfile
4869         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4870         pid=$!
4871         # give multiop a chance to open
4872         sleep 1
4873
4874         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4875         kill -USR1 $pid
4876 }
4877 run_test 43A "execution of file opened for write should return -ETXTBSY"
4878
4879 test_43a() {
4880         test_mkdir $DIR/$tdir
4881         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4882         $DIR/$tdir/sleep 60 &
4883         SLEEP_PID=$!
4884         # Make sure exec of $tdir/sleep wins race with truncate
4885         sleep 1
4886         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4887         kill $SLEEP_PID
4888 }
4889 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4890
4891 test_43b() {
4892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4893
4894         test_mkdir $DIR/$tdir
4895         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4896         $DIR/$tdir/sleep 60 &
4897         SLEEP_PID=$!
4898         # Make sure exec of $tdir/sleep wins race with truncate
4899         sleep 1
4900         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4901         kill $SLEEP_PID
4902 }
4903 run_test 43b "truncate of file being executed should return -ETXTBSY"
4904
4905 test_43c() {
4906         local testdir="$DIR/$tdir"
4907         test_mkdir $testdir
4908         cp $SHELL $testdir/
4909         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4910                 ( cd $testdir && md5sum -c )
4911 }
4912 run_test 43c "md5sum of copy into lustre"
4913
4914 test_44A() { # was test_44
4915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4916
4917         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4918         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4919 }
4920 run_test 44A "zero length read from a sparse stripe"
4921
4922 test_44a() {
4923         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4924                 awk '{ print $2 }')
4925         [ -z "$nstripe" ] && skip "can't get stripe info"
4926         [[ $nstripe -gt $OSTCOUNT ]] &&
4927                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4928
4929         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4930                 awk '{ print $2 }')
4931         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4932                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4933                         awk '{ print $2 }')
4934         fi
4935
4936         OFFSETS="0 $((stride/2)) $((stride-1))"
4937         for offset in $OFFSETS; do
4938                 for i in $(seq 0 $((nstripe-1))); do
4939                         local GLOBALOFFSETS=""
4940                         # size in Bytes
4941                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4942                         local myfn=$DIR/d44a-$size
4943                         echo "--------writing $myfn at $size"
4944                         ll_sparseness_write $myfn $size ||
4945                                 error "ll_sparseness_write"
4946                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4947                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4948                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4949
4950                         for j in $(seq 0 $((nstripe-1))); do
4951                                 # size in Bytes
4952                                 size=$((((j + $nstripe )*$stride + $offset)))
4953                                 ll_sparseness_write $myfn $size ||
4954                                         error "ll_sparseness_write"
4955                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         done
4957                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4958                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4959                         rm -f $myfn
4960                 done
4961         done
4962 }
4963 run_test 44a "test sparse pwrite ==============================="
4964
4965 dirty_osc_total() {
4966         tot=0
4967         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4968                 tot=$(($tot + $d))
4969         done
4970         echo $tot
4971 }
4972 do_dirty_record() {
4973         before=`dirty_osc_total`
4974         echo executing "\"$*\""
4975         eval $*
4976         after=`dirty_osc_total`
4977         echo before $before, after $after
4978 }
4979 test_45() {
4980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4981
4982         f="$DIR/f45"
4983         # Obtain grants from OST if it supports it
4984         echo blah > ${f}_grant
4985         stop_writeback
4986         sync
4987         do_dirty_record "echo blah > $f"
4988         [[ $before -eq $after ]] && error "write wasn't cached"
4989         do_dirty_record "> $f"
4990         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4991         do_dirty_record "echo blah > $f"
4992         [[ $before -eq $after ]] && error "write wasn't cached"
4993         do_dirty_record "sync"
4994         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4995         do_dirty_record "echo blah > $f"
4996         [[ $before -eq $after ]] && error "write wasn't cached"
4997         do_dirty_record "cancel_lru_locks osc"
4998         [[ $before -gt $after ]] ||
4999                 error "lock cancellation didn't lower dirty count"
5000         start_writeback
5001 }
5002 run_test 45 "osc io page accounting ============================"
5003
5004 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5005 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5006 # objects offset and an assert hit when an rpc was built with 1023's mapped
5007 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5008 test_46() {
5009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5010
5011         f="$DIR/f46"
5012         stop_writeback
5013         sync
5014         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5015         sync
5016         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5017         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5018         sync
5019         start_writeback
5020 }
5021 run_test 46 "dirtying a previously written page ================"
5022
5023 # test_47 is removed "Device nodes check" is moved to test_28
5024
5025 test_48a() { # bug 2399
5026         [ "$mds1_FSTYPE" = "zfs" ] &&
5027         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5028                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5029
5030         test_mkdir $DIR/$tdir
5031         cd $DIR/$tdir
5032         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5033         test_mkdir $DIR/$tdir
5034         touch foo || error "'touch foo' failed after recreating cwd"
5035         test_mkdir bar
5036         touch .foo || error "'touch .foo' failed after recreating cwd"
5037         test_mkdir .bar
5038         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5039         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5040         cd . || error "'cd .' failed after recreating cwd"
5041         mkdir . && error "'mkdir .' worked after recreating cwd"
5042         rmdir . && error "'rmdir .' worked after recreating cwd"
5043         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5044         cd .. || error "'cd ..' failed after recreating cwd"
5045 }
5046 run_test 48a "Access renamed working dir (should return errors)="
5047
5048 test_48b() { # bug 2399
5049         rm -rf $DIR/$tdir
5050         test_mkdir $DIR/$tdir
5051         cd $DIR/$tdir
5052         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5053         touch foo && error "'touch foo' worked after removing cwd"
5054         mkdir foo && error "'mkdir foo' worked after removing cwd"
5055         touch .foo && error "'touch .foo' worked after removing cwd"
5056         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5057         ls . > /dev/null && error "'ls .' worked after removing cwd"
5058         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5059         mkdir . && error "'mkdir .' worked after removing cwd"
5060         rmdir . && error "'rmdir .' worked after removing cwd"
5061         ln -s . foo && error "'ln -s .' worked after removing cwd"
5062         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5063 }
5064 run_test 48b "Access removed working dir (should return errors)="
5065
5066 test_48c() { # bug 2350
5067         #lctl set_param debug=-1
5068         #set -vx
5069         rm -rf $DIR/$tdir
5070         test_mkdir -p $DIR/$tdir/dir
5071         cd $DIR/$tdir/dir
5072         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5073         $TRACE touch foo && error "touch foo worked after removing cwd"
5074         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5075         touch .foo && error "touch .foo worked after removing cwd"
5076         mkdir .foo && error "mkdir .foo worked after removing cwd"
5077         $TRACE ls . && error "'ls .' worked after removing cwd"
5078         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5079         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5080         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5081         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5082         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5083 }
5084 run_test 48c "Access removed working subdir (should return errors)"
5085
5086 test_48d() { # bug 2350
5087         #lctl set_param debug=-1
5088         #set -vx
5089         rm -rf $DIR/$tdir
5090         test_mkdir -p $DIR/$tdir/dir
5091         cd $DIR/$tdir/dir
5092         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5093         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5094         $TRACE touch foo && error "'touch foo' worked after removing parent"
5095         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5096         touch .foo && error "'touch .foo' worked after removing parent"
5097         mkdir .foo && error "mkdir .foo worked after removing parent"
5098         $TRACE ls . && error "'ls .' worked after removing parent"
5099         $TRACE ls .. && error "'ls ..' worked after removing parent"
5100         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5101         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5102         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5103         true
5104 }
5105 run_test 48d "Access removed parent subdir (should return errors)"
5106
5107 test_48e() { # bug 4134
5108         #lctl set_param debug=-1
5109         #set -vx
5110         rm -rf $DIR/$tdir
5111         test_mkdir -p $DIR/$tdir/dir
5112         cd $DIR/$tdir/dir
5113         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5114         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5115         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5116         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5117         # On a buggy kernel addition of "touch foo" after cd .. will
5118         # produce kernel oops in lookup_hash_it
5119         touch ../foo && error "'cd ..' worked after recreate parent"
5120         cd $DIR
5121         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5122 }
5123 run_test 48e "Access to recreated parent subdir (should return errors)"
5124
5125 test_49() { # LU-1030
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127         remote_ost_nodsh && skip "remote OST with nodsh"
5128
5129         # get ost1 size - $FSNAME-OST0000
5130         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5131                 awk '{ print $4 }')
5132         # write 800M at maximum
5133         [[ $ost1_size -lt 2 ]] && ost1_size=2
5134         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5135
5136         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5137         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5138         local dd_pid=$!
5139
5140         # change max_pages_per_rpc while writing the file
5141         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5142         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5143         # loop until dd process exits
5144         while ps ax -opid | grep -wq $dd_pid; do
5145                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5146                 sleep $((RANDOM % 5 + 1))
5147         done
5148         # restore original max_pages_per_rpc
5149         $LCTL set_param $osc1_mppc=$orig_mppc
5150         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5151 }
5152 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5153
5154 test_50() {
5155         # bug 1485
5156         test_mkdir $DIR/$tdir
5157         cd $DIR/$tdir
5158         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5159 }
5160 run_test 50 "special situations: /proc symlinks  ==============="
5161
5162 test_51a() {    # was test_51
5163         # bug 1516 - create an empty entry right after ".." then split dir
5164         test_mkdir -c1 $DIR/$tdir
5165         touch $DIR/$tdir/foo
5166         $MCREATE $DIR/$tdir/bar
5167         rm $DIR/$tdir/foo
5168         createmany -m $DIR/$tdir/longfile 201
5169         FNUM=202
5170         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5171                 $MCREATE $DIR/$tdir/longfile$FNUM
5172                 FNUM=$(($FNUM + 1))
5173                 echo -n "+"
5174         done
5175         echo
5176         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5177 }
5178 run_test 51a "special situations: split htree with empty entry =="
5179
5180 cleanup_print_lfs_df () {
5181         trap 0
5182         $LFS df
5183         $LFS df -i
5184 }
5185
5186 test_51b() {
5187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5188
5189         local dir=$DIR/$tdir
5190         local nrdirs=$((65536 + 100))
5191
5192         # cleanup the directory
5193         rm -fr $dir
5194
5195         test_mkdir -c1 $dir
5196
5197         $LFS df
5198         $LFS df -i
5199         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5200         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5201         [[ $numfree -lt $nrdirs ]] &&
5202                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5203
5204         # need to check free space for the directories as well
5205         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5206         numfree=$(( blkfree / $(fs_inode_ksize) ))
5207         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5208
5209         trap cleanup_print_lfs_df EXIT
5210
5211         # create files
5212         createmany -d $dir/d $nrdirs || {
5213                 unlinkmany $dir/d $nrdirs
5214                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5215         }
5216
5217         # really created :
5218         nrdirs=$(ls -U $dir | wc -l)
5219
5220         # unlink all but 100 subdirectories, then check it still works
5221         local left=100
5222         local delete=$((nrdirs - left))
5223
5224         $LFS df
5225         $LFS df -i
5226
5227         # for ldiskfs the nlink count should be 1, but this is OSD specific
5228         # and so this is listed for informational purposes only
5229         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5230         unlinkmany -d $dir/d $delete ||
5231                 error "unlink of first $delete subdirs failed"
5232
5233         echo "nlink between: $(stat -c %h $dir)"
5234         local found=$(ls -U $dir | wc -l)
5235         [ $found -ne $left ] &&
5236                 error "can't find subdirs: found only $found, expected $left"
5237
5238         unlinkmany -d $dir/d $delete $left ||
5239                 error "unlink of second $left subdirs failed"
5240         # regardless of whether the backing filesystem tracks nlink accurately
5241         # or not, the nlink count shouldn't be more than "." and ".." here
5242         local after=$(stat -c %h $dir)
5243         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5244                 echo "nlink after: $after"
5245
5246         cleanup_print_lfs_df
5247 }
5248 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5249
5250 test_51d() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5253
5254         test_mkdir $DIR/$tdir
5255         createmany -o $DIR/$tdir/t- 1000
5256         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5257         for N in $(seq 0 $((OSTCOUNT - 1))); do
5258                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5259                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5260                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5261                         '($1 == '$N') { objs += 1 } \
5262                         END { printf("%0.0f", objs) }')
5263                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5264         done
5265         unlinkmany $DIR/$tdir/t- 1000
5266
5267         NLAST=0
5268         for N in $(seq 1 $((OSTCOUNT - 1))); do
5269                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5270                         error "OST $N has less objects vs OST $NLAST" \
5271                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5272                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5273                         error "OST $N has less objects vs OST $NLAST" \
5274                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5275
5276                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5277                         error "OST $N has less #0 objects vs OST $NLAST" \
5278                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5279                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5280                         error "OST $N has less #0 objects vs OST $NLAST" \
5281                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5282                 NLAST=$N
5283         done
5284         rm -f $TMP/$tfile
5285 }
5286 run_test 51d "check object distribution"
5287
5288 test_51e() {
5289         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5290                 skip_env "ldiskfs only test"
5291         fi
5292
5293         test_mkdir -c1 $DIR/$tdir
5294         test_mkdir -c1 $DIR/$tdir/d0
5295
5296         touch $DIR/$tdir/d0/foo
5297         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5298                 error "file exceed 65000 nlink limit!"
5299         unlinkmany $DIR/$tdir/d0/f- 65001
5300         return 0
5301 }
5302 run_test 51e "check file nlink limit"
5303
5304 test_51f() {
5305         test_mkdir $DIR/$tdir
5306
5307         local max=100000
5308         local ulimit_old=$(ulimit -n)
5309         local spare=20 # number of spare fd's for scripts/libraries, etc.
5310         local mdt=$($LFS getstripe -m $DIR/$tdir)
5311         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5312
5313         echo "MDT$mdt numfree=$numfree, max=$max"
5314         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5315         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5316                 while ! ulimit -n $((numfree + spare)); do
5317                         numfree=$((numfree * 3 / 4))
5318                 done
5319                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5320         else
5321                 echo "left ulimit at $ulimit_old"
5322         fi
5323
5324         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5325                 unlinkmany $DIR/$tdir/f $numfree
5326                 error "create+open $numfree files in $DIR/$tdir failed"
5327         }
5328         ulimit -n $ulimit_old
5329
5330         # if createmany exits at 120s there will be fewer than $numfree files
5331         unlinkmany $DIR/$tdir/f $numfree || true
5332 }
5333 run_test 51f "check many open files limit"
5334
5335 test_52a() {
5336         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5337         test_mkdir $DIR/$tdir
5338         touch $DIR/$tdir/foo
5339         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5340         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5341         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5342         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5343         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5344                                         error "link worked"
5345         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5346         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5347         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5348                                                      error "lsattr"
5349         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5350         cp -r $DIR/$tdir $TMP/
5351         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5352 }
5353 run_test 52a "append-only flag test (should return errors)"
5354
5355 test_52b() {
5356         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5357         test_mkdir $DIR/$tdir
5358         touch $DIR/$tdir/foo
5359         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5360         cat test > $DIR/$tdir/foo && error "cat test worked"
5361         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5362         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5363         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5364                                         error "link worked"
5365         echo foo >> $DIR/$tdir/foo && error "echo worked"
5366         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5367         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5368         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5369         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5370                                                         error "lsattr"
5371         chattr -i $DIR/$tdir/foo || error "chattr failed"
5372
5373         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5374 }
5375 run_test 52b "immutable flag test (should return errors) ======="
5376
5377 test_53() {
5378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5379         remote_mds_nodsh && skip "remote MDS with nodsh"
5380         remote_ost_nodsh && skip "remote OST with nodsh"
5381
5382         local param
5383         local param_seq
5384         local ostname
5385         local mds_last
5386         local mds_last_seq
5387         local ost_last
5388         local ost_last_seq
5389         local ost_last_id
5390         local ostnum
5391         local node
5392         local found=false
5393         local support_last_seq=true
5394
5395         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5396                 support_last_seq=false
5397
5398         # only test MDT0000
5399         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5400         local value
5401         for value in $(do_facet $SINGLEMDS \
5402                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5403                 param=$(echo ${value[0]} | cut -d "=" -f1)
5404                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5405
5406                 if $support_last_seq; then
5407                         param_seq=$(echo $param |
5408                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5409                         mds_last_seq=$(do_facet $SINGLEMDS \
5410                                        $LCTL get_param -n $param_seq)
5411                 fi
5412                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5413
5414                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5415                 node=$(facet_active_host ost$((ostnum+1)))
5416                 param="obdfilter.$ostname.last_id"
5417                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5418                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5419                         ost_last_id=$ost_last
5420
5421                         if $support_last_seq; then
5422                                 ost_last_id=$(echo $ost_last |
5423                                               awk -F':' '{print $2}' |
5424                                               sed -e "s/^0x//g")
5425                                 ost_last_seq=$(echo $ost_last |
5426                                                awk -F':' '{print $1}')
5427                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5428                         fi
5429
5430                         if [[ $ost_last_id != $mds_last ]]; then
5431                                 error "$ost_last_id != $mds_last"
5432                         else
5433                                 found=true
5434                                 break
5435                         fi
5436                 done
5437         done
5438         $found || error "can not match last_seq/last_id for $mdtosc"
5439         return 0
5440 }
5441 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5442
5443 test_54a() {
5444         perl -MSocket -e ';' || skip "no Socket perl module installed"
5445
5446         $SOCKETSERVER $DIR/socket ||
5447                 error "$SOCKETSERVER $DIR/socket failed: $?"
5448         $SOCKETCLIENT $DIR/socket ||
5449                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5450         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5451 }
5452 run_test 54a "unix domain socket test =========================="
5453
5454 test_54b() {
5455         f="$DIR/f54b"
5456         mknod $f c 1 3
5457         chmod 0666 $f
5458         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5459 }
5460 run_test 54b "char device works in lustre ======================"
5461
5462 find_loop_dev() {
5463         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5464         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5465         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5466
5467         for i in $(seq 3 7); do
5468                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5469                 LOOPDEV=$LOOPBASE$i
5470                 LOOPNUM=$i
5471                 break
5472         done
5473 }
5474
5475 cleanup_54c() {
5476         local rc=0
5477         loopdev="$DIR/loop54c"
5478
5479         trap 0
5480         $UMOUNT $DIR/$tdir || rc=$?
5481         losetup -d $loopdev || true
5482         losetup -d $LOOPDEV || true
5483         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5484         return $rc
5485 }
5486
5487 test_54c() {
5488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5489
5490         loopdev="$DIR/loop54c"
5491
5492         find_loop_dev
5493         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5494         trap cleanup_54c EXIT
5495         mknod $loopdev b 7 $LOOPNUM
5496         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5497         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5498         losetup $loopdev $DIR/$tfile ||
5499                 error "can't set up $loopdev for $DIR/$tfile"
5500         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5501         test_mkdir $DIR/$tdir
5502         mount -t ext2 $loopdev $DIR/$tdir ||
5503                 error "error mounting $loopdev on $DIR/$tdir"
5504         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5505                 error "dd write"
5506         df $DIR/$tdir
5507         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5508                 error "dd read"
5509         cleanup_54c
5510 }
5511 run_test 54c "block device works in lustre ====================="
5512
5513 test_54d() {
5514         f="$DIR/f54d"
5515         string="aaaaaa"
5516         mknod $f p
5517         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5518 }
5519 run_test 54d "fifo device works in lustre ======================"
5520
5521 test_54e() {
5522         f="$DIR/f54e"
5523         string="aaaaaa"
5524         cp -aL /dev/console $f
5525         echo $string > $f || error "echo $string to $f failed"
5526 }
5527 run_test 54e "console/tty device works in lustre ======================"
5528
5529 test_56a() {
5530         local numfiles=3
5531         local dir=$DIR/$tdir
5532
5533         rm -rf $dir
5534         test_mkdir -p $dir/dir
5535         for i in $(seq $numfiles); do
5536                 touch $dir/file$i
5537                 touch $dir/dir/file$i
5538         done
5539
5540         local numcomp=$($LFS getstripe --component-count $dir)
5541
5542         [[ $numcomp == 0 ]] && numcomp=1
5543
5544         # test lfs getstripe with --recursive
5545         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5546
5547         [[ $filenum -eq $((numfiles * 2)) ]] ||
5548                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5549         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5550         [[ $filenum -eq $numfiles ]] ||
5551                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5552         echo "$LFS getstripe showed obdidx or l_ost_idx"
5553
5554         # test lfs getstripe with file instead of dir
5555         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5556         [[ $filenum -eq 1 ]] ||
5557                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5558         echo "$LFS getstripe file1 passed"
5559
5560         #test lfs getstripe with --verbose
5561         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5562         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5563                 error "$LFS getstripe --verbose $dir: "\
5564                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5565         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5566                 error "$LFS getstripe $dir: showed lmm_magic"
5567
5568         #test lfs getstripe with -v prints lmm_fid
5569         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5570         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5571                 error "$LFS getstripe -v $dir: "\
5572                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5573         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5574                 error "$LFS getstripe $dir: showed lmm_fid by default"
5575         echo "$LFS getstripe --verbose passed"
5576
5577         #check for FID information
5578         local fid1=$($LFS getstripe --fid $dir/file1)
5579         local fid2=$($LFS getstripe --verbose $dir/file1 |
5580                      awk '/lmm_fid: / { print $2; exit; }')
5581         local fid3=$($LFS path2fid $dir/file1)
5582
5583         [ "$fid1" != "$fid2" ] &&
5584                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5585         [ "$fid1" != "$fid3" ] &&
5586                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5587         echo "$LFS getstripe --fid passed"
5588
5589         #test lfs getstripe with --obd
5590         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5591                 error "$LFS getstripe --obd wrong_uuid: should return error"
5592
5593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5594
5595         local ostidx=1
5596         local obduuid=$(ostuuid_from_index $ostidx)
5597         local found=$($LFS getstripe -r --obd $obduuid $dir |
5598                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5599
5600         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5601         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5602                 ((filenum--))
5603         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5604                 ((filenum--))
5605
5606         [[ $found -eq $filenum ]] ||
5607                 error "$LFS getstripe --obd: found $found expect $filenum"
5608         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5609                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5610                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5611                 error "$LFS getstripe --obd: should not show file on other obd"
5612         echo "$LFS getstripe --obd passed"
5613 }
5614 run_test 56a "check $LFS getstripe"
5615
5616 test_56b() {
5617         local dir=$DIR/$tdir
5618         local numdirs=3
5619
5620         test_mkdir $dir
5621         for i in $(seq $numdirs); do
5622                 test_mkdir $dir/dir$i
5623         done
5624
5625         # test lfs getdirstripe default mode is non-recursion, which is
5626         # different from lfs getstripe
5627         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5628
5629         [[ $dircnt -eq 1 ]] ||
5630                 error "$LFS getdirstripe: found $dircnt, not 1"
5631         dircnt=$($LFS getdirstripe --recursive $dir |
5632                 grep -c lmv_stripe_count)
5633         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5634                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5635 }
5636 run_test 56b "check $LFS getdirstripe"
5637
5638 test_56c() {
5639         remote_ost_nodsh && skip "remote OST with nodsh"
5640
5641         local ost_idx=0
5642         local ost_name=$(ostname_from_index $ost_idx)
5643         local old_status=$(ost_dev_status $ost_idx)
5644         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5645
5646         [[ -z "$old_status" ]] ||
5647                 skip_env "OST $ost_name is in $old_status status"
5648
5649         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5650         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5651                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5652         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5653                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5654                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5655         fi
5656
5657         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5658                 error "$LFS df -v showing inactive devices"
5659         sleep_maxage
5660
5661         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5662
5663         [[ "$new_status" =~ "D" ]] ||
5664                 error "$ost_name status is '$new_status', missing 'D'"
5665         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5666                 [[ "$new_status" =~ "N" ]] ||
5667                         error "$ost_name status is '$new_status', missing 'N'"
5668         fi
5669         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5670                 [[ "$new_status" =~ "f" ]] ||
5671                         error "$ost_name status is '$new_status', missing 'f'"
5672         fi
5673
5674         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5675         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5676                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5677         [[ -z "$p" ]] && restore_lustre_params < $p || true
5678         sleep_maxage
5679
5680         new_status=$(ost_dev_status $ost_idx)
5681         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5682                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5683         # can't check 'f' as devices may actually be on flash
5684 }
5685 run_test 56c "check 'lfs df' showing device status"
5686
5687 test_56d() {
5688         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5689         local osts=$($LFS df -v $MOUNT | grep -c OST)
5690
5691         $LFS df $MOUNT
5692
5693         (( mdts == MDSCOUNT )) ||
5694                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5695         (( osts == OSTCOUNT )) ||
5696                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5697 }
5698 run_test 56d "'lfs df -v' prints only configured devices"
5699
5700 NUMFILES=3
5701 NUMDIRS=3
5702 setup_56() {
5703         local local_tdir="$1"
5704         local local_numfiles="$2"
5705         local local_numdirs="$3"
5706         local dir_params="$4"
5707         local dir_stripe_params="$5"
5708
5709         if [ ! -d "$local_tdir" ] ; then
5710                 test_mkdir -p $dir_stripe_params $local_tdir
5711                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5712                 for i in $(seq $local_numfiles) ; do
5713                         touch $local_tdir/file$i
5714                 done
5715                 for i in $(seq $local_numdirs) ; do
5716                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5717                         for j in $(seq $local_numfiles) ; do
5718                                 touch $local_tdir/dir$i/file$j
5719                         done
5720                 done
5721         fi
5722 }
5723
5724 setup_56_special() {
5725         local local_tdir=$1
5726         local local_numfiles=$2
5727         local local_numdirs=$3
5728
5729         setup_56 $local_tdir $local_numfiles $local_numdirs
5730
5731         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5732                 for i in $(seq $local_numfiles) ; do
5733                         mknod $local_tdir/loop${i}b b 7 $i
5734                         mknod $local_tdir/null${i}c c 1 3
5735                         ln -s $local_tdir/file1 $local_tdir/link${i}
5736                 done
5737                 for i in $(seq $local_numdirs) ; do
5738                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5739                         mknod $local_tdir/dir$i/null${i}c c 1 3
5740                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5741                 done
5742         fi
5743 }
5744
5745 test_56g() {
5746         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5747         local expected=$(($NUMDIRS + 2))
5748
5749         setup_56 $dir $NUMFILES $NUMDIRS
5750
5751         # test lfs find with -name
5752         for i in $(seq $NUMFILES) ; do
5753                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5754
5755                 [ $nums -eq $expected ] ||
5756                         error "lfs find -name '*$i' $dir wrong: "\
5757                               "found $nums, expected $expected"
5758         done
5759 }
5760 run_test 56g "check lfs find -name"
5761
5762 test_56h() {
5763         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5764         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5765
5766         setup_56 $dir $NUMFILES $NUMDIRS
5767
5768         # test lfs find with ! -name
5769         for i in $(seq $NUMFILES) ; do
5770                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5771
5772                 [ $nums -eq $expected ] ||
5773                         error "lfs find ! -name '*$i' $dir wrong: "\
5774                               "found $nums, expected $expected"
5775         done
5776 }
5777 run_test 56h "check lfs find ! -name"
5778
5779 test_56i() {
5780         local dir=$DIR/$tdir
5781
5782         test_mkdir $dir
5783
5784         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5785         local out=$($cmd)
5786
5787         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5788 }
5789 run_test 56i "check 'lfs find -ost UUID' skips directories"
5790
5791 test_56j() {
5792         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5793
5794         setup_56_special $dir $NUMFILES $NUMDIRS
5795
5796         local expected=$((NUMDIRS + 1))
5797         local cmd="$LFS find -type d $dir"
5798         local nums=$($cmd | wc -l)
5799
5800         [ $nums -eq $expected ] ||
5801                 error "'$cmd' wrong: found $nums, expected $expected"
5802 }
5803 run_test 56j "check lfs find -type d"
5804
5805 test_56k() {
5806         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5807
5808         setup_56_special $dir $NUMFILES $NUMDIRS
5809
5810         local expected=$(((NUMDIRS + 1) * NUMFILES))
5811         local cmd="$LFS find -type f $dir"
5812         local nums=$($cmd | wc -l)
5813
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816 }
5817 run_test 56k "check lfs find -type f"
5818
5819 test_56l() {
5820         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5821
5822         setup_56_special $dir $NUMFILES $NUMDIRS
5823
5824         local expected=$((NUMDIRS + NUMFILES))
5825         local cmd="$LFS find -type b $dir"
5826         local nums=$($cmd | wc -l)
5827
5828         [ $nums -eq $expected ] ||
5829                 error "'$cmd' wrong: found $nums, expected $expected"
5830 }
5831 run_test 56l "check lfs find -type b"
5832
5833 test_56m() {
5834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5835
5836         setup_56_special $dir $NUMFILES $NUMDIRS
5837
5838         local expected=$((NUMDIRS + NUMFILES))
5839         local cmd="$LFS find -type c $dir"
5840         local nums=$($cmd | wc -l)
5841         [ $nums -eq $expected ] ||
5842                 error "'$cmd' wrong: found $nums, expected $expected"
5843 }
5844 run_test 56m "check lfs find -type c"
5845
5846 test_56n() {
5847         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5848         setup_56_special $dir $NUMFILES $NUMDIRS
5849
5850         local expected=$((NUMDIRS + NUMFILES))
5851         local cmd="$LFS find -type l $dir"
5852         local nums=$($cmd | wc -l)
5853
5854         [ $nums -eq $expected ] ||
5855                 error "'$cmd' wrong: found $nums, expected $expected"
5856 }
5857 run_test 56n "check lfs find -type l"
5858
5859 test_56o() {
5860         local dir=$DIR/$tdir
5861
5862         setup_56 $dir $NUMFILES $NUMDIRS
5863         utime $dir/file1 > /dev/null || error "utime (1)"
5864         utime $dir/file2 > /dev/null || error "utime (2)"
5865         utime $dir/dir1 > /dev/null || error "utime (3)"
5866         utime $dir/dir2 > /dev/null || error "utime (4)"
5867         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5868         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5869
5870         local expected=4
5871         local nums=$($LFS find -mtime +0 $dir | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5875
5876         expected=12
5877         cmd="$LFS find -mtime 0 $dir"
5878         nums=$($cmd | wc -l)
5879         [ $nums -eq $expected ] ||
5880                 error "'$cmd' wrong: found $nums, expected $expected"
5881 }
5882 run_test 56o "check lfs find -mtime for old files"
5883
5884 test_56ob() {
5885         local dir=$DIR/$tdir
5886         local expected=1
5887         local count=0
5888
5889         # just to make sure there is something that won't be found
5890         test_mkdir $dir
5891         touch $dir/$tfile.now
5892
5893         for age in year week day hour min; do
5894                 count=$((count + 1))
5895
5896                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5897                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5898                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5899
5900                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5901                 local nums=$($cmd | wc -l)
5902                 [ $nums -eq $expected ] ||
5903                         error "'$cmd' wrong: found $nums, expected $expected"
5904
5905                 cmd="$LFS find $dir -atime $count${age:0:1}"
5906                 nums=$($cmd | wc -l)
5907                 [ $nums -eq $expected ] ||
5908                         error "'$cmd' wrong: found $nums, expected $expected"
5909         done
5910
5911         sleep 2
5912         cmd="$LFS find $dir -ctime +1s -type f"
5913         nums=$($cmd | wc -l)
5914         (( $nums == $count * 2 + 1)) ||
5915                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5916 }
5917 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5918
5919 test_newerXY_base() {
5920         local x=$1
5921         local y=$2
5922         local dir=$DIR/$tdir
5923         local ref
5924         local negref
5925
5926         if [ $y == "t" ]; then
5927                 if [ $x == "b" ]; then
5928                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5929                 else
5930                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5931                 fi
5932         else
5933                 ref=$DIR/$tfile.newer.$x$y
5934                 touch $ref || error "touch $ref failed"
5935         fi
5936         sleep 2
5937         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5938         sleep 2
5939         if [ $y == "t" ]; then
5940                 if [ $x == "b" ]; then
5941                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5942                 else
5943                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5944                 fi
5945         else
5946                 negref=$DIR/$tfile.negnewer.$x$y
5947                 touch $negref || error "touch $negref failed"
5948         fi
5949
5950         local cmd="$LFS find $dir -newer$x$y $ref"
5951         local nums=$(eval $cmd | wc -l)
5952         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5953
5954         [ $nums -eq $expected ] ||
5955                 error "'$cmd' wrong: found $nums, expected $expected"
5956
5957         cmd="$LFS find $dir ! -newer$x$y $negref"
5958         nums=$(eval $cmd | wc -l)
5959         [ $nums -eq $expected ] ||
5960                 error "'$cmd' wrong: found $nums, expected $expected"
5961
5962         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5963         nums=$(eval $cmd | wc -l)
5964         [ $nums -eq $expected ] ||
5965                 error "'$cmd' wrong: found $nums, expected $expected"
5966
5967         rm -rf $DIR/*
5968 }
5969
5970 test_56oc() {
5971         test_newerXY_base "b" "t"
5972         test_newerXY_base "a" "a"
5973         test_newerXY_base "a" "m"
5974         test_newerXY_base "a" "c"
5975         test_newerXY_base "m" "a"
5976         test_newerXY_base "m" "m"
5977         test_newerXY_base "m" "c"
5978         test_newerXY_base "c" "a"
5979         test_newerXY_base "c" "m"
5980         test_newerXY_base "c" "c"
5981         test_newerXY_base "b" "b"
5982         test_newerXY_base "a" "t"
5983         test_newerXY_base "m" "t"
5984         test_newerXY_base "c" "t"
5985         test_newerXY_base "b" "t"
5986 }
5987 run_test 56oc "check lfs find -newerXY work"
5988
5989 btime_supported() {
5990         local dir=$DIR/$tdir
5991         local rc
5992
5993         mkdir -p $dir
5994         touch $dir/$tfile
5995         $LFS find $dir -btime -1d -type f
5996         rc=$?
5997         rm -rf $dir
5998         return $rc
5999 }
6000
6001 test_56od() {
6002         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6003                 ! btime_supported && skip "btime unsupported on MDS"
6004
6005         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6006                 ! btime_supported && skip "btime unsupported on clients"
6007
6008         local dir=$DIR/$tdir
6009         local ref=$DIR/$tfile.ref
6010         local negref=$DIR/$tfile.negref
6011
6012         mkdir $dir || error "mkdir $dir failed"
6013         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6014         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6015         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6016         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6017         touch $ref || error "touch $ref failed"
6018         # sleep 3 seconds at least
6019         sleep 3
6020
6021         local before=$(do_facet mds1 date +%s)
6022         local skew=$(($(date +%s) - before + 1))
6023
6024         if (( skew < 0 && skew > -5 )); then
6025                 sleep $((0 - skew + 1))
6026                 skew=0
6027         fi
6028
6029         # Set the dir stripe params to limit files all on MDT0,
6030         # otherwise we need to calc the max clock skew between
6031         # the client and MDTs.
6032         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6033         sleep 2
6034         touch $negref || error "touch $negref failed"
6035
6036         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6037         local nums=$($cmd | wc -l)
6038         local expected=$(((NUMFILES + 1) * NUMDIRS))
6039
6040         [ $nums -eq $expected ] ||
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042
6043         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6044         nums=$($cmd | wc -l)
6045         expected=$((NUMFILES + 1))
6046         [ $nums -eq $expected ] ||
6047                 error "'$cmd' wrong: found $nums, expected $expected"
6048
6049         [ $skew -lt 0 ] && return
6050
6051         local after=$(do_facet mds1 date +%s)
6052         local age=$((after - before + 1 + skew))
6053
6054         cmd="$LFS find $dir -btime -${age}s -type f"
6055         nums=$($cmd | wc -l)
6056         expected=$(((NUMFILES + 1) * NUMDIRS))
6057
6058         echo "Clock skew between client and server: $skew, age:$age"
6059         [ $nums -eq $expected ] ||
6060                 error "'$cmd' wrong: found $nums, expected $expected"
6061
6062         expected=$(($NUMDIRS + 1))
6063         cmd="$LFS find $dir -btime -${age}s -type d"
6064         nums=$($cmd | wc -l)
6065         [ $nums -eq $expected ] ||
6066                 error "'$cmd' wrong: found $nums, expected $expected"
6067         rm -f $ref $negref || error "Failed to remove $ref $negref"
6068 }
6069 run_test 56od "check lfs find -btime with units"
6070
6071 test_56p() {
6072         [ $RUNAS_ID -eq $UID ] &&
6073                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6074
6075         local dir=$DIR/$tdir
6076
6077         setup_56 $dir $NUMFILES $NUMDIRS
6078         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6079
6080         local expected=$NUMFILES
6081         local cmd="$LFS find -uid $RUNAS_ID $dir"
6082         local nums=$($cmd | wc -l)
6083
6084         [ $nums -eq $expected ] ||
6085                 error "'$cmd' wrong: found $nums, expected $expected"
6086
6087         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6088         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6089         nums=$($cmd | wc -l)
6090         [ $nums -eq $expected ] ||
6091                 error "'$cmd' wrong: found $nums, expected $expected"
6092 }
6093 run_test 56p "check lfs find -uid and ! -uid"
6094
6095 test_56q() {
6096         [ $RUNAS_ID -eq $UID ] &&
6097                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6098
6099         local dir=$DIR/$tdir
6100
6101         setup_56 $dir $NUMFILES $NUMDIRS
6102         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6103
6104         local expected=$NUMFILES
6105         local cmd="$LFS find -gid $RUNAS_GID $dir"
6106         local nums=$($cmd | wc -l)
6107
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6112         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6113         nums=$($cmd | wc -l)
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116 }
6117 run_test 56q "check lfs find -gid and ! -gid"
6118
6119 test_56r() {
6120         local dir=$DIR/$tdir
6121
6122         setup_56 $dir $NUMFILES $NUMDIRS
6123
6124         local expected=12
6125         local cmd="$LFS find -size 0 -type f -lazy $dir"
6126         local nums=$($cmd | wc -l)
6127
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130         cmd="$LFS find -size 0 -type f $dir"
6131         nums=$($cmd | wc -l)
6132         [ $nums -eq $expected ] ||
6133                 error "'$cmd' wrong: found $nums, expected $expected"
6134
6135         expected=0
6136         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6137         nums=$($cmd | wc -l)
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140         cmd="$LFS find ! -size 0 -type f $dir"
6141         nums=$($cmd | wc -l)
6142         [ $nums -eq $expected ] ||
6143                 error "'$cmd' wrong: found $nums, expected $expected"
6144
6145         echo "test" > $dir/$tfile
6146         echo "test2" > $dir/$tfile.2 && sync
6147         expected=1
6148         cmd="$LFS find -size 5 -type f -lazy $dir"
6149         nums=$($cmd | wc -l)
6150         [ $nums -eq $expected ] ||
6151                 error "'$cmd' wrong: found $nums, expected $expected"
6152         cmd="$LFS find -size 5 -type f $dir"
6153         nums=$($cmd | wc -l)
6154         [ $nums -eq $expected ] ||
6155                 error "'$cmd' wrong: found $nums, expected $expected"
6156
6157         expected=1
6158         cmd="$LFS find -size +5 -type f -lazy $dir"
6159         nums=$($cmd | wc -l)
6160         [ $nums -eq $expected ] ||
6161                 error "'$cmd' wrong: found $nums, expected $expected"
6162         cmd="$LFS find -size +5 -type f $dir"
6163         nums=$($cmd | wc -l)
6164         [ $nums -eq $expected ] ||
6165                 error "'$cmd' wrong: found $nums, expected $expected"
6166
6167         expected=2
6168         cmd="$LFS find -size +0 -type f -lazy $dir"
6169         nums=$($cmd | wc -l)
6170         [ $nums -eq $expected ] ||
6171                 error "'$cmd' wrong: found $nums, expected $expected"
6172         cmd="$LFS find -size +0 -type f $dir"
6173         nums=$($cmd | wc -l)
6174         [ $nums -eq $expected ] ||
6175                 error "'$cmd' wrong: found $nums, expected $expected"
6176
6177         expected=2
6178         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find ! -size -5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=12
6188         cmd="$LFS find -size -5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size -5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196 }
6197 run_test 56r "check lfs find -size works"
6198
6199 test_56ra_sub() {
6200         local expected=$1
6201         local glimpses=$2
6202         local cmd="$3"
6203
6204         cancel_lru_locks $OSC
6205
6206         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6207         local nums=$($cmd | wc -l)
6208
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211
6212         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6213
6214         if (( rpcs_before + glimpses != rpcs_after )); then
6215                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6216                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6217
6218                 if [[ $glimpses == 0 ]]; then
6219                         error "'$cmd' should not send glimpse RPCs to OST"
6220                 else
6221                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6222                 fi
6223         fi
6224 }
6225
6226 test_56ra() {
6227         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6228                 skip "MDS < 2.12.58 doesn't return LSOM data"
6229         local dir=$DIR/$tdir
6230
6231         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6232
6233         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6234         # open and close all files to ensure LSOM is updated
6235         cancel_lru_locks $OSC
6236         find $dir -type f | xargs cat > /dev/null
6237
6238         #   expect_found  glimpse_rpcs  command_to_run
6239         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6240         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6241         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6242         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6243
6244         echo "test" > $dir/$tfile
6245         echo "test2" > $dir/$tfile.2 && sync
6246         cancel_lru_locks $OSC
6247         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6248
6249         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6250         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6251         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6252         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6253
6254         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6255         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6256         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6257         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6258         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6259         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6260 }
6261 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6262
6263 test_56rb() {
6264         local dir=$DIR/$tdir
6265         local tmp=$TMP/$tfile.log
6266         local mdt_idx;
6267
6268         test_mkdir -p $dir || error "failed to mkdir $dir"
6269         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6270                 error "failed to setstripe $dir/$tfile"
6271         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6272
6273         stack_trap "rm -f $tmp" EXIT
6274         $LFS find --size +100K --ost 0 $dir 2>&1 | tee $tmp
6275         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6276                 error "failed to find --size +100K --ost 0 $dir"
6277         $LFS find --size +100K --mdt $mdt_idx $dir 2>&1 | tee $tmp
6278         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6279                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6280 }
6281 run_test 56rb "check lfs find --size --ost/--mdt works"
6282
6283 test_56s() { # LU-611 #LU-9369
6284         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6285
6286         local dir=$DIR/$tdir
6287         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6288
6289         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6290         for i in $(seq $NUMDIRS); do
6291                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6292         done
6293
6294         local expected=$NUMDIRS
6295         local cmd="$LFS find -c $OSTCOUNT $dir"
6296         local nums=$($cmd | wc -l)
6297
6298         [ $nums -eq $expected ] || {
6299                 $LFS getstripe -R $dir
6300                 error "'$cmd' wrong: found $nums, expected $expected"
6301         }
6302
6303         expected=$((NUMDIRS + onestripe))
6304         cmd="$LFS find -stripe-count +0 -type f $dir"
6305         nums=$($cmd | wc -l)
6306         [ $nums -eq $expected ] || {
6307                 $LFS getstripe -R $dir
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309         }
6310
6311         expected=$onestripe
6312         cmd="$LFS find -stripe-count 1 -type f $dir"
6313         nums=$($cmd | wc -l)
6314         [ $nums -eq $expected ] || {
6315                 $LFS getstripe -R $dir
6316                 error "'$cmd' wrong: found $nums, expected $expected"
6317         }
6318
6319         cmd="$LFS find -stripe-count -2 -type f $dir"
6320         nums=$($cmd | wc -l)
6321         [ $nums -eq $expected ] || {
6322                 $LFS getstripe -R $dir
6323                 error "'$cmd' wrong: found $nums, expected $expected"
6324         }
6325
6326         expected=0
6327         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6328         nums=$($cmd | wc -l)
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333 }
6334 run_test 56s "check lfs find -stripe-count works"
6335
6336 test_56t() { # LU-611 #LU-9369
6337         local dir=$DIR/$tdir
6338
6339         setup_56 $dir 0 $NUMDIRS
6340         for i in $(seq $NUMDIRS); do
6341                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6342         done
6343
6344         local expected=$NUMDIRS
6345         local cmd="$LFS find -S 8M $dir"
6346         local nums=$($cmd | wc -l)
6347
6348         [ $nums -eq $expected ] || {
6349                 $LFS getstripe -R $dir
6350                 error "'$cmd' wrong: found $nums, expected $expected"
6351         }
6352         rm -rf $dir
6353
6354         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6355
6356         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6357
6358         expected=$(((NUMDIRS + 1) * NUMFILES))
6359         cmd="$LFS find -stripe-size 512k -type f $dir"
6360         nums=$($cmd | wc -l)
6361         [ $nums -eq $expected ] ||
6362                 error "'$cmd' wrong: found $nums, expected $expected"
6363
6364         cmd="$LFS find -stripe-size +320k -type f $dir"
6365         nums=$($cmd | wc -l)
6366         [ $nums -eq $expected ] ||
6367                 error "'$cmd' wrong: found $nums, expected $expected"
6368
6369         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6370         cmd="$LFS find -stripe-size +200k -type f $dir"
6371         nums=$($cmd | wc -l)
6372         [ $nums -eq $expected ] ||
6373                 error "'$cmd' wrong: found $nums, expected $expected"
6374
6375         cmd="$LFS find -stripe-size -640k -type f $dir"
6376         nums=$($cmd | wc -l)
6377         [ $nums -eq $expected ] ||
6378                 error "'$cmd' wrong: found $nums, expected $expected"
6379
6380         expected=4
6381         cmd="$LFS find -stripe-size 256k -type f $dir"
6382         nums=$($cmd | wc -l)
6383         [ $nums -eq $expected ] ||
6384                 error "'$cmd' wrong: found $nums, expected $expected"
6385
6386         cmd="$LFS find -stripe-size -320k -type f $dir"
6387         nums=$($cmd | wc -l)
6388         [ $nums -eq $expected ] ||
6389                 error "'$cmd' wrong: found $nums, expected $expected"
6390
6391         expected=0
6392         cmd="$LFS find -stripe-size 1024k -type f $dir"
6393         nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396 }
6397 run_test 56t "check lfs find -stripe-size works"
6398
6399 test_56u() { # LU-611
6400         local dir=$DIR/$tdir
6401
6402         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6403
6404         if [[ $OSTCOUNT -gt 1 ]]; then
6405                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6406                 onestripe=4
6407         else
6408                 onestripe=0
6409         fi
6410
6411         local expected=$(((NUMDIRS + 1) * NUMFILES))
6412         local cmd="$LFS find -stripe-index 0 -type f $dir"
6413         local nums=$($cmd | wc -l)
6414
6415         [ $nums -eq $expected ] ||
6416                 error "'$cmd' wrong: found $nums, expected $expected"
6417
6418         expected=$onestripe
6419         cmd="$LFS find -stripe-index 1 -type f $dir"
6420         nums=$($cmd | wc -l)
6421         [ $nums -eq $expected ] ||
6422                 error "'$cmd' wrong: found $nums, expected $expected"
6423
6424         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6425         nums=$($cmd | wc -l)
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         expected=0
6430         # This should produce an error and not return any files
6431         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6432         nums=$($cmd 2>/dev/null | wc -l)
6433         [ $nums -eq $expected ] ||
6434                 error "'$cmd' wrong: found $nums, expected $expected"
6435
6436         if [[ $OSTCOUNT -gt 1 ]]; then
6437                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6438                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6439                 nums=$($cmd | wc -l)
6440                 [ $nums -eq $expected ] ||
6441                         error "'$cmd' wrong: found $nums, expected $expected"
6442         fi
6443 }
6444 run_test 56u "check lfs find -stripe-index works"
6445
6446 test_56v() {
6447         local mdt_idx=0
6448         local dir=$DIR/$tdir
6449
6450         setup_56 $dir $NUMFILES $NUMDIRS
6451
6452         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6453         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6454
6455         for file in $($LFS find -m $UUID $dir); do
6456                 file_midx=$($LFS getstripe -m $file)
6457                 [ $file_midx -eq $mdt_idx ] ||
6458                         error "lfs find -m $UUID != getstripe -m $file_midx"
6459         done
6460 }
6461 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6462
6463 test_56w() {
6464         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6466
6467         local dir=$DIR/$tdir
6468
6469         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6470
6471         local stripe_size=$($LFS getstripe -S -d $dir) ||
6472                 error "$LFS getstripe -S -d $dir failed"
6473         stripe_size=${stripe_size%% *}
6474
6475         local file_size=$((stripe_size * OSTCOUNT))
6476         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6477         local required_space=$((file_num * file_size))
6478         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6479                            head -n1)
6480         [[ $free_space -le $((required_space / 1024)) ]] &&
6481                 skip_env "need $required_space, have $free_space kbytes"
6482
6483         local dd_bs=65536
6484         local dd_count=$((file_size / dd_bs))
6485
6486         # write data into the files
6487         local i
6488         local j
6489         local file
6490
6491         for i in $(seq $NUMFILES); do
6492                 file=$dir/file$i
6493                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6494                         error "write data into $file failed"
6495         done
6496         for i in $(seq $NUMDIRS); do
6497                 for j in $(seq $NUMFILES); do
6498                         file=$dir/dir$i/file$j
6499                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6500                                 error "write data into $file failed"
6501                 done
6502         done
6503
6504         # $LFS_MIGRATE will fail if hard link migration is unsupported
6505         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6506                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6507                         error "creating links to $dir/dir1/file1 failed"
6508         fi
6509
6510         local expected=-1
6511
6512         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6513
6514         # lfs_migrate file
6515         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6516
6517         echo "$cmd"
6518         eval $cmd || error "$cmd failed"
6519
6520         check_stripe_count $dir/file1 $expected
6521
6522         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6523         then
6524                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6525                 # OST 1 if it is on OST 0. This file is small enough to
6526                 # be on only one stripe.
6527                 file=$dir/migr_1_ost
6528                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6529                         error "write data into $file failed"
6530                 local obdidx=$($LFS getstripe -i $file)
6531                 local oldmd5=$(md5sum $file)
6532                 local newobdidx=0
6533
6534                 [[ $obdidx -eq 0 ]] && newobdidx=1
6535                 cmd="$LFS migrate -i $newobdidx $file"
6536                 echo $cmd
6537                 eval $cmd || error "$cmd failed"
6538
6539                 local realobdix=$($LFS getstripe -i $file)
6540                 local newmd5=$(md5sum $file)
6541
6542                 [[ $newobdidx -ne $realobdix ]] &&
6543                         error "new OST is different (was=$obdidx, "\
6544                               "wanted=$newobdidx, got=$realobdix)"
6545                 [[ "$oldmd5" != "$newmd5" ]] &&
6546                         error "md5sum differ: $oldmd5, $newmd5"
6547         fi
6548
6549         # lfs_migrate dir
6550         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6551         echo "$cmd"
6552         eval $cmd || error "$cmd failed"
6553
6554         for j in $(seq $NUMFILES); do
6555                 check_stripe_count $dir/dir1/file$j $expected
6556         done
6557
6558         # lfs_migrate works with lfs find
6559         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6560              $LFS_MIGRATE -y -c $expected"
6561         echo "$cmd"
6562         eval $cmd || error "$cmd failed"
6563
6564         for i in $(seq 2 $NUMFILES); do
6565                 check_stripe_count $dir/file$i $expected
6566         done
6567         for i in $(seq 2 $NUMDIRS); do
6568                 for j in $(seq $NUMFILES); do
6569                 check_stripe_count $dir/dir$i/file$j $expected
6570                 done
6571         done
6572 }
6573 run_test 56w "check lfs_migrate -c stripe_count works"
6574
6575 test_56wb() {
6576         local file1=$DIR/$tdir/file1
6577         local create_pool=false
6578         local initial_pool=$($LFS getstripe -p $DIR)
6579         local pool_list=()
6580         local pool=""
6581
6582         echo -n "Creating test dir..."
6583         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6584         echo "done."
6585
6586         echo -n "Creating test file..."
6587         touch $file1 || error "cannot create file"
6588         echo "done."
6589
6590         echo -n "Detecting existing pools..."
6591         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6592
6593         if [ ${#pool_list[@]} -gt 0 ]; then
6594                 echo "${pool_list[@]}"
6595                 for thispool in "${pool_list[@]}"; do
6596                         if [[ -z "$initial_pool" ||
6597                               "$initial_pool" != "$thispool" ]]; then
6598                                 pool="$thispool"
6599                                 echo "Using existing pool '$pool'"
6600                                 break
6601                         fi
6602                 done
6603         else
6604                 echo "none detected."
6605         fi
6606         if [ -z "$pool" ]; then
6607                 pool=${POOL:-testpool}
6608                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6609                 echo -n "Creating pool '$pool'..."
6610                 create_pool=true
6611                 pool_add $pool &> /dev/null ||
6612                         error "pool_add failed"
6613                 echo "done."
6614
6615                 echo -n "Adding target to pool..."
6616                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6617                         error "pool_add_targets failed"
6618                 echo "done."
6619         fi
6620
6621         echo -n "Setting pool using -p option..."
6622         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6623                 error "migrate failed rc = $?"
6624         echo "done."
6625
6626         echo -n "Verifying test file is in pool after migrating..."
6627         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6628                 error "file was not migrated to pool $pool"
6629         echo "done."
6630
6631         echo -n "Removing test file from pool '$pool'..."
6632         # "lfs migrate $file" won't remove the file from the pool
6633         # until some striping information is changed.
6634         $LFS migrate -c 1 $file1 &> /dev/null ||
6635                 error "cannot remove from pool"
6636         [ "$($LFS getstripe -p $file1)" ] &&
6637                 error "pool still set"
6638         echo "done."
6639
6640         echo -n "Setting pool using --pool option..."
6641         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6642                 error "migrate failed rc = $?"
6643         echo "done."
6644
6645         # Clean up
6646         rm -f $file1
6647         if $create_pool; then
6648                 destroy_test_pools 2> /dev/null ||
6649                         error "destroy test pools failed"
6650         fi
6651 }
6652 run_test 56wb "check lfs_migrate pool support"
6653
6654 test_56wc() {
6655         local file1="$DIR/$tdir/file1"
6656         local parent_ssize
6657         local parent_scount
6658         local cur_ssize
6659         local cur_scount
6660         local orig_ssize
6661
6662         echo -n "Creating test dir..."
6663         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6664         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6665                 error "cannot set stripe by '-S 1M -c 1'"
6666         echo "done"
6667
6668         echo -n "Setting initial stripe for test file..."
6669         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6670                 error "cannot set stripe"
6671         cur_ssize=$($LFS getstripe -S "$file1")
6672         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6673         echo "done."
6674
6675         # File currently set to -S 512K -c 1
6676
6677         # Ensure -c and -S options are rejected when -R is set
6678         echo -n "Verifying incompatible options are detected..."
6679         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6680                 error "incompatible -c and -R options not detected"
6681         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6682                 error "incompatible -S and -R options not detected"
6683         echo "done."
6684
6685         # Ensure unrecognized options are passed through to 'lfs migrate'
6686         echo -n "Verifying -S option is passed through to lfs migrate..."
6687         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6688                 error "migration failed"
6689         cur_ssize=$($LFS getstripe -S "$file1")
6690         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6691         echo "done."
6692
6693         # File currently set to -S 1M -c 1
6694
6695         # Ensure long options are supported
6696         echo -n "Verifying long options supported..."
6697         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6698                 error "long option without argument not supported"
6699         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6700                 error "long option with argument not supported"
6701         cur_ssize=$($LFS getstripe -S "$file1")
6702         [ $cur_ssize -eq 524288 ] ||
6703                 error "migrate --stripe-size $cur_ssize != 524288"
6704         echo "done."
6705
6706         # File currently set to -S 512K -c 1
6707
6708         if [ "$OSTCOUNT" -gt 1 ]; then
6709                 echo -n "Verifying explicit stripe count can be set..."
6710                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6711                         error "migrate failed"
6712                 cur_scount=$($LFS getstripe -c "$file1")
6713                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6714                 echo "done."
6715         fi
6716
6717         # File currently set to -S 512K -c 1 or -S 512K -c 2
6718
6719         # Ensure parent striping is used if -R is set, and no stripe
6720         # count or size is specified
6721         echo -n "Setting stripe for parent directory..."
6722         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6723                 error "cannot set stripe '-S 2M -c 1'"
6724         echo "done."
6725
6726         echo -n "Verifying restripe option uses parent stripe settings..."
6727         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6728         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6729         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6730                 error "migrate failed"
6731         cur_ssize=$($LFS getstripe -S "$file1")
6732         [ $cur_ssize -eq $parent_ssize ] ||
6733                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6734         cur_scount=$($LFS getstripe -c "$file1")
6735         [ $cur_scount -eq $parent_scount ] ||
6736                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6737         echo "done."
6738
6739         # File currently set to -S 1M -c 1
6740
6741         # Ensure striping is preserved if -R is not set, and no stripe
6742         # count or size is specified
6743         echo -n "Verifying striping size preserved when not specified..."
6744         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6745         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6746                 error "cannot set stripe on parent directory"
6747         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6748                 error "migrate failed"
6749         cur_ssize=$($LFS getstripe -S "$file1")
6750         [ $cur_ssize -eq $orig_ssize ] ||
6751                 error "migrate by default $cur_ssize != $orig_ssize"
6752         echo "done."
6753
6754         # Ensure file name properly detected when final option has no argument
6755         echo -n "Verifying file name properly detected..."
6756         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6757                 error "file name interpreted as option argument"
6758         echo "done."
6759
6760         # Clean up
6761         rm -f "$file1"
6762 }
6763 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6764
6765 test_56wd() {
6766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6767
6768         local file1=$DIR/$tdir/file1
6769
6770         echo -n "Creating test dir..."
6771         test_mkdir $DIR/$tdir || error "cannot create dir"
6772         echo "done."
6773
6774         echo -n "Creating test file..."
6775         touch $file1
6776         echo "done."
6777
6778         # Ensure 'lfs migrate' will fail by using a non-existent option,
6779         # and make sure rsync is not called to recover
6780         echo -n "Make sure --no-rsync option works..."
6781         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6782                 grep -q 'refusing to fall back to rsync' ||
6783                 error "rsync was called with --no-rsync set"
6784         echo "done."
6785
6786         # Ensure rsync is called without trying 'lfs migrate' first
6787         echo -n "Make sure --rsync option works..."
6788         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6789                 grep -q 'falling back to rsync' &&
6790                 error "lfs migrate was called with --rsync set"
6791         echo "done."
6792
6793         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6794         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6795                 grep -q 'at the same time' ||
6796                 error "--rsync and --no-rsync accepted concurrently"
6797         echo "done."
6798
6799         # Clean up
6800         rm -f $file1
6801 }
6802 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6803
6804 test_56we() {
6805         local td=$DIR/$tdir
6806         local tf=$td/$tfile
6807
6808         test_mkdir $td || error "cannot create $td"
6809         touch $tf || error "cannot touch $tf"
6810
6811         echo -n "Make sure --non-direct|-D works..."
6812         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6813                 grep -q "lfs migrate --non-direct" ||
6814                 error "--non-direct option cannot work correctly"
6815         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6816                 grep -q "lfs migrate -D" ||
6817                 error "-D option cannot work correctly"
6818         echo "done."
6819 }
6820 run_test 56we "check lfs_migrate --non-direct|-D support"
6821
6822 test_56x() {
6823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6824         check_swap_layouts_support
6825
6826         local dir=$DIR/$tdir
6827         local ref1=/etc/passwd
6828         local file1=$dir/file1
6829
6830         test_mkdir $dir || error "creating dir $dir"
6831         $LFS setstripe -c 2 $file1
6832         cp $ref1 $file1
6833         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6834         stripe=$($LFS getstripe -c $file1)
6835         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6836         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6837
6838         # clean up
6839         rm -f $file1
6840 }
6841 run_test 56x "lfs migration support"
6842
6843 test_56xa() {
6844         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6845         check_swap_layouts_support
6846
6847         local dir=$DIR/$tdir/$testnum
6848
6849         test_mkdir -p $dir
6850
6851         local ref1=/etc/passwd
6852         local file1=$dir/file1
6853
6854         $LFS setstripe -c 2 $file1
6855         cp $ref1 $file1
6856         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6857
6858         local stripe=$($LFS getstripe -c $file1)
6859
6860         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6861         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6862
6863         # clean up
6864         rm -f $file1
6865 }
6866 run_test 56xa "lfs migration --block support"
6867
6868 check_migrate_links() {
6869         local dir="$1"
6870         local file1="$dir/file1"
6871         local begin="$2"
6872         local count="$3"
6873         local runas="$4"
6874         local total_count=$(($begin + $count - 1))
6875         local symlink_count=10
6876         local uniq_count=10
6877
6878         if [ ! -f "$file1" ]; then
6879                 echo -n "creating initial file..."
6880                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6881                         error "cannot setstripe initial file"
6882                 echo "done"
6883
6884                 echo -n "creating symlinks..."
6885                 for s in $(seq 1 $symlink_count); do
6886                         ln -s "$file1" "$dir/slink$s" ||
6887                                 error "cannot create symlinks"
6888                 done
6889                 echo "done"
6890
6891                 echo -n "creating nonlinked files..."
6892                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6893                         error "cannot create nonlinked files"
6894                 echo "done"
6895         fi
6896
6897         # create hard links
6898         if [ ! -f "$dir/file$total_count" ]; then
6899                 echo -n "creating hard links $begin:$total_count..."
6900                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6901                         /dev/null || error "cannot create hard links"
6902                 echo "done"
6903         fi
6904
6905         echo -n "checking number of hard links listed in xattrs..."
6906         local fid=$($LFS getstripe -F "$file1")
6907         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6908
6909         echo "${#paths[*]}"
6910         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6911                         skip "hard link list has unexpected size, skipping test"
6912         fi
6913         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6914                         error "link names should exceed xattrs size"
6915         fi
6916
6917         echo -n "migrating files..."
6918         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6919         local rc=$?
6920         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6921         echo "done"
6922
6923         # make sure all links have been properly migrated
6924         echo -n "verifying files..."
6925         fid=$($LFS getstripe -F "$file1") ||
6926                 error "cannot get fid for file $file1"
6927         for i in $(seq 2 $total_count); do
6928                 local fid2=$($LFS getstripe -F $dir/file$i)
6929
6930                 [ "$fid2" == "$fid" ] ||
6931                         error "migrated hard link has mismatched FID"
6932         done
6933
6934         # make sure hard links were properly detected, and migration was
6935         # performed only once for the entire link set; nonlinked files should
6936         # also be migrated
6937         local actual=$(grep -c 'done' <<< "$migrate_out")
6938         local expected=$(($uniq_count + 1))
6939
6940         [ "$actual" -eq  "$expected" ] ||
6941                 error "hard links individually migrated ($actual != $expected)"
6942
6943         # make sure the correct number of hard links are present
6944         local hardlinks=$(stat -c '%h' "$file1")
6945
6946         [ $hardlinks -eq $total_count ] ||
6947                 error "num hard links $hardlinks != $total_count"
6948         echo "done"
6949
6950         return 0
6951 }
6952
6953 test_56xb() {
6954         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6955                 skip "Need MDS version at least 2.10.55"
6956
6957         local dir="$DIR/$tdir"
6958
6959         test_mkdir "$dir" || error "cannot create dir $dir"
6960
6961         echo "testing lfs migrate mode when all links fit within xattrs"
6962         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6963
6964         echo "testing rsync mode when all links fit within xattrs"
6965         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6966
6967         echo "testing lfs migrate mode when all links do not fit within xattrs"
6968         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6969
6970         echo "testing rsync mode when all links do not fit within xattrs"
6971         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6972
6973         chown -R $RUNAS_ID $dir
6974         echo "testing non-root lfs migrate mode when not all links are in xattr"
6975         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6976
6977         # clean up
6978         rm -rf $dir
6979 }
6980 run_test 56xb "lfs migration hard link support"
6981
6982 test_56xc() {
6983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6984
6985         local dir="$DIR/$tdir"
6986
6987         test_mkdir "$dir" || error "cannot create dir $dir"
6988
6989         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6990         echo -n "Setting initial stripe for 20MB test file..."
6991         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6992                 error "cannot setstripe 20MB file"
6993         echo "done"
6994         echo -n "Sizing 20MB test file..."
6995         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6996         echo "done"
6997         echo -n "Verifying small file autostripe count is 1..."
6998         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6999                 error "cannot migrate 20MB file"
7000         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7001                 error "cannot get stripe for $dir/20mb"
7002         [ $stripe_count -eq 1 ] ||
7003                 error "unexpected stripe count $stripe_count for 20MB file"
7004         rm -f "$dir/20mb"
7005         echo "done"
7006
7007         # Test 2: File is small enough to fit within the available space on
7008         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7009         # have at least an additional 1KB for each desired stripe for test 3
7010         echo -n "Setting stripe for 1GB test file..."
7011         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7012         echo "done"
7013         echo -n "Sizing 1GB test file..."
7014         # File size is 1GB + 3KB
7015         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7016         echo "done"
7017
7018         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7019         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7020         if (( avail > 524288 * OSTCOUNT )); then
7021                 echo -n "Migrating 1GB file..."
7022                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7023                         error "cannot migrate 1GB file"
7024                 echo "done"
7025                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7026                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7027                         error "cannot getstripe for 1GB file"
7028                 [ $stripe_count -eq 2 ] ||
7029                         error "unexpected stripe count $stripe_count != 2"
7030                 echo "done"
7031         fi
7032
7033         # Test 3: File is too large to fit within the available space on
7034         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7035         if [ $OSTCOUNT -ge 3 ]; then
7036                 # The required available space is calculated as
7037                 # file size (1GB + 3KB) / OST count (3).
7038                 local kb_per_ost=349526
7039
7040                 echo -n "Migrating 1GB file with limit..."
7041                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7042                         error "cannot migrate 1GB file with limit"
7043                 echo "done"
7044
7045                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7046                 echo -n "Verifying 1GB autostripe count with limited space..."
7047                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7048                         error "unexpected stripe count $stripe_count (min 3)"
7049                 echo "done"
7050         fi
7051
7052         # clean up
7053         rm -rf $dir
7054 }
7055 run_test 56xc "lfs migration autostripe"
7056
7057 test_56xd() {
7058         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7059
7060         local dir=$DIR/$tdir
7061         local f_mgrt=$dir/$tfile.mgrt
7062         local f_yaml=$dir/$tfile.yaml
7063         local f_copy=$dir/$tfile.copy
7064         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7065         local layout_copy="-c 2 -S 2M -i 1"
7066         local yamlfile=$dir/yamlfile
7067         local layout_before;
7068         local layout_after;
7069
7070         test_mkdir "$dir" || error "cannot create dir $dir"
7071         $LFS setstripe $layout_yaml $f_yaml ||
7072                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7073         $LFS getstripe --yaml $f_yaml > $yamlfile
7074         $LFS setstripe $layout_copy $f_copy ||
7075                 error "cannot setstripe $f_copy with layout $layout_copy"
7076         touch $f_mgrt
7077         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7078
7079         # 1. test option --yaml
7080         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7081                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7082         layout_before=$(get_layout_param $f_yaml)
7083         layout_after=$(get_layout_param $f_mgrt)
7084         [ "$layout_after" == "$layout_before" ] ||
7085                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7086
7087         # 2. test option --copy
7088         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7089                 error "cannot migrate $f_mgrt with --copy $f_copy"
7090         layout_before=$(get_layout_param $f_copy)
7091         layout_after=$(get_layout_param $f_mgrt)
7092         [ "$layout_after" == "$layout_before" ] ||
7093                 error "lfs_migrate --copy: $layout_after != $layout_before"
7094 }
7095 run_test 56xd "check lfs_migrate --yaml and --copy support"
7096
7097 test_56xe() {
7098         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7099
7100         local dir=$DIR/$tdir
7101         local f_comp=$dir/$tfile
7102         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7103         local layout_before=""
7104         local layout_after=""
7105
7106         test_mkdir "$dir" || error "cannot create dir $dir"
7107         $LFS setstripe $layout $f_comp ||
7108                 error "cannot setstripe $f_comp with layout $layout"
7109         layout_before=$(get_layout_param $f_comp)
7110         dd if=/dev/zero of=$f_comp bs=1M count=4
7111
7112         # 1. migrate a comp layout file by lfs_migrate
7113         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7114         layout_after=$(get_layout_param $f_comp)
7115         [ "$layout_before" == "$layout_after" ] ||
7116                 error "lfs_migrate: $layout_before != $layout_after"
7117
7118         # 2. migrate a comp layout file by lfs migrate
7119         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7120         layout_after=$(get_layout_param $f_comp)
7121         [ "$layout_before" == "$layout_after" ] ||
7122                 error "lfs migrate: $layout_before != $layout_after"
7123 }
7124 run_test 56xe "migrate a composite layout file"
7125
7126 test_56xf() {
7127         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7128
7129         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7130                 skip "Need server version at least 2.13.53"
7131
7132         local dir=$DIR/$tdir
7133         local f_comp=$dir/$tfile
7134         local layout="-E 1M -c1 -E -1 -c2"
7135         local fid_before=""
7136         local fid_after=""
7137
7138         test_mkdir "$dir" || error "cannot create dir $dir"
7139         $LFS setstripe $layout $f_comp ||
7140                 error "cannot setstripe $f_comp with layout $layout"
7141         fid_before=$($LFS getstripe --fid $f_comp)
7142         dd if=/dev/zero of=$f_comp bs=1M count=4
7143
7144         # 1. migrate a comp layout file to a comp layout
7145         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7146         fid_after=$($LFS getstripe --fid $f_comp)
7147         [ "$fid_before" == "$fid_after" ] ||
7148                 error "comp-to-comp migrate: $fid_before != $fid_after"
7149
7150         # 2. migrate a comp layout file to a plain layout
7151         $LFS migrate -c2 $f_comp ||
7152                 error "cannot migrate $f_comp by lfs migrate"
7153         fid_after=$($LFS getstripe --fid $f_comp)
7154         [ "$fid_before" == "$fid_after" ] ||
7155                 error "comp-to-plain migrate: $fid_before != $fid_after"
7156
7157         # 3. migrate a plain layout file to a comp layout
7158         $LFS migrate $layout $f_comp ||
7159                 error "cannot migrate $f_comp by lfs migrate"
7160         fid_after=$($LFS getstripe --fid $f_comp)
7161         [ "$fid_before" == "$fid_after" ] ||
7162                 error "plain-to-comp migrate: $fid_before != $fid_after"
7163 }
7164 run_test 56xf "FID is not lost during migration of a composite layout file"
7165
7166 test_56y() {
7167         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7168                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7169
7170         local res=""
7171         local dir=$DIR/$tdir
7172         local f1=$dir/file1
7173         local f2=$dir/file2
7174
7175         test_mkdir -p $dir || error "creating dir $dir"
7176         touch $f1 || error "creating std file $f1"
7177         $MULTIOP $f2 H2c || error "creating released file $f2"
7178
7179         # a directory can be raid0, so ask only for files
7180         res=$($LFS find $dir -L raid0 -type f | wc -l)
7181         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7182
7183         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7184         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7185
7186         # only files can be released, so no need to force file search
7187         res=$($LFS find $dir -L released)
7188         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7189
7190         res=$($LFS find $dir -type f \! -L released)
7191         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7192 }
7193 run_test 56y "lfs find -L raid0|released"
7194
7195 test_56z() { # LU-4824
7196         # This checks to make sure 'lfs find' continues after errors
7197         # There are two classes of errors that should be caught:
7198         # - If multiple paths are provided, all should be searched even if one
7199         #   errors out
7200         # - If errors are encountered during the search, it should not terminate
7201         #   early
7202         local dir=$DIR/$tdir
7203         local i
7204
7205         test_mkdir $dir
7206         for i in d{0..9}; do
7207                 test_mkdir $dir/$i
7208                 touch $dir/$i/$tfile
7209         done
7210         $LFS find $DIR/non_existent_dir $dir &&
7211                 error "$LFS find did not return an error"
7212         # Make a directory unsearchable. This should NOT be the last entry in
7213         # directory order.  Arbitrarily pick the 6th entry
7214         chmod 700 $($LFS find $dir -type d | sed '6!d')
7215
7216         $RUNAS $LFS find $DIR/non_existent $dir
7217         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7218
7219         # The user should be able to see 10 directories and 9 files
7220         (( count == 19 )) ||
7221                 error "$LFS find found $count != 19 entries after error"
7222 }
7223 run_test 56z "lfs find should continue after an error"
7224
7225 test_56aa() { # LU-5937
7226         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7227
7228         local dir=$DIR/$tdir
7229
7230         mkdir $dir
7231         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7232
7233         createmany -o $dir/striped_dir/${tfile}- 1024
7234         local dirs=$($LFS find --size +8k $dir/)
7235
7236         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7237 }
7238 run_test 56aa "lfs find --size under striped dir"
7239
7240 test_56ab() { # LU-10705
7241         test_mkdir $DIR/$tdir
7242         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7243         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7244         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7245         # Flush writes to ensure valid blocks.  Need to be more thorough for
7246         # ZFS, since blocks are not allocated/returned to client immediately.
7247         sync_all_data
7248         wait_zfs_commit ost1 2
7249         cancel_lru_locks osc
7250         ls -ls $DIR/$tdir
7251
7252         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7253
7254         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7255
7256         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7257         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7258
7259         rm -f $DIR/$tdir/$tfile.[123]
7260 }
7261 run_test 56ab "lfs find --blocks"
7262
7263 test_56ba() {
7264         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7265                 skip "Need MDS version at least 2.10.50"
7266
7267         # Create composite files with one component
7268         local dir=$DIR/$tdir
7269
7270         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7271         # Create composite files with three components
7272         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7273         # Create non-composite files
7274         createmany -o $dir/${tfile}- 10
7275
7276         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7277
7278         [[ $nfiles == 10 ]] ||
7279                 error "lfs find -E 1M found $nfiles != 10 files"
7280
7281         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7282         [[ $nfiles == 25 ]] ||
7283                 error "lfs find ! -E 1M found $nfiles != 25 files"
7284
7285         # All files have a component that starts at 0
7286         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7287         [[ $nfiles == 35 ]] ||
7288                 error "lfs find --component-start 0 - $nfiles != 35 files"
7289
7290         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7291         [[ $nfiles == 15 ]] ||
7292                 error "lfs find --component-start 2M - $nfiles != 15 files"
7293
7294         # All files created here have a componenet that does not starts at 2M
7295         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7296         [[ $nfiles == 35 ]] ||
7297                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7298
7299         # Find files with a specified number of components
7300         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7301         [[ $nfiles == 15 ]] ||
7302                 error "lfs find --component-count 3 - $nfiles != 15 files"
7303
7304         # Remember non-composite files have a component count of zero
7305         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7306         [[ $nfiles == 10 ]] ||
7307                 error "lfs find --component-count 0 - $nfiles != 10 files"
7308
7309         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7310         [[ $nfiles == 20 ]] ||
7311                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7312
7313         # All files have a flag called "init"
7314         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7315         [[ $nfiles == 35 ]] ||
7316                 error "lfs find --component-flags init - $nfiles != 35 files"
7317
7318         # Multi-component files will have a component not initialized
7319         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7320         [[ $nfiles == 15 ]] ||
7321                 error "lfs find !--component-flags init - $nfiles != 15 files"
7322
7323         rm -rf $dir
7324
7325 }
7326 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7327
7328 test_56ca() {
7329         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7330                 skip "Need MDS version at least 2.10.57"
7331
7332         local td=$DIR/$tdir
7333         local tf=$td/$tfile
7334         local dir
7335         local nfiles
7336         local cmd
7337         local i
7338         local j
7339
7340         # create mirrored directories and mirrored files
7341         mkdir $td || error "mkdir $td failed"
7342         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7343         createmany -o $tf- 10 || error "create $tf- failed"
7344
7345         for i in $(seq 2); do
7346                 dir=$td/dir$i
7347                 mkdir $dir || error "mkdir $dir failed"
7348                 $LFS mirror create -N$((3 + i)) $dir ||
7349                         error "create mirrored dir $dir failed"
7350                 createmany -o $dir/$tfile- 10 ||
7351                         error "create $dir/$tfile- failed"
7352         done
7353
7354         # change the states of some mirrored files
7355         echo foo > $tf-6
7356         for i in $(seq 2); do
7357                 dir=$td/dir$i
7358                 for j in $(seq 4 9); do
7359                         echo foo > $dir/$tfile-$j
7360                 done
7361         done
7362
7363         # find mirrored files with specific mirror count
7364         cmd="$LFS find --mirror-count 3 --type f $td"
7365         nfiles=$($cmd | wc -l)
7366         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7367
7368         cmd="$LFS find ! --mirror-count 3 --type f $td"
7369         nfiles=$($cmd | wc -l)
7370         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7371
7372         cmd="$LFS find --mirror-count +2 --type f $td"
7373         nfiles=$($cmd | wc -l)
7374         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7375
7376         cmd="$LFS find --mirror-count -6 --type f $td"
7377         nfiles=$($cmd | wc -l)
7378         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7379
7380         # find mirrored files with specific file state
7381         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7382         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7383
7384         cmd="$LFS find --mirror-state=ro --type f $td"
7385         nfiles=$($cmd | wc -l)
7386         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7387
7388         cmd="$LFS find ! --mirror-state=ro --type f $td"
7389         nfiles=$($cmd | wc -l)
7390         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7391
7392         cmd="$LFS find --mirror-state=wp --type f $td"
7393         nfiles=$($cmd | wc -l)
7394         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7395
7396         cmd="$LFS find ! --mirror-state=sp --type f $td"
7397         nfiles=$($cmd | wc -l)
7398         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7399 }
7400 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7401
7402 test_57a() {
7403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7404         # note test will not do anything if MDS is not local
7405         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7406                 skip_env "ldiskfs only test"
7407         fi
7408         remote_mds_nodsh && skip "remote MDS with nodsh"
7409
7410         local MNTDEV="osd*.*MDT*.mntdev"
7411         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7412         [ -z "$DEV" ] && error "can't access $MNTDEV"
7413         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7414                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7415                         error "can't access $DEV"
7416                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7417                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7418                 rm $TMP/t57a.dump
7419         done
7420 }
7421 run_test 57a "verify MDS filesystem created with large inodes =="
7422
7423 test_57b() {
7424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7425         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7426                 skip_env "ldiskfs only test"
7427         fi
7428         remote_mds_nodsh && skip "remote MDS with nodsh"
7429
7430         local dir=$DIR/$tdir
7431         local filecount=100
7432         local file1=$dir/f1
7433         local fileN=$dir/f$filecount
7434
7435         rm -rf $dir || error "removing $dir"
7436         test_mkdir -c1 $dir
7437         local mdtidx=$($LFS getstripe -m $dir)
7438         local mdtname=MDT$(printf %04x $mdtidx)
7439         local facet=mds$((mdtidx + 1))
7440
7441         echo "mcreating $filecount files"
7442         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7443
7444         # verify that files do not have EAs yet
7445         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7446                 error "$file1 has an EA"
7447         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7448                 error "$fileN has an EA"
7449
7450         sync
7451         sleep 1
7452         df $dir  #make sure we get new statfs data
7453         local mdsfree=$(do_facet $facet \
7454                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7455         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7456         local file
7457
7458         echo "opening files to create objects/EAs"
7459         for file in $(seq -f $dir/f%g 1 $filecount); do
7460                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7461                         error "opening $file"
7462         done
7463
7464         # verify that files have EAs now
7465         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7466         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7467
7468         sleep 1  #make sure we get new statfs data
7469         df $dir
7470         local mdsfree2=$(do_facet $facet \
7471                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7472         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7473
7474         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7475                 if [ "$mdsfree" != "$mdsfree2" ]; then
7476                         error "MDC before $mdcfree != after $mdcfree2"
7477                 else
7478                         echo "MDC before $mdcfree != after $mdcfree2"
7479                         echo "unable to confirm if MDS has large inodes"
7480                 fi
7481         fi
7482         rm -rf $dir
7483 }
7484 run_test 57b "default LOV EAs are stored inside large inodes ==="
7485
7486 test_58() {
7487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7488         [ -z "$(which wiretest 2>/dev/null)" ] &&
7489                         skip_env "could not find wiretest"
7490
7491         wiretest
7492 }
7493 run_test 58 "verify cross-platform wire constants =============="
7494
7495 test_59() {
7496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7497
7498         echo "touch 130 files"
7499         createmany -o $DIR/f59- 130
7500         echo "rm 130 files"
7501         unlinkmany $DIR/f59- 130
7502         sync
7503         # wait for commitment of removal
7504         wait_delete_completed
7505 }
7506 run_test 59 "verify cancellation of llog records async ========="
7507
7508 TEST60_HEAD="test_60 run $RANDOM"
7509 test_60a() {
7510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7511         remote_mgs_nodsh && skip "remote MGS with nodsh"
7512         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7513                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7514                         skip_env "missing subtest run-llog.sh"
7515
7516         log "$TEST60_HEAD - from kernel mode"
7517         do_facet mgs "$LCTL dk > /dev/null"
7518         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7519         do_facet mgs $LCTL dk > $TMP/$tfile
7520
7521         # LU-6388: test llog_reader
7522         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7523         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7524         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7525                         skip_env "missing llog_reader"
7526         local fstype=$(facet_fstype mgs)
7527         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7528                 skip_env "Only for ldiskfs or zfs type mgs"
7529
7530         local mntpt=$(facet_mntpt mgs)
7531         local mgsdev=$(mgsdevname 1)
7532         local fid_list
7533         local fid
7534         local rec_list
7535         local rec
7536         local rec_type
7537         local obj_file
7538         local path
7539         local seq
7540         local oid
7541         local pass=true
7542
7543         #get fid and record list
7544         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7545                 tail -n 4))
7546         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7547                 tail -n 4))
7548         #remount mgs as ldiskfs or zfs type
7549         stop mgs || error "stop mgs failed"
7550         mount_fstype mgs || error "remount mgs failed"
7551         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7552                 fid=${fid_list[i]}
7553                 rec=${rec_list[i]}
7554                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7555                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7556                 oid=$((16#$oid))
7557
7558                 case $fstype in
7559                         ldiskfs )
7560                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7561                         zfs )
7562                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7563                 esac
7564                 echo "obj_file is $obj_file"
7565                 do_facet mgs $llog_reader $obj_file
7566
7567                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7568                         awk '{ print $3 }' | sed -e "s/^type=//g")
7569                 if [ $rec_type != $rec ]; then
7570                         echo "FAILED test_60a wrong record type $rec_type," \
7571                               "should be $rec"
7572                         pass=false
7573                         break
7574                 fi
7575
7576                 #check obj path if record type is LLOG_LOGID_MAGIC
7577                 if [ "$rec" == "1064553b" ]; then
7578                         path=$(do_facet mgs $llog_reader $obj_file |
7579                                 grep "path=" | awk '{ print $NF }' |
7580                                 sed -e "s/^path=//g")
7581                         if [ $obj_file != $mntpt/$path ]; then
7582                                 echo "FAILED test_60a wrong obj path" \
7583                                       "$montpt/$path, should be $obj_file"
7584                                 pass=false
7585                                 break
7586                         fi
7587                 fi
7588         done
7589         rm -f $TMP/$tfile
7590         #restart mgs before "error", otherwise it will block the next test
7591         stop mgs || error "stop mgs failed"
7592         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7593         $pass || error "test failed, see FAILED test_60a messages for specifics"
7594 }
7595 run_test 60a "llog_test run from kernel module and test llog_reader"
7596
7597 test_60b() { # bug 6411
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599
7600         dmesg > $DIR/$tfile
7601         LLOG_COUNT=$(do_facet mgs dmesg |
7602                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7603                           /llog_[a-z]*.c:[0-9]/ {
7604                                 if (marker)
7605                                         from_marker++
7606                                 from_begin++
7607                           }
7608                           END {
7609                                 if (marker)
7610                                         print from_marker
7611                                 else
7612                                         print from_begin
7613                           }")
7614
7615         [[ $LLOG_COUNT -gt 120 ]] &&
7616                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7617 }
7618 run_test 60b "limit repeated messages from CERROR/CWARN"
7619
7620 test_60c() {
7621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7622
7623         echo "create 5000 files"
7624         createmany -o $DIR/f60c- 5000
7625 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7626         lctl set_param fail_loc=0x80000137
7627         unlinkmany $DIR/f60c- 5000
7628         lctl set_param fail_loc=0
7629 }
7630 run_test 60c "unlink file when mds full"
7631
7632 test_60d() {
7633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7634
7635         SAVEPRINTK=$(lctl get_param -n printk)
7636         # verify "lctl mark" is even working"
7637         MESSAGE="test message ID $RANDOM $$"
7638         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7639         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7640
7641         lctl set_param printk=0 || error "set lnet.printk failed"
7642         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7643         MESSAGE="new test message ID $RANDOM $$"
7644         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7645         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7646         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7647
7648         lctl set_param -n printk="$SAVEPRINTK"
7649 }
7650 run_test 60d "test printk console message masking"
7651
7652 test_60e() {
7653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7654         remote_mds_nodsh && skip "remote MDS with nodsh"
7655
7656         touch $DIR/$tfile
7657 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7658         do_facet mds1 lctl set_param fail_loc=0x15b
7659         rm $DIR/$tfile
7660 }
7661 run_test 60e "no space while new llog is being created"
7662
7663 test_60g() {
7664         local pid
7665         local i
7666
7667         test_mkdir -c $MDSCOUNT $DIR/$tdir
7668
7669         (
7670                 local index=0
7671                 while true; do
7672                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7673                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7674                                 2>/dev/null
7675                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7676                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7677                         index=$((index + 1))
7678                 done
7679         ) &
7680
7681         pid=$!
7682
7683         for i in {0..100}; do
7684                 # define OBD_FAIL_OSD_TXN_START    0x19a
7685                 local index=$((i % MDSCOUNT + 1))
7686
7687                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7688                         > /dev/null
7689                 usleep 100
7690         done
7691
7692         kill -9 $pid
7693
7694         for i in $(seq $MDSCOUNT); do
7695                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7696         done
7697
7698         mkdir $DIR/$tdir/new || error "mkdir failed"
7699         rmdir $DIR/$tdir/new || error "rmdir failed"
7700
7701         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7702                 -t namespace
7703         for i in $(seq $MDSCOUNT); do
7704                 wait_update_facet mds$i "$LCTL get_param -n \
7705                         mdd.$(facet_svc mds$i).lfsck_namespace |
7706                         awk '/^status/ { print \\\$2 }'" "completed"
7707         done
7708
7709         ls -R $DIR/$tdir || error "ls failed"
7710         rm -rf $DIR/$tdir || error "rmdir failed"
7711 }
7712 run_test 60g "transaction abort won't cause MDT hung"
7713
7714 test_60h() {
7715         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7716                 skip "Need MDS version at least 2.12.52"
7717         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7718
7719         local f
7720
7721         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7722         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7723         for fail_loc in 0x80000188 0x80000189; do
7724                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7725                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7726                         error "mkdir $dir-$fail_loc failed"
7727                 for i in {0..10}; do
7728                         # create may fail on missing stripe
7729                         echo $i > $DIR/$tdir-$fail_loc/$i
7730                 done
7731                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7732                         error "getdirstripe $tdir-$fail_loc failed"
7733                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7734                         error "migrate $tdir-$fail_loc failed"
7735                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7736                         error "getdirstripe $tdir-$fail_loc failed"
7737                 pushd $DIR/$tdir-$fail_loc
7738                 for f in *; do
7739                         echo $f | cmp $f - || error "$f data mismatch"
7740                 done
7741                 popd
7742                 rm -rf $DIR/$tdir-$fail_loc
7743         done
7744 }
7745 run_test 60h "striped directory with missing stripes can be accessed"
7746
7747 test_61a() {
7748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7749
7750         f="$DIR/f61"
7751         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7752         cancel_lru_locks osc
7753         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7754         sync
7755 }
7756 run_test 61a "mmap() writes don't make sync hang ================"
7757
7758 test_61b() {
7759         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7760 }
7761 run_test 61b "mmap() of unstriped file is successful"
7762
7763 # bug 2330 - insufficient obd_match error checking causes LBUG
7764 test_62() {
7765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7766
7767         f="$DIR/f62"
7768         echo foo > $f
7769         cancel_lru_locks osc
7770         lctl set_param fail_loc=0x405
7771         cat $f && error "cat succeeded, expect -EIO"
7772         lctl set_param fail_loc=0
7773 }
7774 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7775 # match every page all of the time.
7776 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7777
7778 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7779 # Though this test is irrelevant anymore, it helped to reveal some
7780 # other grant bugs (LU-4482), let's keep it.
7781 test_63a() {   # was test_63
7782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7783
7784         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7785
7786         for i in `seq 10` ; do
7787                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7788                 sleep 5
7789                 kill $!
7790                 sleep 1
7791         done
7792
7793         rm -f $DIR/f63 || true
7794 }
7795 run_test 63a "Verify oig_wait interruption does not crash ======="
7796
7797 # bug 2248 - async write errors didn't return to application on sync
7798 # bug 3677 - async write errors left page locked
7799 test_63b() {
7800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7801
7802         debugsave
7803         lctl set_param debug=-1
7804
7805         # ensure we have a grant to do async writes
7806         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7807         rm $DIR/$tfile
7808
7809         sync    # sync lest earlier test intercept the fail_loc
7810
7811         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7812         lctl set_param fail_loc=0x80000406
7813         $MULTIOP $DIR/$tfile Owy && \
7814                 error "sync didn't return ENOMEM"
7815         sync; sleep 2; sync     # do a real sync this time to flush page
7816         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7817                 error "locked page left in cache after async error" || true
7818         debugrestore
7819 }
7820 run_test 63b "async write errors should be returned to fsync ==="
7821
7822 test_64a () {
7823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7824
7825         lfs df $DIR
7826         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7827 }
7828 run_test 64a "verify filter grant calculations (in kernel) ====="
7829
7830 test_64b () {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7834 }
7835 run_test 64b "check out-of-space detection on client"
7836
7837 test_64c() {
7838         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7839 }
7840 run_test 64c "verify grant shrink"
7841
7842 import_param() {
7843         local tgt=$1
7844         local param=$2
7845
7846         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7847 }
7848
7849 # this does exactly what osc_request.c:osc_announce_cached() does in
7850 # order to calculate max amount of grants to ask from server
7851 want_grant() {
7852         local tgt=$1
7853
7854         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7855         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7856
7857         ((rpc_in_flight++));
7858         nrpages=$((nrpages * rpc_in_flight))
7859
7860         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7861
7862         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7863
7864         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7865         local undirty=$((nrpages * PAGE_SIZE))
7866
7867         local max_extent_pages
7868         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7869         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7870         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7871         local grant_extent_tax
7872         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7873
7874         undirty=$((undirty + nrextents * grant_extent_tax))
7875
7876         echo $undirty
7877 }
7878
7879 # this is size of unit for grant allocation. It should be equal to
7880 # what tgt_grant.c:tgt_grant_chunk() calculates
7881 grant_chunk() {
7882         local tgt=$1
7883         local max_brw_size
7884         local grant_extent_tax
7885
7886         max_brw_size=$(import_param $tgt max_brw_size)
7887
7888         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7889
7890         echo $(((max_brw_size + grant_extent_tax) * 2))
7891 }
7892
7893 test_64d() {
7894         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7895                 skip "OST < 2.10.55 doesn't limit grants enough"
7896
7897         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7898
7899         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7900                 skip "no grant_param connect flag"
7901
7902         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7903
7904         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7905         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7906
7907
7908         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7909         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7910
7911         $LFS setstripe $DIR/$tfile -i 0 -c 1
7912         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7913         ddpid=$!
7914
7915         while kill -0 $ddpid; do
7916                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7917
7918                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7919                         kill $ddpid
7920                         error "cur_grant $cur_grant > $max_cur_granted"
7921                 fi
7922
7923                 sleep 1
7924         done
7925 }
7926 run_test 64d "check grant limit exceed"
7927
7928 check_grants() {
7929         local tgt=$1
7930         local expected=$2
7931         local msg=$3
7932         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7933
7934         ((cur_grants == expected)) ||
7935                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7936 }
7937
7938 round_up_p2() {
7939         echo $((($1 + $2 - 1) & ~($2 - 1)))
7940 }
7941
7942 test_64e() {
7943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7944         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7945                 skip "Need OSS version at least 2.11.56"
7946
7947         # Remount client to reset grant
7948         remount_client $MOUNT || error "failed to remount client"
7949         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7950
7951         local init_grants=$(import_param $osc_tgt initial_grant)
7952
7953         check_grants $osc_tgt $init_grants "init grants"
7954
7955         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7956         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7957         local gbs=$(import_param $osc_tgt grant_block_size)
7958
7959         # write random number of bytes from max_brw_size / 4 to max_brw_size
7960         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7961         # align for direct io
7962         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7963         # round to grant consumption unit
7964         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7965
7966         local grants=$((wb_round_up + extent_tax))
7967
7968         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
7969
7970         # define OBD_FAIL_TGT_NO_GRANT 0x725
7971         # make the server not grant more back
7972         do_facet ost1 $LCTL set_param fail_loc=0x725
7973         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
7974
7975         do_facet ost1 $LCTL set_param fail_loc=0
7976
7977         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
7978
7979         rm -f $DIR/$tfile || error "rm failed"
7980
7981         # Remount client to reset grant
7982         remount_client $MOUNT || error "failed to remount client"
7983         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7984
7985         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
7986
7987         # define OBD_FAIL_TGT_NO_GRANT 0x725
7988         # make the server not grant more back
7989         do_facet ost1 $LCTL set_param fail_loc=0x725
7990         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
7991         do_facet ost1 $LCTL set_param fail_loc=0
7992
7993         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
7994 }
7995 run_test 64e "check grant consumption (no grant allocation)"
7996
7997 test_64f() {
7998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7999
8000         # Remount client to reset grant
8001         remount_client $MOUNT || error "failed to remount client"
8002         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8003
8004         local init_grants=$(import_param $osc_tgt initial_grant)
8005         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8006         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8007         local gbs=$(import_param $osc_tgt grant_block_size)
8008         local chunk=$(grant_chunk $osc_tgt)
8009
8010         # write random number of bytes from max_brw_size / 4 to max_brw_size
8011         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8012         # align for direct io
8013         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8014         # round to grant consumption unit
8015         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8016
8017         local grants=$((wb_round_up + extent_tax))
8018
8019         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8020         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8021                 error "error writing to $DIR/$tfile"
8022
8023         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8024                 "direct io with grant allocation"
8025
8026         rm -f $DIR/$tfile || error "rm failed"
8027
8028         # Remount client to reset grant
8029         remount_client $MOUNT || error "failed to remount client"
8030         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8031
8032         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8033
8034         local cmd="oO_WRONLY:w${write_bytes}_yc"
8035
8036         $MULTIOP $DIR/$tfile $cmd &
8037         MULTIPID=$!
8038         sleep 1
8039
8040         check_grants $osc_tgt $((init_grants - grants)) \
8041                 "buffered io, not write rpc"
8042
8043         kill -USR1 $MULTIPID
8044         wait
8045
8046         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8047                 "buffered io, one RPC"
8048 }
8049 run_test 64f "check grant consumption (with grant allocation)"
8050
8051 # bug 1414 - set/get directories' stripe info
8052 test_65a() {
8053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8054
8055         test_mkdir $DIR/$tdir
8056         touch $DIR/$tdir/f1
8057         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8058 }
8059 run_test 65a "directory with no stripe info"
8060
8061 test_65b() {
8062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8063
8064         test_mkdir $DIR/$tdir
8065         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8066
8067         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8068                                                 error "setstripe"
8069         touch $DIR/$tdir/f2
8070         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8071 }
8072 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8073
8074 test_65c() {
8075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8076         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8077
8078         test_mkdir $DIR/$tdir
8079         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8080
8081         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8082                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8083         touch $DIR/$tdir/f3
8084         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8085 }
8086 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8087
8088 test_65d() {
8089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8090
8091         test_mkdir $DIR/$tdir
8092         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8093         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8094
8095         if [[ $STRIPECOUNT -le 0 ]]; then
8096                 sc=1
8097         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8098                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8099                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8100         else
8101                 sc=$(($STRIPECOUNT - 1))
8102         fi
8103         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8104         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8105         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8106                 error "lverify failed"
8107 }
8108 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8109
8110 test_65e() {
8111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8112
8113         test_mkdir $DIR/$tdir
8114
8115         $LFS setstripe $DIR/$tdir || error "setstripe"
8116         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8117                                         error "no stripe info failed"
8118         touch $DIR/$tdir/f6
8119         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8120 }
8121 run_test 65e "directory setstripe defaults"
8122
8123 test_65f() {
8124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8125
8126         test_mkdir $DIR/${tdir}f
8127         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8128                 error "setstripe succeeded" || true
8129 }
8130 run_test 65f "dir setstripe permission (should return error) ==="
8131
8132 test_65g() {
8133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8134
8135         test_mkdir $DIR/$tdir
8136         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8137
8138         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8139                 error "setstripe -S failed"
8140         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8141         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8142                 error "delete default stripe failed"
8143 }
8144 run_test 65g "directory setstripe -d"
8145
8146 test_65h() {
8147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8148
8149         test_mkdir $DIR/$tdir
8150         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8151
8152         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8153                 error "setstripe -S failed"
8154         test_mkdir $DIR/$tdir/dd1
8155         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8156                 error "stripe info inherit failed"
8157 }
8158 run_test 65h "directory stripe info inherit ===================="
8159
8160 test_65i() {
8161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8162
8163         save_layout_restore_at_exit $MOUNT
8164
8165         # bug6367: set non-default striping on root directory
8166         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8167
8168         # bug12836: getstripe on -1 default directory striping
8169         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8170
8171         # bug12836: getstripe -v on -1 default directory striping
8172         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8173
8174         # bug12836: new find on -1 default directory striping
8175         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8176 }
8177 run_test 65i "various tests to set root directory striping"
8178
8179 test_65j() { # bug6367
8180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8181
8182         sync; sleep 1
8183
8184         # if we aren't already remounting for each test, do so for this test
8185         if [ "$I_MOUNTED" = "yes" ]; then
8186                 cleanup || error "failed to unmount"
8187                 setup
8188         fi
8189
8190         save_layout_restore_at_exit $MOUNT
8191
8192         $LFS setstripe -d $MOUNT || error "setstripe failed"
8193 }
8194 run_test 65j "set default striping on root directory (bug 6367)="
8195
8196 cleanup_65k() {
8197         rm -rf $DIR/$tdir
8198         wait_delete_completed
8199         do_facet $SINGLEMDS "lctl set_param -n \
8200                 osp.$ost*MDT0000.max_create_count=$max_count"
8201         do_facet $SINGLEMDS "lctl set_param -n \
8202                 osp.$ost*MDT0000.create_count=$count"
8203         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8204         echo $INACTIVE_OSC "is Activate"
8205
8206         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8207 }
8208
8209 test_65k() { # bug11679
8210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8211         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8212         remote_mds_nodsh && skip "remote MDS with nodsh"
8213
8214         local disable_precreate=true
8215         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8216                 disable_precreate=false
8217
8218         echo "Check OST status: "
8219         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8220                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8221
8222         for OSC in $MDS_OSCS; do
8223                 echo $OSC "is active"
8224                 do_facet $SINGLEMDS lctl --device %$OSC activate
8225         done
8226
8227         for INACTIVE_OSC in $MDS_OSCS; do
8228                 local ost=$(osc_to_ost $INACTIVE_OSC)
8229                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8230                                lov.*md*.target_obd |
8231                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8232
8233                 mkdir -p $DIR/$tdir
8234                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8235                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8236
8237                 echo "Deactivate: " $INACTIVE_OSC
8238                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8239
8240                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8241                               osp.$ost*MDT0000.create_count")
8242                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8243                                   osp.$ost*MDT0000.max_create_count")
8244                 $disable_precreate &&
8245                         do_facet $SINGLEMDS "lctl set_param -n \
8246                                 osp.$ost*MDT0000.max_create_count=0"
8247
8248                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8249                         [ -f $DIR/$tdir/$idx ] && continue
8250                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8251                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8252                                 { cleanup_65k;
8253                                   error "setstripe $idx should succeed"; }
8254                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8255                 done
8256                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8257                 rmdir $DIR/$tdir
8258
8259                 do_facet $SINGLEMDS "lctl set_param -n \
8260                         osp.$ost*MDT0000.max_create_count=$max_count"
8261                 do_facet $SINGLEMDS "lctl set_param -n \
8262                         osp.$ost*MDT0000.create_count=$count"
8263                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8264                 echo $INACTIVE_OSC "is Activate"
8265
8266                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8267         done
8268 }
8269 run_test 65k "validate manual striping works properly with deactivated OSCs"
8270
8271 test_65l() { # bug 12836
8272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8273
8274         test_mkdir -p $DIR/$tdir/test_dir
8275         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8276         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8277 }
8278 run_test 65l "lfs find on -1 stripe dir ========================"
8279
8280 test_65m() {
8281         local layout=$(save_layout $MOUNT)
8282         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8283                 restore_layout $MOUNT $layout
8284                 error "setstripe should fail by non-root users"
8285         }
8286         true
8287 }
8288 run_test 65m "normal user can't set filesystem default stripe"
8289
8290 test_65n() {
8291         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8292         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8293                 skip "Need MDS version at least 2.12.50"
8294         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8295
8296         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8297         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8298         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8299
8300         local root_layout=$(save_layout $MOUNT)
8301         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8302
8303         # new subdirectory under root directory should not inherit
8304         # the default layout from root
8305         local dir1=$MOUNT/$tdir-1
8306         mkdir $dir1 || error "mkdir $dir1 failed"
8307         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8308                 error "$dir1 shouldn't have LOV EA"
8309
8310         # delete the default layout on root directory
8311         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8312
8313         local dir2=$MOUNT/$tdir-2
8314         mkdir $dir2 || error "mkdir $dir2 failed"
8315         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8316                 error "$dir2 shouldn't have LOV EA"
8317
8318         # set a new striping pattern on root directory
8319         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8320         local new_def_stripe_size=$((def_stripe_size * 2))
8321         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8322                 error "set stripe size on $MOUNT failed"
8323
8324         # new file created in $dir2 should inherit the new stripe size from
8325         # the filesystem default
8326         local file2=$dir2/$tfile-2
8327         touch $file2 || error "touch $file2 failed"
8328
8329         local file2_stripe_size=$($LFS getstripe -S $file2)
8330         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8331                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8332
8333         local dir3=$MOUNT/$tdir-3
8334         mkdir $dir3 || error "mkdir $dir3 failed"
8335         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8336         # the root layout, which is the actual default layout that will be used
8337         # when new files are created in $dir3.
8338         local dir3_layout=$(get_layout_param $dir3)
8339         local root_dir_layout=$(get_layout_param $MOUNT)
8340         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8341                 error "$dir3 should show the default layout from $MOUNT"
8342
8343         # set OST pool on root directory
8344         local pool=$TESTNAME
8345         pool_add $pool || error "add $pool failed"
8346         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8347                 error "add targets to $pool failed"
8348
8349         $LFS setstripe -p $pool $MOUNT ||
8350                 error "set OST pool on $MOUNT failed"
8351
8352         # new file created in $dir3 should inherit the pool from
8353         # the filesystem default
8354         local file3=$dir3/$tfile-3
8355         touch $file3 || error "touch $file3 failed"
8356
8357         local file3_pool=$($LFS getstripe -p $file3)
8358         [[ "$file3_pool" = "$pool" ]] ||
8359                 error "$file3 didn't inherit OST pool $pool"
8360
8361         local dir4=$MOUNT/$tdir-4
8362         mkdir $dir4 || error "mkdir $dir4 failed"
8363         local dir4_layout=$(get_layout_param $dir4)
8364         root_dir_layout=$(get_layout_param $MOUNT)
8365         echo "$LFS getstripe -d $dir4"
8366         $LFS getstripe -d $dir4
8367         echo "$LFS getstripe -d $MOUNT"
8368         $LFS getstripe -d $MOUNT
8369         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8370                 error "$dir4 should show the default layout from $MOUNT"
8371
8372         # new file created in $dir4 should inherit the pool from
8373         # the filesystem default
8374         local file4=$dir4/$tfile-4
8375         touch $file4 || error "touch $file4 failed"
8376
8377         local file4_pool=$($LFS getstripe -p $file4)
8378         [[ "$file4_pool" = "$pool" ]] ||
8379                 error "$file4 didn't inherit OST pool $pool"
8380
8381         # new subdirectory under non-root directory should inherit
8382         # the default layout from its parent directory
8383         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8384                 error "set directory layout on $dir4 failed"
8385
8386         local dir5=$dir4/$tdir-5
8387         mkdir $dir5 || error "mkdir $dir5 failed"
8388
8389         dir4_layout=$(get_layout_param $dir4)
8390         local dir5_layout=$(get_layout_param $dir5)
8391         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8392                 error "$dir5 should inherit the default layout from $dir4"
8393
8394         # though subdir under ROOT doesn't inherit default layout, but
8395         # its sub dir/file should be created with default layout.
8396         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8397         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8398                 skip "Need MDS version at least 2.12.59"
8399
8400         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8401         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8402         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8403
8404         if [ $default_lmv_hash == "none" ]; then
8405                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8406         else
8407                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8408                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8409         fi
8410
8411         $LFS setdirstripe -D -c 2 $MOUNT ||
8412                 error "setdirstripe -D -c 2 failed"
8413         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8414         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8415         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8416 }
8417 run_test 65n "don't inherit default layout from root for new subdirectories"
8418
8419 # bug 2543 - update blocks count on client
8420 test_66() {
8421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8422
8423         COUNT=${COUNT:-8}
8424         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8425         sync; sync_all_data; sync; sync_all_data
8426         cancel_lru_locks osc
8427         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8428         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8429 }
8430 run_test 66 "update inode blocks count on client ==============="
8431
8432 meminfo() {
8433         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8434 }
8435
8436 swap_used() {
8437         swapon -s | awk '($1 == "'$1'") { print $4 }'
8438 }
8439
8440 # bug5265, obdfilter oa2dentry return -ENOENT
8441 # #define OBD_FAIL_SRV_ENOENT 0x217
8442 test_69() {
8443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8444         remote_ost_nodsh && skip "remote OST with nodsh"
8445
8446         f="$DIR/$tfile"
8447         $LFS setstripe -c 1 -i 0 $f
8448
8449         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8450
8451         do_facet ost1 lctl set_param fail_loc=0x217
8452         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8453         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8454
8455         do_facet ost1 lctl set_param fail_loc=0
8456         $DIRECTIO write $f 0 2 || error "write error"
8457
8458         cancel_lru_locks osc
8459         $DIRECTIO read $f 0 1 || error "read error"
8460
8461         do_facet ost1 lctl set_param fail_loc=0x217
8462         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8463
8464         do_facet ost1 lctl set_param fail_loc=0
8465         rm -f $f
8466 }
8467 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8468
8469 test_71() {
8470         test_mkdir $DIR/$tdir
8471         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8472         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8473 }
8474 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8475
8476 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8478         [ "$RUNAS_ID" = "$UID" ] &&
8479                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8480         # Check that testing environment is properly set up. Skip if not
8481         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8482                 skip_env "User $RUNAS_ID does not exist - skipping"
8483
8484         touch $DIR/$tfile
8485         chmod 777 $DIR/$tfile
8486         chmod ug+s $DIR/$tfile
8487         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8488                 error "$RUNAS dd $DIR/$tfile failed"
8489         # See if we are still setuid/sgid
8490         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8491                 error "S/gid is not dropped on write"
8492         # Now test that MDS is updated too
8493         cancel_lru_locks mdc
8494         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8495                 error "S/gid is not dropped on MDS"
8496         rm -f $DIR/$tfile
8497 }
8498 run_test 72a "Test that remove suid works properly (bug5695) ===="
8499
8500 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8501         local perm
8502
8503         [ "$RUNAS_ID" = "$UID" ] &&
8504                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8505         [ "$RUNAS_ID" -eq 0 ] &&
8506                 skip_env "RUNAS_ID = 0 -- skipping"
8507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8508         # Check that testing environment is properly set up. Skip if not
8509         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8510                 skip_env "User $RUNAS_ID does not exist - skipping"
8511
8512         touch $DIR/${tfile}-f{g,u}
8513         test_mkdir $DIR/${tfile}-dg
8514         test_mkdir $DIR/${tfile}-du
8515         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8516         chmod g+s $DIR/${tfile}-{f,d}g
8517         chmod u+s $DIR/${tfile}-{f,d}u
8518         for perm in 777 2777 4777; do
8519                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8520                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8521                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8522                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8523         done
8524         true
8525 }
8526 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8527
8528 # bug 3462 - multiple simultaneous MDC requests
8529 test_73() {
8530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8531
8532         test_mkdir $DIR/d73-1
8533         test_mkdir $DIR/d73-2
8534         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8535         pid1=$!
8536
8537         lctl set_param fail_loc=0x80000129
8538         $MULTIOP $DIR/d73-1/f73-2 Oc &
8539         sleep 1
8540         lctl set_param fail_loc=0
8541
8542         $MULTIOP $DIR/d73-2/f73-3 Oc &
8543         pid3=$!
8544
8545         kill -USR1 $pid1
8546         wait $pid1 || return 1
8547
8548         sleep 25
8549
8550         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8551         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8552         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8553
8554         rm -rf $DIR/d73-*
8555 }
8556 run_test 73 "multiple MDC requests (should not deadlock)"
8557
8558 test_74a() { # bug 6149, 6184
8559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8560
8561         touch $DIR/f74a
8562         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8563         #
8564         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8565         # will spin in a tight reconnection loop
8566         $LCTL set_param fail_loc=0x8000030e
8567         # get any lock that won't be difficult - lookup works.
8568         ls $DIR/f74a
8569         $LCTL set_param fail_loc=0
8570         rm -f $DIR/f74a
8571         true
8572 }
8573 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8574
8575 test_74b() { # bug 13310
8576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8577
8578         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8579         #
8580         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8581         # will spin in a tight reconnection loop
8582         $LCTL set_param fail_loc=0x8000030e
8583         # get a "difficult" lock
8584         touch $DIR/f74b
8585         $LCTL set_param fail_loc=0
8586         rm -f $DIR/f74b
8587         true
8588 }
8589 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8590
8591 test_74c() {
8592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8593
8594         #define OBD_FAIL_LDLM_NEW_LOCK
8595         $LCTL set_param fail_loc=0x319
8596         touch $DIR/$tfile && error "touch successful"
8597         $LCTL set_param fail_loc=0
8598         true
8599 }
8600 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8601
8602 num_inodes() {
8603         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8604 }
8605
8606 test_76() { # Now for bug 20433, added originally in bug 1443
8607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8608
8609         cancel_lru_locks osc
8610         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8611         local before=$(num_inodes)
8612         local count=$((512 * cpus))
8613         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8614
8615         echo "before inodes: $before"
8616         for i in $(seq $count); do
8617                 touch $DIR/$tfile
8618                 rm -f $DIR/$tfile
8619         done
8620         cancel_lru_locks osc
8621         local after=$(num_inodes)
8622         echo "after inodes: $after"
8623         while (( after > before + 8 * ${cpus:-1} )); do
8624                 sleep 1
8625                 after=$(num_inodes)
8626                 wait=$((wait + 1))
8627                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8628                 if (( wait > 30 )); then
8629                         error "inode slab grew from $before to $after"
8630                 fi
8631         done
8632 }
8633 run_test 76 "confirm clients recycle inodes properly ===="
8634
8635
8636 export ORIG_CSUM=""
8637 set_checksums()
8638 {
8639         # Note: in sptlrpc modes which enable its own bulk checksum, the
8640         # original crc32_le bulk checksum will be automatically disabled,
8641         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8642         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8643         # In this case set_checksums() will not be no-op, because sptlrpc
8644         # bulk checksum will be enabled all through the test.
8645
8646         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8647         lctl set_param -n osc.*.checksums $1
8648         return 0
8649 }
8650
8651 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8652                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8653 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8654                              tr -d [] | head -n1)}
8655 set_checksum_type()
8656 {
8657         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8658         rc=$?
8659         log "set checksum type to $1, rc = $rc"
8660         return $rc
8661 }
8662
8663 get_osc_checksum_type()
8664 {
8665         # arugment 1: OST name, like OST0000
8666         ost=$1
8667         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8668                         sed 's/.*\[\(.*\)\].*/\1/g')
8669         rc=$?
8670         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8671         echo $checksum_type
8672 }
8673
8674 F77_TMP=$TMP/f77-temp
8675 F77SZ=8
8676 setup_f77() {
8677         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8678                 error "error writing to $F77_TMP"
8679 }
8680
8681 test_77a() { # bug 10889
8682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8683         $GSS && skip_env "could not run with gss"
8684
8685         [ ! -f $F77_TMP ] && setup_f77
8686         set_checksums 1
8687         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8688         set_checksums 0
8689         rm -f $DIR/$tfile
8690 }
8691 run_test 77a "normal checksum read/write operation"
8692
8693 test_77b() { # bug 10889
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695         $GSS && skip_env "could not run with gss"
8696
8697         [ ! -f $F77_TMP ] && setup_f77
8698         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8699         $LCTL set_param fail_loc=0x80000409
8700         set_checksums 1
8701
8702         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8703                 error "dd error: $?"
8704         $LCTL set_param fail_loc=0
8705
8706         for algo in $CKSUM_TYPES; do
8707                 cancel_lru_locks osc
8708                 set_checksum_type $algo
8709                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8710                 $LCTL set_param fail_loc=0x80000408
8711                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8712                 $LCTL set_param fail_loc=0
8713         done
8714         set_checksums 0
8715         set_checksum_type $ORIG_CSUM_TYPE
8716         rm -f $DIR/$tfile
8717 }
8718 run_test 77b "checksum error on client write, read"
8719
8720 cleanup_77c() {
8721         trap 0
8722         set_checksums 0
8723         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8724         $check_ost &&
8725                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8726         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8727         $check_ost && [ -n "$ost_file_prefix" ] &&
8728                 do_facet ost1 rm -f ${ost_file_prefix}\*
8729 }
8730
8731 test_77c() {
8732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8733         $GSS && skip_env "could not run with gss"
8734         remote_ost_nodsh && skip "remote OST with nodsh"
8735
8736         local bad1
8737         local osc_file_prefix
8738         local osc_file
8739         local check_ost=false
8740         local ost_file_prefix
8741         local ost_file
8742         local orig_cksum
8743         local dump_cksum
8744         local fid
8745
8746         # ensure corruption will occur on first OSS/OST
8747         $LFS setstripe -i 0 $DIR/$tfile
8748
8749         [ ! -f $F77_TMP ] && setup_f77
8750         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8751                 error "dd write error: $?"
8752         fid=$($LFS path2fid $DIR/$tfile)
8753
8754         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8755         then
8756                 check_ost=true
8757                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8758                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8759         else
8760                 echo "OSS do not support bulk pages dump upon error"
8761         fi
8762
8763         osc_file_prefix=$($LCTL get_param -n debug_path)
8764         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8765
8766         trap cleanup_77c EXIT
8767
8768         set_checksums 1
8769         # enable bulk pages dump upon error on Client
8770         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8771         # enable bulk pages dump upon error on OSS
8772         $check_ost &&
8773                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8774
8775         # flush Client cache to allow next read to reach OSS
8776         cancel_lru_locks osc
8777
8778         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8779         $LCTL set_param fail_loc=0x80000408
8780         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8781         $LCTL set_param fail_loc=0
8782
8783         rm -f $DIR/$tfile
8784
8785         # check cksum dump on Client
8786         osc_file=$(ls ${osc_file_prefix}*)
8787         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8788         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8789         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8790         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8791         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8792                      cksum)
8793         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8794         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8795                 error "dump content does not match on Client"
8796
8797         $check_ost || skip "No need to check cksum dump on OSS"
8798
8799         # check cksum dump on OSS
8800         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8801         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8802         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8803         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8804         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8805                 error "dump content does not match on OSS"
8806
8807         cleanup_77c
8808 }
8809 run_test 77c "checksum error on client read with debug"
8810
8811 test_77d() { # bug 10889
8812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8813         $GSS && skip_env "could not run with gss"
8814
8815         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8816         $LCTL set_param fail_loc=0x80000409
8817         set_checksums 1
8818         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8819                 error "direct write: rc=$?"
8820         $LCTL set_param fail_loc=0
8821         set_checksums 0
8822
8823         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8824         $LCTL set_param fail_loc=0x80000408
8825         set_checksums 1
8826         cancel_lru_locks osc
8827         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8828                 error "direct read: rc=$?"
8829         $LCTL set_param fail_loc=0
8830         set_checksums 0
8831 }
8832 run_test 77d "checksum error on OST direct write, read"
8833
8834 test_77f() { # bug 10889
8835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8836         $GSS && skip_env "could not run with gss"
8837
8838         set_checksums 1
8839         for algo in $CKSUM_TYPES; do
8840                 cancel_lru_locks osc
8841                 set_checksum_type $algo
8842                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8843                 $LCTL set_param fail_loc=0x409
8844                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8845                         error "direct write succeeded"
8846                 $LCTL set_param fail_loc=0
8847         done
8848         set_checksum_type $ORIG_CSUM_TYPE
8849         set_checksums 0
8850 }
8851 run_test 77f "repeat checksum error on write (expect error)"
8852
8853 test_77g() { # bug 10889
8854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8855         $GSS && skip_env "could not run with gss"
8856         remote_ost_nodsh && skip "remote OST with nodsh"
8857
8858         [ ! -f $F77_TMP ] && setup_f77
8859
8860         local file=$DIR/$tfile
8861         stack_trap "rm -f $file" EXIT
8862
8863         $LFS setstripe -c 1 -i 0 $file
8864         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8865         do_facet ost1 lctl set_param fail_loc=0x8000021a
8866         set_checksums 1
8867         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8868                 error "write error: rc=$?"
8869         do_facet ost1 lctl set_param fail_loc=0
8870         set_checksums 0
8871
8872         cancel_lru_locks osc
8873         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8874         do_facet ost1 lctl set_param fail_loc=0x8000021b
8875         set_checksums 1
8876         cmp $F77_TMP $file || error "file compare failed"
8877         do_facet ost1 lctl set_param fail_loc=0
8878         set_checksums 0
8879 }
8880 run_test 77g "checksum error on OST write, read"
8881
8882 test_77k() { # LU-10906
8883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8884         $GSS && skip_env "could not run with gss"
8885
8886         local cksum_param="osc.$FSNAME*.checksums"
8887         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8888         local checksum
8889         local i
8890
8891         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8892         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8893         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8894
8895         for i in 0 1; do
8896                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8897                         error "failed to set checksum=$i on MGS"
8898                 wait_update $HOSTNAME "$get_checksum" $i
8899                 #remount
8900                 echo "remount client, checksum should be $i"
8901                 remount_client $MOUNT || error "failed to remount client"
8902                 checksum=$(eval $get_checksum)
8903                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8904         done
8905         # remove persistent param to avoid races with checksum mountopt below
8906         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8907                 error "failed to delete checksum on MGS"
8908
8909         for opt in "checksum" "nochecksum"; do
8910                 #remount with mount option
8911                 echo "remount client with option $opt, checksum should be $i"
8912                 umount_client $MOUNT || error "failed to umount client"
8913                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8914                         error "failed to mount client with option '$opt'"
8915                 checksum=$(eval $get_checksum)
8916                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8917                 i=$((i - 1))
8918         done
8919
8920         remount_client $MOUNT || error "failed to remount client"
8921 }
8922 run_test 77k "enable/disable checksum correctly"
8923
8924 test_77l() {
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926         $GSS && skip_env "could not run with gss"
8927
8928         set_checksums 1
8929         stack_trap "set_checksums $ORIG_CSUM" EXIT
8930         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8931
8932         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8933
8934         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8935         for algo in $CKSUM_TYPES; do
8936                 set_checksum_type $algo || error "fail to set checksum type $algo"
8937                 osc_algo=$(get_osc_checksum_type OST0000)
8938                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8939
8940                 # no locks, no reqs to let the connection idle
8941                 cancel_lru_locks osc
8942                 lru_resize_disable osc
8943                 wait_osc_import_state client ost1 IDLE
8944
8945                 # ensure ost1 is connected
8946                 stat $DIR/$tfile >/dev/null || error "can't stat"
8947                 wait_osc_import_state client ost1 FULL
8948
8949                 osc_algo=$(get_osc_checksum_type OST0000)
8950                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8951         done
8952         return 0
8953 }
8954 run_test 77l "preferred checksum type is remembered after reconnected"
8955
8956 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8957 rm -f $F77_TMP
8958 unset F77_TMP
8959
8960 cleanup_test_78() {
8961         trap 0
8962         rm -f $DIR/$tfile
8963 }
8964
8965 test_78() { # bug 10901
8966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8967         remote_ost || skip_env "local OST"
8968
8969         NSEQ=5
8970         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8971         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8972         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8973         echo "MemTotal: $MEMTOTAL"
8974
8975         # reserve 256MB of memory for the kernel and other running processes,
8976         # and then take 1/2 of the remaining memory for the read/write buffers.
8977         if [ $MEMTOTAL -gt 512 ] ;then
8978                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8979         else
8980                 # for those poor memory-starved high-end clusters...
8981                 MEMTOTAL=$((MEMTOTAL / 2))
8982         fi
8983         echo "Mem to use for directio: $MEMTOTAL"
8984
8985         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8986         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8987         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8988         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8989                 head -n1)
8990         echo "Smallest OST: $SMALLESTOST"
8991         [[ $SMALLESTOST -lt 10240 ]] &&
8992                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8993
8994         trap cleanup_test_78 EXIT
8995
8996         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8997                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8998
8999         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9000         echo "File size: $F78SIZE"
9001         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9002         for i in $(seq 1 $NSEQ); do
9003                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9004                 echo directIO rdwr round $i of $NSEQ
9005                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9006         done
9007
9008         cleanup_test_78
9009 }
9010 run_test 78 "handle large O_DIRECT writes correctly ============"
9011
9012 test_79() { # bug 12743
9013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9014
9015         wait_delete_completed
9016
9017         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9018         BKFREE=$(calc_osc_kbytes kbytesfree)
9019         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9020
9021         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9022         DFTOTAL=`echo $STRING | cut -d, -f1`
9023         DFUSED=`echo $STRING  | cut -d, -f2`
9024         DFAVAIL=`echo $STRING | cut -d, -f3`
9025         DFFREE=$(($DFTOTAL - $DFUSED))
9026
9027         ALLOWANCE=$((64 * $OSTCOUNT))
9028
9029         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9030            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9031                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9032         fi
9033         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9034            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9035                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9036         fi
9037         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9038            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9039                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9040         fi
9041 }
9042 run_test 79 "df report consistency check ======================="
9043
9044 test_80() { # bug 10718
9045         remote_ost_nodsh && skip "remote OST with nodsh"
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047
9048         # relax strong synchronous semantics for slow backends like ZFS
9049         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9050                 local soc="obdfilter.*.sync_lock_cancel"
9051                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9052
9053                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9054                 if [ -z "$save" ]; then
9055                         soc="obdfilter.*.sync_on_lock_cancel"
9056                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9057                 fi
9058
9059                 if [ "$save" != "never" ]; then
9060                         local hosts=$(comma_list $(osts_nodes))
9061
9062                         do_nodes $hosts $LCTL set_param $soc=never
9063                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9064                 fi
9065         fi
9066
9067         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9068         sync; sleep 1; sync
9069         local before=$(date +%s)
9070         cancel_lru_locks osc
9071         local after=$(date +%s)
9072         local diff=$((after - before))
9073         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9074
9075         rm -f $DIR/$tfile
9076 }
9077 run_test 80 "Page eviction is equally fast at high offsets too"
9078
9079 test_81a() { # LU-456
9080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9081         remote_ost_nodsh && skip "remote OST with nodsh"
9082
9083         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9084         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9085         do_facet ost1 lctl set_param fail_loc=0x80000228
9086
9087         # write should trigger a retry and success
9088         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9089         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9090         RC=$?
9091         if [ $RC -ne 0 ] ; then
9092                 error "write should success, but failed for $RC"
9093         fi
9094 }
9095 run_test 81a "OST should retry write when get -ENOSPC ==============="
9096
9097 test_81b() { # LU-456
9098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9099         remote_ost_nodsh && skip "remote OST with nodsh"
9100
9101         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9102         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9103         do_facet ost1 lctl set_param fail_loc=0x228
9104
9105         # write should retry several times and return -ENOSPC finally
9106         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9107         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9108         RC=$?
9109         ENOSPC=28
9110         if [ $RC -ne $ENOSPC ] ; then
9111                 error "dd should fail for -ENOSPC, but succeed."
9112         fi
9113 }
9114 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9115
9116 test_82() { # LU-1031
9117         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
9118         local gid1=14091995
9119         local gid2=16022000
9120
9121         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
9122         local MULTIPID1=$!
9123         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
9124         local MULTIPID2=$!
9125         kill -USR1 $MULTIPID2
9126         sleep 2
9127         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
9128                 error "First grouplock does not block second one"
9129         else
9130                 echo "Second grouplock blocks first one"
9131         fi
9132         kill -USR1 $MULTIPID1
9133         wait $MULTIPID1
9134         wait $MULTIPID2
9135 }
9136 run_test 82 "Basic grouplock test"
9137
9138 test_99() {
9139         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9140
9141         test_mkdir $DIR/$tdir.cvsroot
9142         chown $RUNAS_ID $DIR/$tdir.cvsroot
9143
9144         cd $TMP
9145         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9146
9147         cd /etc/init.d
9148         # some versions of cvs import exit(1) when asked to import links or
9149         # files they can't read.  ignore those files.
9150         local toignore=$(find . -type l -printf '-I %f\n' -o \
9151                          ! -perm /4 -printf '-I %f\n')
9152         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9153                 $tdir.reposname vtag rtag
9154
9155         cd $DIR
9156         test_mkdir $DIR/$tdir.reposname
9157         chown $RUNAS_ID $DIR/$tdir.reposname
9158         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9159
9160         cd $DIR/$tdir.reposname
9161         $RUNAS touch foo99
9162         $RUNAS cvs add -m 'addmsg' foo99
9163         $RUNAS cvs update
9164         $RUNAS cvs commit -m 'nomsg' foo99
9165         rm -fr $DIR/$tdir.cvsroot
9166 }
9167 run_test 99 "cvs strange file/directory operations"
9168
9169 test_100() {
9170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9171         [[ "$NETTYPE" =~ tcp ]] ||
9172                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9173         remote_ost_nodsh && skip "remote OST with nodsh"
9174         remote_mds_nodsh && skip "remote MDS with nodsh"
9175         remote_servers ||
9176                 skip "useless for local single node setup"
9177
9178         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9179                 [ "$PROT" != "tcp" ] && continue
9180                 RPORT=$(echo $REMOTE | cut -d: -f2)
9181                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9182
9183                 rc=0
9184                 LPORT=`echo $LOCAL | cut -d: -f2`
9185                 if [ $LPORT -ge 1024 ]; then
9186                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9187                         netstat -tna
9188                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9189                 fi
9190         done
9191         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9192 }
9193 run_test 100 "check local port using privileged port ==========="
9194
9195 function get_named_value()
9196 {
9197     local tag
9198
9199     tag=$1
9200     while read ;do
9201         line=$REPLY
9202         case $line in
9203         $tag*)
9204             echo $line | sed "s/^$tag[ ]*//"
9205             break
9206             ;;
9207         esac
9208     done
9209 }
9210
9211 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9212                    awk '/^max_cached_mb/ { print $2 }')
9213
9214 cleanup_101a() {
9215         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9216         trap 0
9217 }
9218
9219 test_101a() {
9220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9221
9222         local s
9223         local discard
9224         local nreads=10000
9225         local cache_limit=32
9226
9227         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9228         trap cleanup_101a EXIT
9229         $LCTL set_param -n llite.*.read_ahead_stats 0
9230         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9231
9232         #
9233         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9234         #
9235         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9236         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9237
9238         discard=0
9239         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9240                 get_named_value 'read but discarded' | cut -d" " -f1); do
9241                         discard=$(($discard + $s))
9242         done
9243         cleanup_101a
9244
9245         $LCTL get_param osc.*-osc*.rpc_stats
9246         $LCTL get_param llite.*.read_ahead_stats
9247
9248         # Discard is generally zero, but sometimes a few random reads line up
9249         # and trigger larger readahead, which is wasted & leads to discards.
9250         if [[ $(($discard)) -gt $nreads ]]; then
9251                 error "too many ($discard) discarded pages"
9252         fi
9253         rm -f $DIR/$tfile || true
9254 }
9255 run_test 101a "check read-ahead for random reads"
9256
9257 setup_test101bc() {
9258         test_mkdir $DIR/$tdir
9259         local ssize=$1
9260         local FILE_LENGTH=$2
9261         STRIPE_OFFSET=0
9262
9263         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9264
9265         local list=$(comma_list $(osts_nodes))
9266         set_osd_param $list '' read_cache_enable 0
9267         set_osd_param $list '' writethrough_cache_enable 0
9268
9269         trap cleanup_test101bc EXIT
9270         # prepare the read-ahead file
9271         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9272
9273         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9274                                 count=$FILE_SIZE_MB 2> /dev/null
9275
9276 }
9277
9278 cleanup_test101bc() {
9279         trap 0
9280         rm -rf $DIR/$tdir
9281         rm -f $DIR/$tfile
9282
9283         local list=$(comma_list $(osts_nodes))
9284         set_osd_param $list '' read_cache_enable 1
9285         set_osd_param $list '' writethrough_cache_enable 1
9286 }
9287
9288 calc_total() {
9289         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9290 }
9291
9292 ra_check_101() {
9293         local READ_SIZE=$1
9294         local STRIPE_SIZE=$2
9295         local FILE_LENGTH=$3
9296         local RA_INC=1048576
9297         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9298         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9299                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9300         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9301                         get_named_value 'read but discarded' |
9302                         cut -d" " -f1 | calc_total)
9303         if [[ $DISCARD -gt $discard_limit ]]; then
9304                 $LCTL get_param llite.*.read_ahead_stats
9305                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9306         else
9307                 echo "Read-ahead success for size ${READ_SIZE}"
9308         fi
9309 }
9310
9311 test_101b() {
9312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9313         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9314
9315         local STRIPE_SIZE=1048576
9316         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9317
9318         if [ $SLOW == "yes" ]; then
9319                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9320         else
9321                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9322         fi
9323
9324         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9325
9326         # prepare the read-ahead file
9327         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9328         cancel_lru_locks osc
9329         for BIDX in 2 4 8 16 32 64 128 256
9330         do
9331                 local BSIZE=$((BIDX*4096))
9332                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9333                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9334                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9335                 $LCTL set_param -n llite.*.read_ahead_stats 0
9336                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9337                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9338                 cancel_lru_locks osc
9339                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9340         done
9341         cleanup_test101bc
9342         true
9343 }
9344 run_test 101b "check stride-io mode read-ahead ================="
9345
9346 test_101c() {
9347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9348
9349         local STRIPE_SIZE=1048576
9350         local FILE_LENGTH=$((STRIPE_SIZE*100))
9351         local nreads=10000
9352         local rsize=65536
9353         local osc_rpc_stats
9354
9355         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9356
9357         cancel_lru_locks osc
9358         $LCTL set_param osc.*.rpc_stats 0
9359         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9360         $LCTL get_param osc.*.rpc_stats
9361         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9362                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9363                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9364                 local size
9365
9366                 if [ $lines -le 20 ]; then
9367                         echo "continue debug"
9368                         continue
9369                 fi
9370                 for size in 1 2 4 8; do
9371                         local rpc=$(echo "$stats" |
9372                                     awk '($1 == "'$size':") {print $2; exit; }')
9373                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9374                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9375                 done
9376                 echo "$osc_rpc_stats check passed!"
9377         done
9378         cleanup_test101bc
9379         true
9380 }
9381 run_test 101c "check stripe_size aligned read-ahead ================="
9382
9383 test_101d() {
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385
9386         local file=$DIR/$tfile
9387         local sz_MB=${FILESIZE_101d:-80}
9388         local ra_MB=${READAHEAD_MB:-40}
9389
9390         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9391         [ $free_MB -lt $sz_MB ] &&
9392                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9393
9394         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9395         $LFS setstripe -c -1 $file || error "setstripe failed"
9396
9397         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9398         echo Cancel LRU locks on lustre client to flush the client cache
9399         cancel_lru_locks osc
9400
9401         echo Disable read-ahead
9402         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9403         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9404         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9405         $LCTL get_param -n llite.*.max_read_ahead_mb
9406
9407         echo "Reading the test file $file with read-ahead disabled"
9408         local sz_KB=$((sz_MB * 1024 / 4))
9409         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9410         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9411         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9412                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9413
9414         echo "Cancel LRU locks on lustre client to flush the client cache"
9415         cancel_lru_locks osc
9416         echo Enable read-ahead with ${ra_MB}MB
9417         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9418
9419         echo "Reading the test file $file with read-ahead enabled"
9420         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9421                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9422
9423         echo "read-ahead disabled time read $raOFF"
9424         echo "read-ahead enabled time read $raON"
9425
9426         rm -f $file
9427         wait_delete_completed
9428
9429         # use awk for this check instead of bash because it handles decimals
9430         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9431                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9432 }
9433 run_test 101d "file read with and without read-ahead enabled"
9434
9435 test_101e() {
9436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9437
9438         local file=$DIR/$tfile
9439         local size_KB=500  #KB
9440         local count=100
9441         local bsize=1024
9442
9443         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9444         local need_KB=$((count * size_KB))
9445         [[ $free_KB -le $need_KB ]] &&
9446                 skip_env "Need free space $need_KB, have $free_KB"
9447
9448         echo "Creating $count ${size_KB}K test files"
9449         for ((i = 0; i < $count; i++)); do
9450                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9451         done
9452
9453         echo "Cancel LRU locks on lustre client to flush the client cache"
9454         cancel_lru_locks $OSC
9455
9456         echo "Reset readahead stats"
9457         $LCTL set_param -n llite.*.read_ahead_stats 0
9458
9459         for ((i = 0; i < $count; i++)); do
9460                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9461         done
9462
9463         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9464                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9465
9466         for ((i = 0; i < $count; i++)); do
9467                 rm -rf $file.$i 2>/dev/null
9468         done
9469
9470         #10000 means 20% reads are missing in readahead
9471         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9472 }
9473 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9474
9475 test_101f() {
9476         which iozone || skip_env "no iozone installed"
9477
9478         local old_debug=$($LCTL get_param debug)
9479         old_debug=${old_debug#*=}
9480         $LCTL set_param debug="reada mmap"
9481
9482         # create a test file
9483         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9484
9485         echo Cancel LRU locks on lustre client to flush the client cache
9486         cancel_lru_locks osc
9487
9488         echo Reset readahead stats
9489         $LCTL set_param -n llite.*.read_ahead_stats 0
9490
9491         echo mmap read the file with small block size
9492         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9493                 > /dev/null 2>&1
9494
9495         echo checking missing pages
9496         $LCTL get_param llite.*.read_ahead_stats
9497         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9498                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9499
9500         $LCTL set_param debug="$old_debug"
9501         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9502         rm -f $DIR/$tfile
9503 }
9504 run_test 101f "check mmap read performance"
9505
9506 test_101g_brw_size_test() {
9507         local mb=$1
9508         local pages=$((mb * 1048576 / PAGE_SIZE))
9509         local file=$DIR/$tfile
9510
9511         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9512                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9513         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9514                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9515                         return 2
9516         done
9517
9518         stack_trap "rm -f $file" EXIT
9519         $LCTL set_param -n osc.*.rpc_stats=0
9520
9521         # 10 RPCs should be enough for the test
9522         local count=10
9523         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9524                 { error "dd write ${mb} MB blocks failed"; return 3; }
9525         cancel_lru_locks osc
9526         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9527                 { error "dd write ${mb} MB blocks failed"; return 4; }
9528
9529         # calculate number of full-sized read and write RPCs
9530         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9531                 sed -n '/pages per rpc/,/^$/p' |
9532                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9533                 END { print reads,writes }'))
9534         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9535                 return 5
9536         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9537                 return 6
9538
9539         return 0
9540 }
9541
9542 test_101g() {
9543         remote_ost_nodsh && skip "remote OST with nodsh"
9544
9545         local rpcs
9546         local osts=$(get_facets OST)
9547         local list=$(comma_list $(osts_nodes))
9548         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9549         local brw_size="obdfilter.*.brw_size"
9550
9551         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9552
9553         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9554
9555         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9556                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9557                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9558            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9559                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9560                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9561
9562                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9563                         suffix="M"
9564
9565                 if [[ $orig_mb -lt 16 ]]; then
9566                         save_lustre_params $osts "$brw_size" > $p
9567                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9568                                 error "set 16MB RPC size failed"
9569
9570                         echo "remount client to enable new RPC size"
9571                         remount_client $MOUNT || error "remount_client failed"
9572                 fi
9573
9574                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9575                 # should be able to set brw_size=12, but no rpc_stats for that
9576                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9577         fi
9578
9579         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9580
9581         if [[ $orig_mb -lt 16 ]]; then
9582                 restore_lustre_params < $p
9583                 remount_client $MOUNT || error "remount_client restore failed"
9584         fi
9585
9586         rm -f $p $DIR/$tfile
9587 }
9588 run_test 101g "Big bulk(4/16 MiB) readahead"
9589
9590 test_101h() {
9591         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9592
9593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9594                 error "dd 70M file failed"
9595         echo Cancel LRU locks on lustre client to flush the client cache
9596         cancel_lru_locks osc
9597
9598         echo "Reset readahead stats"
9599         $LCTL set_param -n llite.*.read_ahead_stats 0
9600
9601         echo "Read 10M of data but cross 64M bundary"
9602         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9603         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9604                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9605         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9606         rm -f $p $DIR/$tfile
9607 }
9608 run_test 101h "Readahead should cover current read window"
9609
9610 test_101i() {
9611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9612                 error "dd 10M file failed"
9613
9614         local max_per_file_mb=$($LCTL get_param -n \
9615                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9616         cancel_lru_locks osc
9617         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9618         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9619                 error "set max_read_ahead_per_file_mb to 1 failed"
9620
9621         echo "Reset readahead stats"
9622         $LCTL set_param llite.*.read_ahead_stats=0
9623
9624         dd if=$DIR/$tfile of=/dev/null bs=2M
9625
9626         $LCTL get_param llite.*.read_ahead_stats
9627         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9628                      awk '/misses/ { print $2 }')
9629         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9630         rm -f $DIR/$tfile
9631 }
9632 run_test 101i "allow current readahead to exceed reservation"
9633
9634 test_101j() {
9635         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9636                 error "setstripe $DIR/$tfile failed"
9637         local file_size=$((1048576 * 16))
9638         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9639         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9640
9641         echo Disable read-ahead
9642         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9643
9644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9645         for blk in $PAGE_SIZE 1048576 $file_size; do
9646                 cancel_lru_locks osc
9647                 echo "Reset readahead stats"
9648                 $LCTL set_param -n llite.*.read_ahead_stats=0
9649                 local count=$(($file_size / $blk))
9650                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9651                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9652                              get_named_value 'failed to fast read' |
9653                              cut -d" " -f1 | calc_total)
9654                 $LCTL get_param -n llite.*.read_ahead_stats
9655                 [ $miss -eq $count ] || error "expected $count got $miss"
9656         done
9657
9658         rm -f $p $DIR/$tfile
9659 }
9660 run_test 101j "A complete read block should be submitted when no RA"
9661
9662 setup_test102() {
9663         test_mkdir $DIR/$tdir
9664         chown $RUNAS_ID $DIR/$tdir
9665         STRIPE_SIZE=65536
9666         STRIPE_OFFSET=1
9667         STRIPE_COUNT=$OSTCOUNT
9668         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9669
9670         trap cleanup_test102 EXIT
9671         cd $DIR
9672         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9673         cd $DIR/$tdir
9674         for num in 1 2 3 4; do
9675                 for count in $(seq 1 $STRIPE_COUNT); do
9676                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9677                                 local size=`expr $STRIPE_SIZE \* $num`
9678                                 local file=file"$num-$idx-$count"
9679                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9680                         done
9681                 done
9682         done
9683
9684         cd $DIR
9685         $1 tar cf $TMP/f102.tar $tdir --xattrs
9686 }
9687
9688 cleanup_test102() {
9689         trap 0
9690         rm -f $TMP/f102.tar
9691         rm -rf $DIR/d0.sanity/d102
9692 }
9693
9694 test_102a() {
9695         [ "$UID" != 0 ] && skip "must run as root"
9696         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9697                 skip_env "must have user_xattr"
9698
9699         [ -z "$(which setfattr 2>/dev/null)" ] &&
9700                 skip_env "could not find setfattr"
9701
9702         local testfile=$DIR/$tfile
9703
9704         touch $testfile
9705         echo "set/get xattr..."
9706         setfattr -n trusted.name1 -v value1 $testfile ||
9707                 error "setfattr -n trusted.name1=value1 $testfile failed"
9708         getfattr -n trusted.name1 $testfile 2> /dev/null |
9709           grep "trusted.name1=.value1" ||
9710                 error "$testfile missing trusted.name1=value1"
9711
9712         setfattr -n user.author1 -v author1 $testfile ||
9713                 error "setfattr -n user.author1=author1 $testfile failed"
9714         getfattr -n user.author1 $testfile 2> /dev/null |
9715           grep "user.author1=.author1" ||
9716                 error "$testfile missing trusted.author1=author1"
9717
9718         echo "listxattr..."
9719         setfattr -n trusted.name2 -v value2 $testfile ||
9720                 error "$testfile unable to set trusted.name2"
9721         setfattr -n trusted.name3 -v value3 $testfile ||
9722                 error "$testfile unable to set trusted.name3"
9723         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9724             grep "trusted.name" | wc -l) -eq 3 ] ||
9725                 error "$testfile missing 3 trusted.name xattrs"
9726
9727         setfattr -n user.author2 -v author2 $testfile ||
9728                 error "$testfile unable to set user.author2"
9729         setfattr -n user.author3 -v author3 $testfile ||
9730                 error "$testfile unable to set user.author3"
9731         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9732             grep "user.author" | wc -l) -eq 3 ] ||
9733                 error "$testfile missing 3 user.author xattrs"
9734
9735         echo "remove xattr..."
9736         setfattr -x trusted.name1 $testfile ||
9737                 error "$testfile error deleting trusted.name1"
9738         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9739                 error "$testfile did not delete trusted.name1 xattr"
9740
9741         setfattr -x user.author1 $testfile ||
9742                 error "$testfile error deleting user.author1"
9743         echo "set lustre special xattr ..."
9744         $LFS setstripe -c1 $testfile
9745         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9746                 awk -F "=" '/trusted.lov/ { print $2 }' )
9747         setfattr -n "trusted.lov" -v $lovea $testfile ||
9748                 error "$testfile doesn't ignore setting trusted.lov again"
9749         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9750                 error "$testfile allow setting invalid trusted.lov"
9751         rm -f $testfile
9752 }
9753 run_test 102a "user xattr test =================================="
9754
9755 check_102b_layout() {
9756         local layout="$*"
9757         local testfile=$DIR/$tfile
9758
9759         echo "test layout '$layout'"
9760         $LFS setstripe $layout $testfile || error "setstripe failed"
9761         $LFS getstripe -y $testfile
9762
9763         echo "get/set/list trusted.lov xattr ..." # b=10930
9764         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9765         [[ "$value" =~ "trusted.lov" ]] ||
9766                 error "can't get trusted.lov from $testfile"
9767         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9768                 error "getstripe failed"
9769
9770         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9771
9772         value=$(cut -d= -f2 <<<$value)
9773         # LU-13168: truncated xattr should fail if short lov_user_md header
9774         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9775                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9776         for len in $lens; do
9777                 echo "setfattr $len $testfile.2"
9778                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9779                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9780         done
9781         local stripe_size=$($LFS getstripe -S $testfile.2)
9782         local stripe_count=$($LFS getstripe -c $testfile.2)
9783         [[ $stripe_size -eq 65536 ]] ||
9784                 error "stripe size $stripe_size != 65536"
9785         [[ $stripe_count -eq $stripe_count_orig ]] ||
9786                 error "stripe count $stripe_count != $stripe_count_orig"
9787         rm $testfile $testfile.2
9788 }
9789
9790 test_102b() {
9791         [ -z "$(which setfattr 2>/dev/null)" ] &&
9792                 skip_env "could not find setfattr"
9793         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9794
9795         # check plain layout
9796         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9797
9798         # and also check composite layout
9799         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9800
9801 }
9802 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9803
9804 test_102c() {
9805         [ -z "$(which setfattr 2>/dev/null)" ] &&
9806                 skip_env "could not find setfattr"
9807         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9808
9809         # b10930: get/set/list lustre.lov xattr
9810         echo "get/set/list lustre.lov xattr ..."
9811         test_mkdir $DIR/$tdir
9812         chown $RUNAS_ID $DIR/$tdir
9813         local testfile=$DIR/$tdir/$tfile
9814         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9815                 error "setstripe failed"
9816         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9817                 error "getstripe failed"
9818         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9819         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9820
9821         local testfile2=${testfile}2
9822         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9823                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9824
9825         $RUNAS $MCREATE $testfile2
9826         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9827         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9828         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9829         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9830         [ $stripe_count -eq $STRIPECOUNT ] ||
9831                 error "stripe count $stripe_count != $STRIPECOUNT"
9832 }
9833 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9834
9835 compare_stripe_info1() {
9836         local stripe_index_all_zero=true
9837
9838         for num in 1 2 3 4; do
9839                 for count in $(seq 1 $STRIPE_COUNT); do
9840                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9841                                 local size=$((STRIPE_SIZE * num))
9842                                 local file=file"$num-$offset-$count"
9843                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9844                                 [[ $stripe_size -ne $size ]] &&
9845                                     error "$file: size $stripe_size != $size"
9846                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9847                                 # allow fewer stripes to be created, ORI-601
9848                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9849                                     error "$file: count $stripe_count != $count"
9850                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9851                                 [[ $stripe_index -ne 0 ]] &&
9852                                         stripe_index_all_zero=false
9853                         done
9854                 done
9855         done
9856         $stripe_index_all_zero &&
9857                 error "all files are being extracted starting from OST index 0"
9858         return 0
9859 }
9860
9861 have_xattrs_include() {
9862         tar --help | grep -q xattrs-include &&
9863                 echo --xattrs-include="lustre.*"
9864 }
9865
9866 test_102d() {
9867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9869
9870         XINC=$(have_xattrs_include)
9871         setup_test102
9872         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9873         cd $DIR/$tdir/$tdir
9874         compare_stripe_info1
9875 }
9876 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9877
9878 test_102f() {
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9881
9882         XINC=$(have_xattrs_include)
9883         setup_test102
9884         test_mkdir $DIR/$tdir.restore
9885         cd $DIR
9886         tar cf - --xattrs $tdir | tar xf - \
9887                 -C $DIR/$tdir.restore --xattrs $XINC
9888         cd $DIR/$tdir.restore/$tdir
9889         compare_stripe_info1
9890 }
9891 run_test 102f "tar copy files, not keep osts"
9892
9893 grow_xattr() {
9894         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9895                 skip "must have user_xattr"
9896         [ -z "$(which setfattr 2>/dev/null)" ] &&
9897                 skip_env "could not find setfattr"
9898         [ -z "$(which getfattr 2>/dev/null)" ] &&
9899                 skip_env "could not find getfattr"
9900
9901         local xsize=${1:-1024}  # in bytes
9902         local file=$DIR/$tfile
9903         local value="$(generate_string $xsize)"
9904         local xbig=trusted.big
9905         local toobig=$2
9906
9907         touch $file
9908         log "save $xbig on $file"
9909         if [ -z "$toobig" ]
9910         then
9911                 setfattr -n $xbig -v $value $file ||
9912                         error "saving $xbig on $file failed"
9913         else
9914                 setfattr -n $xbig -v $value $file &&
9915                         error "saving $xbig on $file succeeded"
9916                 return 0
9917         fi
9918
9919         local orig=$(get_xattr_value $xbig $file)
9920         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9921
9922         local xsml=trusted.sml
9923         log "save $xsml on $file"
9924         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9925
9926         local new=$(get_xattr_value $xbig $file)
9927         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9928
9929         log "grow $xsml on $file"
9930         setfattr -n $xsml -v "$value" $file ||
9931                 error "growing $xsml on $file failed"
9932
9933         new=$(get_xattr_value $xbig $file)
9934         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9935         log "$xbig still valid after growing $xsml"
9936
9937         rm -f $file
9938 }
9939
9940 test_102h() { # bug 15777
9941         grow_xattr 1024
9942 }
9943 run_test 102h "grow xattr from inside inode to external block"
9944
9945 test_102ha() {
9946         large_xattr_enabled || skip_env "ea_inode feature disabled"
9947
9948         echo "setting xattr of max xattr size: $(max_xattr_size)"
9949         grow_xattr $(max_xattr_size)
9950
9951         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9952         echo "This should fail:"
9953         grow_xattr $(($(max_xattr_size) + 10)) 1
9954 }
9955 run_test 102ha "grow xattr from inside inode to external inode"
9956
9957 test_102i() { # bug 17038
9958         [ -z "$(which getfattr 2>/dev/null)" ] &&
9959                 skip "could not find getfattr"
9960
9961         touch $DIR/$tfile
9962         ln -s $DIR/$tfile $DIR/${tfile}link
9963         getfattr -n trusted.lov $DIR/$tfile ||
9964                 error "lgetxattr on $DIR/$tfile failed"
9965         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9966                 grep -i "no such attr" ||
9967                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9968         rm -f $DIR/$tfile $DIR/${tfile}link
9969 }
9970 run_test 102i "lgetxattr test on symbolic link ============"
9971
9972 test_102j() {
9973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9974         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9975
9976         XINC=$(have_xattrs_include)
9977         setup_test102 "$RUNAS"
9978         chown $RUNAS_ID $DIR/$tdir
9979         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9980         cd $DIR/$tdir/$tdir
9981         compare_stripe_info1 "$RUNAS"
9982 }
9983 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9984
9985 test_102k() {
9986         [ -z "$(which setfattr 2>/dev/null)" ] &&
9987                 skip "could not find setfattr"
9988
9989         touch $DIR/$tfile
9990         # b22187 just check that does not crash for regular file.
9991         setfattr -n trusted.lov $DIR/$tfile
9992         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9993         local test_kdir=$DIR/$tdir
9994         test_mkdir $test_kdir
9995         local default_size=$($LFS getstripe -S $test_kdir)
9996         local default_count=$($LFS getstripe -c $test_kdir)
9997         local default_offset=$($LFS getstripe -i $test_kdir)
9998         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9999                 error 'dir setstripe failed'
10000         setfattr -n trusted.lov $test_kdir
10001         local stripe_size=$($LFS getstripe -S $test_kdir)
10002         local stripe_count=$($LFS getstripe -c $test_kdir)
10003         local stripe_offset=$($LFS getstripe -i $test_kdir)
10004         [ $stripe_size -eq $default_size ] ||
10005                 error "stripe size $stripe_size != $default_size"
10006         [ $stripe_count -eq $default_count ] ||
10007                 error "stripe count $stripe_count != $default_count"
10008         [ $stripe_offset -eq $default_offset ] ||
10009                 error "stripe offset $stripe_offset != $default_offset"
10010         rm -rf $DIR/$tfile $test_kdir
10011 }
10012 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10013
10014 test_102l() {
10015         [ -z "$(which getfattr 2>/dev/null)" ] &&
10016                 skip "could not find getfattr"
10017
10018         # LU-532 trusted. xattr is invisible to non-root
10019         local testfile=$DIR/$tfile
10020
10021         touch $testfile
10022
10023         echo "listxattr as user..."
10024         chown $RUNAS_ID $testfile
10025         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10026             grep -q "trusted" &&
10027                 error "$testfile trusted xattrs are user visible"
10028
10029         return 0;
10030 }
10031 run_test 102l "listxattr size test =================================="
10032
10033 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10034         local path=$DIR/$tfile
10035         touch $path
10036
10037         listxattr_size_check $path || error "listattr_size_check $path failed"
10038 }
10039 run_test 102m "Ensure listxattr fails on small bufffer ========"
10040
10041 cleanup_test102
10042
10043 getxattr() { # getxattr path name
10044         # Return the base64 encoding of the value of xattr name on path.
10045         local path=$1
10046         local name=$2
10047
10048         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10049         # file: $path
10050         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10051         #
10052         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10053
10054         getfattr --absolute-names --encoding=base64 --name=$name $path |
10055                 awk -F= -v name=$name '$1 == name {
10056                         print substr($0, index($0, "=") + 1);
10057         }'
10058 }
10059
10060 test_102n() { # LU-4101 mdt: protect internal xattrs
10061         [ -z "$(which setfattr 2>/dev/null)" ] &&
10062                 skip "could not find setfattr"
10063         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10064         then
10065                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10066         fi
10067
10068         local file0=$DIR/$tfile.0
10069         local file1=$DIR/$tfile.1
10070         local xattr0=$TMP/$tfile.0
10071         local xattr1=$TMP/$tfile.1
10072         local namelist="lov lma lmv link fid version som hsm"
10073         local name
10074         local value
10075
10076         rm -rf $file0 $file1 $xattr0 $xattr1
10077         touch $file0 $file1
10078
10079         # Get 'before' xattrs of $file1.
10080         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10081
10082         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10083                 namelist+=" lfsck_namespace"
10084         for name in $namelist; do
10085                 # Try to copy xattr from $file0 to $file1.
10086                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10087
10088                 setfattr --name=trusted.$name --value="$value" $file1 ||
10089                         error "setxattr 'trusted.$name' failed"
10090
10091                 # Try to set a garbage xattr.
10092                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10093
10094                 if [[ x$name == "xlov" ]]; then
10095                         setfattr --name=trusted.lov --value="$value" $file1 &&
10096                         error "setxattr invalid 'trusted.lov' success"
10097                 else
10098                         setfattr --name=trusted.$name --value="$value" $file1 ||
10099                                 error "setxattr invalid 'trusted.$name' failed"
10100                 fi
10101
10102                 # Try to remove the xattr from $file1. We don't care if this
10103                 # appears to succeed or fail, we just don't want there to be
10104                 # any changes or crashes.
10105                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10106         done
10107
10108         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10109         then
10110                 name="lfsck_ns"
10111                 # Try to copy xattr from $file0 to $file1.
10112                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10113
10114                 setfattr --name=trusted.$name --value="$value" $file1 ||
10115                         error "setxattr 'trusted.$name' failed"
10116
10117                 # Try to set a garbage xattr.
10118                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10119
10120                 setfattr --name=trusted.$name --value="$value" $file1 ||
10121                         error "setxattr 'trusted.$name' failed"
10122
10123                 # Try to remove the xattr from $file1. We don't care if this
10124                 # appears to succeed or fail, we just don't want there to be
10125                 # any changes or crashes.
10126                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10127         fi
10128
10129         # Get 'after' xattrs of file1.
10130         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10131
10132         if ! diff $xattr0 $xattr1; then
10133                 error "before and after xattrs of '$file1' differ"
10134         fi
10135
10136         rm -rf $file0 $file1 $xattr0 $xattr1
10137
10138         return 0
10139 }
10140 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10141
10142 test_102p() { # LU-4703 setxattr did not check ownership
10143         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10144                 skip "MDS needs to be at least 2.5.56"
10145
10146         local testfile=$DIR/$tfile
10147
10148         touch $testfile
10149
10150         echo "setfacl as user..."
10151         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10152         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10153
10154         echo "setfattr as user..."
10155         setfacl -m "u:$RUNAS_ID:---" $testfile
10156         $RUNAS setfattr -x system.posix_acl_access $testfile
10157         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10158 }
10159 run_test 102p "check setxattr(2) correctly fails without permission"
10160
10161 test_102q() {
10162         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10163                 skip "MDS needs to be at least 2.6.92"
10164
10165         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10166 }
10167 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10168
10169 test_102r() {
10170         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10171                 skip "MDS needs to be at least 2.6.93"
10172
10173         touch $DIR/$tfile || error "touch"
10174         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10175         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10176         rm $DIR/$tfile || error "rm"
10177
10178         #normal directory
10179         mkdir -p $DIR/$tdir || error "mkdir"
10180         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10181         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10182         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10183                 error "$testfile error deleting user.author1"
10184         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10185                 grep "user.$(basename $tdir)" &&
10186                 error "$tdir did not delete user.$(basename $tdir)"
10187         rmdir $DIR/$tdir || error "rmdir"
10188
10189         #striped directory
10190         test_mkdir $DIR/$tdir
10191         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10192         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10193         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10194                 error "$testfile error deleting user.author1"
10195         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10196                 grep "user.$(basename $tdir)" &&
10197                 error "$tdir did not delete user.$(basename $tdir)"
10198         rmdir $DIR/$tdir || error "rm striped dir"
10199 }
10200 run_test 102r "set EAs with empty values"
10201
10202 test_102s() {
10203         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10204                 skip "MDS needs to be at least 2.11.52"
10205
10206         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10207
10208         save_lustre_params client "llite.*.xattr_cache" > $save
10209
10210         for cache in 0 1; do
10211                 lctl set_param llite.*.xattr_cache=$cache
10212
10213                 rm -f $DIR/$tfile
10214                 touch $DIR/$tfile || error "touch"
10215                 for prefix in lustre security system trusted user; do
10216                         # Note getxattr() may fail with 'Operation not
10217                         # supported' or 'No such attribute' depending
10218                         # on prefix and cache.
10219                         getfattr -n $prefix.n102s $DIR/$tfile &&
10220                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10221                 done
10222         done
10223
10224         restore_lustre_params < $save
10225 }
10226 run_test 102s "getting nonexistent xattrs should fail"
10227
10228 test_102t() {
10229         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10230                 skip "MDS needs to be at least 2.11.52"
10231
10232         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10233
10234         save_lustre_params client "llite.*.xattr_cache" > $save
10235
10236         for cache in 0 1; do
10237                 lctl set_param llite.*.xattr_cache=$cache
10238
10239                 for buf_size in 0 256; do
10240                         rm -f $DIR/$tfile
10241                         touch $DIR/$tfile || error "touch"
10242                         setfattr -n user.multiop $DIR/$tfile
10243                         $MULTIOP $DIR/$tfile oa$buf_size ||
10244                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10245                 done
10246         done
10247
10248         restore_lustre_params < $save
10249 }
10250 run_test 102t "zero length xattr values handled correctly"
10251
10252 run_acl_subtest()
10253 {
10254     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10255     return $?
10256 }
10257
10258 test_103a() {
10259         [ "$UID" != 0 ] && skip "must run as root"
10260         $GSS && skip_env "could not run under gss"
10261         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10262                 skip_env "must have acl enabled"
10263         [ -z "$(which setfacl 2>/dev/null)" ] &&
10264                 skip_env "could not find setfacl"
10265         remote_mds_nodsh && skip "remote MDS with nodsh"
10266
10267         gpasswd -a daemon bin                           # LU-5641
10268         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10269
10270         declare -a identity_old
10271
10272         for num in $(seq $MDSCOUNT); do
10273                 switch_identity $num true || identity_old[$num]=$?
10274         done
10275
10276         SAVE_UMASK=$(umask)
10277         umask 0022
10278         mkdir -p $DIR/$tdir
10279         cd $DIR/$tdir
10280
10281         echo "performing cp ..."
10282         run_acl_subtest cp || error "run_acl_subtest cp failed"
10283         echo "performing getfacl-noacl..."
10284         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10285         echo "performing misc..."
10286         run_acl_subtest misc || error  "misc test failed"
10287         echo "performing permissions..."
10288         run_acl_subtest permissions || error "permissions failed"
10289         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10290         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10291                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10292                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10293         then
10294                 echo "performing permissions xattr..."
10295                 run_acl_subtest permissions_xattr ||
10296                         error "permissions_xattr failed"
10297         fi
10298         echo "performing setfacl..."
10299         run_acl_subtest setfacl || error  "setfacl test failed"
10300
10301         # inheritance test got from HP
10302         echo "performing inheritance..."
10303         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10304         chmod +x make-tree || error "chmod +x failed"
10305         run_acl_subtest inheritance || error "inheritance test failed"
10306         rm -f make-tree
10307
10308         echo "LU-974 ignore umask when acl is enabled..."
10309         run_acl_subtest 974 || error "LU-974 umask test failed"
10310         if [ $MDSCOUNT -ge 2 ]; then
10311                 run_acl_subtest 974_remote ||
10312                         error "LU-974 umask test failed under remote dir"
10313         fi
10314
10315         echo "LU-2561 newly created file is same size as directory..."
10316         if [ "$mds1_FSTYPE" != "zfs" ]; then
10317                 run_acl_subtest 2561 || error "LU-2561 test failed"
10318         else
10319                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10320         fi
10321
10322         run_acl_subtest 4924 || error "LU-4924 test failed"
10323
10324         cd $SAVE_PWD
10325         umask $SAVE_UMASK
10326
10327         for num in $(seq $MDSCOUNT); do
10328                 if [ "${identity_old[$num]}" = 1 ]; then
10329                         switch_identity $num false || identity_old[$num]=$?
10330                 fi
10331         done
10332 }
10333 run_test 103a "acl test"
10334
10335 test_103b() {
10336         declare -a pids
10337         local U
10338
10339         for U in {0..511}; do
10340                 {
10341                 local O=$(printf "%04o" $U)
10342
10343                 umask $(printf "%04o" $((511 ^ $O)))
10344                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10345                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10346
10347                 (( $S == ($O & 0666) )) ||
10348                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10349
10350                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10351                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10352                 (( $S == ($O & 0666) )) ||
10353                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10354
10355                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10356                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10357                 (( $S == ($O & 0666) )) ||
10358                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10359                 rm -f $DIR/$tfile.[smp]$0
10360                 } &
10361                 local pid=$!
10362
10363                 # limit the concurrently running threads to 64. LU-11878
10364                 local idx=$((U % 64))
10365                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10366                 pids[idx]=$pid
10367         done
10368         wait
10369 }
10370 run_test 103b "umask lfs setstripe"
10371
10372 test_103c() {
10373         mkdir -p $DIR/$tdir
10374         cp -rp $DIR/$tdir $DIR/$tdir.bak
10375
10376         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10377                 error "$DIR/$tdir shouldn't contain default ACL"
10378         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10379                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10380         true
10381 }
10382 run_test 103c "'cp -rp' won't set empty acl"
10383
10384 test_104a() {
10385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10386
10387         touch $DIR/$tfile
10388         lfs df || error "lfs df failed"
10389         lfs df -ih || error "lfs df -ih failed"
10390         lfs df -h $DIR || error "lfs df -h $DIR failed"
10391         lfs df -i $DIR || error "lfs df -i $DIR failed"
10392         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10393         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10394
10395         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10396         lctl --device %$OSC deactivate
10397         lfs df || error "lfs df with deactivated OSC failed"
10398         lctl --device %$OSC activate
10399         # wait the osc back to normal
10400         wait_osc_import_ready client ost
10401
10402         lfs df || error "lfs df with reactivated OSC failed"
10403         rm -f $DIR/$tfile
10404 }
10405 run_test 104a "lfs df [-ih] [path] test ========================="
10406
10407 test_104b() {
10408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10409         [ $RUNAS_ID -eq $UID ] &&
10410                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10411
10412         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10413                         grep "Permission denied" | wc -l)))
10414         if [ $denied_cnt -ne 0 ]; then
10415                 error "lfs check servers test failed"
10416         fi
10417 }
10418 run_test 104b "$RUNAS lfs check servers test ===================="
10419
10420 test_105a() {
10421         # doesn't work on 2.4 kernels
10422         touch $DIR/$tfile
10423         if $(flock_is_enabled); then
10424                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10425         else
10426                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10427         fi
10428         rm -f $DIR/$tfile
10429 }
10430 run_test 105a "flock when mounted without -o flock test ========"
10431
10432 test_105b() {
10433         touch $DIR/$tfile
10434         if $(flock_is_enabled); then
10435                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10436         else
10437                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10438         fi
10439         rm -f $DIR/$tfile
10440 }
10441 run_test 105b "fcntl when mounted without -o flock test ========"
10442
10443 test_105c() {
10444         touch $DIR/$tfile
10445         if $(flock_is_enabled); then
10446                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10447         else
10448                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10449         fi
10450         rm -f $DIR/$tfile
10451 }
10452 run_test 105c "lockf when mounted without -o flock test"
10453
10454 test_105d() { # bug 15924
10455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10456
10457         test_mkdir $DIR/$tdir
10458         flock_is_enabled || skip_env "mount w/o flock enabled"
10459         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10460         $LCTL set_param fail_loc=0x80000315
10461         flocks_test 2 $DIR/$tdir
10462 }
10463 run_test 105d "flock race (should not freeze) ========"
10464
10465 test_105e() { # bug 22660 && 22040
10466         flock_is_enabled || skip_env "mount w/o flock enabled"
10467
10468         touch $DIR/$tfile
10469         flocks_test 3 $DIR/$tfile
10470 }
10471 run_test 105e "Two conflicting flocks from same process"
10472
10473 test_106() { #bug 10921
10474         test_mkdir $DIR/$tdir
10475         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10476         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10477 }
10478 run_test 106 "attempt exec of dir followed by chown of that dir"
10479
10480 test_107() {
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482
10483         CDIR=`pwd`
10484         local file=core
10485
10486         cd $DIR
10487         rm -f $file
10488
10489         local save_pattern=$(sysctl -n kernel.core_pattern)
10490         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10491         sysctl -w kernel.core_pattern=$file
10492         sysctl -w kernel.core_uses_pid=0
10493
10494         ulimit -c unlimited
10495         sleep 60 &
10496         SLEEPPID=$!
10497
10498         sleep 1
10499
10500         kill -s 11 $SLEEPPID
10501         wait $SLEEPPID
10502         if [ -e $file ]; then
10503                 size=`stat -c%s $file`
10504                 [ $size -eq 0 ] && error "Fail to create core file $file"
10505         else
10506                 error "Fail to create core file $file"
10507         fi
10508         rm -f $file
10509         sysctl -w kernel.core_pattern=$save_pattern
10510         sysctl -w kernel.core_uses_pid=$save_uses_pid
10511         cd $CDIR
10512 }
10513 run_test 107 "Coredump on SIG"
10514
10515 test_110() {
10516         test_mkdir $DIR/$tdir
10517         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10518         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10519                 error "mkdir with 256 char should fail, but did not"
10520         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10521                 error "create with 255 char failed"
10522         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10523                 error "create with 256 char should fail, but did not"
10524
10525         ls -l $DIR/$tdir
10526         rm -rf $DIR/$tdir
10527 }
10528 run_test 110 "filename length checking"
10529
10530 #
10531 # Purpose: To verify dynamic thread (OSS) creation.
10532 #
10533 test_115() {
10534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10535         remote_ost_nodsh && skip "remote OST with nodsh"
10536
10537         # Lustre does not stop service threads once they are started.
10538         # Reset number of running threads to default.
10539         stopall
10540         setupall
10541
10542         local OSTIO_pre
10543         local save_params="$TMP/sanity-$TESTNAME.parameters"
10544
10545         # Get ll_ost_io count before I/O
10546         OSTIO_pre=$(do_facet ost1 \
10547                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10548         # Exit if lustre is not running (ll_ost_io not running).
10549         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10550
10551         echo "Starting with $OSTIO_pre threads"
10552         local thread_max=$((OSTIO_pre * 2))
10553         local rpc_in_flight=$((thread_max * 2))
10554         # Number of I/O Process proposed to be started.
10555         local nfiles
10556         local facets=$(get_facets OST)
10557
10558         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10559         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10560
10561         # Set in_flight to $rpc_in_flight
10562         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10563                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10564         nfiles=${rpc_in_flight}
10565         # Set ost thread_max to $thread_max
10566         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10567
10568         # 5 Minutes should be sufficient for max number of OSS
10569         # threads(thread_max) to be created.
10570         local timeout=300
10571
10572         # Start I/O.
10573         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10574         test_mkdir $DIR/$tdir
10575         for i in $(seq $nfiles); do
10576                 local file=$DIR/$tdir/${tfile}-$i
10577                 $LFS setstripe -c -1 -i 0 $file
10578                 ($WTL $file $timeout)&
10579         done
10580
10581         # I/O Started - Wait for thread_started to reach thread_max or report
10582         # error if thread_started is more than thread_max.
10583         echo "Waiting for thread_started to reach thread_max"
10584         local thread_started=0
10585         local end_time=$((SECONDS + timeout))
10586
10587         while [ $SECONDS -le $end_time ] ; do
10588                 echo -n "."
10589                 # Get ost i/o thread_started count.
10590                 thread_started=$(do_facet ost1 \
10591                         "$LCTL get_param \
10592                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10593                 # Break out if thread_started is equal/greater than thread_max
10594                 if [[ $thread_started -ge $thread_max ]]; then
10595                         echo ll_ost_io thread_started $thread_started, \
10596                                 equal/greater than thread_max $thread_max
10597                         break
10598                 fi
10599                 sleep 1
10600         done
10601
10602         # Cleanup - We have the numbers, Kill i/o jobs if running.
10603         jobcount=($(jobs -p))
10604         for i in $(seq 0 $((${#jobcount[@]}-1)))
10605         do
10606                 kill -9 ${jobcount[$i]}
10607                 if [ $? -ne 0 ] ; then
10608                         echo Warning: \
10609                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10610                 fi
10611         done
10612
10613         # Cleanup files left by WTL binary.
10614         for i in $(seq $nfiles); do
10615                 local file=$DIR/$tdir/${tfile}-$i
10616                 rm -rf $file
10617                 if [ $? -ne 0 ] ; then
10618                         echo "Warning: Failed to delete file $file"
10619                 fi
10620         done
10621
10622         restore_lustre_params <$save_params
10623         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10624
10625         # Error out if no new thread has started or Thread started is greater
10626         # than thread max.
10627         if [[ $thread_started -le $OSTIO_pre ||
10628                         $thread_started -gt $thread_max ]]; then
10629                 error "ll_ost_io: thread_started $thread_started" \
10630                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10631                       "No new thread started or thread started greater " \
10632                       "than thread_max."
10633         fi
10634 }
10635 run_test 115 "verify dynamic thread creation===================="
10636
10637 free_min_max () {
10638         wait_delete_completed
10639         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10640         echo "OST kbytes available: ${AVAIL[@]}"
10641         MAXV=${AVAIL[0]}
10642         MAXI=0
10643         MINV=${AVAIL[0]}
10644         MINI=0
10645         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10646                 #echo OST $i: ${AVAIL[i]}kb
10647                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10648                         MAXV=${AVAIL[i]}
10649                         MAXI=$i
10650                 fi
10651                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10652                         MINV=${AVAIL[i]}
10653                         MINI=$i
10654                 fi
10655         done
10656         echo "Min free space: OST $MINI: $MINV"
10657         echo "Max free space: OST $MAXI: $MAXV"
10658 }
10659
10660 test_116a() { # was previously test_116()
10661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10662         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10663         remote_mds_nodsh && skip "remote MDS with nodsh"
10664
10665         echo -n "Free space priority "
10666         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10667                 head -n1
10668         declare -a AVAIL
10669         free_min_max
10670
10671         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10672         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10673         trap simple_cleanup_common EXIT
10674
10675         # Check if we need to generate uneven OSTs
10676         test_mkdir -p $DIR/$tdir/OST${MINI}
10677         local FILL=$((MINV / 4))
10678         local DIFF=$((MAXV - MINV))
10679         local DIFF2=$((DIFF * 100 / MINV))
10680
10681         local threshold=$(do_facet $SINGLEMDS \
10682                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10683         threshold=${threshold%%%}
10684         echo -n "Check for uneven OSTs: "
10685         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10686
10687         if [[ $DIFF2 -gt $threshold ]]; then
10688                 echo "ok"
10689                 echo "Don't need to fill OST$MINI"
10690         else
10691                 # generate uneven OSTs. Write 2% over the QOS threshold value
10692                 echo "no"
10693                 DIFF=$((threshold - DIFF2 + 2))
10694                 DIFF2=$((MINV * DIFF / 100))
10695                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10696                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10697                         error "setstripe failed"
10698                 DIFF=$((DIFF2 / 2048))
10699                 i=0
10700                 while [ $i -lt $DIFF ]; do
10701                         i=$((i + 1))
10702                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10703                                 bs=2M count=1 2>/dev/null
10704                         echo -n .
10705                 done
10706                 echo .
10707                 sync
10708                 sleep_maxage
10709                 free_min_max
10710         fi
10711
10712         DIFF=$((MAXV - MINV))
10713         DIFF2=$((DIFF * 100 / MINV))
10714         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10715         if [ $DIFF2 -gt $threshold ]; then
10716                 echo "ok"
10717         else
10718                 echo "failed - QOS mode won't be used"
10719                 simple_cleanup_common
10720                 skip "QOS imbalance criteria not met"
10721         fi
10722
10723         MINI1=$MINI
10724         MINV1=$MINV
10725         MAXI1=$MAXI
10726         MAXV1=$MAXV
10727
10728         # now fill using QOS
10729         $LFS setstripe -c 1 $DIR/$tdir
10730         FILL=$((FILL / 200))
10731         if [ $FILL -gt 600 ]; then
10732                 FILL=600
10733         fi
10734         echo "writing $FILL files to QOS-assigned OSTs"
10735         i=0
10736         while [ $i -lt $FILL ]; do
10737                 i=$((i + 1))
10738                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10739                         count=1 2>/dev/null
10740                 echo -n .
10741         done
10742         echo "wrote $i 200k files"
10743         sync
10744         sleep_maxage
10745
10746         echo "Note: free space may not be updated, so measurements might be off"
10747         free_min_max
10748         DIFF2=$((MAXV - MINV))
10749         echo "free space delta: orig $DIFF final $DIFF2"
10750         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10751         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10752         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10753         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10754         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10755         if [[ $DIFF -gt 0 ]]; then
10756                 FILL=$((DIFF2 * 100 / DIFF - 100))
10757                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10758         fi
10759
10760         # Figure out which files were written where
10761         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10762                awk '/'$MINI1': / {print $2; exit}')
10763         echo $UUID
10764         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10765         echo "$MINC files created on smaller OST $MINI1"
10766         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10767                awk '/'$MAXI1': / {print $2; exit}')
10768         echo $UUID
10769         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10770         echo "$MAXC files created on larger OST $MAXI1"
10771         if [[ $MINC -gt 0 ]]; then
10772                 FILL=$((MAXC * 100 / MINC - 100))
10773                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10774         fi
10775         [[ $MAXC -gt $MINC ]] ||
10776                 error_ignore LU-9 "stripe QOS didn't balance free space"
10777         simple_cleanup_common
10778 }
10779 run_test 116a "stripe QOS: free space balance ==================="
10780
10781 test_116b() { # LU-2093
10782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10783         remote_mds_nodsh && skip "remote MDS with nodsh"
10784
10785 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10786         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10787                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10788         [ -z "$old_rr" ] && skip "no QOS"
10789         do_facet $SINGLEMDS lctl set_param \
10790                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10791         mkdir -p $DIR/$tdir
10792         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10793         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10794         do_facet $SINGLEMDS lctl set_param fail_loc=0
10795         rm -rf $DIR/$tdir
10796         do_facet $SINGLEMDS lctl set_param \
10797                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10798 }
10799 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10800
10801 test_117() # bug 10891
10802 {
10803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10804
10805         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10806         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10807         lctl set_param fail_loc=0x21e
10808         > $DIR/$tfile || error "truncate failed"
10809         lctl set_param fail_loc=0
10810         echo "Truncate succeeded."
10811         rm -f $DIR/$tfile
10812 }
10813 run_test 117 "verify osd extend =========="
10814
10815 NO_SLOW_RESENDCOUNT=4
10816 export OLD_RESENDCOUNT=""
10817 set_resend_count () {
10818         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10819         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10820         lctl set_param -n $PROC_RESENDCOUNT $1
10821         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10822 }
10823
10824 # for reduce test_118* time (b=14842)
10825 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10826
10827 # Reset async IO behavior after error case
10828 reset_async() {
10829         FILE=$DIR/reset_async
10830
10831         # Ensure all OSCs are cleared
10832         $LFS setstripe -c -1 $FILE
10833         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10834         sync
10835         rm $FILE
10836 }
10837
10838 test_118a() #bug 11710
10839 {
10840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10841
10842         reset_async
10843
10844         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10845         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10846         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10847
10848         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10849                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10850                 return 1;
10851         fi
10852         rm -f $DIR/$tfile
10853 }
10854 run_test 118a "verify O_SYNC works =========="
10855
10856 test_118b()
10857 {
10858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10859         remote_ost_nodsh && skip "remote OST with nodsh"
10860
10861         reset_async
10862
10863         #define OBD_FAIL_SRV_ENOENT 0x217
10864         set_nodes_failloc "$(osts_nodes)" 0x217
10865         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10866         RC=$?
10867         set_nodes_failloc "$(osts_nodes)" 0
10868         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10869         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10870                     grep -c writeback)
10871
10872         if [[ $RC -eq 0 ]]; then
10873                 error "Must return error due to dropped pages, rc=$RC"
10874                 return 1;
10875         fi
10876
10877         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10878                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10879                 return 1;
10880         fi
10881
10882         echo "Dirty pages not leaked on ENOENT"
10883
10884         # Due to the above error the OSC will issue all RPCs syncronously
10885         # until a subsequent RPC completes successfully without error.
10886         $MULTIOP $DIR/$tfile Ow4096yc
10887         rm -f $DIR/$tfile
10888
10889         return 0
10890 }
10891 run_test 118b "Reclaim dirty pages on fatal error =========="
10892
10893 test_118c()
10894 {
10895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10896
10897         # for 118c, restore the original resend count, LU-1940
10898         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10899                                 set_resend_count $OLD_RESENDCOUNT
10900         remote_ost_nodsh && skip "remote OST with nodsh"
10901
10902         reset_async
10903
10904         #define OBD_FAIL_OST_EROFS               0x216
10905         set_nodes_failloc "$(osts_nodes)" 0x216
10906
10907         # multiop should block due to fsync until pages are written
10908         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10909         MULTIPID=$!
10910         sleep 1
10911
10912         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10913                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10914         fi
10915
10916         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10917                     grep -c writeback)
10918         if [[ $WRITEBACK -eq 0 ]]; then
10919                 error "No page in writeback, writeback=$WRITEBACK"
10920         fi
10921
10922         set_nodes_failloc "$(osts_nodes)" 0
10923         wait $MULTIPID
10924         RC=$?
10925         if [[ $RC -ne 0 ]]; then
10926                 error "Multiop fsync failed, rc=$RC"
10927         fi
10928
10929         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10930         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10931                     grep -c writeback)
10932         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10933                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10934         fi
10935
10936         rm -f $DIR/$tfile
10937         echo "Dirty pages flushed via fsync on EROFS"
10938         return 0
10939 }
10940 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10941
10942 # continue to use small resend count to reduce test_118* time (b=14842)
10943 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10944
10945 test_118d()
10946 {
10947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10948         remote_ost_nodsh && skip "remote OST with nodsh"
10949
10950         reset_async
10951
10952         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10953         set_nodes_failloc "$(osts_nodes)" 0x214
10954         # multiop should block due to fsync until pages are written
10955         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10956         MULTIPID=$!
10957         sleep 1
10958
10959         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10960                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10961         fi
10962
10963         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10964                     grep -c writeback)
10965         if [[ $WRITEBACK -eq 0 ]]; then
10966                 error "No page in writeback, writeback=$WRITEBACK"
10967         fi
10968
10969         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10970         set_nodes_failloc "$(osts_nodes)" 0
10971
10972         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10973         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10974                     grep -c writeback)
10975         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10976                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10977         fi
10978
10979         rm -f $DIR/$tfile
10980         echo "Dirty pages gaurenteed flushed via fsync"
10981         return 0
10982 }
10983 run_test 118d "Fsync validation inject a delay of the bulk =========="
10984
10985 test_118f() {
10986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10987
10988         reset_async
10989
10990         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10991         lctl set_param fail_loc=0x8000040a
10992
10993         # Should simulate EINVAL error which is fatal
10994         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10995         RC=$?
10996         if [[ $RC -eq 0 ]]; then
10997                 error "Must return error due to dropped pages, rc=$RC"
10998         fi
10999
11000         lctl set_param fail_loc=0x0
11001
11002         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11003         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11004         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11005                     grep -c writeback)
11006         if [[ $LOCKED -ne 0 ]]; then
11007                 error "Locked pages remain in cache, locked=$LOCKED"
11008         fi
11009
11010         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11011                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11012         fi
11013
11014         rm -f $DIR/$tfile
11015         echo "No pages locked after fsync"
11016
11017         reset_async
11018         return 0
11019 }
11020 run_test 118f "Simulate unrecoverable OSC side error =========="
11021
11022 test_118g() {
11023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11024
11025         reset_async
11026
11027         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11028         lctl set_param fail_loc=0x406
11029
11030         # simulate local -ENOMEM
11031         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11032         RC=$?
11033
11034         lctl set_param fail_loc=0
11035         if [[ $RC -eq 0 ]]; then
11036                 error "Must return error due to dropped pages, rc=$RC"
11037         fi
11038
11039         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11040         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11041         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11042                         grep -c writeback)
11043         if [[ $LOCKED -ne 0 ]]; then
11044                 error "Locked pages remain in cache, locked=$LOCKED"
11045         fi
11046
11047         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11048                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11049         fi
11050
11051         rm -f $DIR/$tfile
11052         echo "No pages locked after fsync"
11053
11054         reset_async
11055         return 0
11056 }
11057 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11058
11059 test_118h() {
11060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11061         remote_ost_nodsh && skip "remote OST with nodsh"
11062
11063         reset_async
11064
11065         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11066         set_nodes_failloc "$(osts_nodes)" 0x20e
11067         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11068         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11069         RC=$?
11070
11071         set_nodes_failloc "$(osts_nodes)" 0
11072         if [[ $RC -eq 0 ]]; then
11073                 error "Must return error due to dropped pages, rc=$RC"
11074         fi
11075
11076         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11077         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11078         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11079                     grep -c writeback)
11080         if [[ $LOCKED -ne 0 ]]; then
11081                 error "Locked pages remain in cache, locked=$LOCKED"
11082         fi
11083
11084         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11085                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11086         fi
11087
11088         rm -f $DIR/$tfile
11089         echo "No pages locked after fsync"
11090
11091         return 0
11092 }
11093 run_test 118h "Verify timeout in handling recoverables errors  =========="
11094
11095 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11096
11097 test_118i() {
11098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11099         remote_ost_nodsh && skip "remote OST with nodsh"
11100
11101         reset_async
11102
11103         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11104         set_nodes_failloc "$(osts_nodes)" 0x20e
11105
11106         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11107         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11108         PID=$!
11109         sleep 5
11110         set_nodes_failloc "$(osts_nodes)" 0
11111
11112         wait $PID
11113         RC=$?
11114         if [[ $RC -ne 0 ]]; then
11115                 error "got error, but should be not, rc=$RC"
11116         fi
11117
11118         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11119         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11120         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11121         if [[ $LOCKED -ne 0 ]]; then
11122                 error "Locked pages remain in cache, locked=$LOCKED"
11123         fi
11124
11125         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11126                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11127         fi
11128
11129         rm -f $DIR/$tfile
11130         echo "No pages locked after fsync"
11131
11132         return 0
11133 }
11134 run_test 118i "Fix error before timeout in recoverable error  =========="
11135
11136 [ "$SLOW" = "no" ] && set_resend_count 4
11137
11138 test_118j() {
11139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11140         remote_ost_nodsh && skip "remote OST with nodsh"
11141
11142         reset_async
11143
11144         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11145         set_nodes_failloc "$(osts_nodes)" 0x220
11146
11147         # return -EIO from OST
11148         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11149         RC=$?
11150         set_nodes_failloc "$(osts_nodes)" 0x0
11151         if [[ $RC -eq 0 ]]; then
11152                 error "Must return error due to dropped pages, rc=$RC"
11153         fi
11154
11155         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11156         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11157         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11158         if [[ $LOCKED -ne 0 ]]; then
11159                 error "Locked pages remain in cache, locked=$LOCKED"
11160         fi
11161
11162         # in recoverable error on OST we want resend and stay until it finished
11163         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11164                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11165         fi
11166
11167         rm -f $DIR/$tfile
11168         echo "No pages locked after fsync"
11169
11170         return 0
11171 }
11172 run_test 118j "Simulate unrecoverable OST side error =========="
11173
11174 test_118k()
11175 {
11176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11177         remote_ost_nodsh && skip "remote OSTs with nodsh"
11178
11179         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11180         set_nodes_failloc "$(osts_nodes)" 0x20e
11181         test_mkdir $DIR/$tdir
11182
11183         for ((i=0;i<10;i++)); do
11184                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11185                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11186                 SLEEPPID=$!
11187                 sleep 0.500s
11188                 kill $SLEEPPID
11189                 wait $SLEEPPID
11190         done
11191
11192         set_nodes_failloc "$(osts_nodes)" 0
11193         rm -rf $DIR/$tdir
11194 }
11195 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11196
11197 test_118l() # LU-646
11198 {
11199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11200
11201         test_mkdir $DIR/$tdir
11202         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11203         rm -rf $DIR/$tdir
11204 }
11205 run_test 118l "fsync dir"
11206
11207 test_118m() # LU-3066
11208 {
11209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11210
11211         test_mkdir $DIR/$tdir
11212         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11213         rm -rf $DIR/$tdir
11214 }
11215 run_test 118m "fdatasync dir ========="
11216
11217 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11218
11219 test_118n()
11220 {
11221         local begin
11222         local end
11223
11224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11225         remote_ost_nodsh && skip "remote OSTs with nodsh"
11226
11227         # Sleep to avoid a cached response.
11228         #define OBD_STATFS_CACHE_SECONDS 1
11229         sleep 2
11230
11231         # Inject a 10 second delay in the OST_STATFS handler.
11232         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11233         set_nodes_failloc "$(osts_nodes)" 0x242
11234
11235         begin=$SECONDS
11236         stat --file-system $MOUNT > /dev/null
11237         end=$SECONDS
11238
11239         set_nodes_failloc "$(osts_nodes)" 0
11240
11241         if ((end - begin > 20)); then
11242             error "statfs took $((end - begin)) seconds, expected 10"
11243         fi
11244 }
11245 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11246
11247 test_119a() # bug 11737
11248 {
11249         BSIZE=$((512 * 1024))
11250         directio write $DIR/$tfile 0 1 $BSIZE
11251         # We ask to read two blocks, which is more than a file size.
11252         # directio will indicate an error when requested and actual
11253         # sizes aren't equeal (a normal situation in this case) and
11254         # print actual read amount.
11255         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11256         if [ "$NOB" != "$BSIZE" ]; then
11257                 error "read $NOB bytes instead of $BSIZE"
11258         fi
11259         rm -f $DIR/$tfile
11260 }
11261 run_test 119a "Short directIO read must return actual read amount"
11262
11263 test_119b() # bug 11737
11264 {
11265         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11266
11267         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11268         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11269         sync
11270         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11271                 error "direct read failed"
11272         rm -f $DIR/$tfile
11273 }
11274 run_test 119b "Sparse directIO read must return actual read amount"
11275
11276 test_119c() # bug 13099
11277 {
11278         BSIZE=1048576
11279         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11280         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11281         rm -f $DIR/$tfile
11282 }
11283 run_test 119c "Testing for direct read hitting hole"
11284
11285 test_119d() # bug 15950
11286 {
11287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11288
11289         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11290         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11291         BSIZE=1048576
11292         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11293         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11294         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11295         lctl set_param fail_loc=0x40d
11296         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11297         pid_dio=$!
11298         sleep 1
11299         cat $DIR/$tfile > /dev/null &
11300         lctl set_param fail_loc=0
11301         pid_reads=$!
11302         wait $pid_dio
11303         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11304         sleep 2
11305         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11306         error "the read rpcs have not completed in 2s"
11307         rm -f $DIR/$tfile
11308         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11309 }
11310 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11311
11312 test_120a() {
11313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11314         remote_mds_nodsh && skip "remote MDS with nodsh"
11315         test_mkdir -i0 -c1 $DIR/$tdir
11316         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11317                 skip_env "no early lock cancel on server"
11318
11319         lru_resize_disable mdc
11320         lru_resize_disable osc
11321         cancel_lru_locks mdc
11322         # asynchronous object destroy at MDT could cause bl ast to client
11323         cancel_lru_locks osc
11324
11325         stat $DIR/$tdir > /dev/null
11326         can1=$(do_facet mds1 \
11327                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11328                awk '/ldlm_cancel/ {print $2}')
11329         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11330                awk '/ldlm_bl_callback/ {print $2}')
11331         test_mkdir -i0 -c1 $DIR/$tdir/d1
11332         can2=$(do_facet mds1 \
11333                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11334                awk '/ldlm_cancel/ {print $2}')
11335         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11336                awk '/ldlm_bl_callback/ {print $2}')
11337         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11338         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11339         lru_resize_enable mdc
11340         lru_resize_enable osc
11341 }
11342 run_test 120a "Early Lock Cancel: mkdir test"
11343
11344 test_120b() {
11345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11346         remote_mds_nodsh && skip "remote MDS with nodsh"
11347         test_mkdir $DIR/$tdir
11348         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11349                 skip_env "no early lock cancel on server"
11350
11351         lru_resize_disable mdc
11352         lru_resize_disable osc
11353         cancel_lru_locks mdc
11354         stat $DIR/$tdir > /dev/null
11355         can1=$(do_facet $SINGLEMDS \
11356                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11357                awk '/ldlm_cancel/ {print $2}')
11358         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11359                awk '/ldlm_bl_callback/ {print $2}')
11360         touch $DIR/$tdir/f1
11361         can2=$(do_facet $SINGLEMDS \
11362                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11363                awk '/ldlm_cancel/ {print $2}')
11364         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11365                awk '/ldlm_bl_callback/ {print $2}')
11366         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11367         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11368         lru_resize_enable mdc
11369         lru_resize_enable osc
11370 }
11371 run_test 120b "Early Lock Cancel: create test"
11372
11373 test_120c() {
11374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11375         remote_mds_nodsh && skip "remote MDS with nodsh"
11376         test_mkdir -i0 -c1 $DIR/$tdir
11377         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11378                 skip "no early lock cancel on server"
11379
11380         lru_resize_disable mdc
11381         lru_resize_disable osc
11382         test_mkdir -i0 -c1 $DIR/$tdir/d1
11383         test_mkdir -i0 -c1 $DIR/$tdir/d2
11384         touch $DIR/$tdir/d1/f1
11385         cancel_lru_locks mdc
11386         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11387         can1=$(do_facet mds1 \
11388                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11389                awk '/ldlm_cancel/ {print $2}')
11390         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11391                awk '/ldlm_bl_callback/ {print $2}')
11392         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11393         can2=$(do_facet mds1 \
11394                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11395                awk '/ldlm_cancel/ {print $2}')
11396         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11397                awk '/ldlm_bl_callback/ {print $2}')
11398         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11399         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11400         lru_resize_enable mdc
11401         lru_resize_enable osc
11402 }
11403 run_test 120c "Early Lock Cancel: link test"
11404
11405 test_120d() {
11406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11407         remote_mds_nodsh && skip "remote MDS with nodsh"
11408         test_mkdir -i0 -c1 $DIR/$tdir
11409         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11410                 skip_env "no early lock cancel on server"
11411
11412         lru_resize_disable mdc
11413         lru_resize_disable osc
11414         touch $DIR/$tdir
11415         cancel_lru_locks mdc
11416         stat $DIR/$tdir > /dev/null
11417         can1=$(do_facet mds1 \
11418                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11419                awk '/ldlm_cancel/ {print $2}')
11420         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11421                awk '/ldlm_bl_callback/ {print $2}')
11422         chmod a+x $DIR/$tdir
11423         can2=$(do_facet mds1 \
11424                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11425                awk '/ldlm_cancel/ {print $2}')
11426         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11427                awk '/ldlm_bl_callback/ {print $2}')
11428         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11429         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11430         lru_resize_enable mdc
11431         lru_resize_enable osc
11432 }
11433 run_test 120d "Early Lock Cancel: setattr test"
11434
11435 test_120e() {
11436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11437         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11438                 skip_env "no early lock cancel on server"
11439         remote_mds_nodsh && skip "remote MDS with nodsh"
11440
11441         local dlmtrace_set=false
11442
11443         test_mkdir -i0 -c1 $DIR/$tdir
11444         lru_resize_disable mdc
11445         lru_resize_disable osc
11446         ! $LCTL get_param debug | grep -q dlmtrace &&
11447                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11448         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11449         cancel_lru_locks mdc
11450         cancel_lru_locks osc
11451         dd if=$DIR/$tdir/f1 of=/dev/null
11452         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11453         # XXX client can not do early lock cancel of OST lock
11454         # during unlink (LU-4206), so cancel osc lock now.
11455         sleep 2
11456         cancel_lru_locks osc
11457         can1=$(do_facet mds1 \
11458                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11459                awk '/ldlm_cancel/ {print $2}')
11460         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11461                awk '/ldlm_bl_callback/ {print $2}')
11462         unlink $DIR/$tdir/f1
11463         sleep 5
11464         can2=$(do_facet mds1 \
11465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11466                awk '/ldlm_cancel/ {print $2}')
11467         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11468                awk '/ldlm_bl_callback/ {print $2}')
11469         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11470                 $LCTL dk $TMP/cancel.debug.txt
11471         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11472                 $LCTL dk $TMP/blocking.debug.txt
11473         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11474         lru_resize_enable mdc
11475         lru_resize_enable osc
11476 }
11477 run_test 120e "Early Lock Cancel: unlink test"
11478
11479 test_120f() {
11480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11481         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11482                 skip_env "no early lock cancel on server"
11483         remote_mds_nodsh && skip "remote MDS with nodsh"
11484
11485         test_mkdir -i0 -c1 $DIR/$tdir
11486         lru_resize_disable mdc
11487         lru_resize_disable osc
11488         test_mkdir -i0 -c1 $DIR/$tdir/d1
11489         test_mkdir -i0 -c1 $DIR/$tdir/d2
11490         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11491         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11492         cancel_lru_locks mdc
11493         cancel_lru_locks osc
11494         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11495         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11496         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11497         # XXX client can not do early lock cancel of OST lock
11498         # during rename (LU-4206), so cancel osc lock now.
11499         sleep 2
11500         cancel_lru_locks osc
11501         can1=$(do_facet mds1 \
11502                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11503                awk '/ldlm_cancel/ {print $2}')
11504         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11505                awk '/ldlm_bl_callback/ {print $2}')
11506         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11507         sleep 5
11508         can2=$(do_facet mds1 \
11509                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11510                awk '/ldlm_cancel/ {print $2}')
11511         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11512                awk '/ldlm_bl_callback/ {print $2}')
11513         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11514         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11515         lru_resize_enable mdc
11516         lru_resize_enable osc
11517 }
11518 run_test 120f "Early Lock Cancel: rename test"
11519
11520 test_120g() {
11521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11522         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11523                 skip_env "no early lock cancel on server"
11524         remote_mds_nodsh && skip "remote MDS with nodsh"
11525
11526         lru_resize_disable mdc
11527         lru_resize_disable osc
11528         count=10000
11529         echo create $count files
11530         test_mkdir $DIR/$tdir
11531         cancel_lru_locks mdc
11532         cancel_lru_locks osc
11533         t0=$(date +%s)
11534
11535         can0=$(do_facet $SINGLEMDS \
11536                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11537                awk '/ldlm_cancel/ {print $2}')
11538         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11539                awk '/ldlm_bl_callback/ {print $2}')
11540         createmany -o $DIR/$tdir/f $count
11541         sync
11542         can1=$(do_facet $SINGLEMDS \
11543                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11544                awk '/ldlm_cancel/ {print $2}')
11545         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11546                awk '/ldlm_bl_callback/ {print $2}')
11547         t1=$(date +%s)
11548         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11549         echo rm $count files
11550         rm -r $DIR/$tdir
11551         sync
11552         can2=$(do_facet $SINGLEMDS \
11553                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11554                awk '/ldlm_cancel/ {print $2}')
11555         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11556                awk '/ldlm_bl_callback/ {print $2}')
11557         t2=$(date +%s)
11558         echo total: $count removes in $((t2-t1))
11559         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11560         sleep 2
11561         # wait for commitment of removal
11562         lru_resize_enable mdc
11563         lru_resize_enable osc
11564 }
11565 run_test 120g "Early Lock Cancel: performance test"
11566
11567 test_121() { #bug #10589
11568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11569
11570         rm -rf $DIR/$tfile
11571         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11572 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11573         lctl set_param fail_loc=0x310
11574         cancel_lru_locks osc > /dev/null
11575         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11576         lctl set_param fail_loc=0
11577         [[ $reads -eq $writes ]] ||
11578                 error "read $reads blocks, must be $writes blocks"
11579 }
11580 run_test 121 "read cancel race ========="
11581
11582 test_123a_base() { # was test 123, statahead(bug 11401)
11583         local lsx="$1"
11584
11585         SLOWOK=0
11586         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11587                 log "testing UP system. Performance may be lower than expected."
11588                 SLOWOK=1
11589         fi
11590
11591         rm -rf $DIR/$tdir
11592         test_mkdir $DIR/$tdir
11593         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11594         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11595         MULT=10
11596         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11597                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11598
11599                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11600                 lctl set_param -n llite.*.statahead_max 0
11601                 lctl get_param llite.*.statahead_max
11602                 cancel_lru_locks mdc
11603                 cancel_lru_locks osc
11604                 stime=$(date +%s)
11605                 time $lsx $DIR/$tdir | wc -l
11606                 etime=$(date +%s)
11607                 delta=$((etime - stime))
11608                 log "$lsx $i files without statahead: $delta sec"
11609                 lctl set_param llite.*.statahead_max=$max
11610
11611                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11612                         grep "statahead wrong:" | awk '{print $3}')
11613                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11614                 cancel_lru_locks mdc
11615                 cancel_lru_locks osc
11616                 stime=$(date +%s)
11617                 time $lsx $DIR/$tdir | wc -l
11618                 etime=$(date +%s)
11619                 delta_sa=$((etime - stime))
11620                 log "$lsx $i files with statahead: $delta_sa sec"
11621                 lctl get_param -n llite.*.statahead_stats
11622                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11623                         grep "statahead wrong:" | awk '{print $3}')
11624
11625                 [[ $swrong -lt $ewrong ]] &&
11626                         log "statahead was stopped, maybe too many locks held!"
11627                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11628
11629                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11630                         max=$(lctl get_param -n llite.*.statahead_max |
11631                                 head -n 1)
11632                         lctl set_param -n llite.*.statahead_max 0
11633                         lctl get_param llite.*.statahead_max
11634                         cancel_lru_locks mdc
11635                         cancel_lru_locks osc
11636                         stime=$(date +%s)
11637                         time $lsx $DIR/$tdir | wc -l
11638                         etime=$(date +%s)
11639                         delta=$((etime - stime))
11640                         log "$lsx $i files again without statahead: $delta sec"
11641                         lctl set_param llite.*.statahead_max=$max
11642                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11643                                 if [  $SLOWOK -eq 0 ]; then
11644                                         error "$lsx $i files is slower with statahead!"
11645                                 else
11646                                         log "$lsx $i files is slower with statahead!"
11647                                 fi
11648                                 break
11649                         fi
11650                 fi
11651
11652                 [ $delta -gt 20 ] && break
11653                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11654                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11655         done
11656         log "$lsx done"
11657
11658         stime=$(date +%s)
11659         rm -r $DIR/$tdir
11660         sync
11661         etime=$(date +%s)
11662         delta=$((etime - stime))
11663         log "rm -r $DIR/$tdir/: $delta seconds"
11664         log "rm done"
11665         lctl get_param -n llite.*.statahead_stats
11666 }
11667
11668 test_123aa() {
11669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11670
11671         test_123a_base "ls -l"
11672 }
11673 run_test 123aa "verify statahead work"
11674
11675 test_123ab() {
11676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11677
11678         statx_supported || skip_env "Test must be statx() syscall supported"
11679
11680         test_123a_base "$STATX -l"
11681 }
11682 run_test 123ab "verify statahead work by using statx"
11683
11684 test_123ac() {
11685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11686
11687         statx_supported || skip_env "Test must be statx() syscall supported"
11688
11689         local rpcs_before
11690         local rpcs_after
11691         local agl_before
11692         local agl_after
11693
11694         cancel_lru_locks $OSC
11695         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11696         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11697                 awk '/agl.total:/ {print $3}')
11698         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11699         test_123a_base "$STATX --cached=always -D"
11700         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11701                 awk '/agl.total:/ {print $3}')
11702         [ $agl_before -eq $agl_after ] ||
11703                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11704         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11705         [ $rpcs_after -eq $rpcs_before ] ||
11706                 error "$STATX should not send glimpse RPCs to $OSC"
11707 }
11708 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11709
11710 test_123b () { # statahead(bug 15027)
11711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11712
11713         test_mkdir $DIR/$tdir
11714         createmany -o $DIR/$tdir/$tfile-%d 1000
11715
11716         cancel_lru_locks mdc
11717         cancel_lru_locks osc
11718
11719 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11720         lctl set_param fail_loc=0x80000803
11721         ls -lR $DIR/$tdir > /dev/null
11722         log "ls done"
11723         lctl set_param fail_loc=0x0
11724         lctl get_param -n llite.*.statahead_stats
11725         rm -r $DIR/$tdir
11726         sync
11727
11728 }
11729 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11730
11731 test_123c() {
11732         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11733
11734         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11735         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11736         touch $DIR/$tdir.1/{1..3}
11737         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11738
11739         remount_client $MOUNT
11740
11741         $MULTIOP $DIR/$tdir.0 Q
11742
11743         # let statahead to complete
11744         ls -l $DIR/$tdir.0 > /dev/null
11745
11746         testid=$(echo $TESTNAME | tr '_' ' ')
11747         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11748                 error "statahead warning" || true
11749 }
11750 run_test 123c "Can not initialize inode warning on DNE statahead"
11751
11752 test_124a() {
11753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11754         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11755                 skip_env "no lru resize on server"
11756
11757         local NR=2000
11758
11759         test_mkdir $DIR/$tdir
11760
11761         log "create $NR files at $DIR/$tdir"
11762         createmany -o $DIR/$tdir/f $NR ||
11763                 error "failed to create $NR files in $DIR/$tdir"
11764
11765         cancel_lru_locks mdc
11766         ls -l $DIR/$tdir > /dev/null
11767
11768         local NSDIR=""
11769         local LRU_SIZE=0
11770         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11771                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11772                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11773                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11774                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11775                         log "NSDIR=$NSDIR"
11776                         log "NS=$(basename $NSDIR)"
11777                         break
11778                 fi
11779         done
11780
11781         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11782                 skip "Not enough cached locks created!"
11783         fi
11784         log "LRU=$LRU_SIZE"
11785
11786         local SLEEP=30
11787
11788         # We know that lru resize allows one client to hold $LIMIT locks
11789         # for 10h. After that locks begin to be killed by client.
11790         local MAX_HRS=10
11791         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11792         log "LIMIT=$LIMIT"
11793         if [ $LIMIT -lt $LRU_SIZE ]; then
11794                 skip "Limit is too small $LIMIT"
11795         fi
11796
11797         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11798         # killing locks. Some time was spent for creating locks. This means
11799         # that up to the moment of sleep finish we must have killed some of
11800         # them (10-100 locks). This depends on how fast ther were created.
11801         # Many of them were touched in almost the same moment and thus will
11802         # be killed in groups.
11803         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11804
11805         # Use $LRU_SIZE_B here to take into account real number of locks
11806         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11807         local LRU_SIZE_B=$LRU_SIZE
11808         log "LVF=$LVF"
11809         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11810         log "OLD_LVF=$OLD_LVF"
11811         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11812
11813         # Let's make sure that we really have some margin. Client checks
11814         # cached locks every 10 sec.
11815         SLEEP=$((SLEEP+20))
11816         log "Sleep ${SLEEP} sec"
11817         local SEC=0
11818         while ((SEC<$SLEEP)); do
11819                 echo -n "..."
11820                 sleep 5
11821                 SEC=$((SEC+5))
11822                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11823                 echo -n "$LRU_SIZE"
11824         done
11825         echo ""
11826         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11827         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11828
11829         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11830                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11831                 unlinkmany $DIR/$tdir/f $NR
11832                 return
11833         }
11834
11835         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11836         log "unlink $NR files at $DIR/$tdir"
11837         unlinkmany $DIR/$tdir/f $NR
11838 }
11839 run_test 124a "lru resize ======================================="
11840
11841 get_max_pool_limit()
11842 {
11843         local limit=$($LCTL get_param \
11844                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11845         local max=0
11846         for l in $limit; do
11847                 if [[ $l -gt $max ]]; then
11848                         max=$l
11849                 fi
11850         done
11851         echo $max
11852 }
11853
11854 test_124b() {
11855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11856         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11857                 skip_env "no lru resize on server"
11858
11859         LIMIT=$(get_max_pool_limit)
11860
11861         NR=$(($(default_lru_size)*20))
11862         if [[ $NR -gt $LIMIT ]]; then
11863                 log "Limit lock number by $LIMIT locks"
11864                 NR=$LIMIT
11865         fi
11866
11867         IFree=$(mdsrate_inodes_available)
11868         if [ $IFree -lt $NR ]; then
11869                 log "Limit lock number by $IFree inodes"
11870                 NR=$IFree
11871         fi
11872
11873         lru_resize_disable mdc
11874         test_mkdir -p $DIR/$tdir/disable_lru_resize
11875
11876         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11877         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11878         cancel_lru_locks mdc
11879         stime=`date +%s`
11880         PID=""
11881         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11882         PID="$PID $!"
11883         sleep 2
11884         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11885         PID="$PID $!"
11886         sleep 2
11887         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11888         PID="$PID $!"
11889         wait $PID
11890         etime=`date +%s`
11891         nolruresize_delta=$((etime-stime))
11892         log "ls -la time: $nolruresize_delta seconds"
11893         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11894         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11895
11896         lru_resize_enable mdc
11897         test_mkdir -p $DIR/$tdir/enable_lru_resize
11898
11899         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11900         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11901         cancel_lru_locks mdc
11902         stime=`date +%s`
11903         PID=""
11904         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11905         PID="$PID $!"
11906         sleep 2
11907         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11908         PID="$PID $!"
11909         sleep 2
11910         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11911         PID="$PID $!"
11912         wait $PID
11913         etime=`date +%s`
11914         lruresize_delta=$((etime-stime))
11915         log "ls -la time: $lruresize_delta seconds"
11916         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11917
11918         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11919                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11920         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11921                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11922         else
11923                 log "lru resize performs the same with no lru resize"
11924         fi
11925         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11926 }
11927 run_test 124b "lru resize (performance test) ======================="
11928
11929 test_124c() {
11930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11931         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11932                 skip_env "no lru resize on server"
11933
11934         # cache ununsed locks on client
11935         local nr=100
11936         cancel_lru_locks mdc
11937         test_mkdir $DIR/$tdir
11938         createmany -o $DIR/$tdir/f $nr ||
11939                 error "failed to create $nr files in $DIR/$tdir"
11940         ls -l $DIR/$tdir > /dev/null
11941
11942         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11943         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11944         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11945         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11946         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11947
11948         # set lru_max_age to 1 sec
11949         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11950         echo "sleep $((recalc_p * 2)) seconds..."
11951         sleep $((recalc_p * 2))
11952
11953         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11954         # restore lru_max_age
11955         $LCTL set_param -n $nsdir.lru_max_age $max_age
11956         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11957         unlinkmany $DIR/$tdir/f $nr
11958 }
11959 run_test 124c "LRUR cancel very aged locks"
11960
11961 test_124d() {
11962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11963         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11964                 skip_env "no lru resize on server"
11965
11966         # cache ununsed locks on client
11967         local nr=100
11968
11969         lru_resize_disable mdc
11970         stack_trap "lru_resize_enable mdc" EXIT
11971
11972         cancel_lru_locks mdc
11973
11974         # asynchronous object destroy at MDT could cause bl ast to client
11975         test_mkdir $DIR/$tdir
11976         createmany -o $DIR/$tdir/f $nr ||
11977                 error "failed to create $nr files in $DIR/$tdir"
11978         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11979
11980         ls -l $DIR/$tdir > /dev/null
11981
11982         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11983         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11984         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11985         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11986
11987         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11988
11989         # set lru_max_age to 1 sec
11990         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11991         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11992
11993         echo "sleep $((recalc_p * 2)) seconds..."
11994         sleep $((recalc_p * 2))
11995
11996         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11997
11998         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11999 }
12000 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12001
12002 test_125() { # 13358
12003         $LCTL get_param -n llite.*.client_type | grep -q local ||
12004                 skip "must run as local client"
12005         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12006                 skip_env "must have acl enabled"
12007         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12008
12009         test_mkdir $DIR/$tdir
12010         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12011         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12012         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12013 }
12014 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12015
12016 test_126() { # bug 12829/13455
12017         $GSS && skip_env "must run as gss disabled"
12018         $LCTL get_param -n llite.*.client_type | grep -q local ||
12019                 skip "must run as local client"
12020         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12021
12022         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12023         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12024         rm -f $DIR/$tfile
12025         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12026 }
12027 run_test 126 "check that the fsgid provided by the client is taken into account"
12028
12029 test_127a() { # bug 15521
12030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12031         local name count samp unit min max sum sumsq
12032
12033         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12034         echo "stats before reset"
12035         $LCTL get_param osc.*.stats
12036         $LCTL set_param osc.*.stats=0
12037         local fsize=$((2048 * 1024))
12038
12039         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12040         cancel_lru_locks osc
12041         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12042
12043         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12044         stack_trap "rm -f $TMP/$tfile.tmp"
12045         while read name count samp unit min max sum sumsq; do
12046                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12047                 [ ! $min ] && error "Missing min value for $name proc entry"
12048                 eval $name=$count || error "Wrong proc format"
12049
12050                 case $name in
12051                 read_bytes|write_bytes)
12052                         [[ "$unit" =~ "bytes" ]] ||
12053                                 error "unit is not 'bytes': $unit"
12054                         (( $min >= 4096 )) || error "min is too small: $min"
12055                         (( $min <= $fsize )) || error "min is too big: $min"
12056                         (( $max >= 4096 )) || error "max is too small: $max"
12057                         (( $max <= $fsize )) || error "max is too big: $max"
12058                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12059                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12060                                 error "sumsquare is too small: $sumsq"
12061                         (( $sumsq <= $fsize * $fsize )) ||
12062                                 error "sumsquare is too big: $sumsq"
12063                         ;;
12064                 ost_read|ost_write)
12065                         [[ "$unit" =~ "usec" ]] ||
12066                                 error "unit is not 'usec': $unit"
12067                         ;;
12068                 *)      ;;
12069                 esac
12070         done < $DIR/$tfile.tmp
12071
12072         #check that we actually got some stats
12073         [ "$read_bytes" ] || error "Missing read_bytes stats"
12074         [ "$write_bytes" ] || error "Missing write_bytes stats"
12075         [ "$read_bytes" != 0 ] || error "no read done"
12076         [ "$write_bytes" != 0 ] || error "no write done"
12077 }
12078 run_test 127a "verify the client stats are sane"
12079
12080 test_127b() { # bug LU-333
12081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12082         local name count samp unit min max sum sumsq
12083
12084         echo "stats before reset"
12085         $LCTL get_param llite.*.stats
12086         $LCTL set_param llite.*.stats=0
12087
12088         # perform 2 reads and writes so MAX is different from SUM.
12089         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12090         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12091         cancel_lru_locks osc
12092         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12093         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12094
12095         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12096         stack_trap "rm -f $TMP/$tfile.tmp"
12097         while read name count samp unit min max sum sumsq; do
12098                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12099                 eval $name=$count || error "Wrong proc format"
12100
12101                 case $name in
12102                 read_bytes|write_bytes)
12103                         [[ "$unit" =~ "bytes" ]] ||
12104                                 error "unit is not 'bytes': $unit"
12105                         (( $count == 2 )) || error "count is not 2: $count"
12106                         (( $min == $PAGE_SIZE )) ||
12107                                 error "min is not $PAGE_SIZE: $min"
12108                         (( $max == $PAGE_SIZE )) ||
12109                                 error "max is not $PAGE_SIZE: $max"
12110                         (( $sum == $PAGE_SIZE * 2 )) ||
12111                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12112                         ;;
12113                 read|write)
12114                         [[ "$unit" =~ "usec" ]] ||
12115                                 error "unit is not 'usec': $unit"
12116                         ;;
12117                 *)      ;;
12118                 esac
12119         done < $TMP/$tfile.tmp
12120
12121         #check that we actually got some stats
12122         [ "$read_bytes" ] || error "Missing read_bytes stats"
12123         [ "$write_bytes" ] || error "Missing write_bytes stats"
12124         [ "$read_bytes" != 0 ] || error "no read done"
12125         [ "$write_bytes" != 0 ] || error "no write done"
12126 }
12127 run_test 127b "verify the llite client stats are sane"
12128
12129 test_127c() { # LU-12394
12130         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12131         local size
12132         local bsize
12133         local reads
12134         local writes
12135         local count
12136
12137         $LCTL set_param llite.*.extents_stats=1
12138         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12139
12140         # Use two stripes so there is enough space in default config
12141         $LFS setstripe -c 2 $DIR/$tfile
12142
12143         # Extent stats start at 0-4K and go in power of two buckets
12144         # LL_HIST_START = 12 --> 2^12 = 4K
12145         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12146         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12147         # small configs
12148         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12149                 do
12150                 # Write and read, 2x each, second time at a non-zero offset
12151                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12152                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12153                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12154                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12155                 rm -f $DIR/$tfile
12156         done
12157
12158         $LCTL get_param llite.*.extents_stats
12159
12160         count=2
12161         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12162                 do
12163                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12164                                 grep -m 1 $bsize)
12165                 reads=$(echo $bucket | awk '{print $5}')
12166                 writes=$(echo $bucket | awk '{print $9}')
12167                 [ "$reads" -eq $count ] ||
12168                         error "$reads reads in < $bsize bucket, expect $count"
12169                 [ "$writes" -eq $count ] ||
12170                         error "$writes writes in < $bsize bucket, expect $count"
12171         done
12172
12173         # Test mmap write and read
12174         $LCTL set_param llite.*.extents_stats=c
12175         size=512
12176         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12177         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12178         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12179
12180         $LCTL get_param llite.*.extents_stats
12181
12182         count=$(((size*1024) / PAGE_SIZE))
12183
12184         bsize=$((2 * PAGE_SIZE / 1024))K
12185
12186         bucket=$($LCTL get_param -n llite.*.extents_stats |
12187                         grep -m 1 $bsize)
12188         reads=$(echo $bucket | awk '{print $5}')
12189         writes=$(echo $bucket | awk '{print $9}')
12190         # mmap writes fault in the page first, creating an additonal read
12191         [ "$reads" -eq $((2 * count)) ] ||
12192                 error "$reads reads in < $bsize bucket, expect $count"
12193         [ "$writes" -eq $count ] ||
12194                 error "$writes writes in < $bsize bucket, expect $count"
12195 }
12196 run_test 127c "test llite extent stats with regular & mmap i/o"
12197
12198 test_128() { # bug 15212
12199         touch $DIR/$tfile
12200         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12201                 find $DIR/$tfile
12202                 find $DIR/$tfile
12203         EOF
12204
12205         result=$(grep error $TMP/$tfile.log)
12206         rm -f $DIR/$tfile $TMP/$tfile.log
12207         [ -z "$result" ] ||
12208                 error "consecutive find's under interactive lfs failed"
12209 }
12210 run_test 128 "interactive lfs for 2 consecutive find's"
12211
12212 set_dir_limits () {
12213         local mntdev
12214         local canondev
12215         local node
12216
12217         local ldproc=/proc/fs/ldiskfs
12218         local facets=$(get_facets MDS)
12219
12220         for facet in ${facets//,/ }; do
12221                 canondev=$(ldiskfs_canon \
12222                            *.$(convert_facet2label $facet).mntdev $facet)
12223                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12224                         ldproc=/sys/fs/ldiskfs
12225                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12226                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12227         done
12228 }
12229
12230 check_mds_dmesg() {
12231         local facets=$(get_facets MDS)
12232         for facet in ${facets//,/ }; do
12233                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12234         done
12235         return 1
12236 }
12237
12238 test_129() {
12239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12240         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12241                 skip "Need MDS version with at least 2.5.56"
12242         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12243                 skip_env "ldiskfs only test"
12244         fi
12245         remote_mds_nodsh && skip "remote MDS with nodsh"
12246
12247         local ENOSPC=28
12248         local has_warning=false
12249
12250         rm -rf $DIR/$tdir
12251         mkdir -p $DIR/$tdir
12252
12253         # block size of mds1
12254         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12255         set_dir_limits $maxsize $((maxsize * 6 / 8))
12256         stack_trap "set_dir_limits 0 0"
12257         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12258         local dirsize=$(stat -c%s "$DIR/$tdir")
12259         local nfiles=0
12260         while (( $dirsize <= $maxsize )); do
12261                 $MCREATE $DIR/$tdir/file_base_$nfiles
12262                 rc=$?
12263                 # check two errors:
12264                 # ENOSPC for ext4 max_dir_size, which has been used since
12265                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12266                 if (( rc == ENOSPC )); then
12267                         set_dir_limits 0 0
12268                         echo "rc=$rc returned as expected after $nfiles files"
12269
12270                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12271                                 error "create failed w/o dir size limit"
12272
12273                         # messages may be rate limited if test is run repeatedly
12274                         check_mds_dmesg '"is approaching max"' ||
12275                                 echo "warning message should be output"
12276                         check_mds_dmesg '"has reached max"' ||
12277                                 echo "reached message should be output"
12278
12279                         dirsize=$(stat -c%s "$DIR/$tdir")
12280
12281                         [[ $dirsize -ge $maxsize ]] && return 0
12282                         error "dirsize $dirsize < $maxsize after $nfiles files"
12283                 elif (( rc != 0 )); then
12284                         break
12285                 fi
12286                 nfiles=$((nfiles + 1))
12287                 dirsize=$(stat -c%s "$DIR/$tdir")
12288         done
12289
12290         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12291 }
12292 run_test 129 "test directory size limit ========================"
12293
12294 OLDIFS="$IFS"
12295 cleanup_130() {
12296         trap 0
12297         IFS="$OLDIFS"
12298 }
12299
12300 test_130a() {
12301         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12302         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12303
12304         trap cleanup_130 EXIT RETURN
12305
12306         local fm_file=$DIR/$tfile
12307         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12308         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12309                 error "dd failed for $fm_file"
12310
12311         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12312         filefrag -ves $fm_file
12313         RC=$?
12314         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12315                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12316         [ $RC != 0 ] && error "filefrag $fm_file failed"
12317
12318         filefrag_op=$(filefrag -ve -k $fm_file |
12319                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12320         lun=$($LFS getstripe -i $fm_file)
12321
12322         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12323         IFS=$'\n'
12324         tot_len=0
12325         for line in $filefrag_op
12326         do
12327                 frag_lun=`echo $line | cut -d: -f5`
12328                 ext_len=`echo $line | cut -d: -f4`
12329                 if (( $frag_lun != $lun )); then
12330                         cleanup_130
12331                         error "FIEMAP on 1-stripe file($fm_file) failed"
12332                         return
12333                 fi
12334                 (( tot_len += ext_len ))
12335         done
12336
12337         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12338                 cleanup_130
12339                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12340                 return
12341         fi
12342
12343         cleanup_130
12344
12345         echo "FIEMAP on single striped file succeeded"
12346 }
12347 run_test 130a "FIEMAP (1-stripe file)"
12348
12349 test_130b() {
12350         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12351
12352         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12353         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12354
12355         trap cleanup_130 EXIT RETURN
12356
12357         local fm_file=$DIR/$tfile
12358         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12359                         error "setstripe on $fm_file"
12360         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12361                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12362
12363         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12364                 error "dd failed on $fm_file"
12365
12366         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12367         filefrag_op=$(filefrag -ve -k $fm_file |
12368                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12369
12370         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12371                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12372
12373         IFS=$'\n'
12374         tot_len=0
12375         num_luns=1
12376         for line in $filefrag_op
12377         do
12378                 frag_lun=$(echo $line | cut -d: -f5 |
12379                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12380                 ext_len=$(echo $line | cut -d: -f4)
12381                 if (( $frag_lun != $last_lun )); then
12382                         if (( tot_len != 1024 )); then
12383                                 cleanup_130
12384                                 error "FIEMAP on $fm_file failed; returned " \
12385                                 "len $tot_len for OST $last_lun instead of 1024"
12386                                 return
12387                         else
12388                                 (( num_luns += 1 ))
12389                                 tot_len=0
12390                         fi
12391                 fi
12392                 (( tot_len += ext_len ))
12393                 last_lun=$frag_lun
12394         done
12395         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12396                 cleanup_130
12397                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12398                         "luns or wrong len for OST $last_lun"
12399                 return
12400         fi
12401
12402         cleanup_130
12403
12404         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12405 }
12406 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12407
12408 test_130c() {
12409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12410
12411         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12412         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12413
12414         trap cleanup_130 EXIT RETURN
12415
12416         local fm_file=$DIR/$tfile
12417         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12418         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12419                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12420
12421         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12422                         error "dd failed on $fm_file"
12423
12424         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12425         filefrag_op=$(filefrag -ve -k $fm_file |
12426                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12427
12428         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12429                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12430
12431         IFS=$'\n'
12432         tot_len=0
12433         num_luns=1
12434         for line in $filefrag_op
12435         do
12436                 frag_lun=$(echo $line | cut -d: -f5 |
12437                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12438                 ext_len=$(echo $line | cut -d: -f4)
12439                 if (( $frag_lun != $last_lun )); then
12440                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12441                         if (( logical != 512 )); then
12442                                 cleanup_130
12443                                 error "FIEMAP on $fm_file failed; returned " \
12444                                 "logical start for lun $logical instead of 512"
12445                                 return
12446                         fi
12447                         if (( tot_len != 512 )); then
12448                                 cleanup_130
12449                                 error "FIEMAP on $fm_file failed; returned " \
12450                                 "len $tot_len for OST $last_lun instead of 1024"
12451                                 return
12452                         else
12453                                 (( num_luns += 1 ))
12454                                 tot_len=0
12455                         fi
12456                 fi
12457                 (( tot_len += ext_len ))
12458                 last_lun=$frag_lun
12459         done
12460         if (( num_luns != 2 || tot_len != 512 )); then
12461                 cleanup_130
12462                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12463                         "luns or wrong len for OST $last_lun"
12464                 return
12465         fi
12466
12467         cleanup_130
12468
12469         echo "FIEMAP on 2-stripe file with hole succeeded"
12470 }
12471 run_test 130c "FIEMAP (2-stripe file with hole)"
12472
12473 test_130d() {
12474         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12475
12476         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12477         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12478
12479         trap cleanup_130 EXIT RETURN
12480
12481         local fm_file=$DIR/$tfile
12482         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12483                         error "setstripe on $fm_file"
12484         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12485                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12486
12487         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12488         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12489                 error "dd failed on $fm_file"
12490
12491         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12492         filefrag_op=$(filefrag -ve -k $fm_file |
12493                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12494
12495         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12496                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12497
12498         IFS=$'\n'
12499         tot_len=0
12500         num_luns=1
12501         for line in $filefrag_op
12502         do
12503                 frag_lun=$(echo $line | cut -d: -f5 |
12504                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12505                 ext_len=$(echo $line | cut -d: -f4)
12506                 if (( $frag_lun != $last_lun )); then
12507                         if (( tot_len != 1024 )); then
12508                                 cleanup_130
12509                                 error "FIEMAP on $fm_file failed; returned " \
12510                                 "len $tot_len for OST $last_lun instead of 1024"
12511                                 return
12512                         else
12513                                 (( num_luns += 1 ))
12514                                 tot_len=0
12515                         fi
12516                 fi
12517                 (( tot_len += ext_len ))
12518                 last_lun=$frag_lun
12519         done
12520         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12521                 cleanup_130
12522                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12523                         "luns or wrong len for OST $last_lun"
12524                 return
12525         fi
12526
12527         cleanup_130
12528
12529         echo "FIEMAP on N-stripe file succeeded"
12530 }
12531 run_test 130d "FIEMAP (N-stripe file)"
12532
12533 test_130e() {
12534         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12535
12536         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12537         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12538
12539         trap cleanup_130 EXIT RETURN
12540
12541         local fm_file=$DIR/$tfile
12542         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12543         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12544                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12545
12546         NUM_BLKS=512
12547         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12548         for ((i = 0; i < $NUM_BLKS; i++))
12549         do
12550                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12551         done
12552
12553         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12554         filefrag_op=$(filefrag -ve -k $fm_file |
12555                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12556
12557         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12558                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12559
12560         IFS=$'\n'
12561         tot_len=0
12562         num_luns=1
12563         for line in $filefrag_op
12564         do
12565                 frag_lun=$(echo $line | cut -d: -f5 |
12566                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12567                 ext_len=$(echo $line | cut -d: -f4)
12568                 if (( $frag_lun != $last_lun )); then
12569                         if (( tot_len != $EXPECTED_LEN )); then
12570                                 cleanup_130
12571                                 error "FIEMAP on $fm_file failed; returned " \
12572                                 "len $tot_len for OST $last_lun instead " \
12573                                 "of $EXPECTED_LEN"
12574                                 return
12575                         else
12576                                 (( num_luns += 1 ))
12577                                 tot_len=0
12578                         fi
12579                 fi
12580                 (( tot_len += ext_len ))
12581                 last_lun=$frag_lun
12582         done
12583         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12584                 cleanup_130
12585                 error "FIEMAP on $fm_file failed; returned wrong number " \
12586                         "of luns or wrong len for OST $last_lun"
12587                 return
12588         fi
12589
12590         cleanup_130
12591
12592         echo "FIEMAP with continuation calls succeeded"
12593 }
12594 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12595
12596 test_130f() {
12597         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12598         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12599
12600         local fm_file=$DIR/$tfile
12601         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12602                 error "multiop create with lov_delay_create on $fm_file"
12603
12604         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12605         filefrag_extents=$(filefrag -vek $fm_file |
12606                            awk '/extents? found/ { print $2 }')
12607         if [[ "$filefrag_extents" != "0" ]]; then
12608                 error "FIEMAP on $fm_file failed; " \
12609                       "returned $filefrag_extents expected 0"
12610         fi
12611
12612         rm -f $fm_file
12613 }
12614 run_test 130f "FIEMAP (unstriped file)"
12615
12616 # Test for writev/readv
12617 test_131a() {
12618         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12619                 error "writev test failed"
12620         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12621                 error "readv failed"
12622         rm -f $DIR/$tfile
12623 }
12624 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12625
12626 test_131b() {
12627         local fsize=$((524288 + 1048576 + 1572864))
12628         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12629                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12630                         error "append writev test failed"
12631
12632         ((fsize += 1572864 + 1048576))
12633         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12634                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12635                         error "append writev test failed"
12636         rm -f $DIR/$tfile
12637 }
12638 run_test 131b "test append writev"
12639
12640 test_131c() {
12641         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12642         error "NOT PASS"
12643 }
12644 run_test 131c "test read/write on file w/o objects"
12645
12646 test_131d() {
12647         rwv -f $DIR/$tfile -w -n 1 1572864
12648         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12649         if [ "$NOB" != 1572864 ]; then
12650                 error "Short read filed: read $NOB bytes instead of 1572864"
12651         fi
12652         rm -f $DIR/$tfile
12653 }
12654 run_test 131d "test short read"
12655
12656 test_131e() {
12657         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12658         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12659         error "read hitting hole failed"
12660         rm -f $DIR/$tfile
12661 }
12662 run_test 131e "test read hitting hole"
12663
12664 check_stats() {
12665         local facet=$1
12666         local op=$2
12667         local want=${3:-0}
12668         local res
12669
12670         case $facet in
12671         mds*) res=$(do_facet $facet \
12672                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12673                  ;;
12674         ost*) res=$(do_facet $facet \
12675                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12676                  ;;
12677         *) error "Wrong facet '$facet'" ;;
12678         esac
12679         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12680         # if the argument $3 is zero, it means any stat increment is ok.
12681         if [[ $want -gt 0 ]]; then
12682                 local count=$(echo $res | awk '{ print $2 }')
12683                 [[ $count -ne $want ]] &&
12684                         error "The $op counter on $facet is $count, not $want"
12685         fi
12686 }
12687
12688 test_133a() {
12689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12690         remote_ost_nodsh && skip "remote OST with nodsh"
12691         remote_mds_nodsh && skip "remote MDS with nodsh"
12692         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12693                 skip_env "MDS doesn't support rename stats"
12694
12695         local testdir=$DIR/${tdir}/stats_testdir
12696
12697         mkdir -p $DIR/${tdir}
12698
12699         # clear stats.
12700         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12701         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12702
12703         # verify mdt stats first.
12704         mkdir ${testdir} || error "mkdir failed"
12705         check_stats $SINGLEMDS "mkdir" 1
12706         touch ${testdir}/${tfile} || error "touch failed"
12707         check_stats $SINGLEMDS "open" 1
12708         check_stats $SINGLEMDS "close" 1
12709         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12710                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12711                 check_stats $SINGLEMDS "mknod" 2
12712         }
12713         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12714         check_stats $SINGLEMDS "unlink" 1
12715         rm -f ${testdir}/${tfile} || error "file remove failed"
12716         check_stats $SINGLEMDS "unlink" 2
12717
12718         # remove working dir and check mdt stats again.
12719         rmdir ${testdir} || error "rmdir failed"
12720         check_stats $SINGLEMDS "rmdir" 1
12721
12722         local testdir1=$DIR/${tdir}/stats_testdir1
12723         mkdir -p ${testdir}
12724         mkdir -p ${testdir1}
12725         touch ${testdir1}/test1
12726         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12727         check_stats $SINGLEMDS "crossdir_rename" 1
12728
12729         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12730         check_stats $SINGLEMDS "samedir_rename" 1
12731
12732         rm -rf $DIR/${tdir}
12733 }
12734 run_test 133a "Verifying MDT stats ========================================"
12735
12736 test_133b() {
12737         local res
12738
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740         remote_ost_nodsh && skip "remote OST with nodsh"
12741         remote_mds_nodsh && skip "remote MDS with nodsh"
12742
12743         local testdir=$DIR/${tdir}/stats_testdir
12744
12745         mkdir -p ${testdir} || error "mkdir failed"
12746         touch ${testdir}/${tfile} || error "touch failed"
12747         cancel_lru_locks mdc
12748
12749         # clear stats.
12750         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12751         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12752
12753         # extra mdt stats verification.
12754         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12755         check_stats $SINGLEMDS "setattr" 1
12756         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12757         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12758         then            # LU-1740
12759                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12760                 check_stats $SINGLEMDS "getattr" 1
12761         fi
12762         rm -rf $DIR/${tdir}
12763
12764         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12765         # so the check below is not reliable
12766         [ $MDSCOUNT -eq 1 ] || return 0
12767
12768         # Sleep to avoid a cached response.
12769         #define OBD_STATFS_CACHE_SECONDS 1
12770         sleep 2
12771         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12772         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12773         $LFS df || error "lfs failed"
12774         check_stats $SINGLEMDS "statfs" 1
12775
12776         # check aggregated statfs (LU-10018)
12777         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12778                 return 0
12779         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12780                 return 0
12781         sleep 2
12782         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12783         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12784         df $DIR
12785         check_stats $SINGLEMDS "statfs" 1
12786
12787         # We want to check that the client didn't send OST_STATFS to
12788         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12789         # extra care is needed here.
12790         if remote_mds; then
12791                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12792                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12793
12794                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12795                 [ "$res" ] && error "OST got STATFS"
12796         fi
12797
12798         return 0
12799 }
12800 run_test 133b "Verifying extra MDT stats =================================="
12801
12802 test_133c() {
12803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12804         remote_ost_nodsh && skip "remote OST with nodsh"
12805         remote_mds_nodsh && skip "remote MDS with nodsh"
12806
12807         local testdir=$DIR/$tdir/stats_testdir
12808
12809         test_mkdir -p $testdir
12810
12811         # verify obdfilter stats.
12812         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12813         sync
12814         cancel_lru_locks osc
12815         wait_delete_completed
12816
12817         # clear stats.
12818         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12819         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12820
12821         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12822                 error "dd failed"
12823         sync
12824         cancel_lru_locks osc
12825         check_stats ost1 "write" 1
12826
12827         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12828         check_stats ost1 "read" 1
12829
12830         > $testdir/$tfile || error "truncate failed"
12831         check_stats ost1 "punch" 1
12832
12833         rm -f $testdir/$tfile || error "file remove failed"
12834         wait_delete_completed
12835         check_stats ost1 "destroy" 1
12836
12837         rm -rf $DIR/$tdir
12838 }
12839 run_test 133c "Verifying OST stats ========================================"
12840
12841 order_2() {
12842         local value=$1
12843         local orig=$value
12844         local order=1
12845
12846         while [ $value -ge 2 ]; do
12847                 order=$((order*2))
12848                 value=$((value/2))
12849         done
12850
12851         if [ $orig -gt $order ]; then
12852                 order=$((order*2))
12853         fi
12854         echo $order
12855 }
12856
12857 size_in_KMGT() {
12858     local value=$1
12859     local size=('K' 'M' 'G' 'T');
12860     local i=0
12861     local size_string=$value
12862
12863     while [ $value -ge 1024 ]; do
12864         if [ $i -gt 3 ]; then
12865             #T is the biggest unit we get here, if that is bigger,
12866             #just return XXXT
12867             size_string=${value}T
12868             break
12869         fi
12870         value=$((value >> 10))
12871         if [ $value -lt 1024 ]; then
12872             size_string=${value}${size[$i]}
12873             break
12874         fi
12875         i=$((i + 1))
12876     done
12877
12878     echo $size_string
12879 }
12880
12881 get_rename_size() {
12882         local size=$1
12883         local context=${2:-.}
12884         local sample=$(do_facet $SINGLEMDS $LCTL \
12885                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12886                 grep -A1 $context |
12887                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12888         echo $sample
12889 }
12890
12891 test_133d() {
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893         remote_ost_nodsh && skip "remote OST with nodsh"
12894         remote_mds_nodsh && skip "remote MDS with nodsh"
12895         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12896                 skip_env "MDS doesn't support rename stats"
12897
12898         local testdir1=$DIR/${tdir}/stats_testdir1
12899         local testdir2=$DIR/${tdir}/stats_testdir2
12900         mkdir -p $DIR/${tdir}
12901
12902         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12903
12904         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12905         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12906
12907         createmany -o $testdir1/test 512 || error "createmany failed"
12908
12909         # check samedir rename size
12910         mv ${testdir1}/test0 ${testdir1}/test_0
12911
12912         local testdir1_size=$(ls -l $DIR/${tdir} |
12913                 awk '/stats_testdir1/ {print $5}')
12914         local testdir2_size=$(ls -l $DIR/${tdir} |
12915                 awk '/stats_testdir2/ {print $5}')
12916
12917         testdir1_size=$(order_2 $testdir1_size)
12918         testdir2_size=$(order_2 $testdir2_size)
12919
12920         testdir1_size=$(size_in_KMGT $testdir1_size)
12921         testdir2_size=$(size_in_KMGT $testdir2_size)
12922
12923         echo "source rename dir size: ${testdir1_size}"
12924         echo "target rename dir size: ${testdir2_size}"
12925
12926         local cmd="do_facet $SINGLEMDS $LCTL "
12927         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12928
12929         eval $cmd || error "$cmd failed"
12930         local samedir=$($cmd | grep 'same_dir')
12931         local same_sample=$(get_rename_size $testdir1_size)
12932         [ -z "$samedir" ] && error "samedir_rename_size count error"
12933         [[ $same_sample -eq 1 ]] ||
12934                 error "samedir_rename_size error $same_sample"
12935         echo "Check same dir rename stats success"
12936
12937         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12938
12939         # check crossdir rename size
12940         mv ${testdir1}/test_0 ${testdir2}/test_0
12941
12942         testdir1_size=$(ls -l $DIR/${tdir} |
12943                 awk '/stats_testdir1/ {print $5}')
12944         testdir2_size=$(ls -l $DIR/${tdir} |
12945                 awk '/stats_testdir2/ {print $5}')
12946
12947         testdir1_size=$(order_2 $testdir1_size)
12948         testdir2_size=$(order_2 $testdir2_size)
12949
12950         testdir1_size=$(size_in_KMGT $testdir1_size)
12951         testdir2_size=$(size_in_KMGT $testdir2_size)
12952
12953         echo "source rename dir size: ${testdir1_size}"
12954         echo "target rename dir size: ${testdir2_size}"
12955
12956         eval $cmd || error "$cmd failed"
12957         local crossdir=$($cmd | grep 'crossdir')
12958         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12959         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12960         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12961         [[ $src_sample -eq 1 ]] ||
12962                 error "crossdir_rename_size error $src_sample"
12963         [[ $tgt_sample -eq 1 ]] ||
12964                 error "crossdir_rename_size error $tgt_sample"
12965         echo "Check cross dir rename stats success"
12966         rm -rf $DIR/${tdir}
12967 }
12968 run_test 133d "Verifying rename_stats ========================================"
12969
12970 test_133e() {
12971         remote_mds_nodsh && skip "remote MDS with nodsh"
12972         remote_ost_nodsh && skip "remote OST with nodsh"
12973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12974
12975         local testdir=$DIR/${tdir}/stats_testdir
12976         local ctr f0 f1 bs=32768 count=42 sum
12977
12978         mkdir -p ${testdir} || error "mkdir failed"
12979
12980         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12981
12982         for ctr in {write,read}_bytes; do
12983                 sync
12984                 cancel_lru_locks osc
12985
12986                 do_facet ost1 $LCTL set_param -n \
12987                         "obdfilter.*.exports.clear=clear"
12988
12989                 if [ $ctr = write_bytes ]; then
12990                         f0=/dev/zero
12991                         f1=${testdir}/${tfile}
12992                 else
12993                         f0=${testdir}/${tfile}
12994                         f1=/dev/null
12995                 fi
12996
12997                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12998                         error "dd failed"
12999                 sync
13000                 cancel_lru_locks osc
13001
13002                 sum=$(do_facet ost1 $LCTL get_param \
13003                         "obdfilter.*.exports.*.stats" |
13004                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13005                                 $1 == ctr { sum += $7 }
13006                                 END { printf("%0.0f", sum) }')
13007
13008                 if ((sum != bs * count)); then
13009                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13010                 fi
13011         done
13012
13013         rm -rf $DIR/${tdir}
13014 }
13015 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13016
13017 test_133f() {
13018         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13019                 skip "too old lustre for get_param -R ($facet_ver)"
13020
13021         # verifying readability.
13022         $LCTL get_param -R '*' &> /dev/null
13023
13024         # Verifing writability with badarea_io.
13025         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13026                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13027                 error "client badarea_io failed"
13028
13029         # remount the FS in case writes/reads /proc break the FS
13030         cleanup || error "failed to unmount"
13031         setup || error "failed to setup"
13032 }
13033 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13034
13035 test_133g() {
13036         remote_mds_nodsh && skip "remote MDS with nodsh"
13037         remote_ost_nodsh && skip "remote OST with nodsh"
13038
13039         local facet
13040         for facet in mds1 ost1; do
13041                 local facet_ver=$(lustre_version_code $facet)
13042                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13043                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13044                 else
13045                         log "$facet: too old lustre for get_param -R"
13046                 fi
13047                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13048                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13049                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13050                                 xargs badarea_io" ||
13051                                         error "$facet badarea_io failed"
13052                 else
13053                         skip_noexit "$facet: too old lustre for get_param -R"
13054                 fi
13055         done
13056
13057         # remount the FS in case writes/reads /proc break the FS
13058         cleanup || error "failed to unmount"
13059         setup || error "failed to setup"
13060 }
13061 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13062
13063 test_133h() {
13064         remote_mds_nodsh && skip "remote MDS with nodsh"
13065         remote_ost_nodsh && skip "remote OST with nodsh"
13066         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13067                 skip "Need MDS version at least 2.9.54"
13068
13069         local facet
13070         for facet in client mds1 ost1; do
13071                 # Get the list of files that are missing the terminating newline
13072                 local plist=$(do_facet $facet
13073                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13074                 local ent
13075                 for ent in $plist; do
13076                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13077                                 awk -v FS='\v' -v RS='\v\v' \
13078                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13079                                         print FILENAME}'" 2>/dev/null)
13080                         [ -z $missing ] || {
13081                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13082                                 error "file does not end with newline: $facet-$ent"
13083                         }
13084                 done
13085         done
13086 }
13087 run_test 133h "Proc files should end with newlines"
13088
13089 test_134a() {
13090         remote_mds_nodsh && skip "remote MDS with nodsh"
13091         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13092                 skip "Need MDS version at least 2.7.54"
13093
13094         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13095         cancel_lru_locks mdc
13096
13097         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13098         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13099         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13100
13101         local nr=1000
13102         createmany -o $DIR/$tdir/f $nr ||
13103                 error "failed to create $nr files in $DIR/$tdir"
13104         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13105
13106         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13107         do_facet mds1 $LCTL set_param fail_loc=0x327
13108         do_facet mds1 $LCTL set_param fail_val=500
13109         touch $DIR/$tdir/m
13110
13111         echo "sleep 10 seconds ..."
13112         sleep 10
13113         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13114
13115         do_facet mds1 $LCTL set_param fail_loc=0
13116         do_facet mds1 $LCTL set_param fail_val=0
13117         [ $lck_cnt -lt $unused ] ||
13118                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13119
13120         rm $DIR/$tdir/m
13121         unlinkmany $DIR/$tdir/f $nr
13122 }
13123 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13124
13125 test_134b() {
13126         remote_mds_nodsh && skip "remote MDS with nodsh"
13127         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13128                 skip "Need MDS version at least 2.7.54"
13129
13130         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13131         cancel_lru_locks mdc
13132
13133         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13134                         ldlm.lock_reclaim_threshold_mb)
13135         # disable reclaim temporarily
13136         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13137
13138         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13139         do_facet mds1 $LCTL set_param fail_loc=0x328
13140         do_facet mds1 $LCTL set_param fail_val=500
13141
13142         $LCTL set_param debug=+trace
13143
13144         local nr=600
13145         createmany -o $DIR/$tdir/f $nr &
13146         local create_pid=$!
13147
13148         echo "Sleep $TIMEOUT seconds ..."
13149         sleep $TIMEOUT
13150         if ! ps -p $create_pid  > /dev/null 2>&1; then
13151                 do_facet mds1 $LCTL set_param fail_loc=0
13152                 do_facet mds1 $LCTL set_param fail_val=0
13153                 do_facet mds1 $LCTL set_param \
13154                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13155                 error "createmany finished incorrectly!"
13156         fi
13157         do_facet mds1 $LCTL set_param fail_loc=0
13158         do_facet mds1 $LCTL set_param fail_val=0
13159         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13160         wait $create_pid || return 1
13161
13162         unlinkmany $DIR/$tdir/f $nr
13163 }
13164 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13165
13166 test_135() {
13167         remote_mds_nodsh && skip "remote MDS with nodsh"
13168         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13169                 skip "Need MDS version at least 2.13.50"
13170         local fname
13171
13172         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13173
13174 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13175         #set only one record at plain llog
13176         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13177
13178         #fill already existed plain llog each 64767
13179         #wrapping whole catalog
13180         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13181
13182         createmany -o $DIR/$tdir/$tfile_ 64700
13183         for (( i = 0; i < 64700; i = i + 2 ))
13184         do
13185                 rm $DIR/$tdir/$tfile_$i &
13186                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13187                 local pid=$!
13188                 wait $pid
13189         done
13190
13191         #waiting osp synchronization
13192         wait_delete_completed
13193 }
13194 run_test 135 "Race catalog processing"
13195
13196 test_136() {
13197         remote_mds_nodsh && skip "remote MDS with nodsh"
13198         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13199                 skip "Need MDS version at least 2.13.50"
13200         local fname
13201
13202         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13203         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13204         #set only one record at plain llog
13205 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13206         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13207
13208         #fill already existed 2 plain llogs each 64767
13209         #wrapping whole catalog
13210         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13211         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13212         wait_delete_completed
13213
13214         createmany -o $DIR/$tdir/$tfile_ 10
13215         sleep 25
13216
13217         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13218         for (( i = 0; i < 10; i = i + 3 ))
13219         do
13220                 rm $DIR/$tdir/$tfile_$i &
13221                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13222                 local pid=$!
13223                 wait $pid
13224                 sleep 7
13225                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13226         done
13227
13228         #waiting osp synchronization
13229         wait_delete_completed
13230 }
13231 run_test 136 "Race catalog processing 2"
13232
13233 test_140() { #bug-17379
13234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13235
13236         test_mkdir $DIR/$tdir
13237         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13238         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13239
13240         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13241         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13242         local i=0
13243         while i=$((i + 1)); do
13244                 test_mkdir $i
13245                 cd $i || error "Changing to $i"
13246                 ln -s ../stat stat || error "Creating stat symlink"
13247                 # Read the symlink until ELOOP present,
13248                 # not LBUGing the system is considered success,
13249                 # we didn't overrun the stack.
13250                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13251                 if [ $ret -ne 0 ]; then
13252                         if [ $ret -eq 40 ]; then
13253                                 break  # -ELOOP
13254                         else
13255                                 error "Open stat symlink"
13256                                         return
13257                         fi
13258                 fi
13259         done
13260         i=$((i - 1))
13261         echo "The symlink depth = $i"
13262         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13263                 error "Invalid symlink depth"
13264
13265         # Test recursive symlink
13266         ln -s symlink_self symlink_self
13267         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13268         echo "open symlink_self returns $ret"
13269         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13270 }
13271 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13272
13273 test_150a() {
13274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13275
13276         local TF="$TMP/$tfile"
13277
13278         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13279         cp $TF $DIR/$tfile
13280         cancel_lru_locks $OSC
13281         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13282         remount_client $MOUNT
13283         df -P $MOUNT
13284         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13285
13286         $TRUNCATE $TF 6000
13287         $TRUNCATE $DIR/$tfile 6000
13288         cancel_lru_locks $OSC
13289         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13290
13291         echo "12345" >>$TF
13292         echo "12345" >>$DIR/$tfile
13293         cancel_lru_locks $OSC
13294         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13295
13296         echo "12345" >>$TF
13297         echo "12345" >>$DIR/$tfile
13298         cancel_lru_locks $OSC
13299         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13300
13301         rm -f $TF
13302         true
13303 }
13304 run_test 150a "truncate/append tests"
13305
13306 test_150b() {
13307         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13308         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13309                 skip "Need OST version at least 2.13.53"
13310         touch $DIR/$tfile
13311         check_fallocate $DIR/$tfile || error "fallocate failed"
13312 }
13313 run_test 150b "Verify fallocate (prealloc) functionality"
13314
13315 test_150c() {
13316         local bytes
13317         local want
13318
13319         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13320         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13321                 skip "Need OST version at least 2.13.53"
13322
13323         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13324         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13325         sync; sync_all_data
13326         cancel_lru_locks $OSC
13327         sleep 5
13328         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13329         want=$((OSTCOUNT * 1048576))
13330
13331         # Must allocate all requested space, not more than 5% extra
13332         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13333                 error "bytes $bytes is not $want"
13334 }
13335 run_test 150c "Verify fallocate Size and Blocks"
13336
13337 test_150d() {
13338         local bytes
13339         local want
13340
13341         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13342         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13343                 skip "Need OST version at least 2.13.53"
13344
13345         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13346         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13347         sync; sync_all_data
13348         cancel_lru_locks $OSC
13349         sleep 5
13350         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13351         want=$((OSTCOUNT * 1048576))
13352
13353         # Must allocate all requested space, not more than 5% extra
13354         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13355                 error "bytes $bytes is not $want"
13356 }
13357 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13358
13359 #LU-2902 roc_hit was not able to read all values from lproc
13360 function roc_hit_init() {
13361         local list=$(comma_list $(osts_nodes))
13362         local dir=$DIR/$tdir-check
13363         local file=$dir/$tfile
13364         local BEFORE
13365         local AFTER
13366         local idx
13367
13368         test_mkdir $dir
13369         #use setstripe to do a write to every ost
13370         for i in $(seq 0 $((OSTCOUNT-1))); do
13371                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13372                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13373                 idx=$(printf %04x $i)
13374                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13375                         awk '$1 == "cache_access" {sum += $7}
13376                                 END { printf("%0.0f", sum) }')
13377
13378                 cancel_lru_locks osc
13379                 cat $file >/dev/null
13380
13381                 AFTER=$(get_osd_param $list *OST*$idx stats |
13382                         awk '$1 == "cache_access" {sum += $7}
13383                                 END { printf("%0.0f", sum) }')
13384
13385                 echo BEFORE:$BEFORE AFTER:$AFTER
13386                 if ! let "AFTER - BEFORE == 4"; then
13387                         rm -rf $dir
13388                         error "roc_hit is not safe to use"
13389                 fi
13390                 rm $file
13391         done
13392
13393         rm -rf $dir
13394 }
13395
13396 function roc_hit() {
13397         local list=$(comma_list $(osts_nodes))
13398         echo $(get_osd_param $list '' stats |
13399                 awk '$1 == "cache_hit" {sum += $7}
13400                         END { printf("%0.0f", sum) }')
13401 }
13402
13403 function set_cache() {
13404         local on=1
13405
13406         if [ "$2" == "off" ]; then
13407                 on=0;
13408         fi
13409         local list=$(comma_list $(osts_nodes))
13410         set_osd_param $list '' $1_cache_enable $on
13411
13412         cancel_lru_locks osc
13413 }
13414
13415 test_151() {
13416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13417         remote_ost_nodsh && skip "remote OST with nodsh"
13418
13419         local CPAGES=3
13420         local list=$(comma_list $(osts_nodes))
13421
13422         # check whether obdfilter is cache capable at all
13423         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13424                 skip "not cache-capable obdfilter"
13425         fi
13426
13427         # check cache is enabled on all obdfilters
13428         if get_osd_param $list '' read_cache_enable | grep 0; then
13429                 skip "oss cache is disabled"
13430         fi
13431
13432         set_osd_param $list '' writethrough_cache_enable 1
13433
13434         # check write cache is enabled on all obdfilters
13435         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13436                 skip "oss write cache is NOT enabled"
13437         fi
13438
13439         roc_hit_init
13440
13441         #define OBD_FAIL_OBD_NO_LRU  0x609
13442         do_nodes $list $LCTL set_param fail_loc=0x609
13443
13444         # pages should be in the case right after write
13445         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13446                 error "dd failed"
13447
13448         local BEFORE=$(roc_hit)
13449         cancel_lru_locks osc
13450         cat $DIR/$tfile >/dev/null
13451         local AFTER=$(roc_hit)
13452
13453         do_nodes $list $LCTL set_param fail_loc=0
13454
13455         if ! let "AFTER - BEFORE == CPAGES"; then
13456                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13457         fi
13458
13459         cancel_lru_locks osc
13460         # invalidates OST cache
13461         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13462         set_osd_param $list '' read_cache_enable 0
13463         cat $DIR/$tfile >/dev/null
13464
13465         # now data shouldn't be found in the cache
13466         BEFORE=$(roc_hit)
13467         cancel_lru_locks osc
13468         cat $DIR/$tfile >/dev/null
13469         AFTER=$(roc_hit)
13470         if let "AFTER - BEFORE != 0"; then
13471                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13472         fi
13473
13474         set_osd_param $list '' read_cache_enable 1
13475         rm -f $DIR/$tfile
13476 }
13477 run_test 151 "test cache on oss and controls ==============================="
13478
13479 test_152() {
13480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13481
13482         local TF="$TMP/$tfile"
13483
13484         # simulate ENOMEM during write
13485 #define OBD_FAIL_OST_NOMEM      0x226
13486         lctl set_param fail_loc=0x80000226
13487         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13488         cp $TF $DIR/$tfile
13489         sync || error "sync failed"
13490         lctl set_param fail_loc=0
13491
13492         # discard client's cache
13493         cancel_lru_locks osc
13494
13495         # simulate ENOMEM during read
13496         lctl set_param fail_loc=0x80000226
13497         cmp $TF $DIR/$tfile || error "cmp failed"
13498         lctl set_param fail_loc=0
13499
13500         rm -f $TF
13501 }
13502 run_test 152 "test read/write with enomem ============================"
13503
13504 test_153() {
13505         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13506 }
13507 run_test 153 "test if fdatasync does not crash ======================="
13508
13509 dot_lustre_fid_permission_check() {
13510         local fid=$1
13511         local ffid=$MOUNT/.lustre/fid/$fid
13512         local test_dir=$2
13513
13514         echo "stat fid $fid"
13515         stat $ffid > /dev/null || error "stat $ffid failed."
13516         echo "touch fid $fid"
13517         touch $ffid || error "touch $ffid failed."
13518         echo "write to fid $fid"
13519         cat /etc/hosts > $ffid || error "write $ffid failed."
13520         echo "read fid $fid"
13521         diff /etc/hosts $ffid || error "read $ffid failed."
13522         echo "append write to fid $fid"
13523         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13524         echo "rename fid $fid"
13525         mv $ffid $test_dir/$tfile.1 &&
13526                 error "rename $ffid to $tfile.1 should fail."
13527         touch $test_dir/$tfile.1
13528         mv $test_dir/$tfile.1 $ffid &&
13529                 error "rename $tfile.1 to $ffid should fail."
13530         rm -f $test_dir/$tfile.1
13531         echo "truncate fid $fid"
13532         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13533         echo "link fid $fid"
13534         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13535         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13536                 echo "setfacl fid $fid"
13537                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13538                 echo "getfacl fid $fid"
13539                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13540         fi
13541         echo "unlink fid $fid"
13542         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13543         echo "mknod fid $fid"
13544         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13545
13546         fid=[0xf00000400:0x1:0x0]
13547         ffid=$MOUNT/.lustre/fid/$fid
13548
13549         echo "stat non-exist fid $fid"
13550         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13551         echo "write to non-exist fid $fid"
13552         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13553         echo "link new fid $fid"
13554         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13555
13556         mkdir -p $test_dir/$tdir
13557         touch $test_dir/$tdir/$tfile
13558         fid=$($LFS path2fid $test_dir/$tdir)
13559         rc=$?
13560         [ $rc -ne 0 ] &&
13561                 error "error: could not get fid for $test_dir/$dir/$tfile."
13562
13563         ffid=$MOUNT/.lustre/fid/$fid
13564
13565         echo "ls $fid"
13566         ls $ffid > /dev/null || error "ls $ffid failed."
13567         echo "touch $fid/$tfile.1"
13568         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13569
13570         echo "touch $MOUNT/.lustre/fid/$tfile"
13571         touch $MOUNT/.lustre/fid/$tfile && \
13572                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13573
13574         echo "setxattr to $MOUNT/.lustre/fid"
13575         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13576
13577         echo "listxattr for $MOUNT/.lustre/fid"
13578         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13579
13580         echo "delxattr from $MOUNT/.lustre/fid"
13581         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13582
13583         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13584         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13585                 error "touch invalid fid should fail."
13586
13587         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13588         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13589                 error "touch non-normal fid should fail."
13590
13591         echo "rename $tdir to $MOUNT/.lustre/fid"
13592         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13593                 error "rename to $MOUNT/.lustre/fid should fail."
13594
13595         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13596         then            # LU-3547
13597                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13598                 local new_obf_mode=777
13599
13600                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13601                 chmod $new_obf_mode $DIR/.lustre/fid ||
13602                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13603
13604                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13605                 [ $obf_mode -eq $new_obf_mode ] ||
13606                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13607
13608                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13609                 chmod $old_obf_mode $DIR/.lustre/fid ||
13610                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13611         fi
13612
13613         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13614         fid=$($LFS path2fid $test_dir/$tfile-2)
13615
13616         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13617         then # LU-5424
13618                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13619                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13620                         error "create lov data thru .lustre failed"
13621         fi
13622         echo "cp /etc/passwd $test_dir/$tfile-2"
13623         cp /etc/passwd $test_dir/$tfile-2 ||
13624                 error "copy to $test_dir/$tfile-2 failed."
13625         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13626         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13627                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13628
13629         rm -rf $test_dir/tfile.lnk
13630         rm -rf $test_dir/$tfile-2
13631 }
13632
13633 test_154A() {
13634         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13635                 skip "Need MDS version at least 2.4.1"
13636
13637         local tf=$DIR/$tfile
13638         touch $tf
13639
13640         local fid=$($LFS path2fid $tf)
13641         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13642
13643         # check that we get the same pathname back
13644         local found=$($LFS fid2path $MOUNT "$fid")
13645         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13646         [ "$found" == "$tf" ] ||
13647                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13648 }
13649 run_test 154A "lfs path2fid and fid2path basic checks"
13650
13651 test_154B() {
13652         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13653                 skip "Need MDS version at least 2.4.1"
13654
13655         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13656         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13657         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13658         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13659
13660         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13661         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13662
13663         # check that we get the same pathname
13664         echo "PFID: $PFID, name: $name"
13665         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13666         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13667         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13668                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13669
13670         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13671 }
13672 run_test 154B "verify the ll_decode_linkea tool"
13673
13674 test_154a() {
13675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13676         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13677         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13678                 skip "Need MDS version at least 2.2.51"
13679         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13680
13681         cp /etc/hosts $DIR/$tfile
13682
13683         fid=$($LFS path2fid $DIR/$tfile)
13684         rc=$?
13685         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13686
13687         dot_lustre_fid_permission_check "$fid" $DIR ||
13688                 error "dot lustre permission check $fid failed"
13689
13690         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13691
13692         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13693
13694         touch $MOUNT/.lustre/file &&
13695                 error "creation is not allowed under .lustre"
13696
13697         mkdir $MOUNT/.lustre/dir &&
13698                 error "mkdir is not allowed under .lustre"
13699
13700         rm -rf $DIR/$tfile
13701 }
13702 run_test 154a "Open-by-FID"
13703
13704 test_154b() {
13705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13706         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13708         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13709                 skip "Need MDS version at least 2.2.51"
13710
13711         local remote_dir=$DIR/$tdir/remote_dir
13712         local MDTIDX=1
13713         local rc=0
13714
13715         mkdir -p $DIR/$tdir
13716         $LFS mkdir -i $MDTIDX $remote_dir ||
13717                 error "create remote directory failed"
13718
13719         cp /etc/hosts $remote_dir/$tfile
13720
13721         fid=$($LFS path2fid $remote_dir/$tfile)
13722         rc=$?
13723         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13724
13725         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13726                 error "dot lustre permission check $fid failed"
13727         rm -rf $DIR/$tdir
13728 }
13729 run_test 154b "Open-by-FID for remote directory"
13730
13731 test_154c() {
13732         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13733                 skip "Need MDS version at least 2.4.1"
13734
13735         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13736         local FID1=$($LFS path2fid $DIR/$tfile.1)
13737         local FID2=$($LFS path2fid $DIR/$tfile.2)
13738         local FID3=$($LFS path2fid $DIR/$tfile.3)
13739
13740         local N=1
13741         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13742                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13743                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13744                 local want=FID$N
13745                 [ "$FID" = "${!want}" ] ||
13746                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13747                 N=$((N + 1))
13748         done
13749
13750         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13751         do
13752                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13753                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13754                 N=$((N + 1))
13755         done
13756 }
13757 run_test 154c "lfs path2fid and fid2path multiple arguments"
13758
13759 test_154d() {
13760         remote_mds_nodsh && skip "remote MDS with nodsh"
13761         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13762                 skip "Need MDS version at least 2.5.53"
13763
13764         if remote_mds; then
13765                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13766         else
13767                 nid="0@lo"
13768         fi
13769         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13770         local fd
13771         local cmd
13772
13773         rm -f $DIR/$tfile
13774         touch $DIR/$tfile
13775
13776         local fid=$($LFS path2fid $DIR/$tfile)
13777         # Open the file
13778         fd=$(free_fd)
13779         cmd="exec $fd<$DIR/$tfile"
13780         eval $cmd
13781         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13782         echo "$fid_list" | grep "$fid"
13783         rc=$?
13784
13785         cmd="exec $fd>/dev/null"
13786         eval $cmd
13787         if [ $rc -ne 0 ]; then
13788                 error "FID $fid not found in open files list $fid_list"
13789         fi
13790 }
13791 run_test 154d "Verify open file fid"
13792
13793 test_154e()
13794 {
13795         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13796                 skip "Need MDS version at least 2.6.50"
13797
13798         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13799                 error ".lustre returned by readdir"
13800         fi
13801 }
13802 run_test 154e ".lustre is not returned by readdir"
13803
13804 test_154f() {
13805         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13806
13807         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13808         test_mkdir -p -c1 $DIR/$tdir/d
13809         # test dirs inherit from its stripe
13810         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13811         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13812         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13813         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13814         touch $DIR/f
13815
13816         # get fid of parents
13817         local FID0=$($LFS path2fid $DIR/$tdir/d)
13818         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13819         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13820         local FID3=$($LFS path2fid $DIR)
13821
13822         # check that path2fid --parents returns expected <parent_fid>/name
13823         # 1) test for a directory (single parent)
13824         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13825         [ "$parent" == "$FID0/foo1" ] ||
13826                 error "expected parent: $FID0/foo1, got: $parent"
13827
13828         # 2) test for a file with nlink > 1 (multiple parents)
13829         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13830         echo "$parent" | grep -F "$FID1/$tfile" ||
13831                 error "$FID1/$tfile not returned in parent list"
13832         echo "$parent" | grep -F "$FID2/link" ||
13833                 error "$FID2/link not returned in parent list"
13834
13835         # 3) get parent by fid
13836         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13837         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13838         echo "$parent" | grep -F "$FID1/$tfile" ||
13839                 error "$FID1/$tfile not returned in parent list (by fid)"
13840         echo "$parent" | grep -F "$FID2/link" ||
13841                 error "$FID2/link not returned in parent list (by fid)"
13842
13843         # 4) test for entry in root directory
13844         parent=$($LFS path2fid --parents $DIR/f)
13845         echo "$parent" | grep -F "$FID3/f" ||
13846                 error "$FID3/f not returned in parent list"
13847
13848         # 5) test it on root directory
13849         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13850                 error "$MOUNT should not have parents"
13851
13852         # enable xattr caching and check that linkea is correctly updated
13853         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13854         save_lustre_params client "llite.*.xattr_cache" > $save
13855         lctl set_param llite.*.xattr_cache 1
13856
13857         # 6.1) linkea update on rename
13858         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13859
13860         # get parents by fid
13861         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13862         # foo1 should no longer be returned in parent list
13863         echo "$parent" | grep -F "$FID1" &&
13864                 error "$FID1 should no longer be in parent list"
13865         # the new path should appear
13866         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13867                 error "$FID2/$tfile.moved is not in parent list"
13868
13869         # 6.2) linkea update on unlink
13870         rm -f $DIR/$tdir/d/foo2/link
13871         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13872         # foo2/link should no longer be returned in parent list
13873         echo "$parent" | grep -F "$FID2/link" &&
13874                 error "$FID2/link should no longer be in parent list"
13875         true
13876
13877         rm -f $DIR/f
13878         restore_lustre_params < $save
13879         rm -f $save
13880 }
13881 run_test 154f "get parent fids by reading link ea"
13882
13883 test_154g()
13884 {
13885         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13886         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13887            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13888                 skip "Need MDS version at least 2.6.92"
13889
13890         mkdir -p $DIR/$tdir
13891         llapi_fid_test -d $DIR/$tdir
13892 }
13893 run_test 154g "various llapi FID tests"
13894
13895 test_155_small_load() {
13896     local temp=$TMP/$tfile
13897     local file=$DIR/$tfile
13898
13899     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13900         error "dd of=$temp bs=6096 count=1 failed"
13901     cp $temp $file
13902     cancel_lru_locks $OSC
13903     cmp $temp $file || error "$temp $file differ"
13904
13905     $TRUNCATE $temp 6000
13906     $TRUNCATE $file 6000
13907     cmp $temp $file || error "$temp $file differ (truncate1)"
13908
13909     echo "12345" >>$temp
13910     echo "12345" >>$file
13911     cmp $temp $file || error "$temp $file differ (append1)"
13912
13913     echo "12345" >>$temp
13914     echo "12345" >>$file
13915     cmp $temp $file || error "$temp $file differ (append2)"
13916
13917     rm -f $temp $file
13918     true
13919 }
13920
13921 test_155_big_load() {
13922         remote_ost_nodsh && skip "remote OST with nodsh"
13923
13924         local temp=$TMP/$tfile
13925         local file=$DIR/$tfile
13926
13927         free_min_max
13928         local cache_size=$(do_facet ost$((MAXI+1)) \
13929                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13930         local large_file_size=$((cache_size * 2))
13931
13932         echo "OSS cache size: $cache_size KB"
13933         echo "Large file size: $large_file_size KB"
13934
13935         [ $MAXV -le $large_file_size ] &&
13936                 skip_env "max available OST size needs > $large_file_size KB"
13937
13938         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13939
13940         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13941                 error "dd of=$temp bs=$large_file_size count=1k failed"
13942         cp $temp $file
13943         ls -lh $temp $file
13944         cancel_lru_locks osc
13945         cmp $temp $file || error "$temp $file differ"
13946
13947         rm -f $temp $file
13948         true
13949 }
13950
13951 save_writethrough() {
13952         local facets=$(get_facets OST)
13953
13954         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13955 }
13956
13957 test_155a() {
13958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13959
13960         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13961
13962         save_writethrough $p
13963
13964         set_cache read on
13965         set_cache writethrough on
13966         test_155_small_load
13967         restore_lustre_params < $p
13968         rm -f $p
13969 }
13970 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13971
13972 test_155b() {
13973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13974
13975         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13976
13977         save_writethrough $p
13978
13979         set_cache read on
13980         set_cache writethrough off
13981         test_155_small_load
13982         restore_lustre_params < $p
13983         rm -f $p
13984 }
13985 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13986
13987 test_155c() {
13988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13989
13990         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13991
13992         save_writethrough $p
13993
13994         set_cache read off
13995         set_cache writethrough on
13996         test_155_small_load
13997         restore_lustre_params < $p
13998         rm -f $p
13999 }
14000 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14001
14002 test_155d() {
14003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14004
14005         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14006
14007         save_writethrough $p
14008
14009         set_cache read off
14010         set_cache writethrough off
14011         test_155_small_load
14012         restore_lustre_params < $p
14013         rm -f $p
14014 }
14015 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14016
14017 test_155e() {
14018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14019
14020         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14021
14022         save_writethrough $p
14023
14024         set_cache read on
14025         set_cache writethrough on
14026         test_155_big_load
14027         restore_lustre_params < $p
14028         rm -f $p
14029 }
14030 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14031
14032 test_155f() {
14033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14034
14035         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14036
14037         save_writethrough $p
14038
14039         set_cache read on
14040         set_cache writethrough off
14041         test_155_big_load
14042         restore_lustre_params < $p
14043         rm -f $p
14044 }
14045 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14046
14047 test_155g() {
14048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14049
14050         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14051
14052         save_writethrough $p
14053
14054         set_cache read off
14055         set_cache writethrough on
14056         test_155_big_load
14057         restore_lustre_params < $p
14058         rm -f $p
14059 }
14060 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14061
14062 test_155h() {
14063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14064
14065         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14066
14067         save_writethrough $p
14068
14069         set_cache read off
14070         set_cache writethrough off
14071         test_155_big_load
14072         restore_lustre_params < $p
14073         rm -f $p
14074 }
14075 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14076
14077 test_156() {
14078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14079         remote_ost_nodsh && skip "remote OST with nodsh"
14080         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14081                 skip "stats not implemented on old servers"
14082         [ "$ost1_FSTYPE" = "zfs" ] &&
14083                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14084
14085         local CPAGES=3
14086         local BEFORE
14087         local AFTER
14088         local file="$DIR/$tfile"
14089         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14090
14091         save_writethrough $p
14092         roc_hit_init
14093
14094         log "Turn on read and write cache"
14095         set_cache read on
14096         set_cache writethrough on
14097
14098         log "Write data and read it back."
14099         log "Read should be satisfied from the cache."
14100         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14101         BEFORE=$(roc_hit)
14102         cancel_lru_locks osc
14103         cat $file >/dev/null
14104         AFTER=$(roc_hit)
14105         if ! let "AFTER - BEFORE == CPAGES"; then
14106                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14107         else
14108                 log "cache hits: before: $BEFORE, after: $AFTER"
14109         fi
14110
14111         log "Read again; it should be satisfied from the cache."
14112         BEFORE=$AFTER
14113         cancel_lru_locks osc
14114         cat $file >/dev/null
14115         AFTER=$(roc_hit)
14116         if ! let "AFTER - BEFORE == CPAGES"; then
14117                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14118         else
14119                 log "cache hits:: before: $BEFORE, after: $AFTER"
14120         fi
14121
14122         log "Turn off the read cache and turn on the write cache"
14123         set_cache read off
14124         set_cache writethrough on
14125
14126         log "Read again; it should be satisfied from the cache."
14127         BEFORE=$(roc_hit)
14128         cancel_lru_locks osc
14129         cat $file >/dev/null
14130         AFTER=$(roc_hit)
14131         if ! let "AFTER - BEFORE == CPAGES"; then
14132                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14133         else
14134                 log "cache hits:: before: $BEFORE, after: $AFTER"
14135         fi
14136
14137         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14138                 # > 2.12.56 uses pagecache if cached
14139                 log "Read again; it should not be satisfied from the cache."
14140                 BEFORE=$AFTER
14141                 cancel_lru_locks osc
14142                 cat $file >/dev/null
14143                 AFTER=$(roc_hit)
14144                 if ! let "AFTER - BEFORE == 0"; then
14145                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14146                 else
14147                         log "cache hits:: before: $BEFORE, after: $AFTER"
14148                 fi
14149         fi
14150
14151         log "Write data and read it back."
14152         log "Read should be satisfied from the cache."
14153         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14154         BEFORE=$(roc_hit)
14155         cancel_lru_locks osc
14156         cat $file >/dev/null
14157         AFTER=$(roc_hit)
14158         if ! let "AFTER - BEFORE == CPAGES"; then
14159                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14160         else
14161                 log "cache hits:: before: $BEFORE, after: $AFTER"
14162         fi
14163
14164         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14165                 # > 2.12.56 uses pagecache if cached
14166                 log "Read again; it should not be satisfied from the cache."
14167                 BEFORE=$AFTER
14168                 cancel_lru_locks osc
14169                 cat $file >/dev/null
14170                 AFTER=$(roc_hit)
14171                 if ! let "AFTER - BEFORE == 0"; then
14172                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14173                 else
14174                         log "cache hits:: before: $BEFORE, after: $AFTER"
14175                 fi
14176         fi
14177
14178         log "Turn off read and write cache"
14179         set_cache read off
14180         set_cache writethrough off
14181
14182         log "Write data and read it back"
14183         log "It should not be satisfied from the cache."
14184         rm -f $file
14185         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14186         cancel_lru_locks osc
14187         BEFORE=$(roc_hit)
14188         cat $file >/dev/null
14189         AFTER=$(roc_hit)
14190         if ! let "AFTER - BEFORE == 0"; then
14191                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14192         else
14193                 log "cache hits:: before: $BEFORE, after: $AFTER"
14194         fi
14195
14196         log "Turn on the read cache and turn off the write cache"
14197         set_cache read on
14198         set_cache writethrough off
14199
14200         log "Write data and read it back"
14201         log "It should not be satisfied from the cache."
14202         rm -f $file
14203         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14204         BEFORE=$(roc_hit)
14205         cancel_lru_locks osc
14206         cat $file >/dev/null
14207         AFTER=$(roc_hit)
14208         if ! let "AFTER - BEFORE == 0"; then
14209                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14210         else
14211                 log "cache hits:: before: $BEFORE, after: $AFTER"
14212         fi
14213
14214         log "Read again; it should be satisfied from the cache."
14215         BEFORE=$(roc_hit)
14216         cancel_lru_locks osc
14217         cat $file >/dev/null
14218         AFTER=$(roc_hit)
14219         if ! let "AFTER - BEFORE == CPAGES"; then
14220                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14221         else
14222                 log "cache hits:: before: $BEFORE, after: $AFTER"
14223         fi
14224
14225         restore_lustre_params < $p
14226         rm -f $p $file
14227 }
14228 run_test 156 "Verification of tunables"
14229
14230 test_160a() {
14231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14232         remote_mds_nodsh && skip "remote MDS with nodsh"
14233         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14234                 skip "Need MDS version at least 2.2.0"
14235
14236         changelog_register || error "changelog_register failed"
14237         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14238         changelog_users $SINGLEMDS | grep -q $cl_user ||
14239                 error "User $cl_user not found in changelog_users"
14240
14241         # change something
14242         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14243         changelog_clear 0 || error "changelog_clear failed"
14244         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14245         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14246         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14247         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14248         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14249         rm $DIR/$tdir/pics/desktop.jpg
14250
14251         changelog_dump | tail -10
14252
14253         echo "verifying changelog mask"
14254         changelog_chmask "-MKDIR"
14255         changelog_chmask "-CLOSE"
14256
14257         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14258         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14259
14260         changelog_chmask "+MKDIR"
14261         changelog_chmask "+CLOSE"
14262
14263         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14264         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14265
14266         changelog_dump | tail -10
14267         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14268         CLOSES=$(changelog_dump | grep -c "CLOSE")
14269         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14270         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14271
14272         # verify contents
14273         echo "verifying target fid"
14274         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14275         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14276         [ "$fidc" == "$fidf" ] ||
14277                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14278         echo "verifying parent fid"
14279         # The FID returned from the Changelog may be the directory shard on
14280         # a different MDT, and not the FID returned by path2fid on the parent.
14281         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14282         # since this is what will matter when recreating this file in the tree.
14283         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14284         local pathp=$($LFS fid2path $MOUNT "$fidp")
14285         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14286                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14287
14288         echo "getting records for $cl_user"
14289         changelog_users $SINGLEMDS
14290         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14291         local nclr=3
14292         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14293                 error "changelog_clear failed"
14294         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14295         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14296         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14297                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14298
14299         local min0_rec=$(changelog_users $SINGLEMDS |
14300                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14301         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14302                           awk '{ print $1; exit; }')
14303
14304         changelog_dump | tail -n 5
14305         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14306         [ $first_rec == $((min0_rec + 1)) ] ||
14307                 error "first index should be $min0_rec + 1 not $first_rec"
14308
14309         # LU-3446 changelog index reset on MDT restart
14310         local cur_rec1=$(changelog_users $SINGLEMDS |
14311                          awk '/^current.index:/ { print $NF }')
14312         changelog_clear 0 ||
14313                 error "clear all changelog records for $cl_user failed"
14314         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14315         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14316                 error "Fail to start $SINGLEMDS"
14317         local cur_rec2=$(changelog_users $SINGLEMDS |
14318                          awk '/^current.index:/ { print $NF }')
14319         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14320         [ $cur_rec1 == $cur_rec2 ] ||
14321                 error "current index should be $cur_rec1 not $cur_rec2"
14322
14323         echo "verifying users from this test are deregistered"
14324         changelog_deregister || error "changelog_deregister failed"
14325         changelog_users $SINGLEMDS | grep -q $cl_user &&
14326                 error "User '$cl_user' still in changelog_users"
14327
14328         # lctl get_param -n mdd.*.changelog_users
14329         # current index: 144
14330         # ID    index (idle seconds)
14331         # cl3   144 (2)
14332         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14333                 # this is the normal case where all users were deregistered
14334                 # make sure no new records are added when no users are present
14335                 local last_rec1=$(changelog_users $SINGLEMDS |
14336                                   awk '/^current.index:/ { print $NF }')
14337                 touch $DIR/$tdir/chloe
14338                 local last_rec2=$(changelog_users $SINGLEMDS |
14339                                   awk '/^current.index:/ { print $NF }')
14340                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14341                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14342         else
14343                 # any changelog users must be leftovers from a previous test
14344                 changelog_users $SINGLEMDS
14345                 echo "other changelog users; can't verify off"
14346         fi
14347 }
14348 run_test 160a "changelog sanity"
14349
14350 test_160b() { # LU-3587
14351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14352         remote_mds_nodsh && skip "remote MDS with nodsh"
14353         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14354                 skip "Need MDS version at least 2.2.0"
14355
14356         changelog_register || error "changelog_register failed"
14357         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14358         changelog_users $SINGLEMDS | grep -q $cl_user ||
14359                 error "User '$cl_user' not found in changelog_users"
14360
14361         local longname1=$(str_repeat a 255)
14362         local longname2=$(str_repeat b 255)
14363
14364         cd $DIR
14365         echo "creating very long named file"
14366         touch $longname1 || error "create of '$longname1' failed"
14367         echo "renaming very long named file"
14368         mv $longname1 $longname2
14369
14370         changelog_dump | grep RENME | tail -n 5
14371         rm -f $longname2
14372 }
14373 run_test 160b "Verify that very long rename doesn't crash in changelog"
14374
14375 test_160c() {
14376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14377         remote_mds_nodsh && skip "remote MDS with nodsh"
14378
14379         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14380                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14381                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14382                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14383
14384         local rc=0
14385
14386         # Registration step
14387         changelog_register || error "changelog_register failed"
14388
14389         rm -rf $DIR/$tdir
14390         mkdir -p $DIR/$tdir
14391         $MCREATE $DIR/$tdir/foo_160c
14392         changelog_chmask "-TRUNC"
14393         $TRUNCATE $DIR/$tdir/foo_160c 200
14394         changelog_chmask "+TRUNC"
14395         $TRUNCATE $DIR/$tdir/foo_160c 199
14396         changelog_dump | tail -n 5
14397         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14398         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14399 }
14400 run_test 160c "verify that changelog log catch the truncate event"
14401
14402 test_160d() {
14403         remote_mds_nodsh && skip "remote MDS with nodsh"
14404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14406         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14407                 skip "Need MDS version at least 2.7.60"
14408
14409         # Registration step
14410         changelog_register || error "changelog_register failed"
14411
14412         mkdir -p $DIR/$tdir/migrate_dir
14413         changelog_clear 0 || error "changelog_clear failed"
14414
14415         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14416         changelog_dump | tail -n 5
14417         local migrates=$(changelog_dump | grep -c "MIGRT")
14418         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14419 }
14420 run_test 160d "verify that changelog log catch the migrate event"
14421
14422 test_160e() {
14423         remote_mds_nodsh && skip "remote MDS with nodsh"
14424
14425         # Create a user
14426         changelog_register || error "changelog_register failed"
14427
14428         # Delete a future user (expect fail)
14429         local MDT0=$(facet_svc $SINGLEMDS)
14430         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14431         local rc=$?
14432
14433         if [ $rc -eq 0 ]; then
14434                 error "Deleted non-existant user cl77"
14435         elif [ $rc -ne 2 ]; then
14436                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14437         fi
14438
14439         # Clear to a bad index (1 billion should be safe)
14440         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14441         rc=$?
14442
14443         if [ $rc -eq 0 ]; then
14444                 error "Successfully cleared to invalid CL index"
14445         elif [ $rc -ne 22 ]; then
14446                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14447         fi
14448 }
14449 run_test 160e "changelog negative testing (should return errors)"
14450
14451 test_160f() {
14452         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14453         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14454                 skip "Need MDS version at least 2.10.56"
14455
14456         local mdts=$(comma_list $(mdts_nodes))
14457
14458         # Create a user
14459         changelog_register || error "first changelog_register failed"
14460         changelog_register || error "second changelog_register failed"
14461         local cl_users
14462         declare -A cl_user1
14463         declare -A cl_user2
14464         local user_rec1
14465         local user_rec2
14466         local i
14467
14468         # generate some changelog records to accumulate on each MDT
14469         # use fnv1a because created files should be evenly distributed
14470         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14471                 error "test_mkdir $tdir failed"
14472         log "$(date +%s): creating first files"
14473         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14474                 error "create $DIR/$tdir/$tfile failed"
14475
14476         # check changelogs have been generated
14477         local start=$SECONDS
14478         local idle_time=$((MDSCOUNT * 5 + 5))
14479         local nbcl=$(changelog_dump | wc -l)
14480         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14481
14482         for param in "changelog_max_idle_time=$idle_time" \
14483                      "changelog_gc=1" \
14484                      "changelog_min_gc_interval=2" \
14485                      "changelog_min_free_cat_entries=3"; do
14486                 local MDT0=$(facet_svc $SINGLEMDS)
14487                 local var="${param%=*}"
14488                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14489
14490                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14491                 do_nodes $mdts $LCTL set_param mdd.*.$param
14492         done
14493
14494         # force cl_user2 to be idle (1st part), but also cancel the
14495         # cl_user1 records so that it is not evicted later in the test.
14496         local sleep1=$((idle_time / 2))
14497         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14498         sleep $sleep1
14499
14500         # simulate changelog catalog almost full
14501         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14502         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14503
14504         for i in $(seq $MDSCOUNT); do
14505                 cl_users=(${CL_USERS[mds$i]})
14506                 cl_user1[mds$i]="${cl_users[0]}"
14507                 cl_user2[mds$i]="${cl_users[1]}"
14508
14509                 [ -n "${cl_user1[mds$i]}" ] ||
14510                         error "mds$i: no user registered"
14511                 [ -n "${cl_user2[mds$i]}" ] ||
14512                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14513
14514                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14515                 [ -n "$user_rec1" ] ||
14516                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14517                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14518                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14519                 [ -n "$user_rec2" ] ||
14520                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14521                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14522                      "$user_rec1 + 2 == $user_rec2"
14523                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14524                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14525                               "$user_rec1 + 2, but is $user_rec2"
14526                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14527                 [ -n "$user_rec2" ] ||
14528                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14529                 [ $user_rec1 == $user_rec2 ] ||
14530                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14531                               "$user_rec1, but is $user_rec2"
14532         done
14533
14534         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14535         local sleep2=$((idle_time - (SECONDS - start) + 1))
14536         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14537         sleep $sleep2
14538
14539         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14540         # cl_user1 should be OK because it recently processed records.
14541         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14542         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14543                 error "create $DIR/$tdir/${tfile}b failed"
14544
14545         # ensure gc thread is done
14546         for i in $(mdts_nodes); do
14547                 wait_update $i \
14548                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14549                         error "$i: GC-thread not done"
14550         done
14551
14552         local first_rec
14553         for i in $(seq $MDSCOUNT); do
14554                 # check cl_user1 still registered
14555                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14556                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14557                 # check cl_user2 unregistered
14558                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14559                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14560
14561                 # check changelogs are present and starting at $user_rec1 + 1
14562                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14563                 [ -n "$user_rec1" ] ||
14564                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14565                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14566                             awk '{ print $1; exit; }')
14567
14568                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14569                 [ $((user_rec1 + 1)) == $first_rec ] ||
14570                         error "mds$i: first index should be $user_rec1 + 1, " \
14571                               "but is $first_rec"
14572         done
14573 }
14574 run_test 160f "changelog garbage collect (timestamped users)"
14575
14576 test_160g() {
14577         remote_mds_nodsh && skip "remote MDS with nodsh"
14578         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14579                 skip "Need MDS version at least 2.10.56"
14580
14581         local mdts=$(comma_list $(mdts_nodes))
14582
14583         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14584         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14585
14586         # Create a user
14587         changelog_register || error "first changelog_register failed"
14588         changelog_register || error "second changelog_register failed"
14589         local cl_users
14590         declare -A cl_user1
14591         declare -A cl_user2
14592         local user_rec1
14593         local user_rec2
14594         local i
14595
14596         # generate some changelog records to accumulate on each MDT
14597         # use fnv1a because created files should be evenly distributed
14598         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14599                 error "mkdir $tdir failed"
14600         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14601                 error "create $DIR/$tdir/$tfile failed"
14602
14603         # check changelogs have been generated
14604         local nbcl=$(changelog_dump | wc -l)
14605         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14606
14607         # reduce the max_idle_indexes value to make sure we exceed it
14608         max_ndx=$((nbcl / 2 - 1))
14609
14610         for param in "changelog_max_idle_indexes=$max_ndx" \
14611                      "changelog_gc=1" \
14612                      "changelog_min_gc_interval=2" \
14613                      "changelog_min_free_cat_entries=3"; do
14614                 local MDT0=$(facet_svc $SINGLEMDS)
14615                 local var="${param%=*}"
14616                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14617
14618                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14619                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14620                         error "unable to set mdd.*.$param"
14621         done
14622
14623         # simulate changelog catalog almost full
14624         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14625         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14626
14627         for i in $(seq $MDSCOUNT); do
14628                 cl_users=(${CL_USERS[mds$i]})
14629                 cl_user1[mds$i]="${cl_users[0]}"
14630                 cl_user2[mds$i]="${cl_users[1]}"
14631
14632                 [ -n "${cl_user1[mds$i]}" ] ||
14633                         error "mds$i: no user registered"
14634                 [ -n "${cl_user2[mds$i]}" ] ||
14635                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14636
14637                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14638                 [ -n "$user_rec1" ] ||
14639                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14640                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14641                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14642                 [ -n "$user_rec2" ] ||
14643                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14644                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14645                      "$user_rec1 + 2 == $user_rec2"
14646                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14647                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14648                               "$user_rec1 + 2, but is $user_rec2"
14649                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14650                 [ -n "$user_rec2" ] ||
14651                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14652                 [ $user_rec1 == $user_rec2 ] ||
14653                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14654                               "$user_rec1, but is $user_rec2"
14655         done
14656
14657         # ensure we are past the previous changelog_min_gc_interval set above
14658         sleep 2
14659
14660         # generate one more changelog to trigger fail_loc
14661         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14662                 error "create $DIR/$tdir/${tfile}bis failed"
14663
14664         # ensure gc thread is done
14665         for i in $(mdts_nodes); do
14666                 wait_update $i \
14667                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14668                         error "$i: GC-thread not done"
14669         done
14670
14671         local first_rec
14672         for i in $(seq $MDSCOUNT); do
14673                 # check cl_user1 still registered
14674                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14675                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14676                 # check cl_user2 unregistered
14677                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14678                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14679
14680                 # check changelogs are present and starting at $user_rec1 + 1
14681                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14682                 [ -n "$user_rec1" ] ||
14683                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14684                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14685                             awk '{ print $1; exit; }')
14686
14687                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14688                 [ $((user_rec1 + 1)) == $first_rec ] ||
14689                         error "mds$i: first index should be $user_rec1 + 1, " \
14690                               "but is $first_rec"
14691         done
14692 }
14693 run_test 160g "changelog garbage collect (old users)"
14694
14695 test_160h() {
14696         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14697         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14698                 skip "Need MDS version at least 2.10.56"
14699
14700         local mdts=$(comma_list $(mdts_nodes))
14701
14702         # Create a user
14703         changelog_register || error "first changelog_register failed"
14704         changelog_register || error "second changelog_register failed"
14705         local cl_users
14706         declare -A cl_user1
14707         declare -A cl_user2
14708         local user_rec1
14709         local user_rec2
14710         local i
14711
14712         # generate some changelog records to accumulate on each MDT
14713         # use fnv1a because created files should be evenly distributed
14714         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14715                 error "test_mkdir $tdir failed"
14716         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14717                 error "create $DIR/$tdir/$tfile failed"
14718
14719         # check changelogs have been generated
14720         local nbcl=$(changelog_dump | wc -l)
14721         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14722
14723         for param in "changelog_max_idle_time=10" \
14724                      "changelog_gc=1" \
14725                      "changelog_min_gc_interval=2"; do
14726                 local MDT0=$(facet_svc $SINGLEMDS)
14727                 local var="${param%=*}"
14728                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14729
14730                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14731                 do_nodes $mdts $LCTL set_param mdd.*.$param
14732         done
14733
14734         # force cl_user2 to be idle (1st part)
14735         sleep 9
14736
14737         for i in $(seq $MDSCOUNT); do
14738                 cl_users=(${CL_USERS[mds$i]})
14739                 cl_user1[mds$i]="${cl_users[0]}"
14740                 cl_user2[mds$i]="${cl_users[1]}"
14741
14742                 [ -n "${cl_user1[mds$i]}" ] ||
14743                         error "mds$i: no user registered"
14744                 [ -n "${cl_user2[mds$i]}" ] ||
14745                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14746
14747                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14748                 [ -n "$user_rec1" ] ||
14749                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14750                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14751                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14752                 [ -n "$user_rec2" ] ||
14753                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14754                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14755                      "$user_rec1 + 2 == $user_rec2"
14756                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14757                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14758                               "$user_rec1 + 2, but is $user_rec2"
14759                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14760                 [ -n "$user_rec2" ] ||
14761                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14762                 [ $user_rec1 == $user_rec2 ] ||
14763                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14764                               "$user_rec1, but is $user_rec2"
14765         done
14766
14767         # force cl_user2 to be idle (2nd part) and to reach
14768         # changelog_max_idle_time
14769         sleep 2
14770
14771         # force each GC-thread start and block then
14772         # one per MDT/MDD, set fail_val accordingly
14773         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14774         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14775
14776         # generate more changelogs to trigger fail_loc
14777         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14778                 error "create $DIR/$tdir/${tfile}bis failed"
14779
14780         # stop MDT to stop GC-thread, should be done in back-ground as it will
14781         # block waiting for the thread to be released and exit
14782         declare -A stop_pids
14783         for i in $(seq $MDSCOUNT); do
14784                 stop mds$i &
14785                 stop_pids[mds$i]=$!
14786         done
14787
14788         for i in $(mdts_nodes); do
14789                 local facet
14790                 local nb=0
14791                 local facets=$(facets_up_on_host $i)
14792
14793                 for facet in ${facets//,/ }; do
14794                         if [[ $facet == mds* ]]; then
14795                                 nb=$((nb + 1))
14796                         fi
14797                 done
14798                 # ensure each MDS's gc threads are still present and all in "R"
14799                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14800                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14801                         error "$i: expected $nb GC-thread"
14802                 wait_update $i \
14803                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14804                         "R" 20 ||
14805                         error "$i: GC-thread not found in R-state"
14806                 # check umounts of each MDT on MDS have reached kthread_stop()
14807                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14808                         error "$i: expected $nb umount"
14809                 wait_update $i \
14810                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14811                         error "$i: umount not found in D-state"
14812         done
14813
14814         # release all GC-threads
14815         do_nodes $mdts $LCTL set_param fail_loc=0
14816
14817         # wait for MDT stop to complete
14818         for i in $(seq $MDSCOUNT); do
14819                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14820         done
14821
14822         # XXX
14823         # may try to check if any orphan changelog records are present
14824         # via ldiskfs/zfs and llog_reader...
14825
14826         # re-start/mount MDTs
14827         for i in $(seq $MDSCOUNT); do
14828                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14829                         error "Fail to start mds$i"
14830         done
14831
14832         local first_rec
14833         for i in $(seq $MDSCOUNT); do
14834                 # check cl_user1 still registered
14835                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14836                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14837                 # check cl_user2 unregistered
14838                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14839                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14840
14841                 # check changelogs are present and starting at $user_rec1 + 1
14842                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14843                 [ -n "$user_rec1" ] ||
14844                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14845                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14846                             awk '{ print $1; exit; }')
14847
14848                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14849                 [ $((user_rec1 + 1)) == $first_rec ] ||
14850                         error "mds$i: first index should be $user_rec1 + 1, " \
14851                               "but is $first_rec"
14852         done
14853 }
14854 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14855               "during mount"
14856
14857 test_160i() {
14858
14859         local mdts=$(comma_list $(mdts_nodes))
14860
14861         changelog_register || error "first changelog_register failed"
14862
14863         # generate some changelog records to accumulate on each MDT
14864         # use fnv1a because created files should be evenly distributed
14865         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14866                 error "mkdir $tdir failed"
14867         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14868                 error "create $DIR/$tdir/$tfile failed"
14869
14870         # check changelogs have been generated
14871         local nbcl=$(changelog_dump | wc -l)
14872         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14873
14874         # simulate race between register and unregister
14875         # XXX as fail_loc is set per-MDS, with DNE configs the race
14876         # simulation will only occur for one MDT per MDS and for the
14877         # others the normal race scenario will take place
14878         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14879         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14880         do_nodes $mdts $LCTL set_param fail_val=1
14881
14882         # unregister 1st user
14883         changelog_deregister &
14884         local pid1=$!
14885         # wait some time for deregister work to reach race rdv
14886         sleep 2
14887         # register 2nd user
14888         changelog_register || error "2nd user register failed"
14889
14890         wait $pid1 || error "1st user deregister failed"
14891
14892         local i
14893         local last_rec
14894         declare -A LAST_REC
14895         for i in $(seq $MDSCOUNT); do
14896                 if changelog_users mds$i | grep "^cl"; then
14897                         # make sure new records are added with one user present
14898                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14899                                           awk '/^current.index:/ { print $NF }')
14900                 else
14901                         error "mds$i has no user registered"
14902                 fi
14903         done
14904
14905         # generate more changelog records to accumulate on each MDT
14906         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14907                 error "create $DIR/$tdir/${tfile}bis failed"
14908
14909         for i in $(seq $MDSCOUNT); do
14910                 last_rec=$(changelog_users $SINGLEMDS |
14911                            awk '/^current.index:/ { print $NF }')
14912                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14913                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14914                         error "changelogs are off on mds$i"
14915         done
14916 }
14917 run_test 160i "changelog user register/unregister race"
14918
14919 test_160j() {
14920         remote_mds_nodsh && skip "remote MDS with nodsh"
14921         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14922                 skip "Need MDS version at least 2.12.56"
14923
14924         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14925         stack_trap "umount $MOUNT2" EXIT
14926
14927         changelog_register || error "first changelog_register failed"
14928         stack_trap "changelog_deregister" EXIT
14929
14930         # generate some changelog
14931         # use fnv1a because created files should be evenly distributed
14932         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14933                 error "mkdir $tdir failed"
14934         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14935                 error "create $DIR/$tdir/${tfile}bis failed"
14936
14937         # open the changelog device
14938         exec 3>/dev/changelog-$FSNAME-MDT0000
14939         stack_trap "exec 3>&-" EXIT
14940         exec 4</dev/changelog-$FSNAME-MDT0000
14941         stack_trap "exec 4<&-" EXIT
14942
14943         # umount the first lustre mount
14944         umount $MOUNT
14945         stack_trap "mount_client $MOUNT" EXIT
14946
14947         # read changelog
14948         cat <&4 >/dev/null || error "read changelog failed"
14949
14950         # clear changelog
14951         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14952         changelog_users $SINGLEMDS | grep -q $cl_user ||
14953                 error "User $cl_user not found in changelog_users"
14954
14955         printf 'clear:'$cl_user':0' >&3
14956 }
14957 run_test 160j "client can be umounted  while its chanangelog is being used"
14958
14959 test_160k() {
14960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14961         remote_mds_nodsh && skip "remote MDS with nodsh"
14962
14963         mkdir -p $DIR/$tdir/1/1
14964
14965         changelog_register || error "changelog_register failed"
14966         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14967
14968         changelog_users $SINGLEMDS | grep -q $cl_user ||
14969                 error "User '$cl_user' not found in changelog_users"
14970 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14971         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14972         rmdir $DIR/$tdir/1/1 & sleep 1
14973         mkdir $DIR/$tdir/2
14974         touch $DIR/$tdir/2/2
14975         rm -rf $DIR/$tdir/2
14976
14977         wait
14978         sleep 4
14979
14980         changelog_dump | grep rmdir || error "rmdir not recorded"
14981
14982         rm -rf $DIR/$tdir
14983         changelog_deregister
14984 }
14985 run_test 160k "Verify that changelog records are not lost"
14986
14987 test_161a() {
14988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14989
14990         test_mkdir -c1 $DIR/$tdir
14991         cp /etc/hosts $DIR/$tdir/$tfile
14992         test_mkdir -c1 $DIR/$tdir/foo1
14993         test_mkdir -c1 $DIR/$tdir/foo2
14994         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14995         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14996         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14997         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14998         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14999         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15000                 $LFS fid2path $DIR $FID
15001                 error "bad link ea"
15002         fi
15003         # middle
15004         rm $DIR/$tdir/foo2/zachary
15005         # last
15006         rm $DIR/$tdir/foo2/thor
15007         # first
15008         rm $DIR/$tdir/$tfile
15009         # rename
15010         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15011         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15012                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15013         rm $DIR/$tdir/foo2/maggie
15014
15015         # overflow the EA
15016         local longname=$tfile.avg_len_is_thirty_two_
15017         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15018                 error_noexit 'failed to unlink many hardlinks'" EXIT
15019         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15020                 error "failed to hardlink many files"
15021         links=$($LFS fid2path $DIR $FID | wc -l)
15022         echo -n "${links}/1000 links in link EA"
15023         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15024 }
15025 run_test 161a "link ea sanity"
15026
15027 test_161b() {
15028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15029         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15030
15031         local MDTIDX=1
15032         local remote_dir=$DIR/$tdir/remote_dir
15033
15034         mkdir -p $DIR/$tdir
15035         $LFS mkdir -i $MDTIDX $remote_dir ||
15036                 error "create remote directory failed"
15037
15038         cp /etc/hosts $remote_dir/$tfile
15039         mkdir -p $remote_dir/foo1
15040         mkdir -p $remote_dir/foo2
15041         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15042         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15043         ln $remote_dir/$tfile $remote_dir/foo1/luna
15044         ln $remote_dir/$tfile $remote_dir/foo2/thor
15045
15046         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15047                      tr -d ']')
15048         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15049                 $LFS fid2path $DIR $FID
15050                 error "bad link ea"
15051         fi
15052         # middle
15053         rm $remote_dir/foo2/zachary
15054         # last
15055         rm $remote_dir/foo2/thor
15056         # first
15057         rm $remote_dir/$tfile
15058         # rename
15059         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15060         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15061         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15062                 $LFS fid2path $DIR $FID
15063                 error "bad link rename"
15064         fi
15065         rm $remote_dir/foo2/maggie
15066
15067         # overflow the EA
15068         local longname=filename_avg_len_is_thirty_two_
15069         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15070                 error "failed to hardlink many files"
15071         links=$($LFS fid2path $DIR $FID | wc -l)
15072         echo -n "${links}/1000 links in link EA"
15073         [[ ${links} -gt 60 ]] ||
15074                 error "expected at least 60 links in link EA"
15075         unlinkmany $remote_dir/foo2/$longname 1000 ||
15076         error "failed to unlink many hardlinks"
15077 }
15078 run_test 161b "link ea sanity under remote directory"
15079
15080 test_161c() {
15081         remote_mds_nodsh && skip "remote MDS with nodsh"
15082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15083         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15084                 skip "Need MDS version at least 2.1.5"
15085
15086         # define CLF_RENAME_LAST 0x0001
15087         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15088         changelog_register || error "changelog_register failed"
15089
15090         rm -rf $DIR/$tdir
15091         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15092         touch $DIR/$tdir/foo_161c
15093         touch $DIR/$tdir/bar_161c
15094         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15095         changelog_dump | grep RENME | tail -n 5
15096         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15097         changelog_clear 0 || error "changelog_clear failed"
15098         if [ x$flags != "x0x1" ]; then
15099                 error "flag $flags is not 0x1"
15100         fi
15101
15102         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15103         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15104         touch $DIR/$tdir/foo_161c
15105         touch $DIR/$tdir/bar_161c
15106         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15107         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15108         changelog_dump | grep RENME | tail -n 5
15109         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15110         changelog_clear 0 || error "changelog_clear failed"
15111         if [ x$flags != "x0x0" ]; then
15112                 error "flag $flags is not 0x0"
15113         fi
15114         echo "rename overwrite a target having nlink > 1," \
15115                 "changelog record has flags of $flags"
15116
15117         # rename doesn't overwrite a target (changelog flag 0x0)
15118         touch $DIR/$tdir/foo_161c
15119         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15120         changelog_dump | grep RENME | tail -n 5
15121         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15122         changelog_clear 0 || error "changelog_clear failed"
15123         if [ x$flags != "x0x0" ]; then
15124                 error "flag $flags is not 0x0"
15125         fi
15126         echo "rename doesn't overwrite a target," \
15127                 "changelog record has flags of $flags"
15128
15129         # define CLF_UNLINK_LAST 0x0001
15130         # unlink a file having nlink = 1 (changelog flag 0x1)
15131         rm -f $DIR/$tdir/foo2_161c
15132         changelog_dump | grep UNLNK | tail -n 5
15133         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15134         changelog_clear 0 || error "changelog_clear failed"
15135         if [ x$flags != "x0x1" ]; then
15136                 error "flag $flags is not 0x1"
15137         fi
15138         echo "unlink a file having nlink = 1," \
15139                 "changelog record has flags of $flags"
15140
15141         # unlink a file having nlink > 1 (changelog flag 0x0)
15142         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15143         rm -f $DIR/$tdir/foobar_161c
15144         changelog_dump | grep UNLNK | tail -n 5
15145         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15146         changelog_clear 0 || error "changelog_clear failed"
15147         if [ x$flags != "x0x0" ]; then
15148                 error "flag $flags is not 0x0"
15149         fi
15150         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15151 }
15152 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15153
15154 test_161d() {
15155         remote_mds_nodsh && skip "remote MDS with nodsh"
15156         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15157
15158         local pid
15159         local fid
15160
15161         changelog_register || error "changelog_register failed"
15162
15163         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15164         # interfer with $MOUNT/.lustre/fid/ access
15165         mkdir $DIR/$tdir
15166         [[ $? -eq 0 ]] || error "mkdir failed"
15167
15168         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15169         $LCTL set_param fail_loc=0x8000140c
15170         # 5s pause
15171         $LCTL set_param fail_val=5
15172
15173         # create file
15174         echo foofoo > $DIR/$tdir/$tfile &
15175         pid=$!
15176
15177         # wait for create to be delayed
15178         sleep 2
15179
15180         ps -p $pid
15181         [[ $? -eq 0 ]] || error "create should be blocked"
15182
15183         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15184         stack_trap "rm -f $tempfile"
15185         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15186         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15187         # some delay may occur during ChangeLog publishing and file read just
15188         # above, that could allow file write to happen finally
15189         [[ -s $tempfile ]] && echo "file should be empty"
15190
15191         $LCTL set_param fail_loc=0
15192
15193         wait $pid
15194         [[ $? -eq 0 ]] || error "create failed"
15195 }
15196 run_test 161d "create with concurrent .lustre/fid access"
15197
15198 check_path() {
15199         local expected="$1"
15200         shift
15201         local fid="$2"
15202
15203         local path
15204         path=$($LFS fid2path "$@")
15205         local rc=$?
15206
15207         if [ $rc -ne 0 ]; then
15208                 error "path looked up of '$expected' failed: rc=$rc"
15209         elif [ "$path" != "$expected" ]; then
15210                 error "path looked up '$path' instead of '$expected'"
15211         else
15212                 echo "FID '$fid' resolves to path '$path' as expected"
15213         fi
15214 }
15215
15216 test_162a() { # was test_162
15217         test_mkdir -p -c1 $DIR/$tdir/d2
15218         touch $DIR/$tdir/d2/$tfile
15219         touch $DIR/$tdir/d2/x1
15220         touch $DIR/$tdir/d2/x2
15221         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15222         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15223         # regular file
15224         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15225         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15226
15227         # softlink
15228         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15229         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15230         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15231
15232         # softlink to wrong file
15233         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15234         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15235         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15236
15237         # hardlink
15238         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15239         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15240         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15241         # fid2path dir/fsname should both work
15242         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15243         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15244
15245         # hardlink count: check that there are 2 links
15246         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15247         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15248
15249         # hardlink indexing: remove the first link
15250         rm $DIR/$tdir/d2/p/q/r/hlink
15251         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15252 }
15253 run_test 162a "path lookup sanity"
15254
15255 test_162b() {
15256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15258
15259         mkdir $DIR/$tdir
15260         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15261                                 error "create striped dir failed"
15262
15263         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15264                                         tail -n 1 | awk '{print $2}')
15265         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15266
15267         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15268         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15269
15270         # regular file
15271         for ((i=0;i<5;i++)); do
15272                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15273                         error "get fid for f$i failed"
15274                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15275
15276                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15277                         error "get fid for d$i failed"
15278                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15279         done
15280
15281         return 0
15282 }
15283 run_test 162b "striped directory path lookup sanity"
15284
15285 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15286 test_162c() {
15287         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15288                 skip "Need MDS version at least 2.7.51"
15289
15290         local lpath=$tdir.local
15291         local rpath=$tdir.remote
15292
15293         test_mkdir $DIR/$lpath
15294         test_mkdir $DIR/$rpath
15295
15296         for ((i = 0; i <= 101; i++)); do
15297                 lpath="$lpath/$i"
15298                 mkdir $DIR/$lpath
15299                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15300                         error "get fid for local directory $DIR/$lpath failed"
15301                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15302
15303                 rpath="$rpath/$i"
15304                 test_mkdir $DIR/$rpath
15305                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15306                         error "get fid for remote directory $DIR/$rpath failed"
15307                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15308         done
15309
15310         return 0
15311 }
15312 run_test 162c "fid2path works with paths 100 or more directories deep"
15313
15314 oalr_event_count() {
15315         local event="${1}"
15316         local trace="${2}"
15317
15318         awk -v name="${FSNAME}-OST0000" \
15319             -v event="${event}" \
15320             '$1 == "TRACE" && $2 == event && $3 == name' \
15321             "${trace}" |
15322         wc -l
15323 }
15324
15325 oalr_expect_event_count() {
15326         local event="${1}"
15327         local trace="${2}"
15328         local expect="${3}"
15329         local count
15330
15331         count=$(oalr_event_count "${event}" "${trace}")
15332         if ((count == expect)); then
15333                 return 0
15334         fi
15335
15336         error_noexit "${event} event count was '${count}', expected ${expect}"
15337         cat "${trace}" >&2
15338         exit 1
15339 }
15340
15341 cleanup_165() {
15342         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15343         stop ost1
15344         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15345 }
15346
15347 setup_165() {
15348         sync # Flush previous IOs so we can count log entries.
15349         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15350         stack_trap cleanup_165 EXIT
15351 }
15352
15353 test_165a() {
15354         local trace="/tmp/${tfile}.trace"
15355         local rc
15356         local count
15357
15358         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15359         setup_165
15360         sleep 5
15361
15362         do_facet ost1 ofd_access_log_reader --list
15363         stop ost1
15364
15365         do_facet ost1 killall -TERM ofd_access_log_reader
15366         wait
15367         rc=$?
15368
15369         if ((rc != 0)); then
15370                 error "ofd_access_log_reader exited with rc = '${rc}'"
15371         fi
15372
15373         # Parse trace file for discovery events:
15374         oalr_expect_event_count alr_log_add "${trace}" 1
15375         oalr_expect_event_count alr_log_eof "${trace}" 1
15376         oalr_expect_event_count alr_log_free "${trace}" 1
15377 }
15378 run_test 165a "ofd access log discovery"
15379
15380 test_165b() {
15381         local trace="/tmp/${tfile}.trace"
15382         local file="${DIR}/${tfile}"
15383         local pfid1
15384         local pfid2
15385         local -a entry
15386         local rc
15387         local count
15388         local size
15389         local flags
15390
15391         setup_165
15392
15393         lfs setstripe -c 1 -i 0 "${file}"
15394         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15395         do_facet ost1 ofd_access_log_reader --list
15396
15397         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15398         sleep 5
15399         do_facet ost1 killall -TERM ofd_access_log_reader
15400         wait
15401         rc=$?
15402
15403         if ((rc != 0)); then
15404                 error "ofd_access_log_reader exited with rc = '${rc}'"
15405         fi
15406
15407         oalr_expect_event_count alr_log_entry "${trace}" 1
15408
15409         pfid1=$($LFS path2fid "${file}")
15410
15411         # 1     2             3   4    5     6   7    8    9     10
15412         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15413         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15414
15415         echo "entry = '${entry[*]}'" >&2
15416
15417         pfid2=${entry[4]}
15418         if [[ "${pfid1}" != "${pfid2}" ]]; then
15419                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15420         fi
15421
15422         size=${entry[8]}
15423         if ((size != 1048576)); then
15424                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15425         fi
15426
15427         flags=${entry[10]}
15428         if [[ "${flags}" != "w" ]]; then
15429                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15430         fi
15431
15432         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15433         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15434         sleep 5
15435         do_facet ost1 killall -TERM ofd_access_log_reader
15436         wait
15437         rc=$?
15438
15439         if ((rc != 0)); then
15440                 error "ofd_access_log_reader exited with rc = '${rc}'"
15441         fi
15442
15443         oalr_expect_event_count alr_log_entry "${trace}" 1
15444
15445         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15446         echo "entry = '${entry[*]}'" >&2
15447
15448         pfid2=${entry[4]}
15449         if [[ "${pfid1}" != "${pfid2}" ]]; then
15450                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15451         fi
15452
15453         size=${entry[8]}
15454         if ((size != 524288)); then
15455                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15456         fi
15457
15458         flags=${entry[10]}
15459         if [[ "${flags}" != "r" ]]; then
15460                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15461         fi
15462 }
15463 run_test 165b "ofd access log entries are produced and consumed"
15464
15465 test_165c() {
15466         local file="${DIR}/${tdir}/${tfile}"
15467         test_mkdir "${DIR}/${tdir}"
15468
15469         setup_165
15470
15471         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15472
15473         # 4096 / 64 = 64. Create twice as many entries.
15474         for ((i = 0; i < 128; i++)); do
15475                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15476         done
15477
15478         sync
15479         do_facet ost1 ofd_access_log_reader --list
15480         unlinkmany  "${file}-%d" 128
15481 }
15482 run_test 165c "full ofd access logs do not block IOs"
15483
15484 oal_peek_entry_count() {
15485         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15486 }
15487
15488 oal_expect_entry_count() {
15489         local entry_count=$(oal_peek_entry_count)
15490         local expect="$1"
15491
15492         if ((entry_count == expect)); then
15493                 return 0
15494         fi
15495
15496         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15497         do_facet ost1 ofd_access_log_reader --list >&2
15498         exit 1
15499 }
15500
15501 test_165d() {
15502         local trace="/tmp/${tfile}.trace"
15503         local file="${DIR}/${tdir}/${tfile}"
15504         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15505         local entry_count
15506         test_mkdir "${DIR}/${tdir}"
15507
15508         setup_165
15509         lfs setstripe -c 1 -i 0 "${file}"
15510
15511         do_facet ost1 lctl set_param "${param}=rw"
15512         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15513         oal_expect_entry_count 1
15514
15515         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15516         oal_expect_entry_count 2
15517
15518         do_facet ost1 lctl set_param "${param}=r"
15519         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15520         oal_expect_entry_count 2
15521
15522         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15523         oal_expect_entry_count 3
15524
15525         do_facet ost1 lctl set_param "${param}=w"
15526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15527         oal_expect_entry_count 4
15528
15529         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15530         oal_expect_entry_count 4
15531
15532         do_facet ost1 lctl set_param "${param}=0"
15533         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15534         oal_expect_entry_count 4
15535
15536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15537         oal_expect_entry_count 4
15538 }
15539 run_test 165d "ofd_access_log mask works"
15540
15541 test_169() {
15542         # do directio so as not to populate the page cache
15543         log "creating a 10 Mb file"
15544         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15545         log "starting reads"
15546         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15547         log "truncating the file"
15548         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15549         log "killing dd"
15550         kill %+ || true # reads might have finished
15551         echo "wait until dd is finished"
15552         wait
15553         log "removing the temporary file"
15554         rm -rf $DIR/$tfile || error "tmp file removal failed"
15555 }
15556 run_test 169 "parallel read and truncate should not deadlock"
15557
15558 test_170() {
15559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15560
15561         $LCTL clear     # bug 18514
15562         $LCTL debug_daemon start $TMP/${tfile}_log_good
15563         touch $DIR/$tfile
15564         $LCTL debug_daemon stop
15565         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15566                 error "sed failed to read log_good"
15567
15568         $LCTL debug_daemon start $TMP/${tfile}_log_good
15569         rm -rf $DIR/$tfile
15570         $LCTL debug_daemon stop
15571
15572         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15573                error "lctl df log_bad failed"
15574
15575         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15576         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15577
15578         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15579         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15580
15581         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15582                 error "bad_line good_line1 good_line2 are empty"
15583
15584         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15585         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15586         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15587
15588         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15589         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15590         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15591
15592         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15593                 error "bad_line_new good_line_new are empty"
15594
15595         local expected_good=$((good_line1 + good_line2*2))
15596
15597         rm -f $TMP/${tfile}*
15598         # LU-231, short malformed line may not be counted into bad lines
15599         if [ $bad_line -ne $bad_line_new ] &&
15600                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15601                 error "expected $bad_line bad lines, but got $bad_line_new"
15602                 return 1
15603         fi
15604
15605         if [ $expected_good -ne $good_line_new ]; then
15606                 error "expected $expected_good good lines, but got $good_line_new"
15607                 return 2
15608         fi
15609         true
15610 }
15611 run_test 170 "test lctl df to handle corrupted log ====================="
15612
15613 test_171() { # bug20592
15614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15615
15616         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15617         $LCTL set_param fail_loc=0x50e
15618         $LCTL set_param fail_val=3000
15619         multiop_bg_pause $DIR/$tfile O_s || true
15620         local MULTIPID=$!
15621         kill -USR1 $MULTIPID
15622         # cause log dump
15623         sleep 3
15624         wait $MULTIPID
15625         if dmesg | grep "recursive fault"; then
15626                 error "caught a recursive fault"
15627         fi
15628         $LCTL set_param fail_loc=0
15629         true
15630 }
15631 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15632
15633 # it would be good to share it with obdfilter-survey/iokit-libecho code
15634 setup_obdecho_osc () {
15635         local rc=0
15636         local ost_nid=$1
15637         local obdfilter_name=$2
15638         echo "Creating new osc for $obdfilter_name on $ost_nid"
15639         # make sure we can find loopback nid
15640         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15641
15642         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15643                            ${obdfilter_name}_osc_UUID || rc=2; }
15644         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15645                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15646         return $rc
15647 }
15648
15649 cleanup_obdecho_osc () {
15650         local obdfilter_name=$1
15651         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15652         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15653         return 0
15654 }
15655
15656 obdecho_test() {
15657         local OBD=$1
15658         local node=$2
15659         local pages=${3:-64}
15660         local rc=0
15661         local id
15662
15663         local count=10
15664         local obd_size=$(get_obd_size $node $OBD)
15665         local page_size=$(get_page_size $node)
15666         if [[ -n "$obd_size" ]]; then
15667                 local new_count=$((obd_size / (pages * page_size / 1024)))
15668                 [[ $new_count -ge $count ]] || count=$new_count
15669         fi
15670
15671         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15672         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15673                            rc=2; }
15674         if [ $rc -eq 0 ]; then
15675             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15676             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15677         fi
15678         echo "New object id is $id"
15679         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15680                            rc=4; }
15681         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15682                            "test_brw $count w v $pages $id" || rc=4; }
15683         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15684                            rc=4; }
15685         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15686                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15687         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15688                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15689         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15690         return $rc
15691 }
15692
15693 test_180a() {
15694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15695
15696         if ! module_loaded obdecho; then
15697                 load_module obdecho/obdecho &&
15698                         stack_trap "rmmod obdecho" EXIT ||
15699                         error "unable to load obdecho on client"
15700         fi
15701
15702         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15703         local host=$($LCTL get_param -n osc.$osc.import |
15704                      awk '/current_connection:/ { print $2 }' )
15705         local target=$($LCTL get_param -n osc.$osc.import |
15706                        awk '/target:/ { print $2 }' )
15707         target=${target%_UUID}
15708
15709         if [ -n "$target" ]; then
15710                 setup_obdecho_osc $host $target &&
15711                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15712                         { error "obdecho setup failed with $?"; return; }
15713
15714                 obdecho_test ${target}_osc client ||
15715                         error "obdecho_test failed on ${target}_osc"
15716         else
15717                 $LCTL get_param osc.$osc.import
15718                 error "there is no osc.$osc.import target"
15719         fi
15720 }
15721 run_test 180a "test obdecho on osc"
15722
15723 test_180b() {
15724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15725         remote_ost_nodsh && skip "remote OST with nodsh"
15726
15727         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15728                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15729                 error "failed to load module obdecho"
15730
15731         local target=$(do_facet ost1 $LCTL dl |
15732                        awk '/obdfilter/ { print $4; exit; }')
15733
15734         if [ -n "$target" ]; then
15735                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15736         else
15737                 do_facet ost1 $LCTL dl
15738                 error "there is no obdfilter target on ost1"
15739         fi
15740 }
15741 run_test 180b "test obdecho directly on obdfilter"
15742
15743 test_180c() { # LU-2598
15744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15745         remote_ost_nodsh && skip "remote OST with nodsh"
15746         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15747                 skip "Need MDS version at least 2.4.0"
15748
15749         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15750                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15751                 error "failed to load module obdecho"
15752
15753         local target=$(do_facet ost1 $LCTL dl |
15754                        awk '/obdfilter/ { print $4; exit; }')
15755
15756         if [ -n "$target" ]; then
15757                 local pages=16384 # 64MB bulk I/O RPC size
15758
15759                 obdecho_test "$target" ost1 "$pages" ||
15760                         error "obdecho_test with pages=$pages failed with $?"
15761         else
15762                 do_facet ost1 $LCTL dl
15763                 error "there is no obdfilter target on ost1"
15764         fi
15765 }
15766 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15767
15768 test_181() { # bug 22177
15769         test_mkdir $DIR/$tdir
15770         # create enough files to index the directory
15771         createmany -o $DIR/$tdir/foobar 4000
15772         # print attributes for debug purpose
15773         lsattr -d .
15774         # open dir
15775         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15776         MULTIPID=$!
15777         # remove the files & current working dir
15778         unlinkmany $DIR/$tdir/foobar 4000
15779         rmdir $DIR/$tdir
15780         kill -USR1 $MULTIPID
15781         wait $MULTIPID
15782         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15783         return 0
15784 }
15785 run_test 181 "Test open-unlinked dir ========================"
15786
15787 test_182() {
15788         local fcount=1000
15789         local tcount=10
15790
15791         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15792
15793         $LCTL set_param mdc.*.rpc_stats=clear
15794
15795         for (( i = 0; i < $tcount; i++ )) ; do
15796                 mkdir $DIR/$tdir/$i
15797         done
15798
15799         for (( i = 0; i < $tcount; i++ )) ; do
15800                 createmany -o $DIR/$tdir/$i/f- $fcount &
15801         done
15802         wait
15803
15804         for (( i = 0; i < $tcount; i++ )) ; do
15805                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15806         done
15807         wait
15808
15809         $LCTL get_param mdc.*.rpc_stats
15810
15811         rm -rf $DIR/$tdir
15812 }
15813 run_test 182 "Test parallel modify metadata operations ================"
15814
15815 test_183() { # LU-2275
15816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15817         remote_mds_nodsh && skip "remote MDS with nodsh"
15818         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15819                 skip "Need MDS version at least 2.3.56"
15820
15821         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15822         echo aaa > $DIR/$tdir/$tfile
15823
15824 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15825         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15826
15827         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15828         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15829
15830         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15831
15832         # Flush negative dentry cache
15833         touch $DIR/$tdir/$tfile
15834
15835         # We are not checking for any leaked references here, they'll
15836         # become evident next time we do cleanup with module unload.
15837         rm -rf $DIR/$tdir
15838 }
15839 run_test 183 "No crash or request leak in case of strange dispositions ========"
15840
15841 # test suite 184 is for LU-2016, LU-2017
15842 test_184a() {
15843         check_swap_layouts_support
15844
15845         dir0=$DIR/$tdir/$testnum
15846         test_mkdir -p -c1 $dir0
15847         ref1=/etc/passwd
15848         ref2=/etc/group
15849         file1=$dir0/f1
15850         file2=$dir0/f2
15851         $LFS setstripe -c1 $file1
15852         cp $ref1 $file1
15853         $LFS setstripe -c2 $file2
15854         cp $ref2 $file2
15855         gen1=$($LFS getstripe -g $file1)
15856         gen2=$($LFS getstripe -g $file2)
15857
15858         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15859         gen=$($LFS getstripe -g $file1)
15860         [[ $gen1 != $gen ]] ||
15861                 "Layout generation on $file1 does not change"
15862         gen=$($LFS getstripe -g $file2)
15863         [[ $gen2 != $gen ]] ||
15864                 "Layout generation on $file2 does not change"
15865
15866         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15867         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15868
15869         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15870 }
15871 run_test 184a "Basic layout swap"
15872
15873 test_184b() {
15874         check_swap_layouts_support
15875
15876         dir0=$DIR/$tdir/$testnum
15877         mkdir -p $dir0 || error "creating dir $dir0"
15878         file1=$dir0/f1
15879         file2=$dir0/f2
15880         file3=$dir0/f3
15881         dir1=$dir0/d1
15882         dir2=$dir0/d2
15883         mkdir $dir1 $dir2
15884         $LFS setstripe -c1 $file1
15885         $LFS setstripe -c2 $file2
15886         $LFS setstripe -c1 $file3
15887         chown $RUNAS_ID $file3
15888         gen1=$($LFS getstripe -g $file1)
15889         gen2=$($LFS getstripe -g $file2)
15890
15891         $LFS swap_layouts $dir1 $dir2 &&
15892                 error "swap of directories layouts should fail"
15893         $LFS swap_layouts $dir1 $file1 &&
15894                 error "swap of directory and file layouts should fail"
15895         $RUNAS $LFS swap_layouts $file1 $file2 &&
15896                 error "swap of file we cannot write should fail"
15897         $LFS swap_layouts $file1 $file3 &&
15898                 error "swap of file with different owner should fail"
15899         /bin/true # to clear error code
15900 }
15901 run_test 184b "Forbidden layout swap (will generate errors)"
15902
15903 test_184c() {
15904         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15905         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15906         check_swap_layouts_support
15907
15908         local dir0=$DIR/$tdir/$testnum
15909         mkdir -p $dir0 || error "creating dir $dir0"
15910
15911         local ref1=$dir0/ref1
15912         local ref2=$dir0/ref2
15913         local file1=$dir0/file1
15914         local file2=$dir0/file2
15915         # create a file large enough for the concurrent test
15916         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15917         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15918         echo "ref file size: ref1($(stat -c %s $ref1))," \
15919              "ref2($(stat -c %s $ref2))"
15920
15921         cp $ref2 $file2
15922         dd if=$ref1 of=$file1 bs=16k &
15923         local DD_PID=$!
15924
15925         # Make sure dd starts to copy file
15926         while [ ! -f $file1 ]; do sleep 0.1; done
15927
15928         $LFS swap_layouts $file1 $file2
15929         local rc=$?
15930         wait $DD_PID
15931         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15932         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15933
15934         # how many bytes copied before swapping layout
15935         local copied=$(stat -c %s $file2)
15936         local remaining=$(stat -c %s $ref1)
15937         remaining=$((remaining - copied))
15938         echo "Copied $copied bytes before swapping layout..."
15939
15940         cmp -n $copied $file1 $ref2 | grep differ &&
15941                 error "Content mismatch [0, $copied) of ref2 and file1"
15942         cmp -n $copied $file2 $ref1 ||
15943                 error "Content mismatch [0, $copied) of ref1 and file2"
15944         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15945                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15946
15947         # clean up
15948         rm -f $ref1 $ref2 $file1 $file2
15949 }
15950 run_test 184c "Concurrent write and layout swap"
15951
15952 test_184d() {
15953         check_swap_layouts_support
15954         [ -z "$(which getfattr 2>/dev/null)" ] &&
15955                 skip_env "no getfattr command"
15956
15957         local file1=$DIR/$tdir/$tfile-1
15958         local file2=$DIR/$tdir/$tfile-2
15959         local file3=$DIR/$tdir/$tfile-3
15960         local lovea1
15961         local lovea2
15962
15963         mkdir -p $DIR/$tdir
15964         touch $file1 || error "create $file1 failed"
15965         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15966                 error "create $file2 failed"
15967         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15968                 error "create $file3 failed"
15969         lovea1=$(get_layout_param $file1)
15970
15971         $LFS swap_layouts $file2 $file3 ||
15972                 error "swap $file2 $file3 layouts failed"
15973         $LFS swap_layouts $file1 $file2 ||
15974                 error "swap $file1 $file2 layouts failed"
15975
15976         lovea2=$(get_layout_param $file2)
15977         echo "$lovea1"
15978         echo "$lovea2"
15979         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15980
15981         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15982         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15983 }
15984 run_test 184d "allow stripeless layouts swap"
15985
15986 test_184e() {
15987         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15988                 skip "Need MDS version at least 2.6.94"
15989         check_swap_layouts_support
15990         [ -z "$(which getfattr 2>/dev/null)" ] &&
15991                 skip_env "no getfattr command"
15992
15993         local file1=$DIR/$tdir/$tfile-1
15994         local file2=$DIR/$tdir/$tfile-2
15995         local file3=$DIR/$tdir/$tfile-3
15996         local lovea
15997
15998         mkdir -p $DIR/$tdir
15999         touch $file1 || error "create $file1 failed"
16000         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16001                 error "create $file2 failed"
16002         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16003                 error "create $file3 failed"
16004
16005         $LFS swap_layouts $file1 $file2 ||
16006                 error "swap $file1 $file2 layouts failed"
16007
16008         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16009         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16010
16011         echo 123 > $file1 || error "Should be able to write into $file1"
16012
16013         $LFS swap_layouts $file1 $file3 ||
16014                 error "swap $file1 $file3 layouts failed"
16015
16016         echo 123 > $file1 || error "Should be able to write into $file1"
16017
16018         rm -rf $file1 $file2 $file3
16019 }
16020 run_test 184e "Recreate layout after stripeless layout swaps"
16021
16022 test_184f() {
16023         # Create a file with name longer than sizeof(struct stat) ==
16024         # 144 to see if we can get chars from the file name to appear
16025         # in the returned striping. Note that 'f' == 0x66.
16026         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16027
16028         mkdir -p $DIR/$tdir
16029         mcreate $DIR/$tdir/$file
16030         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16031                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16032         fi
16033 }
16034 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16035
16036 test_185() { # LU-2441
16037         # LU-3553 - no volatile file support in old servers
16038         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16039                 skip "Need MDS version at least 2.3.60"
16040
16041         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16042         touch $DIR/$tdir/spoo
16043         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16044         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16045                 error "cannot create/write a volatile file"
16046         [ "$FILESET" == "" ] &&
16047         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16048                 error "FID is still valid after close"
16049
16050         multiop_bg_pause $DIR/$tdir vVw4096_c
16051         local multi_pid=$!
16052
16053         local OLD_IFS=$IFS
16054         IFS=":"
16055         local fidv=($fid)
16056         IFS=$OLD_IFS
16057         # assume that the next FID for this client is sequential, since stdout
16058         # is unfortunately eaten by multiop_bg_pause
16059         local n=$((${fidv[1]} + 1))
16060         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16061         if [ "$FILESET" == "" ]; then
16062                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16063                         error "FID is missing before close"
16064         fi
16065         kill -USR1 $multi_pid
16066         # 1 second delay, so if mtime change we will see it
16067         sleep 1
16068         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16069         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16070 }
16071 run_test 185 "Volatile file support"
16072
16073 function create_check_volatile() {
16074         local idx=$1
16075         local tgt
16076
16077         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16078         local PID=$!
16079         sleep 1
16080         local FID=$(cat /tmp/${tfile}.fid)
16081         [ "$FID" == "" ] && error "can't get FID for volatile"
16082         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16083         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16084         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16085         kill -USR1 $PID
16086         wait
16087         sleep 1
16088         cancel_lru_locks mdc # flush opencache
16089         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16090         return 0
16091 }
16092
16093 test_185a(){
16094         # LU-12516 - volatile creation via .lustre
16095         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16096                 skip "Need MDS version at least 2.3.55"
16097
16098         create_check_volatile 0
16099         [ $MDSCOUNT -lt 2 ] && return 0
16100
16101         # DNE case
16102         create_check_volatile 1
16103
16104         return 0
16105 }
16106 run_test 185a "Volatile file creation in .lustre/fid/"
16107
16108 test_187a() {
16109         remote_mds_nodsh && skip "remote MDS with nodsh"
16110         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16111                 skip "Need MDS version at least 2.3.0"
16112
16113         local dir0=$DIR/$tdir/$testnum
16114         mkdir -p $dir0 || error "creating dir $dir0"
16115
16116         local file=$dir0/file1
16117         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16118         local dv1=$($LFS data_version $file)
16119         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16120         local dv2=$($LFS data_version $file)
16121         [[ $dv1 != $dv2 ]] ||
16122                 error "data version did not change on write $dv1 == $dv2"
16123
16124         # clean up
16125         rm -f $file1
16126 }
16127 run_test 187a "Test data version change"
16128
16129 test_187b() {
16130         remote_mds_nodsh && skip "remote MDS with nodsh"
16131         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16132                 skip "Need MDS version at least 2.3.0"
16133
16134         local dir0=$DIR/$tdir/$testnum
16135         mkdir -p $dir0 || error "creating dir $dir0"
16136
16137         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16138         [[ ${DV[0]} != ${DV[1]} ]] ||
16139                 error "data version did not change on write"\
16140                       " ${DV[0]} == ${DV[1]}"
16141
16142         # clean up
16143         rm -f $file1
16144 }
16145 run_test 187b "Test data version change on volatile file"
16146
16147 test_200() {
16148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16149         remote_mgs_nodsh && skip "remote MGS with nodsh"
16150         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16151
16152         local POOL=${POOL:-cea1}
16153         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16154         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16155         # Pool OST targets
16156         local first_ost=0
16157         local last_ost=$(($OSTCOUNT - 1))
16158         local ost_step=2
16159         local ost_list=$(seq $first_ost $ost_step $last_ost)
16160         local ost_range="$first_ost $last_ost $ost_step"
16161         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16162         local file_dir=$POOL_ROOT/file_tst
16163         local subdir=$test_path/subdir
16164         local rc=0
16165
16166         while : ; do
16167                 # former test_200a test_200b
16168                 pool_add $POOL                          || { rc=$? ; break; }
16169                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16170                 # former test_200c test_200d
16171                 mkdir -p $test_path
16172                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16173                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16174                 mkdir -p $subdir
16175                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16176                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16177                                                         || { rc=$? ; break; }
16178                 # former test_200e test_200f
16179                 local files=$((OSTCOUNT*3))
16180                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16181                                                         || { rc=$? ; break; }
16182                 pool_create_files $POOL $file_dir $files "$ost_list" \
16183                                                         || { rc=$? ; break; }
16184                 # former test_200g test_200h
16185                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16186                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16187
16188                 # former test_201a test_201b test_201c
16189                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16190
16191                 local f=$test_path/$tfile
16192                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16193                 pool_remove $POOL $f                    || { rc=$? ; break; }
16194                 break
16195         done
16196
16197         destroy_test_pools
16198
16199         return $rc
16200 }
16201 run_test 200 "OST pools"
16202
16203 # usage: default_attr <count | size | offset>
16204 default_attr() {
16205         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16206 }
16207
16208 # usage: check_default_stripe_attr
16209 check_default_stripe_attr() {
16210         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16211         case $1 in
16212         --stripe-count|-c)
16213                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16214         --stripe-size|-S)
16215                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16216         --stripe-index|-i)
16217                 EXPECTED=-1;;
16218         *)
16219                 error "unknown getstripe attr '$1'"
16220         esac
16221
16222         [ $ACTUAL == $EXPECTED ] ||
16223                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16224 }
16225
16226 test_204a() {
16227         test_mkdir $DIR/$tdir
16228         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16229
16230         check_default_stripe_attr --stripe-count
16231         check_default_stripe_attr --stripe-size
16232         check_default_stripe_attr --stripe-index
16233 }
16234 run_test 204a "Print default stripe attributes"
16235
16236 test_204b() {
16237         test_mkdir $DIR/$tdir
16238         $LFS setstripe --stripe-count 1 $DIR/$tdir
16239
16240         check_default_stripe_attr --stripe-size
16241         check_default_stripe_attr --stripe-index
16242 }
16243 run_test 204b "Print default stripe size and offset"
16244
16245 test_204c() {
16246         test_mkdir $DIR/$tdir
16247         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16248
16249         check_default_stripe_attr --stripe-count
16250         check_default_stripe_attr --stripe-index
16251 }
16252 run_test 204c "Print default stripe count and offset"
16253
16254 test_204d() {
16255         test_mkdir $DIR/$tdir
16256         $LFS setstripe --stripe-index 0 $DIR/$tdir
16257
16258         check_default_stripe_attr --stripe-count
16259         check_default_stripe_attr --stripe-size
16260 }
16261 run_test 204d "Print default stripe count and size"
16262
16263 test_204e() {
16264         test_mkdir $DIR/$tdir
16265         $LFS setstripe -d $DIR/$tdir
16266
16267         check_default_stripe_attr --stripe-count --raw
16268         check_default_stripe_attr --stripe-size --raw
16269         check_default_stripe_attr --stripe-index --raw
16270 }
16271 run_test 204e "Print raw stripe attributes"
16272
16273 test_204f() {
16274         test_mkdir $DIR/$tdir
16275         $LFS setstripe --stripe-count 1 $DIR/$tdir
16276
16277         check_default_stripe_attr --stripe-size --raw
16278         check_default_stripe_attr --stripe-index --raw
16279 }
16280 run_test 204f "Print raw stripe size and offset"
16281
16282 test_204g() {
16283         test_mkdir $DIR/$tdir
16284         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16285
16286         check_default_stripe_attr --stripe-count --raw
16287         check_default_stripe_attr --stripe-index --raw
16288 }
16289 run_test 204g "Print raw stripe count and offset"
16290
16291 test_204h() {
16292         test_mkdir $DIR/$tdir
16293         $LFS setstripe --stripe-index 0 $DIR/$tdir
16294
16295         check_default_stripe_attr --stripe-count --raw
16296         check_default_stripe_attr --stripe-size --raw
16297 }
16298 run_test 204h "Print raw stripe count and size"
16299
16300 # Figure out which job scheduler is being used, if any,
16301 # or use a fake one
16302 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16303         JOBENV=SLURM_JOB_ID
16304 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16305         JOBENV=LSB_JOBID
16306 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16307         JOBENV=PBS_JOBID
16308 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16309         JOBENV=LOADL_STEP_ID
16310 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16311         JOBENV=JOB_ID
16312 else
16313         $LCTL list_param jobid_name > /dev/null 2>&1
16314         if [ $? -eq 0 ]; then
16315                 JOBENV=nodelocal
16316         else
16317                 JOBENV=FAKE_JOBID
16318         fi
16319 fi
16320 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16321
16322 verify_jobstats() {
16323         local cmd=($1)
16324         shift
16325         local facets="$@"
16326
16327 # we don't really need to clear the stats for this test to work, since each
16328 # command has a unique jobid, but it makes debugging easier if needed.
16329 #       for facet in $facets; do
16330 #               local dev=$(convert_facet2label $facet)
16331 #               # clear old jobstats
16332 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16333 #       done
16334
16335         # use a new JobID for each test, or we might see an old one
16336         [ "$JOBENV" = "FAKE_JOBID" ] &&
16337                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16338
16339         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16340
16341         [ "$JOBENV" = "nodelocal" ] && {
16342                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16343                 $LCTL set_param jobid_name=$FAKE_JOBID
16344                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16345         }
16346
16347         log "Test: ${cmd[*]}"
16348         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16349
16350         if [ $JOBENV = "FAKE_JOBID" ]; then
16351                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16352         else
16353                 ${cmd[*]}
16354         fi
16355
16356         # all files are created on OST0000
16357         for facet in $facets; do
16358                 local stats="*.$(convert_facet2label $facet).job_stats"
16359
16360                 # strip out libtool wrappers for in-tree executables
16361                 if [ $(do_facet $facet lctl get_param $stats |
16362                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16363                         do_facet $facet lctl get_param $stats
16364                         error "No jobstats for $JOBVAL found on $facet::$stats"
16365                 fi
16366         done
16367 }
16368
16369 jobstats_set() {
16370         local new_jobenv=$1
16371
16372         set_persistent_param_and_check client "jobid_var" \
16373                 "$FSNAME.sys.jobid_var" $new_jobenv
16374 }
16375
16376 test_205a() { # Job stats
16377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16378         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16379                 skip "Need MDS version with at least 2.7.1"
16380         remote_mgs_nodsh && skip "remote MGS with nodsh"
16381         remote_mds_nodsh && skip "remote MDS with nodsh"
16382         remote_ost_nodsh && skip "remote OST with nodsh"
16383         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16384                 skip "Server doesn't support jobstats"
16385         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16386
16387         local old_jobenv=$($LCTL get_param -n jobid_var)
16388         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16389
16390         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16391                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16392         else
16393                 stack_trap "do_facet mgs $PERM_CMD \
16394                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16395         fi
16396         changelog_register
16397
16398         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16399                                 mdt.*.job_cleanup_interval | head -n 1)
16400         local new_interval=5
16401         do_facet $SINGLEMDS \
16402                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16403         stack_trap "do_facet $SINGLEMDS \
16404                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16405         local start=$SECONDS
16406
16407         local cmd
16408         # mkdir
16409         cmd="mkdir $DIR/$tdir"
16410         verify_jobstats "$cmd" "$SINGLEMDS"
16411         # rmdir
16412         cmd="rmdir $DIR/$tdir"
16413         verify_jobstats "$cmd" "$SINGLEMDS"
16414         # mkdir on secondary MDT
16415         if [ $MDSCOUNT -gt 1 ]; then
16416                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16417                 verify_jobstats "$cmd" "mds2"
16418         fi
16419         # mknod
16420         cmd="mknod $DIR/$tfile c 1 3"
16421         verify_jobstats "$cmd" "$SINGLEMDS"
16422         # unlink
16423         cmd="rm -f $DIR/$tfile"
16424         verify_jobstats "$cmd" "$SINGLEMDS"
16425         # create all files on OST0000 so verify_jobstats can find OST stats
16426         # open & close
16427         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16428         verify_jobstats "$cmd" "$SINGLEMDS"
16429         # setattr
16430         cmd="touch $DIR/$tfile"
16431         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16432         # write
16433         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16434         verify_jobstats "$cmd" "ost1"
16435         # read
16436         cancel_lru_locks osc
16437         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16438         verify_jobstats "$cmd" "ost1"
16439         # truncate
16440         cmd="$TRUNCATE $DIR/$tfile 0"
16441         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16442         # rename
16443         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16444         verify_jobstats "$cmd" "$SINGLEMDS"
16445         # jobstats expiry - sleep until old stats should be expired
16446         local left=$((new_interval + 5 - (SECONDS - start)))
16447         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16448                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16449                         "0" $left
16450         cmd="mkdir $DIR/$tdir.expire"
16451         verify_jobstats "$cmd" "$SINGLEMDS"
16452         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16453             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16454
16455         # Ensure that jobid are present in changelog (if supported by MDS)
16456         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16457                 changelog_dump | tail -10
16458                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16459                 [ $jobids -eq 9 ] ||
16460                         error "Wrong changelog jobid count $jobids != 9"
16461
16462                 # LU-5862
16463                 JOBENV="disable"
16464                 jobstats_set $JOBENV
16465                 touch $DIR/$tfile
16466                 changelog_dump | grep $tfile
16467                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16468                 [ $jobids -eq 0 ] ||
16469                         error "Unexpected jobids when jobid_var=$JOBENV"
16470         fi
16471
16472         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16473         JOBENV="JOBCOMPLEX"
16474         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16475
16476         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16477 }
16478 run_test 205a "Verify job stats"
16479
16480 # LU-13117, LU-13597
16481 test_205b() {
16482         job_stats="mdt.*.job_stats"
16483         $LCTL set_param $job_stats=clear
16484         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16485         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16486         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16487                 grep "job_id:.*foolish" &&
16488                         error "Unexpected jobid found"
16489         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16490                 grep "open:.*min.*max.*sum" ||
16491                         error "wrong job_stats format found"
16492 }
16493 run_test 205b "Verify job stats jobid and output format"
16494
16495 # LU-1480, LU-1773 and LU-1657
16496 test_206() {
16497         mkdir -p $DIR/$tdir
16498         $LFS setstripe -c -1 $DIR/$tdir
16499 #define OBD_FAIL_LOV_INIT 0x1403
16500         $LCTL set_param fail_loc=0xa0001403
16501         $LCTL set_param fail_val=1
16502         touch $DIR/$tdir/$tfile || true
16503 }
16504 run_test 206 "fail lov_init_raid0() doesn't lbug"
16505
16506 test_207a() {
16507         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16508         local fsz=`stat -c %s $DIR/$tfile`
16509         cancel_lru_locks mdc
16510
16511         # do not return layout in getattr intent
16512 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16513         $LCTL set_param fail_loc=0x170
16514         local sz=`stat -c %s $DIR/$tfile`
16515
16516         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16517
16518         rm -rf $DIR/$tfile
16519 }
16520 run_test 207a "can refresh layout at glimpse"
16521
16522 test_207b() {
16523         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16524         local cksum=`md5sum $DIR/$tfile`
16525         local fsz=`stat -c %s $DIR/$tfile`
16526         cancel_lru_locks mdc
16527         cancel_lru_locks osc
16528
16529         # do not return layout in getattr intent
16530 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16531         $LCTL set_param fail_loc=0x171
16532
16533         # it will refresh layout after the file is opened but before read issues
16534         echo checksum is "$cksum"
16535         echo "$cksum" |md5sum -c --quiet || error "file differs"
16536
16537         rm -rf $DIR/$tfile
16538 }
16539 run_test 207b "can refresh layout at open"
16540
16541 test_208() {
16542         # FIXME: in this test suite, only RD lease is used. This is okay
16543         # for now as only exclusive open is supported. After generic lease
16544         # is done, this test suite should be revised. - Jinshan
16545
16546         remote_mds_nodsh && skip "remote MDS with nodsh"
16547         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16548                 skip "Need MDS version at least 2.4.52"
16549
16550         echo "==== test 1: verify get lease work"
16551         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16552
16553         echo "==== test 2: verify lease can be broken by upcoming open"
16554         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16555         local PID=$!
16556         sleep 1
16557
16558         $MULTIOP $DIR/$tfile oO_RDONLY:c
16559         kill -USR1 $PID && wait $PID || error "break lease error"
16560
16561         echo "==== test 3: verify lease can't be granted if an open already exists"
16562         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16563         local PID=$!
16564         sleep 1
16565
16566         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16567         kill -USR1 $PID && wait $PID || error "open file error"
16568
16569         echo "==== test 4: lease can sustain over recovery"
16570         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16571         PID=$!
16572         sleep 1
16573
16574         fail mds1
16575
16576         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16577
16578         echo "==== test 5: lease broken can't be regained by replay"
16579         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16580         PID=$!
16581         sleep 1
16582
16583         # open file to break lease and then recovery
16584         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16585         fail mds1
16586
16587         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16588
16589         rm -f $DIR/$tfile
16590 }
16591 run_test 208 "Exclusive open"
16592
16593 test_209() {
16594         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16595                 skip_env "must have disp_stripe"
16596
16597         touch $DIR/$tfile
16598         sync; sleep 5; sync;
16599
16600         echo 3 > /proc/sys/vm/drop_caches
16601         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16602
16603         # open/close 500 times
16604         for i in $(seq 500); do
16605                 cat $DIR/$tfile
16606         done
16607
16608         echo 3 > /proc/sys/vm/drop_caches
16609         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16610
16611         echo "before: $req_before, after: $req_after"
16612         [ $((req_after - req_before)) -ge 300 ] &&
16613                 error "open/close requests are not freed"
16614         return 0
16615 }
16616 run_test 209 "read-only open/close requests should be freed promptly"
16617
16618 test_210() {
16619         local pid
16620
16621         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16622         pid=$!
16623         sleep 1
16624
16625         $LFS getstripe $DIR/$tfile
16626         kill -USR1 $pid
16627         wait $pid || error "multiop failed"
16628
16629         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16630         pid=$!
16631         sleep 1
16632
16633         $LFS getstripe $DIR/$tfile
16634         kill -USR1 $pid
16635         wait $pid || error "multiop failed"
16636 }
16637 run_test 210 "lfs getstripe does not break leases"
16638
16639 test_212() {
16640         size=`date +%s`
16641         size=$((size % 8192 + 1))
16642         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16643         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16644         rm -f $DIR/f212 $DIR/f212.xyz
16645 }
16646 run_test 212 "Sendfile test ============================================"
16647
16648 test_213() {
16649         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16650         cancel_lru_locks osc
16651         lctl set_param fail_loc=0x8000040f
16652         # generate a read lock
16653         cat $DIR/$tfile > /dev/null
16654         # write to the file, it will try to cancel the above read lock.
16655         cat /etc/hosts >> $DIR/$tfile
16656 }
16657 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16658
16659 test_214() { # for bug 20133
16660         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16661         for (( i=0; i < 340; i++ )) ; do
16662                 touch $DIR/$tdir/d214c/a$i
16663         done
16664
16665         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16666         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16667         ls $DIR/d214c || error "ls $DIR/d214c failed"
16668         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16669         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16670 }
16671 run_test 214 "hash-indexed directory test - bug 20133"
16672
16673 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16674 create_lnet_proc_files() {
16675         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16676 }
16677
16678 # counterpart of create_lnet_proc_files
16679 remove_lnet_proc_files() {
16680         rm -f $TMP/lnet_$1.sys
16681 }
16682
16683 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16684 # 3rd arg as regexp for body
16685 check_lnet_proc_stats() {
16686         local l=$(cat "$TMP/lnet_$1" |wc -l)
16687         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16688
16689         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16690 }
16691
16692 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16693 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16694 # optional and can be regexp for 2nd line (lnet.routes case)
16695 check_lnet_proc_entry() {
16696         local blp=2          # blp stands for 'position of 1st line of body'
16697         [ -z "$5" ] || blp=3 # lnet.routes case
16698
16699         local l=$(cat "$TMP/lnet_$1" |wc -l)
16700         # subtracting one from $blp because the body can be empty
16701         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16702
16703         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16704                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16705
16706         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16707                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16708
16709         # bail out if any unexpected line happened
16710         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16711         [ "$?" != 0 ] || error "$2 misformatted"
16712 }
16713
16714 test_215() { # for bugs 18102, 21079, 21517
16715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16716
16717         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16718         local P='[1-9][0-9]*'           # positive numeric
16719         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16720         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16721         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16722         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16723
16724         local L1 # regexp for 1st line
16725         local L2 # regexp for 2nd line (optional)
16726         local BR # regexp for the rest (body)
16727
16728         # lnet.stats should look as 11 space-separated non-negative numerics
16729         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16730         create_lnet_proc_files "stats"
16731         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16732         remove_lnet_proc_files "stats"
16733
16734         # lnet.routes should look like this:
16735         # Routing disabled/enabled
16736         # net hops priority state router
16737         # where net is a string like tcp0, hops > 0, priority >= 0,
16738         # state is up/down,
16739         # router is a string like 192.168.1.1@tcp2
16740         L1="^Routing (disabled|enabled)$"
16741         L2="^net +hops +priority +state +router$"
16742         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16743         create_lnet_proc_files "routes"
16744         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16745         remove_lnet_proc_files "routes"
16746
16747         # lnet.routers should look like this:
16748         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16749         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16750         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16751         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16752         L1="^ref +rtr_ref +alive +router$"
16753         BR="^$P +$P +(up|down) +$NID$"
16754         create_lnet_proc_files "routers"
16755         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16756         remove_lnet_proc_files "routers"
16757
16758         # lnet.peers should look like this:
16759         # nid refs state last max rtr min tx min queue
16760         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16761         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16762         # numeric (0 or >0 or <0), queue >= 0.
16763         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16764         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16765         create_lnet_proc_files "peers"
16766         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16767         remove_lnet_proc_files "peers"
16768
16769         # lnet.buffers  should look like this:
16770         # pages count credits min
16771         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16772         L1="^pages +count +credits +min$"
16773         BR="^ +$N +$N +$I +$I$"
16774         create_lnet_proc_files "buffers"
16775         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16776         remove_lnet_proc_files "buffers"
16777
16778         # lnet.nis should look like this:
16779         # nid status alive refs peer rtr max tx min
16780         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16781         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16782         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16783         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16784         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16785         create_lnet_proc_files "nis"
16786         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16787         remove_lnet_proc_files "nis"
16788
16789         # can we successfully write to lnet.stats?
16790         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16791 }
16792 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16793
16794 test_216() { # bug 20317
16795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16796         remote_ost_nodsh && skip "remote OST with nodsh"
16797
16798         local node
16799         local facets=$(get_facets OST)
16800         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16801
16802         save_lustre_params client "osc.*.contention_seconds" > $p
16803         save_lustre_params $facets \
16804                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16805         save_lustre_params $facets \
16806                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16807         save_lustre_params $facets \
16808                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16809         clear_stats osc.*.osc_stats
16810
16811         # agressive lockless i/o settings
16812         do_nodes $(comma_list $(osts_nodes)) \
16813                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16814                         ldlm.namespaces.filter-*.contended_locks=0 \
16815                         ldlm.namespaces.filter-*.contention_seconds=60"
16816         lctl set_param -n osc.*.contention_seconds=60
16817
16818         $DIRECTIO write $DIR/$tfile 0 10 4096
16819         $CHECKSTAT -s 40960 $DIR/$tfile
16820
16821         # disable lockless i/o
16822         do_nodes $(comma_list $(osts_nodes)) \
16823                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16824                         ldlm.namespaces.filter-*.contended_locks=32 \
16825                         ldlm.namespaces.filter-*.contention_seconds=0"
16826         lctl set_param -n osc.*.contention_seconds=0
16827         clear_stats osc.*.osc_stats
16828
16829         dd if=/dev/zero of=$DIR/$tfile count=0
16830         $CHECKSTAT -s 0 $DIR/$tfile
16831
16832         restore_lustre_params <$p
16833         rm -f $p
16834         rm $DIR/$tfile
16835 }
16836 run_test 216 "check lockless direct write updates file size and kms correctly"
16837
16838 test_217() { # bug 22430
16839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16840
16841         local node
16842         local nid
16843
16844         for node in $(nodes_list); do
16845                 nid=$(host_nids_address $node $NETTYPE)
16846                 if [[ $nid = *-* ]] ; then
16847                         echo "lctl ping $(h2nettype $nid)"
16848                         lctl ping $(h2nettype $nid)
16849                 else
16850                         echo "skipping $node (no hyphen detected)"
16851                 fi
16852         done
16853 }
16854 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16855
16856 test_218() {
16857        # do directio so as not to populate the page cache
16858        log "creating a 10 Mb file"
16859        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16860        log "starting reads"
16861        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16862        log "truncating the file"
16863        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16864        log "killing dd"
16865        kill %+ || true # reads might have finished
16866        echo "wait until dd is finished"
16867        wait
16868        log "removing the temporary file"
16869        rm -rf $DIR/$tfile || error "tmp file removal failed"
16870 }
16871 run_test 218 "parallel read and truncate should not deadlock"
16872
16873 test_219() {
16874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16875
16876         # write one partial page
16877         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16878         # set no grant so vvp_io_commit_write will do sync write
16879         $LCTL set_param fail_loc=0x411
16880         # write a full page at the end of file
16881         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16882
16883         $LCTL set_param fail_loc=0
16884         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16885         $LCTL set_param fail_loc=0x411
16886         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16887
16888         # LU-4201
16889         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16890         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16891 }
16892 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16893
16894 test_220() { #LU-325
16895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16896         remote_ost_nodsh && skip "remote OST with nodsh"
16897         remote_mds_nodsh && skip "remote MDS with nodsh"
16898         remote_mgs_nodsh && skip "remote MGS with nodsh"
16899
16900         local OSTIDX=0
16901
16902         # create on MDT0000 so the last_id and next_id are correct
16903         mkdir $DIR/$tdir
16904         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16905         OST=${OST%_UUID}
16906
16907         # on the mdt's osc
16908         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16909         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16910                         osp.$mdtosc_proc1.prealloc_last_id)
16911         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16912                         osp.$mdtosc_proc1.prealloc_next_id)
16913
16914         $LFS df -i
16915
16916         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16917         #define OBD_FAIL_OST_ENOINO              0x229
16918         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16919         create_pool $FSNAME.$TESTNAME || return 1
16920         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16921
16922         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16923
16924         MDSOBJS=$((last_id - next_id))
16925         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16926
16927         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16928         echo "OST still has $count kbytes free"
16929
16930         echo "create $MDSOBJS files @next_id..."
16931         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16932
16933         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16934                         osp.$mdtosc_proc1.prealloc_last_id)
16935         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16936                         osp.$mdtosc_proc1.prealloc_next_id)
16937
16938         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16939         $LFS df -i
16940
16941         echo "cleanup..."
16942
16943         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16944         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16945
16946         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16947                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16948         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16949                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16950         echo "unlink $MDSOBJS files @$next_id..."
16951         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16952 }
16953 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16954
16955 test_221() {
16956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16957
16958         dd if=`which date` of=$MOUNT/date oflag=sync
16959         chmod +x $MOUNT/date
16960
16961         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16962         $LCTL set_param fail_loc=0x80001401
16963
16964         $MOUNT/date > /dev/null
16965         rm -f $MOUNT/date
16966 }
16967 run_test 221 "make sure fault and truncate race to not cause OOM"
16968
16969 test_222a () {
16970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16971
16972         rm -rf $DIR/$tdir
16973         test_mkdir $DIR/$tdir
16974         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16975         createmany -o $DIR/$tdir/$tfile 10
16976         cancel_lru_locks mdc
16977         cancel_lru_locks osc
16978         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16979         $LCTL set_param fail_loc=0x31a
16980         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16981         $LCTL set_param fail_loc=0
16982         rm -r $DIR/$tdir
16983 }
16984 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16985
16986 test_222b () {
16987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16988
16989         rm -rf $DIR/$tdir
16990         test_mkdir $DIR/$tdir
16991         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16992         createmany -o $DIR/$tdir/$tfile 10
16993         cancel_lru_locks mdc
16994         cancel_lru_locks osc
16995         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16996         $LCTL set_param fail_loc=0x31a
16997         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16998         $LCTL set_param fail_loc=0
16999 }
17000 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17001
17002 test_223 () {
17003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17004
17005         rm -rf $DIR/$tdir
17006         test_mkdir $DIR/$tdir
17007         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17008         createmany -o $DIR/$tdir/$tfile 10
17009         cancel_lru_locks mdc
17010         cancel_lru_locks osc
17011         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17012         $LCTL set_param fail_loc=0x31b
17013         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17014         $LCTL set_param fail_loc=0
17015         rm -r $DIR/$tdir
17016 }
17017 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17018
17019 test_224a() { # LU-1039, MRP-303
17020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17021
17022         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17023         $LCTL set_param fail_loc=0x508
17024         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17025         $LCTL set_param fail_loc=0
17026         df $DIR
17027 }
17028 run_test 224a "Don't panic on bulk IO failure"
17029
17030 test_224b() { # LU-1039, MRP-303
17031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17032
17033         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17034         cancel_lru_locks osc
17035         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17036         $LCTL set_param fail_loc=0x515
17037         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17038         $LCTL set_param fail_loc=0
17039         df $DIR
17040 }
17041 run_test 224b "Don't panic on bulk IO failure"
17042
17043 test_224c() { # LU-6441
17044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17045         remote_mds_nodsh && skip "remote MDS with nodsh"
17046
17047         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17048         save_writethrough $p
17049         set_cache writethrough on
17050
17051         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17052         local at_max=$($LCTL get_param -n at_max)
17053         local timeout=$($LCTL get_param -n timeout)
17054         local test_at="at_max"
17055         local param_at="$FSNAME.sys.at_max"
17056         local test_timeout="timeout"
17057         local param_timeout="$FSNAME.sys.timeout"
17058
17059         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17060
17061         set_persistent_param_and_check client "$test_at" "$param_at" 0
17062         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17063
17064         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17065         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17066         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17067         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17068         sync
17069         do_facet ost1 "$LCTL set_param fail_loc=0"
17070
17071         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17072         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17073                 $timeout
17074
17075         $LCTL set_param -n $pages_per_rpc
17076         restore_lustre_params < $p
17077         rm -f $p
17078 }
17079 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17080
17081 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17082 test_225a () {
17083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17084         if [ -z ${MDSSURVEY} ]; then
17085                 skip_env "mds-survey not found"
17086         fi
17087         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17088                 skip "Need MDS version at least 2.2.51"
17089
17090         local mds=$(facet_host $SINGLEMDS)
17091         local target=$(do_nodes $mds 'lctl dl' |
17092                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17093
17094         local cmd1="file_count=1000 thrhi=4"
17095         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17096         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17097         local cmd="$cmd1 $cmd2 $cmd3"
17098
17099         rm -f ${TMP}/mds_survey*
17100         echo + $cmd
17101         eval $cmd || error "mds-survey with zero-stripe failed"
17102         cat ${TMP}/mds_survey*
17103         rm -f ${TMP}/mds_survey*
17104 }
17105 run_test 225a "Metadata survey sanity with zero-stripe"
17106
17107 test_225b () {
17108         if [ -z ${MDSSURVEY} ]; then
17109                 skip_env "mds-survey not found"
17110         fi
17111         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17112                 skip "Need MDS version at least 2.2.51"
17113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17114         remote_mds_nodsh && skip "remote MDS with nodsh"
17115         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17116                 skip_env "Need to mount OST to test"
17117         fi
17118
17119         local mds=$(facet_host $SINGLEMDS)
17120         local target=$(do_nodes $mds 'lctl dl' |
17121                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17122
17123         local cmd1="file_count=1000 thrhi=4"
17124         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17125         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17126         local cmd="$cmd1 $cmd2 $cmd3"
17127
17128         rm -f ${TMP}/mds_survey*
17129         echo + $cmd
17130         eval $cmd || error "mds-survey with stripe_count failed"
17131         cat ${TMP}/mds_survey*
17132         rm -f ${TMP}/mds_survey*
17133 }
17134 run_test 225b "Metadata survey sanity with stripe_count = 1"
17135
17136 mcreate_path2fid () {
17137         local mode=$1
17138         local major=$2
17139         local minor=$3
17140         local name=$4
17141         local desc=$5
17142         local path=$DIR/$tdir/$name
17143         local fid
17144         local rc
17145         local fid_path
17146
17147         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17148                 error "cannot create $desc"
17149
17150         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17151         rc=$?
17152         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17153
17154         fid_path=$($LFS fid2path $MOUNT $fid)
17155         rc=$?
17156         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17157
17158         [ "$path" == "$fid_path" ] ||
17159                 error "fid2path returned $fid_path, expected $path"
17160
17161         echo "pass with $path and $fid"
17162 }
17163
17164 test_226a () {
17165         rm -rf $DIR/$tdir
17166         mkdir -p $DIR/$tdir
17167
17168         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17169         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17170         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17171         mcreate_path2fid 0040666 0 0 dir "directory"
17172         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17173         mcreate_path2fid 0100666 0 0 file "regular file"
17174         mcreate_path2fid 0120666 0 0 link "symbolic link"
17175         mcreate_path2fid 0140666 0 0 sock "socket"
17176 }
17177 run_test 226a "call path2fid and fid2path on files of all type"
17178
17179 test_226b () {
17180         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17181
17182         local MDTIDX=1
17183
17184         rm -rf $DIR/$tdir
17185         mkdir -p $DIR/$tdir
17186         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17187                 error "create remote directory failed"
17188         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17189         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17190                                 "character special file (null)"
17191         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17192                                 "character special file (no device)"
17193         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17194         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17195                                 "block special file (loop)"
17196         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17197         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17198         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17199 }
17200 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17201
17202 # LU-1299 Executing or running ldd on a truncated executable does not
17203 # cause an out-of-memory condition.
17204 test_227() {
17205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17206         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17207
17208         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17209         chmod +x $MOUNT/date
17210
17211         $MOUNT/date > /dev/null
17212         ldd $MOUNT/date > /dev/null
17213         rm -f $MOUNT/date
17214 }
17215 run_test 227 "running truncated executable does not cause OOM"
17216
17217 # LU-1512 try to reuse idle OI blocks
17218 test_228a() {
17219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17220         remote_mds_nodsh && skip "remote MDS with nodsh"
17221         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17222
17223         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17224         local myDIR=$DIR/$tdir
17225
17226         mkdir -p $myDIR
17227         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17228         $LCTL set_param fail_loc=0x80001002
17229         createmany -o $myDIR/t- 10000
17230         $LCTL set_param fail_loc=0
17231         # The guard is current the largest FID holder
17232         touch $myDIR/guard
17233         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17234                     tr -d '[')
17235         local IDX=$(($SEQ % 64))
17236
17237         do_facet $SINGLEMDS sync
17238         # Make sure journal flushed.
17239         sleep 6
17240         local blk1=$(do_facet $SINGLEMDS \
17241                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17242                      grep Blockcount | awk '{print $4}')
17243
17244         # Remove old files, some OI blocks will become idle.
17245         unlinkmany $myDIR/t- 10000
17246         # Create new files, idle OI blocks should be reused.
17247         createmany -o $myDIR/t- 2000
17248         do_facet $SINGLEMDS sync
17249         # Make sure journal flushed.
17250         sleep 6
17251         local blk2=$(do_facet $SINGLEMDS \
17252                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17253                      grep Blockcount | awk '{print $4}')
17254
17255         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17256 }
17257 run_test 228a "try to reuse idle OI blocks"
17258
17259 test_228b() {
17260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17261         remote_mds_nodsh && skip "remote MDS with nodsh"
17262         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17263
17264         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17265         local myDIR=$DIR/$tdir
17266
17267         mkdir -p $myDIR
17268         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17269         $LCTL set_param fail_loc=0x80001002
17270         createmany -o $myDIR/t- 10000
17271         $LCTL set_param fail_loc=0
17272         # The guard is current the largest FID holder
17273         touch $myDIR/guard
17274         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17275                     tr -d '[')
17276         local IDX=$(($SEQ % 64))
17277
17278         do_facet $SINGLEMDS sync
17279         # Make sure journal flushed.
17280         sleep 6
17281         local blk1=$(do_facet $SINGLEMDS \
17282                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17283                      grep Blockcount | awk '{print $4}')
17284
17285         # Remove old files, some OI blocks will become idle.
17286         unlinkmany $myDIR/t- 10000
17287
17288         # stop the MDT
17289         stop $SINGLEMDS || error "Fail to stop MDT."
17290         # remount the MDT
17291         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17292
17293         df $MOUNT || error "Fail to df."
17294         # Create new files, idle OI blocks should be reused.
17295         createmany -o $myDIR/t- 2000
17296         do_facet $SINGLEMDS sync
17297         # Make sure journal flushed.
17298         sleep 6
17299         local blk2=$(do_facet $SINGLEMDS \
17300                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17301                      grep Blockcount | awk '{print $4}')
17302
17303         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17304 }
17305 run_test 228b "idle OI blocks can be reused after MDT restart"
17306
17307 #LU-1881
17308 test_228c() {
17309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17310         remote_mds_nodsh && skip "remote MDS with nodsh"
17311         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17312
17313         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17314         local myDIR=$DIR/$tdir
17315
17316         mkdir -p $myDIR
17317         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17318         $LCTL set_param fail_loc=0x80001002
17319         # 20000 files can guarantee there are index nodes in the OI file
17320         createmany -o $myDIR/t- 20000
17321         $LCTL set_param fail_loc=0
17322         # The guard is current the largest FID holder
17323         touch $myDIR/guard
17324         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17325                     tr -d '[')
17326         local IDX=$(($SEQ % 64))
17327
17328         do_facet $SINGLEMDS sync
17329         # Make sure journal flushed.
17330         sleep 6
17331         local blk1=$(do_facet $SINGLEMDS \
17332                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17333                      grep Blockcount | awk '{print $4}')
17334
17335         # Remove old files, some OI blocks will become idle.
17336         unlinkmany $myDIR/t- 20000
17337         rm -f $myDIR/guard
17338         # The OI file should become empty now
17339
17340         # Create new files, idle OI blocks should be reused.
17341         createmany -o $myDIR/t- 2000
17342         do_facet $SINGLEMDS sync
17343         # Make sure journal flushed.
17344         sleep 6
17345         local blk2=$(do_facet $SINGLEMDS \
17346                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17347                      grep Blockcount | awk '{print $4}')
17348
17349         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17350 }
17351 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17352
17353 test_229() { # LU-2482, LU-3448
17354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17355         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17356         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17357                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17358
17359         rm -f $DIR/$tfile
17360
17361         # Create a file with a released layout and stripe count 2.
17362         $MULTIOP $DIR/$tfile H2c ||
17363                 error "failed to create file with released layout"
17364
17365         $LFS getstripe -v $DIR/$tfile
17366
17367         local pattern=$($LFS getstripe -L $DIR/$tfile)
17368         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17369
17370         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17371                 error "getstripe"
17372         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17373         stat $DIR/$tfile || error "failed to stat released file"
17374
17375         chown $RUNAS_ID $DIR/$tfile ||
17376                 error "chown $RUNAS_ID $DIR/$tfile failed"
17377
17378         chgrp $RUNAS_ID $DIR/$tfile ||
17379                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17380
17381         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17382         rm $DIR/$tfile || error "failed to remove released file"
17383 }
17384 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17385
17386 test_230a() {
17387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17389         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17390                 skip "Need MDS version at least 2.11.52"
17391
17392         local MDTIDX=1
17393
17394         test_mkdir $DIR/$tdir
17395         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17396         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17397         [ $mdt_idx -ne 0 ] &&
17398                 error "create local directory on wrong MDT $mdt_idx"
17399
17400         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17401                         error "create remote directory failed"
17402         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17403         [ $mdt_idx -ne $MDTIDX ] &&
17404                 error "create remote directory on wrong MDT $mdt_idx"
17405
17406         createmany -o $DIR/$tdir/test_230/t- 10 ||
17407                 error "create files on remote directory failed"
17408         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17409         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17410         rm -r $DIR/$tdir || error "unlink remote directory failed"
17411 }
17412 run_test 230a "Create remote directory and files under the remote directory"
17413
17414 test_230b() {
17415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17417         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17418                 skip "Need MDS version at least 2.11.52"
17419
17420         local MDTIDX=1
17421         local mdt_index
17422         local i
17423         local file
17424         local pid
17425         local stripe_count
17426         local migrate_dir=$DIR/$tdir/migrate_dir
17427         local other_dir=$DIR/$tdir/other_dir
17428
17429         test_mkdir $DIR/$tdir
17430         test_mkdir -i0 -c1 $migrate_dir
17431         test_mkdir -i0 -c1 $other_dir
17432         for ((i=0; i<10; i++)); do
17433                 mkdir -p $migrate_dir/dir_${i}
17434                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17435                         error "create files under remote dir failed $i"
17436         done
17437
17438         cp /etc/passwd $migrate_dir/$tfile
17439         cp /etc/passwd $other_dir/$tfile
17440         chattr +SAD $migrate_dir
17441         chattr +SAD $migrate_dir/$tfile
17442
17443         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17444         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17445         local old_dir_mode=$(stat -c%f $migrate_dir)
17446         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17447
17448         mkdir -p $migrate_dir/dir_default_stripe2
17449         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17450         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17451
17452         mkdir -p $other_dir
17453         ln $migrate_dir/$tfile $other_dir/luna
17454         ln $migrate_dir/$tfile $migrate_dir/sofia
17455         ln $other_dir/$tfile $migrate_dir/david
17456         ln -s $migrate_dir/$tfile $other_dir/zachary
17457         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17458         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17459
17460         local len
17461         local lnktgt
17462
17463         # inline symlink
17464         for len in 58 59 60; do
17465                 lnktgt=$(str_repeat 'l' $len)
17466                 touch $migrate_dir/$lnktgt
17467                 ln -s $lnktgt $migrate_dir/${len}char_ln
17468         done
17469
17470         # PATH_MAX
17471         for len in 4094 4095; do
17472                 lnktgt=$(str_repeat 'l' $len)
17473                 ln -s $lnktgt $migrate_dir/${len}char_ln
17474         done
17475
17476         # NAME_MAX
17477         for len in 254 255; do
17478                 touch $migrate_dir/$(str_repeat 'l' $len)
17479         done
17480
17481         $LFS migrate -m $MDTIDX $migrate_dir ||
17482                 error "fails on migrating remote dir to MDT1"
17483
17484         echo "migratate to MDT1, then checking.."
17485         for ((i = 0; i < 10; i++)); do
17486                 for file in $(find $migrate_dir/dir_${i}); do
17487                         mdt_index=$($LFS getstripe -m $file)
17488                         # broken symlink getstripe will fail
17489                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17490                                 error "$file is not on MDT${MDTIDX}"
17491                 done
17492         done
17493
17494         # the multiple link file should still in MDT0
17495         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17496         [ $mdt_index == 0 ] ||
17497                 error "$file is not on MDT${MDTIDX}"
17498
17499         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17500         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17501                 error " expect $old_dir_flag get $new_dir_flag"
17502
17503         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17504         [ "$old_file_flag" = "$new_file_flag" ] ||
17505                 error " expect $old_file_flag get $new_file_flag"
17506
17507         local new_dir_mode=$(stat -c%f $migrate_dir)
17508         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17509                 error "expect mode $old_dir_mode get $new_dir_mode"
17510
17511         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17512         [ "$old_file_mode" = "$new_file_mode" ] ||
17513                 error "expect mode $old_file_mode get $new_file_mode"
17514
17515         diff /etc/passwd $migrate_dir/$tfile ||
17516                 error "$tfile different after migration"
17517
17518         diff /etc/passwd $other_dir/luna ||
17519                 error "luna different after migration"
17520
17521         diff /etc/passwd $migrate_dir/sofia ||
17522                 error "sofia different after migration"
17523
17524         diff /etc/passwd $migrate_dir/david ||
17525                 error "david different after migration"
17526
17527         diff /etc/passwd $other_dir/zachary ||
17528                 error "zachary different after migration"
17529
17530         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17531                 error "${tfile}_ln different after migration"
17532
17533         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17534                 error "${tfile}_ln_other different after migration"
17535
17536         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17537         [ $stripe_count = 2 ] ||
17538                 error "dir strpe_count $d != 2 after migration."
17539
17540         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17541         [ $stripe_count = 2 ] ||
17542                 error "file strpe_count $d != 2 after migration."
17543
17544         #migrate back to MDT0
17545         MDTIDX=0
17546
17547         $LFS migrate -m $MDTIDX $migrate_dir ||
17548                 error "fails on migrating remote dir to MDT0"
17549
17550         echo "migrate back to MDT0, checking.."
17551         for file in $(find $migrate_dir); do
17552                 mdt_index=$($LFS getstripe -m $file)
17553                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17554                         error "$file is not on MDT${MDTIDX}"
17555         done
17556
17557         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17558         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17559                 error " expect $old_dir_flag get $new_dir_flag"
17560
17561         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17562         [ "$old_file_flag" = "$new_file_flag" ] ||
17563                 error " expect $old_file_flag get $new_file_flag"
17564
17565         local new_dir_mode=$(stat -c%f $migrate_dir)
17566         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17567                 error "expect mode $old_dir_mode get $new_dir_mode"
17568
17569         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17570         [ "$old_file_mode" = "$new_file_mode" ] ||
17571                 error "expect mode $old_file_mode get $new_file_mode"
17572
17573         diff /etc/passwd ${migrate_dir}/$tfile ||
17574                 error "$tfile different after migration"
17575
17576         diff /etc/passwd ${other_dir}/luna ||
17577                 error "luna different after migration"
17578
17579         diff /etc/passwd ${migrate_dir}/sofia ||
17580                 error "sofia different after migration"
17581
17582         diff /etc/passwd ${other_dir}/zachary ||
17583                 error "zachary different after migration"
17584
17585         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17586                 error "${tfile}_ln different after migration"
17587
17588         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17589                 error "${tfile}_ln_other different after migration"
17590
17591         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17592         [ $stripe_count = 2 ] ||
17593                 error "dir strpe_count $d != 2 after migration."
17594
17595         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17596         [ $stripe_count = 2 ] ||
17597                 error "file strpe_count $d != 2 after migration."
17598
17599         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17600 }
17601 run_test 230b "migrate directory"
17602
17603 test_230c() {
17604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17606         remote_mds_nodsh && skip "remote MDS with nodsh"
17607         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17608                 skip "Need MDS version at least 2.11.52"
17609
17610         local MDTIDX=1
17611         local total=3
17612         local mdt_index
17613         local file
17614         local migrate_dir=$DIR/$tdir/migrate_dir
17615
17616         #If migrating directory fails in the middle, all entries of
17617         #the directory is still accessiable.
17618         test_mkdir $DIR/$tdir
17619         test_mkdir -i0 -c1 $migrate_dir
17620         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17621         stat $migrate_dir
17622         createmany -o $migrate_dir/f $total ||
17623                 error "create files under ${migrate_dir} failed"
17624
17625         # fail after migrating top dir, and this will fail only once, so the
17626         # first sub file migration will fail (currently f3), others succeed.
17627         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17628         do_facet mds1 lctl set_param fail_loc=0x1801
17629         local t=$(ls $migrate_dir | wc -l)
17630         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17631                 error "migrate should fail"
17632         local u=$(ls $migrate_dir | wc -l)
17633         [ "$u" == "$t" ] || error "$u != $t during migration"
17634
17635         # add new dir/file should succeed
17636         mkdir $migrate_dir/dir ||
17637                 error "mkdir failed under migrating directory"
17638         touch $migrate_dir/file ||
17639                 error "create file failed under migrating directory"
17640
17641         # add file with existing name should fail
17642         for file in $migrate_dir/f*; do
17643                 stat $file > /dev/null || error "stat $file failed"
17644                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17645                         error "open(O_CREAT|O_EXCL) $file should fail"
17646                 $MULTIOP $file m && error "create $file should fail"
17647                 touch $DIR/$tdir/remote_dir/$tfile ||
17648                         error "touch $tfile failed"
17649                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17650                         error "link $file should fail"
17651                 mdt_index=$($LFS getstripe -m $file)
17652                 if [ $mdt_index == 0 ]; then
17653                         # file failed to migrate is not allowed to rename to
17654                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17655                                 error "rename to $file should fail"
17656                 else
17657                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17658                                 error "rename to $file failed"
17659                 fi
17660                 echo hello >> $file || error "write $file failed"
17661         done
17662
17663         # resume migration with different options should fail
17664         $LFS migrate -m 0 $migrate_dir &&
17665                 error "migrate -m 0 $migrate_dir should fail"
17666
17667         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17668                 error "migrate -c 2 $migrate_dir should fail"
17669
17670         # resume migration should succeed
17671         $LFS migrate -m $MDTIDX $migrate_dir ||
17672                 error "migrate $migrate_dir failed"
17673
17674         echo "Finish migration, then checking.."
17675         for file in $(find $migrate_dir); do
17676                 mdt_index=$($LFS getstripe -m $file)
17677                 [ $mdt_index == $MDTIDX ] ||
17678                         error "$file is not on MDT${MDTIDX}"
17679         done
17680
17681         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17682 }
17683 run_test 230c "check directory accessiblity if migration failed"
17684
17685 test_230d() {
17686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17688         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17689                 skip "Need MDS version at least 2.11.52"
17690         # LU-11235
17691         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17692
17693         local migrate_dir=$DIR/$tdir/migrate_dir
17694         local old_index
17695         local new_index
17696         local old_count
17697         local new_count
17698         local new_hash
17699         local mdt_index
17700         local i
17701         local j
17702
17703         old_index=$((RANDOM % MDSCOUNT))
17704         old_count=$((MDSCOUNT - old_index))
17705         new_index=$((RANDOM % MDSCOUNT))
17706         new_count=$((MDSCOUNT - new_index))
17707         new_hash=1 # for all_char
17708
17709         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17710         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17711
17712         test_mkdir $DIR/$tdir
17713         test_mkdir -i $old_index -c $old_count $migrate_dir
17714
17715         for ((i=0; i<100; i++)); do
17716                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17717                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17718                         error "create files under remote dir failed $i"
17719         done
17720
17721         echo -n "Migrate from MDT$old_index "
17722         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17723         echo -n "to MDT$new_index"
17724         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17725         echo
17726
17727         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17728         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17729                 error "migrate remote dir error"
17730
17731         echo "Finish migration, then checking.."
17732         for file in $(find $migrate_dir); do
17733                 mdt_index=$($LFS getstripe -m $file)
17734                 if [ $mdt_index -lt $new_index ] ||
17735                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17736                         error "$file is on MDT$mdt_index"
17737                 fi
17738         done
17739
17740         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17741 }
17742 run_test 230d "check migrate big directory"
17743
17744 test_230e() {
17745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17747         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17748                 skip "Need MDS version at least 2.11.52"
17749
17750         local i
17751         local j
17752         local a_fid
17753         local b_fid
17754
17755         mkdir -p $DIR/$tdir
17756         mkdir $DIR/$tdir/migrate_dir
17757         mkdir $DIR/$tdir/other_dir
17758         touch $DIR/$tdir/migrate_dir/a
17759         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17760         ls $DIR/$tdir/other_dir
17761
17762         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17763                 error "migrate dir fails"
17764
17765         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17766         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17767
17768         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17769         [ $mdt_index == 0 ] || error "a is not on MDT0"
17770
17771         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17772                 error "migrate dir fails"
17773
17774         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17775         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17776
17777         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17778         [ $mdt_index == 1 ] || error "a is not on MDT1"
17779
17780         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17781         [ $mdt_index == 1 ] || error "b is not on MDT1"
17782
17783         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17784         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17785
17786         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17787
17788         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17789 }
17790 run_test 230e "migrate mulitple local link files"
17791
17792 test_230f() {
17793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17795         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17796                 skip "Need MDS version at least 2.11.52"
17797
17798         local a_fid
17799         local ln_fid
17800
17801         mkdir -p $DIR/$tdir
17802         mkdir $DIR/$tdir/migrate_dir
17803         $LFS mkdir -i1 $DIR/$tdir/other_dir
17804         touch $DIR/$tdir/migrate_dir/a
17805         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17806         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17807         ls $DIR/$tdir/other_dir
17808
17809         # a should be migrated to MDT1, since no other links on MDT0
17810         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17811                 error "#1 migrate dir fails"
17812         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17813         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17814         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17815         [ $mdt_index == 1 ] || error "a is not on MDT1"
17816
17817         # a should stay on MDT1, because it is a mulitple link file
17818         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17819                 error "#2 migrate dir fails"
17820         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17821         [ $mdt_index == 1 ] || error "a is not on MDT1"
17822
17823         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17824                 error "#3 migrate dir fails"
17825
17826         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17827         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17828         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17829
17830         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17831         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17832
17833         # a should be migrated to MDT0, since no other links on MDT1
17834         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17835                 error "#4 migrate dir fails"
17836         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17837         [ $mdt_index == 0 ] || error "a is not on MDT0"
17838
17839         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17840 }
17841 run_test 230f "migrate mulitple remote link files"
17842
17843 test_230g() {
17844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17845         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17846         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17847                 skip "Need MDS version at least 2.11.52"
17848
17849         mkdir -p $DIR/$tdir/migrate_dir
17850
17851         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17852                 error "migrating dir to non-exist MDT succeeds"
17853         true
17854 }
17855 run_test 230g "migrate dir to non-exist MDT"
17856
17857 test_230h() {
17858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17860         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17861                 skip "Need MDS version at least 2.11.52"
17862
17863         local mdt_index
17864
17865         mkdir -p $DIR/$tdir/migrate_dir
17866
17867         $LFS migrate -m1 $DIR &&
17868                 error "migrating mountpoint1 should fail"
17869
17870         $LFS migrate -m1 $DIR/$tdir/.. &&
17871                 error "migrating mountpoint2 should fail"
17872
17873         # same as mv
17874         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17875                 error "migrating $tdir/migrate_dir/.. should fail"
17876
17877         true
17878 }
17879 run_test 230h "migrate .. and root"
17880
17881 test_230i() {
17882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17884         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17885                 skip "Need MDS version at least 2.11.52"
17886
17887         mkdir -p $DIR/$tdir/migrate_dir
17888
17889         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17890                 error "migration fails with a tailing slash"
17891
17892         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17893                 error "migration fails with two tailing slashes"
17894 }
17895 run_test 230i "lfs migrate -m tolerates trailing slashes"
17896
17897 test_230j() {
17898         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17899         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
17900                 skip "Need MDS version at least 2.11.52"
17901
17902         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17903         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17904                 error "create $tfile failed"
17905         cat /etc/passwd > $DIR/$tdir/$tfile
17906
17907         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17908
17909         cmp /etc/passwd $DIR/$tdir/$tfile ||
17910                 error "DoM file mismatch after migration"
17911 }
17912 run_test 230j "DoM file data not changed after dir migration"
17913
17914 test_230k() {
17915         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17916         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17917                 skip "Need MDS version at least 2.11.56"
17918
17919         local total=20
17920         local files_on_starting_mdt=0
17921
17922         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17923         $LFS getdirstripe $DIR/$tdir
17924         for i in $(seq $total); do
17925                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17926                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17927                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17928         done
17929
17930         echo "$files_on_starting_mdt files on MDT0"
17931
17932         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17933         $LFS getdirstripe $DIR/$tdir
17934
17935         files_on_starting_mdt=0
17936         for i in $(seq $total); do
17937                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17938                         error "file $tfile.$i mismatch after migration"
17939                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17940                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17941         done
17942
17943         echo "$files_on_starting_mdt files on MDT1 after migration"
17944         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17945
17946         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17947         $LFS getdirstripe $DIR/$tdir
17948
17949         files_on_starting_mdt=0
17950         for i in $(seq $total); do
17951                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17952                         error "file $tfile.$i mismatch after 2nd migration"
17953                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17954                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17955         done
17956
17957         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17958         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17959
17960         true
17961 }
17962 run_test 230k "file data not changed after dir migration"
17963
17964 test_230l() {
17965         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17966         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17967                 skip "Need MDS version at least 2.11.56"
17968
17969         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17970         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17971                 error "create files under remote dir failed $i"
17972         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17973 }
17974 run_test 230l "readdir between MDTs won't crash"
17975
17976 test_230m() {
17977         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17978         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17979                 skip "Need MDS version at least 2.11.56"
17980
17981         local MDTIDX=1
17982         local mig_dir=$DIR/$tdir/migrate_dir
17983         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17984         local shortstr="b"
17985         local val
17986
17987         echo "Creating files and dirs with xattrs"
17988         test_mkdir $DIR/$tdir
17989         test_mkdir -i0 -c1 $mig_dir
17990         mkdir $mig_dir/dir
17991         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17992                 error "cannot set xattr attr1 on dir"
17993         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17994                 error "cannot set xattr attr2 on dir"
17995         touch $mig_dir/dir/f0
17996         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17997                 error "cannot set xattr attr1 on file"
17998         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17999                 error "cannot set xattr attr2 on file"
18000         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18001         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18002         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18003         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18004         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18005         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18006         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18007         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18008         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18009
18010         echo "Migrating to MDT1"
18011         $LFS migrate -m $MDTIDX $mig_dir ||
18012                 error "fails on migrating dir to MDT1"
18013
18014         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18015         echo "Checking xattrs"
18016         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18017         [ "$val" = $longstr ] ||
18018                 error "expecting xattr1 $longstr on dir, found $val"
18019         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18020         [ "$val" = $shortstr ] ||
18021                 error "expecting xattr2 $shortstr on dir, found $val"
18022         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18023         [ "$val" = $longstr ] ||
18024                 error "expecting xattr1 $longstr on file, found $val"
18025         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18026         [ "$val" = $shortstr ] ||
18027                 error "expecting xattr2 $shortstr on file, found $val"
18028 }
18029 run_test 230m "xattrs not changed after dir migration"
18030
18031 test_230n() {
18032         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18033         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18034                 skip "Need MDS version at least 2.13.53"
18035
18036         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18037         cat /etc/hosts > $DIR/$tdir/$tfile
18038         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18039         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18040
18041         cmp /etc/hosts $DIR/$tdir/$tfile ||
18042                 error "File data mismatch after migration"
18043 }
18044 run_test 230n "Dir migration with mirrored file"
18045
18046 test_230o() {
18047         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18048         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18049                 skip "Need MDS version at least 2.13.52"
18050
18051         local mdts=$(comma_list $(mdts_nodes))
18052
18053         local restripe_status
18054         local delta
18055         local i
18056         local j
18057
18058         # in case "crush" hash type is not set
18059         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18060
18061         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18062                            mdt.*MDT0000.enable_dir_restripe)
18063         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18064         stack_trap "do_nodes $mdts $LCTL set_param \
18065                     mdt.*.enable_dir_restripe=$restripe_status"
18066
18067         mkdir $DIR/$tdir
18068         createmany -m $DIR/$tdir/f 100 ||
18069                 error "create files under remote dir failed $i"
18070         createmany -d $DIR/$tdir/d 100 ||
18071                 error "create dirs under remote dir failed $i"
18072
18073         for i in $(seq 2 $MDSCOUNT); do
18074                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18075                 $LFS setdirstripe -c $i $DIR/$tdir ||
18076                         error "split -c $i $tdir failed"
18077                 wait_update $HOSTNAME \
18078                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 100 ||
18079                         error "dir split not finished"
18080                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18081                         awk '/migrate/ {sum += $2} END { print sum }')
18082                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18083                 # delta is around total_files/stripe_count
18084                 [ $delta -lt $((200 /(i - 1))) ] ||
18085                         error "$delta files migrated"
18086         done
18087 }
18088 run_test 230o "dir split"
18089
18090 test_230p() {
18091         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18092         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18093                 skip "Need MDS version at least 2.13.52"
18094
18095         local mdts=$(comma_list $(mdts_nodes))
18096
18097         local restripe_status
18098         local delta
18099         local i
18100         local j
18101
18102         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18103
18104         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18105                            mdt.*MDT0000.enable_dir_restripe)
18106         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18107         stack_trap "do_nodes $mdts $LCTL set_param \
18108                     mdt.*.enable_dir_restripe=$restripe_status"
18109
18110         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18111         createmany -m $DIR/$tdir/f 100 ||
18112                 error "create files under remote dir failed $i"
18113         createmany -d $DIR/$tdir/d 100 ||
18114                 error "create dirs under remote dir failed $i"
18115
18116         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18117                 local mdt_hash="crush"
18118
18119                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18120                 $LFS setdirstripe -c $i $DIR/$tdir ||
18121                         error "split -c $i $tdir failed"
18122                 [ $i -eq 1 ] && mdt_hash="none"
18123                 wait_update $HOSTNAME \
18124                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash 100 ||
18125                         error "dir merge not finished"
18126                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18127                         awk '/migrate/ {sum += $2} END { print sum }')
18128                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18129                 # delta is around total_files/stripe_count
18130                 [ $delta -lt $((200 / i)) ] ||
18131                         error "$delta files migrated"
18132         done
18133 }
18134 run_test 230p "dir merge"
18135
18136 test_230q() {
18137         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18138         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18139                 skip "Need MDS version at least 2.13.52"
18140
18141         local mdts=$(comma_list $(mdts_nodes))
18142         local saved_threshold=$(do_facet mds1 \
18143                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18144         local saved_delta=$(do_facet mds1 \
18145                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18146         local threshold=100
18147         local delta=2
18148         local total=0
18149         local stripe_count=0
18150         local stripe_index
18151         local nr_files
18152
18153         stack_trap "do_nodes $mdts $LCTL set_param \
18154                     mdt.*.dir_split_count=$saved_threshold"
18155         stack_trap "do_nodes $mdts $LCTL set_param \
18156                     mdt.*.dir_split_delta=$saved_delta"
18157         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18158         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18159         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18160         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18161         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18162         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18163
18164         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18165         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18166
18167         while [ $stripe_count -lt $MDSCOUNT ]; do
18168                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18169                         error "create sub files failed"
18170                 stat $DIR/$tdir > /dev/null
18171                 total=$((total + threshold * 3 / 2))
18172                 stripe_count=$((stripe_count + delta))
18173                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18174
18175                 wait_update $HOSTNAME \
18176                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18177                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18178
18179                 wait_update $HOSTNAME \
18180                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18181                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18182
18183                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18184                            grep -w $stripe_index | wc -l)
18185                 echo "$nr_files files on MDT$stripe_index after split"
18186                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18187                         error "$nr_files files on MDT$stripe_index after split"
18188
18189                 nr_files=$(ls $DIR/$tdir | wc -w)
18190                 [ $nr_files -eq $total ] ||
18191                         error "total sub files $nr_files != $total"
18192         done
18193 }
18194 run_test 230q "dir auto split"
18195
18196 test_231a()
18197 {
18198         # For simplicity this test assumes that max_pages_per_rpc
18199         # is the same across all OSCs
18200         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18201         local bulk_size=$((max_pages * PAGE_SIZE))
18202         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18203                                        head -n 1)
18204
18205         mkdir -p $DIR/$tdir
18206         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18207                 error "failed to set stripe with -S ${brw_size}M option"
18208
18209         # clear the OSC stats
18210         $LCTL set_param osc.*.stats=0 &>/dev/null
18211         stop_writeback
18212
18213         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18214         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18215                 oflag=direct &>/dev/null || error "dd failed"
18216
18217         sync; sleep 1; sync # just to be safe
18218         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18219         if [ x$nrpcs != "x1" ]; then
18220                 $LCTL get_param osc.*.stats
18221                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18222         fi
18223
18224         start_writeback
18225         # Drop the OSC cache, otherwise we will read from it
18226         cancel_lru_locks osc
18227
18228         # clear the OSC stats
18229         $LCTL set_param osc.*.stats=0 &>/dev/null
18230
18231         # Client reads $bulk_size.
18232         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18233                 iflag=direct &>/dev/null || error "dd failed"
18234
18235         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18236         if [ x$nrpcs != "x1" ]; then
18237                 $LCTL get_param osc.*.stats
18238                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18239         fi
18240 }
18241 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18242
18243 test_231b() {
18244         mkdir -p $DIR/$tdir
18245         local i
18246         for i in {0..1023}; do
18247                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18248                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18249                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18250         done
18251         sync
18252 }
18253 run_test 231b "must not assert on fully utilized OST request buffer"
18254
18255 test_232a() {
18256         mkdir -p $DIR/$tdir
18257         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18258
18259         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18260         do_facet ost1 $LCTL set_param fail_loc=0x31c
18261
18262         # ignore dd failure
18263         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18264
18265         do_facet ost1 $LCTL set_param fail_loc=0
18266         umount_client $MOUNT || error "umount failed"
18267         mount_client $MOUNT || error "mount failed"
18268         stop ost1 || error "cannot stop ost1"
18269         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18270 }
18271 run_test 232a "failed lock should not block umount"
18272
18273 test_232b() {
18274         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18275                 skip "Need MDS version at least 2.10.58"
18276
18277         mkdir -p $DIR/$tdir
18278         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18279         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18280         sync
18281         cancel_lru_locks osc
18282
18283         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18284         do_facet ost1 $LCTL set_param fail_loc=0x31c
18285
18286         # ignore failure
18287         $LFS data_version $DIR/$tdir/$tfile || true
18288
18289         do_facet ost1 $LCTL set_param fail_loc=0
18290         umount_client $MOUNT || error "umount failed"
18291         mount_client $MOUNT || error "mount failed"
18292         stop ost1 || error "cannot stop ost1"
18293         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18294 }
18295 run_test 232b "failed data version lock should not block umount"
18296
18297 test_233a() {
18298         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18299                 skip "Need MDS version at least 2.3.64"
18300         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18301
18302         local fid=$($LFS path2fid $MOUNT)
18303
18304         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18305                 error "cannot access $MOUNT using its FID '$fid'"
18306 }
18307 run_test 233a "checking that OBF of the FS root succeeds"
18308
18309 test_233b() {
18310         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18311                 skip "Need MDS version at least 2.5.90"
18312         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18313
18314         local fid=$($LFS path2fid $MOUNT/.lustre)
18315
18316         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18317                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18318
18319         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18320         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18321                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18322 }
18323 run_test 233b "checking that OBF of the FS .lustre succeeds"
18324
18325 test_234() {
18326         local p="$TMP/sanityN-$TESTNAME.parameters"
18327         save_lustre_params client "llite.*.xattr_cache" > $p
18328         lctl set_param llite.*.xattr_cache 1 ||
18329                 skip_env "xattr cache is not supported"
18330
18331         mkdir -p $DIR/$tdir || error "mkdir failed"
18332         touch $DIR/$tdir/$tfile || error "touch failed"
18333         # OBD_FAIL_LLITE_XATTR_ENOMEM
18334         $LCTL set_param fail_loc=0x1405
18335         getfattr -n user.attr $DIR/$tdir/$tfile &&
18336                 error "getfattr should have failed with ENOMEM"
18337         $LCTL set_param fail_loc=0x0
18338         rm -rf $DIR/$tdir
18339
18340         restore_lustre_params < $p
18341         rm -f $p
18342 }
18343 run_test 234 "xattr cache should not crash on ENOMEM"
18344
18345 test_235() {
18346         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18347                 skip "Need MDS version at least 2.4.52"
18348
18349         flock_deadlock $DIR/$tfile
18350         local RC=$?
18351         case $RC in
18352                 0)
18353                 ;;
18354                 124) error "process hangs on a deadlock"
18355                 ;;
18356                 *) error "error executing flock_deadlock $DIR/$tfile"
18357                 ;;
18358         esac
18359 }
18360 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18361
18362 #LU-2935
18363 test_236() {
18364         check_swap_layouts_support
18365
18366         local ref1=/etc/passwd
18367         local ref2=/etc/group
18368         local file1=$DIR/$tdir/f1
18369         local file2=$DIR/$tdir/f2
18370
18371         test_mkdir -c1 $DIR/$tdir
18372         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18373         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18374         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18375         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18376         local fd=$(free_fd)
18377         local cmd="exec $fd<>$file2"
18378         eval $cmd
18379         rm $file2
18380         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18381                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18382         cmd="exec $fd>&-"
18383         eval $cmd
18384         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18385
18386         #cleanup
18387         rm -rf $DIR/$tdir
18388 }
18389 run_test 236 "Layout swap on open unlinked file"
18390
18391 # LU-4659 linkea consistency
18392 test_238() {
18393         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18394                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18395                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18396                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18397
18398         touch $DIR/$tfile
18399         ln $DIR/$tfile $DIR/$tfile.lnk
18400         touch $DIR/$tfile.new
18401         mv $DIR/$tfile.new $DIR/$tfile
18402         local fid1=$($LFS path2fid $DIR/$tfile)
18403         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18404         local path1=$($LFS fid2path $FSNAME "$fid1")
18405         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18406         local path2=$($LFS fid2path $FSNAME "$fid2")
18407         [ $tfile.lnk == $path2 ] ||
18408                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18409         rm -f $DIR/$tfile*
18410 }
18411 run_test 238 "Verify linkea consistency"
18412
18413 test_239A() { # was test_239
18414         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18415                 skip "Need MDS version at least 2.5.60"
18416
18417         local list=$(comma_list $(mdts_nodes))
18418
18419         mkdir -p $DIR/$tdir
18420         createmany -o $DIR/$tdir/f- 5000
18421         unlinkmany $DIR/$tdir/f- 5000
18422         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18423                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18424         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18425                         osp.*MDT*.sync_in_flight" | calc_sum)
18426         [ "$changes" -eq 0 ] || error "$changes not synced"
18427 }
18428 run_test 239A "osp_sync test"
18429
18430 test_239a() { #LU-5297
18431         remote_mds_nodsh && skip "remote MDS with nodsh"
18432
18433         touch $DIR/$tfile
18434         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18435         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18436         chgrp $RUNAS_GID $DIR/$tfile
18437         wait_delete_completed
18438 }
18439 run_test 239a "process invalid osp sync record correctly"
18440
18441 test_239b() { #LU-5297
18442         remote_mds_nodsh && skip "remote MDS with nodsh"
18443
18444         touch $DIR/$tfile1
18445         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18446         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18447         chgrp $RUNAS_GID $DIR/$tfile1
18448         wait_delete_completed
18449         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18450         touch $DIR/$tfile2
18451         chgrp $RUNAS_GID $DIR/$tfile2
18452         wait_delete_completed
18453 }
18454 run_test 239b "process osp sync record with ENOMEM error correctly"
18455
18456 test_240() {
18457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18458         remote_mds_nodsh && skip "remote MDS with nodsh"
18459
18460         mkdir -p $DIR/$tdir
18461
18462         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18463                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18464         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18465                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18466
18467         umount_client $MOUNT || error "umount failed"
18468         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18469         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18470         mount_client $MOUNT || error "failed to mount client"
18471
18472         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18473         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18474 }
18475 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18476
18477 test_241_bio() {
18478         local count=$1
18479         local bsize=$2
18480
18481         for LOOP in $(seq $count); do
18482                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18483                 cancel_lru_locks $OSC || true
18484         done
18485 }
18486
18487 test_241_dio() {
18488         local count=$1
18489         local bsize=$2
18490
18491         for LOOP in $(seq $1); do
18492                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18493                         2>/dev/null
18494         done
18495 }
18496
18497 test_241a() { # was test_241
18498         local bsize=$PAGE_SIZE
18499
18500         (( bsize < 40960 )) && bsize=40960
18501         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18502         ls -la $DIR/$tfile
18503         cancel_lru_locks $OSC
18504         test_241_bio 1000 $bsize &
18505         PID=$!
18506         test_241_dio 1000 $bsize
18507         wait $PID
18508 }
18509 run_test 241a "bio vs dio"
18510
18511 test_241b() {
18512         local bsize=$PAGE_SIZE
18513
18514         (( bsize < 40960 )) && bsize=40960
18515         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18516         ls -la $DIR/$tfile
18517         test_241_dio 1000 $bsize &
18518         PID=$!
18519         test_241_dio 1000 $bsize
18520         wait $PID
18521 }
18522 run_test 241b "dio vs dio"
18523
18524 test_242() {
18525         remote_mds_nodsh && skip "remote MDS with nodsh"
18526
18527         mkdir -p $DIR/$tdir
18528         touch $DIR/$tdir/$tfile
18529
18530         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18531         do_facet mds1 lctl set_param fail_loc=0x105
18532         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18533
18534         do_facet mds1 lctl set_param fail_loc=0
18535         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18536 }
18537 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18538
18539 test_243()
18540 {
18541         test_mkdir $DIR/$tdir
18542         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18543 }
18544 run_test 243 "various group lock tests"
18545
18546 test_244a()
18547 {
18548         test_mkdir $DIR/$tdir
18549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18550         sendfile_grouplock $DIR/$tdir/$tfile || \
18551                 error "sendfile+grouplock failed"
18552         rm -rf $DIR/$tdir
18553 }
18554 run_test 244a "sendfile with group lock tests"
18555
18556 test_244b()
18557 {
18558         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18559
18560         local threads=50
18561         local size=$((1024*1024))
18562
18563         test_mkdir $DIR/$tdir
18564         for i in $(seq 1 $threads); do
18565                 local file=$DIR/$tdir/file_$((i / 10))
18566                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18567                 local pids[$i]=$!
18568         done
18569         for i in $(seq 1 $threads); do
18570                 wait ${pids[$i]}
18571         done
18572 }
18573 run_test 244b "multi-threaded write with group lock"
18574
18575 test_245() {
18576         local flagname="multi_mod_rpcs"
18577         local connect_data_name="max_mod_rpcs"
18578         local out
18579
18580         # check if multiple modify RPCs flag is set
18581         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18582                 grep "connect_flags:")
18583         echo "$out"
18584
18585         echo "$out" | grep -qw $flagname
18586         if [ $? -ne 0 ]; then
18587                 echo "connect flag $flagname is not set"
18588                 return
18589         fi
18590
18591         # check if multiple modify RPCs data is set
18592         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18593         echo "$out"
18594
18595         echo "$out" | grep -qw $connect_data_name ||
18596                 error "import should have connect data $connect_data_name"
18597 }
18598 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18599
18600 cleanup_247() {
18601         local submount=$1
18602
18603         trap 0
18604         umount_client $submount
18605         rmdir $submount
18606 }
18607
18608 test_247a() {
18609         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18610                 grep -q subtree ||
18611                 skip_env "Fileset feature is not supported"
18612
18613         local submount=${MOUNT}_$tdir
18614
18615         mkdir $MOUNT/$tdir
18616         mkdir -p $submount || error "mkdir $submount failed"
18617         FILESET="$FILESET/$tdir" mount_client $submount ||
18618                 error "mount $submount failed"
18619         trap "cleanup_247 $submount" EXIT
18620         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18621         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18622                 error "read $MOUNT/$tdir/$tfile failed"
18623         cleanup_247 $submount
18624 }
18625 run_test 247a "mount subdir as fileset"
18626
18627 test_247b() {
18628         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18629                 skip_env "Fileset feature is not supported"
18630
18631         local submount=${MOUNT}_$tdir
18632
18633         rm -rf $MOUNT/$tdir
18634         mkdir -p $submount || error "mkdir $submount failed"
18635         SKIP_FILESET=1
18636         FILESET="$FILESET/$tdir" mount_client $submount &&
18637                 error "mount $submount should fail"
18638         rmdir $submount
18639 }
18640 run_test 247b "mount subdir that dose not exist"
18641
18642 test_247c() {
18643         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18644                 skip_env "Fileset feature is not supported"
18645
18646         local submount=${MOUNT}_$tdir
18647
18648         mkdir -p $MOUNT/$tdir/dir1
18649         mkdir -p $submount || error "mkdir $submount failed"
18650         trap "cleanup_247 $submount" EXIT
18651         FILESET="$FILESET/$tdir" mount_client $submount ||
18652                 error "mount $submount failed"
18653         local fid=$($LFS path2fid $MOUNT/)
18654         $LFS fid2path $submount $fid && error "fid2path should fail"
18655         cleanup_247 $submount
18656 }
18657 run_test 247c "running fid2path outside root"
18658
18659 test_247d() {
18660         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18661                 skip "Fileset feature is not supported"
18662
18663         local submount=${MOUNT}_$tdir
18664
18665         mkdir -p $MOUNT/$tdir/dir1
18666         mkdir -p $submount || error "mkdir $submount failed"
18667         FILESET="$FILESET/$tdir" mount_client $submount ||
18668                 error "mount $submount failed"
18669         trap "cleanup_247 $submount" EXIT
18670         local fid=$($LFS path2fid $submount/dir1)
18671         $LFS fid2path $submount $fid || error "fid2path should succeed"
18672         cleanup_247 $submount
18673 }
18674 run_test 247d "running fid2path inside root"
18675
18676 # LU-8037
18677 test_247e() {
18678         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18679                 grep -q subtree ||
18680                 skip "Fileset feature is not supported"
18681
18682         local submount=${MOUNT}_$tdir
18683
18684         mkdir $MOUNT/$tdir
18685         mkdir -p $submount || error "mkdir $submount failed"
18686         FILESET="$FILESET/.." mount_client $submount &&
18687                 error "mount $submount should fail"
18688         rmdir $submount
18689 }
18690 run_test 247e "mount .. as fileset"
18691
18692 test_247f() {
18693         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18694         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18695                 skip "Need at least version 2.13.52"
18696         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18697                 grep -q subtree ||
18698                 skip "Fileset feature is not supported"
18699
18700         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18701         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18702                 error "mkdir remote failed"
18703         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18704         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18705                 error "mkdir striped failed"
18706         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18707
18708         local submount=${MOUNT}_$tdir
18709
18710         mkdir -p $submount || error "mkdir $submount failed"
18711
18712         local dir
18713         local fileset=$FILESET
18714
18715         for dir in $tdir/remote $tdir/remote/subdir \
18716                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18717                 FILESET="$fileset/$dir" mount_client $submount ||
18718                         error "mount $dir failed"
18719                 umount_client $submount
18720         done
18721 }
18722 run_test 247f "mount striped or remote directory as fileset"
18723
18724 test_248a() {
18725         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18726         [ -z "$fast_read_sav" ] && skip "no fast read support"
18727
18728         # create a large file for fast read verification
18729         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18730
18731         # make sure the file is created correctly
18732         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18733                 { rm -f $DIR/$tfile; skip "file creation error"; }
18734
18735         echo "Test 1: verify that fast read is 4 times faster on cache read"
18736
18737         # small read with fast read enabled
18738         $LCTL set_param -n llite.*.fast_read=1
18739         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18740                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18741                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18742         # small read with fast read disabled
18743         $LCTL set_param -n llite.*.fast_read=0
18744         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18745                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18746                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18747
18748         # verify that fast read is 4 times faster for cache read
18749         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18750                 error_not_in_vm "fast read was not 4 times faster: " \
18751                            "$t_fast vs $t_slow"
18752
18753         echo "Test 2: verify the performance between big and small read"
18754         $LCTL set_param -n llite.*.fast_read=1
18755
18756         # 1k non-cache read
18757         cancel_lru_locks osc
18758         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18759                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18760                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18761
18762         # 1M non-cache read
18763         cancel_lru_locks osc
18764         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18765                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18766                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18767
18768         # verify that big IO is not 4 times faster than small IO
18769         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18770                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18771
18772         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18773         rm -f $DIR/$tfile
18774 }
18775 run_test 248a "fast read verification"
18776
18777 test_248b() {
18778         # Default short_io_bytes=16384, try both smaller and larger sizes.
18779         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18780         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18781         echo "bs=53248 count=113 normal buffered write"
18782         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18783                 error "dd of initial data file failed"
18784         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18785
18786         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18787         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18788                 error "dd with sync normal writes failed"
18789         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18790
18791         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18792         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18793                 error "dd with sync small writes failed"
18794         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18795
18796         cancel_lru_locks osc
18797
18798         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18799         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18800         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18801         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18802                 iflag=direct || error "dd with O_DIRECT small read failed"
18803         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18804         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18805                 error "compare $TMP/$tfile.1 failed"
18806
18807         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18808         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18809
18810         # just to see what the maximum tunable value is, and test parsing
18811         echo "test invalid parameter 2MB"
18812         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18813                 error "too-large short_io_bytes allowed"
18814         echo "test maximum parameter 512KB"
18815         # if we can set a larger short_io_bytes, run test regardless of version
18816         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18817                 # older clients may not allow setting it this large, that's OK
18818                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18819                         skip "Need at least client version 2.13.50"
18820                 error "medium short_io_bytes failed"
18821         fi
18822         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18823         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18824
18825         echo "test large parameter 64KB"
18826         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18827         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18828
18829         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18830         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18831                 error "dd with sync large writes failed"
18832         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18833
18834         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18835         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18836         num=$((113 * 4096 / PAGE_SIZE))
18837         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18838         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18839                 error "dd with O_DIRECT large writes failed"
18840         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18841                 error "compare $DIR/$tfile.3 failed"
18842
18843         cancel_lru_locks osc
18844
18845         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18846         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18847                 error "dd with O_DIRECT large read failed"
18848         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18849                 error "compare $TMP/$tfile.2 failed"
18850
18851         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18852         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18853                 error "dd with O_DIRECT large read failed"
18854         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18855                 error "compare $TMP/$tfile.3 failed"
18856 }
18857 run_test 248b "test short_io read and write for both small and large sizes"
18858
18859 test_249() { # LU-7890
18860         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18861                 skip "Need at least version 2.8.54"
18862
18863         rm -f $DIR/$tfile
18864         $LFS setstripe -c 1 $DIR/$tfile
18865         # Offset 2T == 4k * 512M
18866         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18867                 error "dd to 2T offset failed"
18868 }
18869 run_test 249 "Write above 2T file size"
18870
18871 test_250() {
18872         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18873          && skip "no 16TB file size limit on ZFS"
18874
18875         $LFS setstripe -c 1 $DIR/$tfile
18876         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18877         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18878         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18879         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18880                 conv=notrunc,fsync && error "append succeeded"
18881         return 0
18882 }
18883 run_test 250 "Write above 16T limit"
18884
18885 test_251() {
18886         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18887
18888         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18889         #Skip once - writing the first stripe will succeed
18890         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18891         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18892                 error "short write happened"
18893
18894         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18895         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18896                 error "short read happened"
18897
18898         rm -f $DIR/$tfile
18899 }
18900 run_test 251 "Handling short read and write correctly"
18901
18902 test_252() {
18903         remote_mds_nodsh && skip "remote MDS with nodsh"
18904         remote_ost_nodsh && skip "remote OST with nodsh"
18905         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18906                 skip_env "ldiskfs only test"
18907         fi
18908
18909         local tgt
18910         local dev
18911         local out
18912         local uuid
18913         local num
18914         local gen
18915
18916         # check lr_reader on OST0000
18917         tgt=ost1
18918         dev=$(facet_device $tgt)
18919         out=$(do_facet $tgt $LR_READER $dev)
18920         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18921         echo "$out"
18922         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18923         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18924                 error "Invalid uuid returned by $LR_READER on target $tgt"
18925         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18926
18927         # check lr_reader -c on MDT0000
18928         tgt=mds1
18929         dev=$(facet_device $tgt)
18930         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18931                 skip "$LR_READER does not support additional options"
18932         fi
18933         out=$(do_facet $tgt $LR_READER -c $dev)
18934         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18935         echo "$out"
18936         num=$(echo "$out" | grep -c "mdtlov")
18937         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18938                 error "Invalid number of mdtlov clients returned by $LR_READER"
18939         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18940
18941         # check lr_reader -cr on MDT0000
18942         out=$(do_facet $tgt $LR_READER -cr $dev)
18943         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18944         echo "$out"
18945         echo "$out" | grep -q "^reply_data:$" ||
18946                 error "$LR_READER should have returned 'reply_data' section"
18947         num=$(echo "$out" | grep -c "client_generation")
18948         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18949 }
18950 run_test 252 "check lr_reader tool"
18951
18952 test_253() {
18953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18954         remote_mds_nodsh && skip "remote MDS with nodsh"
18955         remote_mgs_nodsh && skip "remote MGS with nodsh"
18956
18957         local ostidx=0
18958         local rc=0
18959         local ost_name=$(ostname_from_index $ostidx)
18960
18961         # on the mdt's osc
18962         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18963         do_facet $SINGLEMDS $LCTL get_param -n \
18964                 osp.$mdtosc_proc1.reserved_mb_high ||
18965                 skip  "remote MDS does not support reserved_mb_high"
18966
18967         rm -rf $DIR/$tdir
18968         wait_mds_ost_sync
18969         wait_delete_completed
18970         mkdir $DIR/$tdir
18971
18972         pool_add $TESTNAME || error "Pool creation failed"
18973         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
18974
18975         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
18976                 error "Setstripe failed"
18977
18978         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
18979
18980         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
18981                     grep "watermarks")
18982         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
18983
18984         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18985                         osp.$mdtosc_proc1.prealloc_status)
18986         echo "prealloc_status $oa_status"
18987
18988         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
18989                 error "File creation should fail"
18990
18991         #object allocation was stopped, but we still able to append files
18992         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
18993                 oflag=append || error "Append failed"
18994
18995         rm -f $DIR/$tdir/$tfile.0
18996
18997         # For this test, we want to delete the files we created to go out of
18998         # space but leave the watermark, so we remain nearly out of space
18999         ost_watermarks_enospc_delete_files $tfile $ostidx
19000
19001         wait_delete_completed
19002
19003         sleep_maxage
19004
19005         for i in $(seq 10 12); do
19006                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19007                         2>/dev/null || error "File creation failed after rm"
19008         done
19009
19010         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19011                         osp.$mdtosc_proc1.prealloc_status)
19012         echo "prealloc_status $oa_status"
19013
19014         if (( oa_status != 0 )); then
19015                 error "Object allocation still disable after rm"
19016         fi
19017 }
19018 run_test 253 "Check object allocation limit"
19019
19020 test_254() {
19021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19022         remote_mds_nodsh && skip "remote MDS with nodsh"
19023         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19024                 skip "MDS does not support changelog_size"
19025
19026         local cl_user
19027         local MDT0=$(facet_svc $SINGLEMDS)
19028
19029         changelog_register || error "changelog_register failed"
19030
19031         changelog_clear 0 || error "changelog_clear failed"
19032
19033         local size1=$(do_facet $SINGLEMDS \
19034                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19035         echo "Changelog size $size1"
19036
19037         rm -rf $DIR/$tdir
19038         $LFS mkdir -i 0 $DIR/$tdir
19039         # change something
19040         mkdir -p $DIR/$tdir/pics/2008/zachy
19041         touch $DIR/$tdir/pics/2008/zachy/timestamp
19042         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19043         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19044         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19045         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19046         rm $DIR/$tdir/pics/desktop.jpg
19047
19048         local size2=$(do_facet $SINGLEMDS \
19049                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19050         echo "Changelog size after work $size2"
19051
19052         (( $size2 > $size1 )) ||
19053                 error "new Changelog size=$size2 less than old size=$size1"
19054 }
19055 run_test 254 "Check changelog size"
19056
19057 ladvise_no_type()
19058 {
19059         local type=$1
19060         local file=$2
19061
19062         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19063                 awk -F: '{print $2}' | grep $type > /dev/null
19064         if [ $? -ne 0 ]; then
19065                 return 0
19066         fi
19067         return 1
19068 }
19069
19070 ladvise_no_ioctl()
19071 {
19072         local file=$1
19073
19074         lfs ladvise -a willread $file > /dev/null 2>&1
19075         if [ $? -eq 0 ]; then
19076                 return 1
19077         fi
19078
19079         lfs ladvise -a willread $file 2>&1 |
19080                 grep "Inappropriate ioctl for device" > /dev/null
19081         if [ $? -eq 0 ]; then
19082                 return 0
19083         fi
19084         return 1
19085 }
19086
19087 percent() {
19088         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19089 }
19090
19091 # run a random read IO workload
19092 # usage: random_read_iops <filename> <filesize> <iosize>
19093 random_read_iops() {
19094         local file=$1
19095         local fsize=$2
19096         local iosize=${3:-4096}
19097
19098         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19099                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19100 }
19101
19102 drop_file_oss_cache() {
19103         local file="$1"
19104         local nodes="$2"
19105
19106         $LFS ladvise -a dontneed $file 2>/dev/null ||
19107                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19108 }
19109
19110 ladvise_willread_performance()
19111 {
19112         local repeat=10
19113         local average_origin=0
19114         local average_cache=0
19115         local average_ladvise=0
19116
19117         for ((i = 1; i <= $repeat; i++)); do
19118                 echo "Iter $i/$repeat: reading without willread hint"
19119                 cancel_lru_locks osc
19120                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19121                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19122                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19123                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19124
19125                 cancel_lru_locks osc
19126                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19127                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19128                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19129
19130                 cancel_lru_locks osc
19131                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19132                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19133                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19134                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19135                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19136         done
19137         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19138         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19139         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19140
19141         speedup_cache=$(percent $average_cache $average_origin)
19142         speedup_ladvise=$(percent $average_ladvise $average_origin)
19143
19144         echo "Average uncached read: $average_origin"
19145         echo "Average speedup with OSS cached read: " \
19146                 "$average_cache = +$speedup_cache%"
19147         echo "Average speedup with ladvise willread: " \
19148                 "$average_ladvise = +$speedup_ladvise%"
19149
19150         local lowest_speedup=20
19151         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19152                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19153                         "got $average_cache%. Skipping ladvise willread check."
19154                 return 0
19155         fi
19156
19157         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19158         # it is still good to run until then to exercise 'ladvise willread'
19159         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19160                 [ "$ost1_FSTYPE" = "zfs" ] &&
19161                 echo "osd-zfs does not support dontneed or drop_caches" &&
19162                 return 0
19163
19164         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19165         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19166                 error_not_in_vm "Speedup with willread is less than " \
19167                         "$lowest_speedup%, got $average_ladvise%"
19168 }
19169
19170 test_255a() {
19171         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19172                 skip "lustre < 2.8.54 does not support ladvise "
19173         remote_ost_nodsh && skip "remote OST with nodsh"
19174
19175         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19176
19177         ladvise_no_type willread $DIR/$tfile &&
19178                 skip "willread ladvise is not supported"
19179
19180         ladvise_no_ioctl $DIR/$tfile &&
19181                 skip "ladvise ioctl is not supported"
19182
19183         local size_mb=100
19184         local size=$((size_mb * 1048576))
19185         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19186                 error "dd to $DIR/$tfile failed"
19187
19188         lfs ladvise -a willread $DIR/$tfile ||
19189                 error "Ladvise failed with no range argument"
19190
19191         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19192                 error "Ladvise failed with no -l or -e argument"
19193
19194         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19195                 error "Ladvise failed with only -e argument"
19196
19197         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19198                 error "Ladvise failed with only -l argument"
19199
19200         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19201                 error "End offset should not be smaller than start offset"
19202
19203         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19204                 error "End offset should not be equal to start offset"
19205
19206         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19207                 error "Ladvise failed with overflowing -s argument"
19208
19209         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19210                 error "Ladvise failed with overflowing -e argument"
19211
19212         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19213                 error "Ladvise failed with overflowing -l argument"
19214
19215         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19216                 error "Ladvise succeeded with conflicting -l and -e arguments"
19217
19218         echo "Synchronous ladvise should wait"
19219         local delay=4
19220 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19221         do_nodes $(comma_list $(osts_nodes)) \
19222                 $LCTL set_param fail_val=$delay fail_loc=0x237
19223
19224         local start_ts=$SECONDS
19225         lfs ladvise -a willread $DIR/$tfile ||
19226                 error "Ladvise failed with no range argument"
19227         local end_ts=$SECONDS
19228         local inteval_ts=$((end_ts - start_ts))
19229
19230         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19231                 error "Synchronous advice didn't wait reply"
19232         fi
19233
19234         echo "Asynchronous ladvise shouldn't wait"
19235         local start_ts=$SECONDS
19236         lfs ladvise -a willread -b $DIR/$tfile ||
19237                 error "Ladvise failed with no range argument"
19238         local end_ts=$SECONDS
19239         local inteval_ts=$((end_ts - start_ts))
19240
19241         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19242                 error "Asynchronous advice blocked"
19243         fi
19244
19245         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19246         ladvise_willread_performance
19247 }
19248 run_test 255a "check 'lfs ladvise -a willread'"
19249
19250 facet_meminfo() {
19251         local facet=$1
19252         local info=$2
19253
19254         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19255 }
19256
19257 test_255b() {
19258         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19259                 skip "lustre < 2.8.54 does not support ladvise "
19260         remote_ost_nodsh && skip "remote OST with nodsh"
19261
19262         lfs setstripe -c 1 -i 0 $DIR/$tfile
19263
19264         ladvise_no_type dontneed $DIR/$tfile &&
19265                 skip "dontneed ladvise is not supported"
19266
19267         ladvise_no_ioctl $DIR/$tfile &&
19268                 skip "ladvise ioctl is not supported"
19269
19270         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19271                 [ "$ost1_FSTYPE" = "zfs" ] &&
19272                 skip "zfs-osd does not support 'ladvise dontneed'"
19273
19274         local size_mb=100
19275         local size=$((size_mb * 1048576))
19276         # In order to prevent disturbance of other processes, only check 3/4
19277         # of the memory usage
19278         local kibibytes=$((size_mb * 1024 * 3 / 4))
19279
19280         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19281                 error "dd to $DIR/$tfile failed"
19282
19283         #force write to complete before dropping OST cache & checking memory
19284         sync
19285
19286         local total=$(facet_meminfo ost1 MemTotal)
19287         echo "Total memory: $total KiB"
19288
19289         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19290         local before_read=$(facet_meminfo ost1 Cached)
19291         echo "Cache used before read: $before_read KiB"
19292
19293         lfs ladvise -a willread $DIR/$tfile ||
19294                 error "Ladvise willread failed"
19295         local after_read=$(facet_meminfo ost1 Cached)
19296         echo "Cache used after read: $after_read KiB"
19297
19298         lfs ladvise -a dontneed $DIR/$tfile ||
19299                 error "Ladvise dontneed again failed"
19300         local no_read=$(facet_meminfo ost1 Cached)
19301         echo "Cache used after dontneed ladvise: $no_read KiB"
19302
19303         if [ $total -lt $((before_read + kibibytes)) ]; then
19304                 echo "Memory is too small, abort checking"
19305                 return 0
19306         fi
19307
19308         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19309                 error "Ladvise willread should use more memory" \
19310                         "than $kibibytes KiB"
19311         fi
19312
19313         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19314                 error "Ladvise dontneed should release more memory" \
19315                         "than $kibibytes KiB"
19316         fi
19317 }
19318 run_test 255b "check 'lfs ladvise -a dontneed'"
19319
19320 test_255c() {
19321         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19322                 skip "lustre < 2.10.50 does not support lockahead"
19323
19324         local count
19325         local new_count
19326         local difference
19327         local i
19328         local rc
19329
19330         test_mkdir -p $DIR/$tdir
19331         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19332
19333         #test 10 returns only success/failure
19334         i=10
19335         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19336         rc=$?
19337         if [ $rc -eq 255 ]; then
19338                 error "Ladvise test${i} failed, ${rc}"
19339         fi
19340
19341         #test 11 counts lock enqueue requests, all others count new locks
19342         i=11
19343         count=$(do_facet ost1 \
19344                 $LCTL get_param -n ost.OSS.ost.stats)
19345         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19346
19347         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19348         rc=$?
19349         if [ $rc -eq 255 ]; then
19350                 error "Ladvise test${i} failed, ${rc}"
19351         fi
19352
19353         new_count=$(do_facet ost1 \
19354                 $LCTL get_param -n ost.OSS.ost.stats)
19355         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19356                    awk '{ print $2 }')
19357
19358         difference="$((new_count - count))"
19359         if [ $difference -ne $rc ]; then
19360                 error "Ladvise test${i}, bad enqueue count, returned " \
19361                       "${rc}, actual ${difference}"
19362         fi
19363
19364         for i in $(seq 12 21); do
19365                 # If we do not do this, we run the risk of having too many
19366                 # locks and starting lock cancellation while we are checking
19367                 # lock counts.
19368                 cancel_lru_locks osc
19369
19370                 count=$($LCTL get_param -n \
19371                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19372
19373                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19374                 rc=$?
19375                 if [ $rc -eq 255 ]; then
19376                         error "Ladvise test ${i} failed, ${rc}"
19377                 fi
19378
19379                 new_count=$($LCTL get_param -n \
19380                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19381                 difference="$((new_count - count))"
19382
19383                 # Test 15 output is divided by 100 to map down to valid return
19384                 if [ $i -eq 15 ]; then
19385                         rc="$((rc * 100))"
19386                 fi
19387
19388                 if [ $difference -ne $rc ]; then
19389                         error "Ladvise test ${i}, bad lock count, returned " \
19390                               "${rc}, actual ${difference}"
19391                 fi
19392         done
19393
19394         #test 22 returns only success/failure
19395         i=22
19396         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19397         rc=$?
19398         if [ $rc -eq 255 ]; then
19399                 error "Ladvise test${i} failed, ${rc}"
19400         fi
19401 }
19402 run_test 255c "suite of ladvise lockahead tests"
19403
19404 test_256() {
19405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19406         remote_mds_nodsh && skip "remote MDS with nodsh"
19407         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19408         changelog_users $SINGLEMDS | grep "^cl" &&
19409                 skip "active changelog user"
19410
19411         local cl_user
19412         local cat_sl
19413         local mdt_dev
19414
19415         mdt_dev=$(mdsdevname 1)
19416         echo $mdt_dev
19417
19418         changelog_register || error "changelog_register failed"
19419
19420         rm -rf $DIR/$tdir
19421         mkdir -p $DIR/$tdir
19422
19423         changelog_clear 0 || error "changelog_clear failed"
19424
19425         # change something
19426         touch $DIR/$tdir/{1..10}
19427
19428         # stop the MDT
19429         stop $SINGLEMDS || error "Fail to stop MDT"
19430
19431         # remount the MDT
19432
19433         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19434
19435         #after mount new plainllog is used
19436         touch $DIR/$tdir/{11..19}
19437         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19438         stack_trap "rm -f $tmpfile"
19439         cat_sl=$(do_facet $SINGLEMDS "sync; \
19440                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19441                  llog_reader $tmpfile | grep -c type=1064553b")
19442         do_facet $SINGLEMDS llog_reader $tmpfile
19443
19444         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19445
19446         changelog_clear 0 || error "changelog_clear failed"
19447
19448         cat_sl=$(do_facet $SINGLEMDS "sync; \
19449                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19450                  llog_reader $tmpfile | grep -c type=1064553b")
19451
19452         if (( cat_sl == 2 )); then
19453                 error "Empty plain llog was not deleted from changelog catalog"
19454         elif (( cat_sl != 1 )); then
19455                 error "Active plain llog shouldn't be deleted from catalog"
19456         fi
19457 }
19458 run_test 256 "Check llog delete for empty and not full state"
19459
19460 test_257() {
19461         remote_mds_nodsh && skip "remote MDS with nodsh"
19462         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19463                 skip "Need MDS version at least 2.8.55"
19464
19465         test_mkdir $DIR/$tdir
19466
19467         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19468                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19469         stat $DIR/$tdir
19470
19471 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19472         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19473         local facet=mds$((mdtidx + 1))
19474         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19475         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19476
19477         stop $facet || error "stop MDS failed"
19478         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19479                 error "start MDS fail"
19480         wait_recovery_complete $facet
19481 }
19482 run_test 257 "xattr locks are not lost"
19483
19484 # Verify we take the i_mutex when security requires it
19485 test_258a() {
19486 #define OBD_FAIL_IMUTEX_SEC 0x141c
19487         $LCTL set_param fail_loc=0x141c
19488         touch $DIR/$tfile
19489         chmod u+s $DIR/$tfile
19490         chmod a+rwx $DIR/$tfile
19491         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19492         RC=$?
19493         if [ $RC -ne 0 ]; then
19494                 error "error, failed to take i_mutex, rc=$?"
19495         fi
19496         rm -f $DIR/$tfile
19497 }
19498 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19499
19500 # Verify we do NOT take the i_mutex in the normal case
19501 test_258b() {
19502 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19503         $LCTL set_param fail_loc=0x141d
19504         touch $DIR/$tfile
19505         chmod a+rwx $DIR
19506         chmod a+rw $DIR/$tfile
19507         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19508         RC=$?
19509         if [ $RC -ne 0 ]; then
19510                 error "error, took i_mutex unnecessarily, rc=$?"
19511         fi
19512         rm -f $DIR/$tfile
19513
19514 }
19515 run_test 258b "verify i_mutex security behavior"
19516
19517 test_259() {
19518         local file=$DIR/$tfile
19519         local before
19520         local after
19521
19522         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19523
19524         stack_trap "rm -f $file" EXIT
19525
19526         wait_delete_completed
19527         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19528         echo "before: $before"
19529
19530         $LFS setstripe -i 0 -c 1 $file
19531         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19532         sync_all_data
19533         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19534         echo "after write: $after"
19535
19536 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19537         do_facet ost1 $LCTL set_param fail_loc=0x2301
19538         $TRUNCATE $file 0
19539         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19540         echo "after truncate: $after"
19541
19542         stop ost1
19543         do_facet ost1 $LCTL set_param fail_loc=0
19544         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19545         sleep 2
19546         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19547         echo "after restart: $after"
19548         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19549                 error "missing truncate?"
19550
19551         return 0
19552 }
19553 run_test 259 "crash at delayed truncate"
19554
19555 test_260() {
19556 #define OBD_FAIL_MDC_CLOSE               0x806
19557         $LCTL set_param fail_loc=0x80000806
19558         touch $DIR/$tfile
19559
19560 }
19561 run_test 260 "Check mdc_close fail"
19562
19563 ### Data-on-MDT sanity tests ###
19564 test_270a() {
19565         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19566                 skip "Need MDS version at least 2.10.55 for DoM"
19567
19568         # create DoM file
19569         local dom=$DIR/$tdir/dom_file
19570         local tmp=$DIR/$tdir/tmp_file
19571
19572         mkdir -p $DIR/$tdir
19573
19574         # basic checks for DoM component creation
19575         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19576                 error "Can set MDT layout to non-first entry"
19577
19578         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19579                 error "Can define multiple entries as MDT layout"
19580
19581         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19582
19583         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19584         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19585         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19586
19587         local mdtidx=$($LFS getstripe -m $dom)
19588         local mdtname=MDT$(printf %04x $mdtidx)
19589         local facet=mds$((mdtidx + 1))
19590         local space_check=1
19591
19592         # Skip free space checks with ZFS
19593         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19594
19595         # write
19596         sync
19597         local size_tmp=$((65536 * 3))
19598         local mdtfree1=$(do_facet $facet \
19599                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19600
19601         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19602         # check also direct IO along write
19603         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19604         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19605         sync
19606         cmp $tmp $dom || error "file data is different"
19607         [ $(stat -c%s $dom) == $size_tmp ] ||
19608                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19609         if [ $space_check == 1 ]; then
19610                 local mdtfree2=$(do_facet $facet \
19611                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19612
19613                 # increase in usage from by $size_tmp
19614                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19615                         error "MDT free space wrong after write: " \
19616                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19617         fi
19618
19619         # truncate
19620         local size_dom=10000
19621
19622         $TRUNCATE $dom $size_dom
19623         [ $(stat -c%s $dom) == $size_dom ] ||
19624                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19625         if [ $space_check == 1 ]; then
19626                 mdtfree1=$(do_facet $facet \
19627                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19628                 # decrease in usage from $size_tmp to new $size_dom
19629                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19630                   $(((size_tmp - size_dom) / 1024)) ] ||
19631                         error "MDT free space is wrong after truncate: " \
19632                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19633         fi
19634
19635         # append
19636         cat $tmp >> $dom
19637         sync
19638         size_dom=$((size_dom + size_tmp))
19639         [ $(stat -c%s $dom) == $size_dom ] ||
19640                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19641         if [ $space_check == 1 ]; then
19642                 mdtfree2=$(do_facet $facet \
19643                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19644                 # increase in usage by $size_tmp from previous
19645                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19646                         error "MDT free space is wrong after append: " \
19647                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19648         fi
19649
19650         # delete
19651         rm $dom
19652         if [ $space_check == 1 ]; then
19653                 mdtfree1=$(do_facet $facet \
19654                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19655                 # decrease in usage by $size_dom from previous
19656                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19657                         error "MDT free space is wrong after removal: " \
19658                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19659         fi
19660
19661         # combined striping
19662         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19663                 error "Can't create DoM + OST striping"
19664
19665         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19666         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19667         # check also direct IO along write
19668         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19669         sync
19670         cmp $tmp $dom || error "file data is different"
19671         [ $(stat -c%s $dom) == $size_tmp ] ||
19672                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19673         rm $dom $tmp
19674
19675         return 0
19676 }
19677 run_test 270a "DoM: basic functionality tests"
19678
19679 test_270b() {
19680         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19681                 skip "Need MDS version at least 2.10.55"
19682
19683         local dom=$DIR/$tdir/dom_file
19684         local max_size=1048576
19685
19686         mkdir -p $DIR/$tdir
19687         $LFS setstripe -E $max_size -L mdt $dom
19688
19689         # truncate over the limit
19690         $TRUNCATE $dom $(($max_size + 1)) &&
19691                 error "successful truncate over the maximum size"
19692         # write over the limit
19693         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19694                 error "successful write over the maximum size"
19695         # append over the limit
19696         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19697         echo "12345" >> $dom && error "successful append over the maximum size"
19698         rm $dom
19699
19700         return 0
19701 }
19702 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19703
19704 test_270c() {
19705         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19706                 skip "Need MDS version at least 2.10.55"
19707
19708         mkdir -p $DIR/$tdir
19709         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19710
19711         # check files inherit DoM EA
19712         touch $DIR/$tdir/first
19713         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19714                 error "bad pattern"
19715         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19716                 error "bad stripe count"
19717         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19718                 error "bad stripe size"
19719
19720         # check directory inherits DoM EA and uses it as default
19721         mkdir $DIR/$tdir/subdir
19722         touch $DIR/$tdir/subdir/second
19723         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19724                 error "bad pattern in sub-directory"
19725         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19726                 error "bad stripe count in sub-directory"
19727         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19728                 error "bad stripe size in sub-directory"
19729         return 0
19730 }
19731 run_test 270c "DoM: DoM EA inheritance tests"
19732
19733 test_270d() {
19734         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19735                 skip "Need MDS version at least 2.10.55"
19736
19737         mkdir -p $DIR/$tdir
19738         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19739
19740         # inherit default DoM striping
19741         mkdir $DIR/$tdir/subdir
19742         touch $DIR/$tdir/subdir/f1
19743
19744         # change default directory striping
19745         $LFS setstripe -c 1 $DIR/$tdir/subdir
19746         touch $DIR/$tdir/subdir/f2
19747         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19748                 error "wrong default striping in file 2"
19749         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19750                 error "bad pattern in file 2"
19751         return 0
19752 }
19753 run_test 270d "DoM: change striping from DoM to RAID0"
19754
19755 test_270e() {
19756         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19757                 skip "Need MDS version at least 2.10.55"
19758
19759         mkdir -p $DIR/$tdir/dom
19760         mkdir -p $DIR/$tdir/norm
19761         DOMFILES=20
19762         NORMFILES=10
19763         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19764         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19765
19766         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19767         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19768
19769         # find DoM files by layout
19770         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19771         [ $NUM -eq  $DOMFILES ] ||
19772                 error "lfs find -L: found $NUM, expected $DOMFILES"
19773         echo "Test 1: lfs find 20 DOM files by layout: OK"
19774
19775         # there should be 1 dir with default DOM striping
19776         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19777         [ $NUM -eq  1 ] ||
19778                 error "lfs find -L: found $NUM, expected 1 dir"
19779         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19780
19781         # find DoM files by stripe size
19782         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19783         [ $NUM -eq  $DOMFILES ] ||
19784                 error "lfs find -S: found $NUM, expected $DOMFILES"
19785         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19786
19787         # find files by stripe offset except DoM files
19788         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19789         [ $NUM -eq  $NORMFILES ] ||
19790                 error "lfs find -i: found $NUM, expected $NORMFILES"
19791         echo "Test 5: lfs find no DOM files by stripe index: OK"
19792         return 0
19793 }
19794 run_test 270e "DoM: lfs find with DoM files test"
19795
19796 test_270f() {
19797         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19798                 skip "Need MDS version at least 2.10.55"
19799
19800         local mdtname=${FSNAME}-MDT0000-mdtlov
19801         local dom=$DIR/$tdir/dom_file
19802         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19803                                                 lod.$mdtname.dom_stripesize)
19804         local dom_limit=131072
19805
19806         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19807         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19808                                                 lod.$mdtname.dom_stripesize)
19809         [ ${dom_limit} -eq ${dom_current} ] ||
19810                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19811
19812         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19813         $LFS setstripe -d $DIR/$tdir
19814         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19815                 error "Can't set directory default striping"
19816
19817         # exceed maximum stripe size
19818         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19819                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19820         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19821                 error "Able to create DoM component size more than LOD limit"
19822
19823         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19824         dom_current=$(do_facet mds1 $LCTL get_param -n \
19825                                                 lod.$mdtname.dom_stripesize)
19826         [ 0 -eq ${dom_current} ] ||
19827                 error "Can't set zero DoM stripe limit"
19828         rm $dom
19829
19830         # attempt to create DoM file on server with disabled DoM should
19831         # remove DoM entry from layout and be succeed
19832         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19833                 error "Can't create DoM file (DoM is disabled)"
19834         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19835                 error "File has DoM component while DoM is disabled"
19836         rm $dom
19837
19838         # attempt to create DoM file with only DoM stripe should return error
19839         $LFS setstripe -E $dom_limit -L mdt $dom &&
19840                 error "Able to create DoM-only file while DoM is disabled"
19841
19842         # too low values to be aligned with smallest stripe size 64K
19843         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19844         dom_current=$(do_facet mds1 $LCTL get_param -n \
19845                                                 lod.$mdtname.dom_stripesize)
19846         [ 30000 -eq ${dom_current} ] &&
19847                 error "Can set too small DoM stripe limit"
19848
19849         # 64K is a minimal stripe size in Lustre, expect limit of that size
19850         [ 65536 -eq ${dom_current} ] ||
19851                 error "Limit is not set to 64K but ${dom_current}"
19852
19853         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19854         dom_current=$(do_facet mds1 $LCTL get_param -n \
19855                                                 lod.$mdtname.dom_stripesize)
19856         echo $dom_current
19857         [ 2147483648 -eq ${dom_current} ] &&
19858                 error "Can set too large DoM stripe limit"
19859
19860         do_facet mds1 $LCTL set_param -n \
19861                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19862         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19863                 error "Can't create DoM component size after limit change"
19864         do_facet mds1 $LCTL set_param -n \
19865                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19866         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19867                 error "Can't create DoM file after limit decrease"
19868         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19869                 error "Can create big DoM component after limit decrease"
19870         touch ${dom}_def ||
19871                 error "Can't create file with old default layout"
19872
19873         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19874         return 0
19875 }
19876 run_test 270f "DoM: maximum DoM stripe size checks"
19877
19878 test_270g() {
19879         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19880                 skip "Need MDS version at least 2.13.52"
19881         local dom=$DIR/$tdir/$tfile
19882
19883         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19884         local lodname=${FSNAME}-MDT0000-mdtlov
19885
19886         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19887         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19888         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19889         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19890
19891         local dom_limit=1024
19892         local dom_threshold="50%"
19893
19894         $LFS setstripe -d $DIR/$tdir
19895         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19896                 error "Can't set directory default striping"
19897
19898         do_facet mds1 $LCTL set_param -n \
19899                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19900         # set 0 threshold and create DOM file to change tunable stripesize
19901         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19902         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19903                 error "Failed to create $dom file"
19904         # now tunable dom_cur_stripesize should reach maximum
19905         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19906                                         lod.${lodname}.dom_stripesize_cur_kb)
19907         [[ $dom_current == $dom_limit ]] ||
19908                 error "Current DOM stripesize is not maximum"
19909         rm $dom
19910
19911         # set threshold for further tests
19912         do_facet mds1 $LCTL set_param -n \
19913                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19914         echo "DOM threshold is $dom_threshold free space"
19915         local dom_def
19916         local dom_set
19917         # Spoof bfree to exceed threshold
19918         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19919         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19920         for spfree in 40 20 0 15 30 55; do
19921                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19922                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19923                         error "Failed to create $dom file"
19924                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19925                                         lod.${lodname}.dom_stripesize_cur_kb)
19926                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19927                 [[ $dom_def != $dom_current ]] ||
19928                         error "Default stripe size was not changed"
19929                 if [[ $spfree > 0 ]] ; then
19930                         dom_set=$($LFS getstripe -S $dom)
19931                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19932                                 error "DOM component size is still old"
19933                 else
19934                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19935                                 error "DoM component is set with no free space"
19936                 fi
19937                 rm $dom
19938                 dom_current=$dom_def
19939         done
19940 }
19941 run_test 270g "DoM: default DoM stripe size depends on free space"
19942
19943 test_270h() {
19944         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19945                 skip "Need MDS version at least 2.13.53"
19946
19947         local mdtname=${FSNAME}-MDT0000-mdtlov
19948         local dom=$DIR/$tdir/$tfile
19949         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19950
19951         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
19952         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19953
19954         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19955         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
19956                 error "can't create OST file"
19957         # mirrored file with DOM entry in the second mirror
19958         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
19959                 error "can't create mirror with DoM component"
19960
19961         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19962
19963         # DOM component in the middle and has other enries in the same mirror,
19964         # should succeed but lost DoM component
19965         $LFS setstripe --copy=${dom}_1 $dom ||
19966                 error "Can't create file from OST|DOM mirror layout"
19967         # check new file has no DoM layout after all
19968         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19969                 error "File has DoM component while DoM is disabled"
19970 }
19971 run_test 270h "DoM: DoM stripe removal when disabled on server"
19972
19973 test_271a() {
19974         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19975                 skip "Need MDS version at least 2.10.55"
19976
19977         local dom=$DIR/$tdir/dom
19978
19979         mkdir -p $DIR/$tdir
19980
19981         $LFS setstripe -E 1024K -L mdt $dom
19982
19983         lctl set_param -n mdc.*.stats=clear
19984         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19985         cat $dom > /dev/null
19986         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
19987         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
19988         ls $dom
19989         rm -f $dom
19990 }
19991 run_test 271a "DoM: data is cached for read after write"
19992
19993 test_271b() {
19994         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19995                 skip "Need MDS version at least 2.10.55"
19996
19997         local dom=$DIR/$tdir/dom
19998
19999         mkdir -p $DIR/$tdir
20000
20001         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20002
20003         lctl set_param -n mdc.*.stats=clear
20004         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20005         cancel_lru_locks mdc
20006         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20007         # second stat to check size is cached on client
20008         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20009         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20010         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20011         rm -f $dom
20012 }
20013 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20014
20015 test_271ba() {
20016         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20017                 skip "Need MDS version at least 2.10.55"
20018
20019         local dom=$DIR/$tdir/dom
20020
20021         mkdir -p $DIR/$tdir
20022
20023         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20024
20025         lctl set_param -n mdc.*.stats=clear
20026         lctl set_param -n osc.*.stats=clear
20027         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20028         cancel_lru_locks mdc
20029         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20030         # second stat to check size is cached on client
20031         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20032         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20033         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20034         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20035         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20036         rm -f $dom
20037 }
20038 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20039
20040
20041 get_mdc_stats() {
20042         local mdtidx=$1
20043         local param=$2
20044         local mdt=MDT$(printf %04x $mdtidx)
20045
20046         if [ -z $param ]; then
20047                 lctl get_param -n mdc.*$mdt*.stats
20048         else
20049                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20050         fi
20051 }
20052
20053 test_271c() {
20054         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20055                 skip "Need MDS version at least 2.10.55"
20056
20057         local dom=$DIR/$tdir/dom
20058
20059         mkdir -p $DIR/$tdir
20060
20061         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20062
20063         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20064         local facet=mds$((mdtidx + 1))
20065
20066         cancel_lru_locks mdc
20067         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20068         createmany -o $dom 1000
20069         lctl set_param -n mdc.*.stats=clear
20070         smalliomany -w $dom 1000 200
20071         get_mdc_stats $mdtidx
20072         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20073         # Each file has 1 open, 1 IO enqueues, total 2000
20074         # but now we have also +1 getxattr for security.capability, total 3000
20075         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20076         unlinkmany $dom 1000
20077
20078         cancel_lru_locks mdc
20079         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20080         createmany -o $dom 1000
20081         lctl set_param -n mdc.*.stats=clear
20082         smalliomany -w $dom 1000 200
20083         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20084         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20085         # for OPEN and IO lock.
20086         [ $((enq - enq_2)) -ge 1000 ] ||
20087                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20088         unlinkmany $dom 1000
20089         return 0
20090 }
20091 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20092
20093 cleanup_271def_tests() {
20094         trap 0
20095         rm -f $1
20096 }
20097
20098 test_271d() {
20099         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20100                 skip "Need MDS version at least 2.10.57"
20101
20102         local dom=$DIR/$tdir/dom
20103         local tmp=$TMP/$tfile
20104         trap "cleanup_271def_tests $tmp" EXIT
20105
20106         mkdir -p $DIR/$tdir
20107
20108         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20109
20110         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20111
20112         cancel_lru_locks mdc
20113         dd if=/dev/urandom of=$tmp bs=1000 count=1
20114         dd if=$tmp of=$dom bs=1000 count=1
20115         cancel_lru_locks mdc
20116
20117         cat /etc/hosts >> $tmp
20118         lctl set_param -n mdc.*.stats=clear
20119
20120         # append data to the same file it should update local page
20121         echo "Append to the same page"
20122         cat /etc/hosts >> $dom
20123         local num=$(get_mdc_stats $mdtidx ost_read)
20124         local ra=$(get_mdc_stats $mdtidx req_active)
20125         local rw=$(get_mdc_stats $mdtidx req_waittime)
20126
20127         [ -z $num ] || error "$num READ RPC occured"
20128         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20129         echo "... DONE"
20130
20131         # compare content
20132         cmp $tmp $dom || error "file miscompare"
20133
20134         cancel_lru_locks mdc
20135         lctl set_param -n mdc.*.stats=clear
20136
20137         echo "Open and read file"
20138         cat $dom > /dev/null
20139         local num=$(get_mdc_stats $mdtidx ost_read)
20140         local ra=$(get_mdc_stats $mdtidx req_active)
20141         local rw=$(get_mdc_stats $mdtidx req_waittime)
20142
20143         [ -z $num ] || error "$num READ RPC occured"
20144         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20145         echo "... DONE"
20146
20147         # compare content
20148         cmp $tmp $dom || error "file miscompare"
20149
20150         return 0
20151 }
20152 run_test 271d "DoM: read on open (1K file in reply buffer)"
20153
20154 test_271f() {
20155         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20156                 skip "Need MDS version at least 2.10.57"
20157
20158         local dom=$DIR/$tdir/dom
20159         local tmp=$TMP/$tfile
20160         trap "cleanup_271def_tests $tmp" EXIT
20161
20162         mkdir -p $DIR/$tdir
20163
20164         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20165
20166         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20167
20168         cancel_lru_locks mdc
20169         dd if=/dev/urandom of=$tmp bs=265000 count=1
20170         dd if=$tmp of=$dom bs=265000 count=1
20171         cancel_lru_locks mdc
20172         cat /etc/hosts >> $tmp
20173         lctl set_param -n mdc.*.stats=clear
20174
20175         echo "Append to the same page"
20176         cat /etc/hosts >> $dom
20177         local num=$(get_mdc_stats $mdtidx ost_read)
20178         local ra=$(get_mdc_stats $mdtidx req_active)
20179         local rw=$(get_mdc_stats $mdtidx req_waittime)
20180
20181         [ -z $num ] || error "$num READ RPC occured"
20182         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20183         echo "... DONE"
20184
20185         # compare content
20186         cmp $tmp $dom || error "file miscompare"
20187
20188         cancel_lru_locks mdc
20189         lctl set_param -n mdc.*.stats=clear
20190
20191         echo "Open and read file"
20192         cat $dom > /dev/null
20193         local num=$(get_mdc_stats $mdtidx ost_read)
20194         local ra=$(get_mdc_stats $mdtidx req_active)
20195         local rw=$(get_mdc_stats $mdtidx req_waittime)
20196
20197         [ -z $num ] && num=0
20198         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20199         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20200         echo "... DONE"
20201
20202         # compare content
20203         cmp $tmp $dom || error "file miscompare"
20204
20205         return 0
20206 }
20207 run_test 271f "DoM: read on open (200K file and read tail)"
20208
20209 test_271g() {
20210         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20211                 skip "Skipping due to old client or server version"
20212
20213         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20214         # to get layout
20215         $CHECKSTAT -t file $DIR1/$tfile
20216
20217         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20218         MULTIOP_PID=$!
20219         sleep 1
20220         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20221         $LCTL set_param fail_loc=0x80000314
20222         rm $DIR1/$tfile || error "Unlink fails"
20223         RC=$?
20224         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20225         [ $RC -eq 0 ] || error "Failed write to stale object"
20226 }
20227 run_test 271g "Discard DoM data vs client flush race"
20228
20229 test_272a() {
20230         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20231                 skip "Need MDS version at least 2.11.50"
20232
20233         local dom=$DIR/$tdir/dom
20234         mkdir -p $DIR/$tdir
20235
20236         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20237         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20238                 error "failed to write data into $dom"
20239         local old_md5=$(md5sum $dom)
20240
20241         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20242                 error "failed to migrate to the same DoM component"
20243
20244         local new_md5=$(md5sum $dom)
20245
20246         [ "$old_md5" == "$new_md5" ] ||
20247                 error "md5sum differ: $old_md5, $new_md5"
20248
20249         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20250                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20251 }
20252 run_test 272a "DoM migration: new layout with the same DOM component"
20253
20254 test_272b() {
20255         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20256                 skip "Need MDS version at least 2.11.50"
20257
20258         local dom=$DIR/$tdir/dom
20259         mkdir -p $DIR/$tdir
20260         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20261
20262         local mdtidx=$($LFS getstripe -m $dom)
20263         local mdtname=MDT$(printf %04x $mdtidx)
20264         local facet=mds$((mdtidx + 1))
20265
20266         local mdtfree1=$(do_facet $facet \
20267                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20268         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20269                 error "failed to write data into $dom"
20270         local old_md5=$(md5sum $dom)
20271         cancel_lru_locks mdc
20272         local mdtfree1=$(do_facet $facet \
20273                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20274
20275         $LFS migrate -c2 $dom ||
20276                 error "failed to migrate to the new composite layout"
20277         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20278                 error "MDT stripe was not removed"
20279
20280         cancel_lru_locks mdc
20281         local new_md5=$(md5sum $dom)
20282         [ "$old_md5" == "$new_md5" ] ||
20283                 error "$old_md5 != $new_md5"
20284
20285         # Skip free space checks with ZFS
20286         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20287                 local mdtfree2=$(do_facet $facet \
20288                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20289                 [ $mdtfree2 -gt $mdtfree1 ] ||
20290                         error "MDT space is not freed after migration"
20291         fi
20292         return 0
20293 }
20294 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20295
20296 test_272c() {
20297         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20298                 skip "Need MDS version at least 2.11.50"
20299
20300         local dom=$DIR/$tdir/$tfile
20301         mkdir -p $DIR/$tdir
20302         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20303
20304         local mdtidx=$($LFS getstripe -m $dom)
20305         local mdtname=MDT$(printf %04x $mdtidx)
20306         local facet=mds$((mdtidx + 1))
20307
20308         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20309                 error "failed to write data into $dom"
20310         local old_md5=$(md5sum $dom)
20311         cancel_lru_locks mdc
20312         local mdtfree1=$(do_facet $facet \
20313                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20314
20315         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20316                 error "failed to migrate to the new composite layout"
20317         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20318                 error "MDT stripe was not removed"
20319
20320         cancel_lru_locks mdc
20321         local new_md5=$(md5sum $dom)
20322         [ "$old_md5" == "$new_md5" ] ||
20323                 error "$old_md5 != $new_md5"
20324
20325         # Skip free space checks with ZFS
20326         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20327                 local mdtfree2=$(do_facet $facet \
20328                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20329                 [ $mdtfree2 -gt $mdtfree1 ] ||
20330                         error "MDS space is not freed after migration"
20331         fi
20332         return 0
20333 }
20334 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20335
20336 test_272d() {
20337         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20338                 skip "Need MDS version at least 2.12.55"
20339
20340         local dom=$DIR/$tdir/$tfile
20341         mkdir -p $DIR/$tdir
20342         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20343
20344         local mdtidx=$($LFS getstripe -m $dom)
20345         local mdtname=MDT$(printf %04x $mdtidx)
20346         local facet=mds$((mdtidx + 1))
20347
20348         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20349                 error "failed to write data into $dom"
20350         local old_md5=$(md5sum $dom)
20351         cancel_lru_locks mdc
20352         local mdtfree1=$(do_facet $facet \
20353                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20354
20355         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20356                 error "failed mirroring to the new composite layout"
20357         $LFS mirror resync $dom ||
20358                 error "failed mirror resync"
20359         $LFS mirror split --mirror-id 1 -d $dom ||
20360                 error "failed mirror split"
20361
20362         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20363                 error "MDT stripe was not removed"
20364
20365         cancel_lru_locks mdc
20366         local new_md5=$(md5sum $dom)
20367         [ "$old_md5" == "$new_md5" ] ||
20368                 error "$old_md5 != $new_md5"
20369
20370         # Skip free space checks with ZFS
20371         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20372                 local mdtfree2=$(do_facet $facet \
20373                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20374                 [ $mdtfree2 -gt $mdtfree1 ] ||
20375                         error "MDS space is not freed after DOM mirror deletion"
20376         fi
20377         return 0
20378 }
20379 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20380
20381 test_272e() {
20382         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20383                 skip "Need MDS version at least 2.12.55"
20384
20385         local dom=$DIR/$tdir/$tfile
20386         mkdir -p $DIR/$tdir
20387         $LFS setstripe -c 2 $dom
20388
20389         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20390                 error "failed to write data into $dom"
20391         local old_md5=$(md5sum $dom)
20392         cancel_lru_locks mdc
20393
20394         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20395                 error "failed mirroring to the DOM layout"
20396         $LFS mirror resync $dom ||
20397                 error "failed mirror resync"
20398         $LFS mirror split --mirror-id 1 -d $dom ||
20399                 error "failed mirror split"
20400
20401         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20402                 error "MDT stripe was not removed"
20403
20404         cancel_lru_locks mdc
20405         local new_md5=$(md5sum $dom)
20406         [ "$old_md5" == "$new_md5" ] ||
20407                 error "$old_md5 != $new_md5"
20408
20409         return 0
20410 }
20411 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20412
20413 test_272f() {
20414         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20415                 skip "Need MDS version at least 2.12.55"
20416
20417         local dom=$DIR/$tdir/$tfile
20418         mkdir -p $DIR/$tdir
20419         $LFS setstripe -c 2 $dom
20420
20421         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20422                 error "failed to write data into $dom"
20423         local old_md5=$(md5sum $dom)
20424         cancel_lru_locks mdc
20425
20426         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20427                 error "failed migrating to the DOM file"
20428
20429         cancel_lru_locks mdc
20430         local new_md5=$(md5sum $dom)
20431         [ "$old_md5" != "$new_md5" ] &&
20432                 error "$old_md5 != $new_md5"
20433
20434         return 0
20435 }
20436 run_test 272f "DoM migration: OST-striped file to DOM file"
20437
20438 test_273a() {
20439         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20440                 skip "Need MDS version at least 2.11.50"
20441
20442         # Layout swap cannot be done if either file has DOM component,
20443         # this will never be supported, migration should be used instead
20444
20445         local dom=$DIR/$tdir/$tfile
20446         mkdir -p $DIR/$tdir
20447
20448         $LFS setstripe -c2 ${dom}_plain
20449         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20450         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20451                 error "can swap layout with DoM component"
20452         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20453                 error "can swap layout with DoM component"
20454
20455         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20456         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20457                 error "can swap layout with DoM component"
20458         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20459                 error "can swap layout with DoM component"
20460         return 0
20461 }
20462 run_test 273a "DoM: layout swapping should fail with DOM"
20463
20464 test_275() {
20465         remote_ost_nodsh && skip "remote OST with nodsh"
20466         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20467                 skip "Need OST version >= 2.10.57"
20468
20469         local file=$DIR/$tfile
20470         local oss
20471
20472         oss=$(comma_list $(osts_nodes))
20473
20474         dd if=/dev/urandom of=$file bs=1M count=2 ||
20475                 error "failed to create a file"
20476         cancel_lru_locks osc
20477
20478         #lock 1
20479         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20480                 error "failed to read a file"
20481
20482 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20483         $LCTL set_param fail_loc=0x8000031f
20484
20485         cancel_lru_locks osc &
20486         sleep 1
20487
20488 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20489         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20490         #IO takes another lock, but matches the PENDING one
20491         #and places it to the IO RPC
20492         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20493                 error "failed to read a file with PENDING lock"
20494 }
20495 run_test 275 "Read on a canceled duplicate lock"
20496
20497 test_276() {
20498         remote_ost_nodsh && skip "remote OST with nodsh"
20499         local pid
20500
20501         do_facet ost1 "(while true; do \
20502                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20503                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20504         pid=$!
20505
20506         for LOOP in $(seq 20); do
20507                 stop ost1
20508                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20509         done
20510         kill -9 $pid
20511         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20512                 rm $TMP/sanity_276_pid"
20513 }
20514 run_test 276 "Race between mount and obd_statfs"
20515
20516 test_277() {
20517         $LCTL set_param ldlm.namespaces.*.lru_size=0
20518         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20519         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20520                         grep ^used_mb | awk '{print $2}')
20521         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20522         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20523                 oflag=direct conv=notrunc
20524         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20525                         grep ^used_mb | awk '{print $2}')
20526         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20527 }
20528 run_test 277 "Direct IO shall drop page cache"
20529
20530 test_278() {
20531         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20532         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20533         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20534                 skip "needs the same host for mdt1 mdt2" && return
20535
20536         local pid1
20537         local pid2
20538
20539 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20540         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20541         stop mds2 &
20542         pid2=$!
20543
20544         stop mds1
20545
20546         echo "Starting MDTs"
20547         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20548         wait $pid2
20549 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20550 #will return NULL
20551         do_facet mds2 $LCTL set_param fail_loc=0
20552
20553         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20554         wait_recovery_complete mds2
20555 }
20556 run_test 278 "Race starting MDS between MDTs stop/start"
20557
20558 test_280() {
20559         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20560                 skip "Need MGS version at least 2.13.52"
20561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20562         combined_mgs_mds || skip "needs combined MGS/MDT"
20563
20564         umount_client $MOUNT
20565 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20566         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20567
20568         mount_client $MOUNT &
20569         sleep 1
20570         stop mgs || error "stop mgs failed"
20571         #for a race mgs would crash
20572         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20573         mount_client $MOUNT || error "mount client failed"
20574 }
20575 run_test 280 "Race between MGS umount and client llog processing"
20576
20577 cleanup_test_300() {
20578         trap 0
20579         umask $SAVE_UMASK
20580 }
20581 test_striped_dir() {
20582         local mdt_index=$1
20583         local stripe_count
20584         local stripe_index
20585
20586         mkdir -p $DIR/$tdir
20587
20588         SAVE_UMASK=$(umask)
20589         trap cleanup_test_300 RETURN EXIT
20590
20591         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20592                                                 $DIR/$tdir/striped_dir ||
20593                 error "set striped dir error"
20594
20595         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20596         [ "$mode" = "755" ] || error "expect 755 got $mode"
20597
20598         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20599                 error "getdirstripe failed"
20600         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20601         if [ "$stripe_count" != "2" ]; then
20602                 error "1:stripe_count is $stripe_count, expect 2"
20603         fi
20604         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20605         if [ "$stripe_count" != "2" ]; then
20606                 error "2:stripe_count is $stripe_count, expect 2"
20607         fi
20608
20609         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20610         if [ "$stripe_index" != "$mdt_index" ]; then
20611                 error "stripe_index is $stripe_index, expect $mdt_index"
20612         fi
20613
20614         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20615                 error "nlink error after create striped dir"
20616
20617         mkdir $DIR/$tdir/striped_dir/a
20618         mkdir $DIR/$tdir/striped_dir/b
20619
20620         stat $DIR/$tdir/striped_dir/a ||
20621                 error "create dir under striped dir failed"
20622         stat $DIR/$tdir/striped_dir/b ||
20623                 error "create dir under striped dir failed"
20624
20625         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20626                 error "nlink error after mkdir"
20627
20628         rmdir $DIR/$tdir/striped_dir/a
20629         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20630                 error "nlink error after rmdir"
20631
20632         rmdir $DIR/$tdir/striped_dir/b
20633         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20634                 error "nlink error after rmdir"
20635
20636         chattr +i $DIR/$tdir/striped_dir
20637         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20638                 error "immutable flags not working under striped dir!"
20639         chattr -i $DIR/$tdir/striped_dir
20640
20641         rmdir $DIR/$tdir/striped_dir ||
20642                 error "rmdir striped dir error"
20643
20644         cleanup_test_300
20645
20646         true
20647 }
20648
20649 test_300a() {
20650         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20651                 skip "skipped for lustre < 2.7.0"
20652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20654
20655         test_striped_dir 0 || error "failed on striped dir on MDT0"
20656         test_striped_dir 1 || error "failed on striped dir on MDT0"
20657 }
20658 run_test 300a "basic striped dir sanity test"
20659
20660 test_300b() {
20661         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20662                 skip "skipped for lustre < 2.7.0"
20663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20664         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20665
20666         local i
20667         local mtime1
20668         local mtime2
20669         local mtime3
20670
20671         test_mkdir $DIR/$tdir || error "mkdir fail"
20672         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20673                 error "set striped dir error"
20674         for i in {0..9}; do
20675                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20676                 sleep 1
20677                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20678                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20679                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20680                 sleep 1
20681                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20682                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20683                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20684         done
20685         true
20686 }
20687 run_test 300b "check ctime/mtime for striped dir"
20688
20689 test_300c() {
20690         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20691                 skip "skipped for lustre < 2.7.0"
20692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20693         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20694
20695         local file_count
20696
20697         mkdir -p $DIR/$tdir
20698         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20699                 error "set striped dir error"
20700
20701         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20702                 error "chown striped dir failed"
20703
20704         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20705                 error "create 5k files failed"
20706
20707         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20708
20709         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20710
20711         rm -rf $DIR/$tdir
20712 }
20713 run_test 300c "chown && check ls under striped directory"
20714
20715 test_300d() {
20716         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20717                 skip "skipped for lustre < 2.7.0"
20718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20720
20721         local stripe_count
20722         local file
20723
20724         mkdir -p $DIR/$tdir
20725         $LFS setstripe -c 2 $DIR/$tdir
20726
20727         #local striped directory
20728         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20729                 error "set striped dir error"
20730         #look at the directories for debug purposes
20731         ls -l $DIR/$tdir
20732         $LFS getdirstripe $DIR/$tdir
20733         ls -l $DIR/$tdir/striped_dir
20734         $LFS getdirstripe $DIR/$tdir/striped_dir
20735         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20736                 error "create 10 files failed"
20737
20738         #remote striped directory
20739         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20740                 error "set striped dir error"
20741         #look at the directories for debug purposes
20742         ls -l $DIR/$tdir
20743         $LFS getdirstripe $DIR/$tdir
20744         ls -l $DIR/$tdir/remote_striped_dir
20745         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20746         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20747                 error "create 10 files failed"
20748
20749         for file in $(find $DIR/$tdir); do
20750                 stripe_count=$($LFS getstripe -c $file)
20751                 [ $stripe_count -eq 2 ] ||
20752                         error "wrong stripe $stripe_count for $file"
20753         done
20754
20755         rm -rf $DIR/$tdir
20756 }
20757 run_test 300d "check default stripe under striped directory"
20758
20759 test_300e() {
20760         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20761                 skip "Need MDS version at least 2.7.55"
20762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20764
20765         local stripe_count
20766         local file
20767
20768         mkdir -p $DIR/$tdir
20769
20770         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20771                 error "set striped dir error"
20772
20773         touch $DIR/$tdir/striped_dir/a
20774         touch $DIR/$tdir/striped_dir/b
20775         touch $DIR/$tdir/striped_dir/c
20776
20777         mkdir $DIR/$tdir/striped_dir/dir_a
20778         mkdir $DIR/$tdir/striped_dir/dir_b
20779         mkdir $DIR/$tdir/striped_dir/dir_c
20780
20781         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20782                 error "set striped adir under striped dir error"
20783
20784         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20785                 error "set striped bdir under striped dir error"
20786
20787         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20788                 error "set striped cdir under striped dir error"
20789
20790         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20791                 error "rename dir under striped dir fails"
20792
20793         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20794                 error "rename dir under different stripes fails"
20795
20796         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20797                 error "rename file under striped dir should succeed"
20798
20799         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20800                 error "rename dir under striped dir should succeed"
20801
20802         rm -rf $DIR/$tdir
20803 }
20804 run_test 300e "check rename under striped directory"
20805
20806 test_300f() {
20807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20809         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20810                 skip "Need MDS version at least 2.7.55"
20811
20812         local stripe_count
20813         local file
20814
20815         rm -rf $DIR/$tdir
20816         mkdir -p $DIR/$tdir
20817
20818         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20819                 error "set striped dir error"
20820
20821         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20822                 error "set striped dir error"
20823
20824         touch $DIR/$tdir/striped_dir/a
20825         mkdir $DIR/$tdir/striped_dir/dir_a
20826         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20827                 error "create striped dir under striped dir fails"
20828
20829         touch $DIR/$tdir/striped_dir1/b
20830         mkdir $DIR/$tdir/striped_dir1/dir_b
20831         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20832                 error "create striped dir under striped dir fails"
20833
20834         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20835                 error "rename dir under different striped dir should fail"
20836
20837         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20838                 error "rename striped dir under diff striped dir should fail"
20839
20840         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20841                 error "rename file under diff striped dirs fails"
20842
20843         rm -rf $DIR/$tdir
20844 }
20845 run_test 300f "check rename cross striped directory"
20846
20847 test_300_check_default_striped_dir()
20848 {
20849         local dirname=$1
20850         local default_count=$2
20851         local default_index=$3
20852         local stripe_count
20853         local stripe_index
20854         local dir_stripe_index
20855         local dir
20856
20857         echo "checking $dirname $default_count $default_index"
20858         $LFS setdirstripe -D -c $default_count -i $default_index \
20859                                 -t all_char $DIR/$tdir/$dirname ||
20860                 error "set default stripe on striped dir error"
20861         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20862         [ $stripe_count -eq $default_count ] ||
20863                 error "expect $default_count get $stripe_count for $dirname"
20864
20865         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20866         [ $stripe_index -eq $default_index ] ||
20867                 error "expect $default_index get $stripe_index for $dirname"
20868
20869         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20870                                                 error "create dirs failed"
20871
20872         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20873         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20874         for dir in $(find $DIR/$tdir/$dirname/*); do
20875                 stripe_count=$($LFS getdirstripe -c $dir)
20876                 [ $stripe_count -eq $default_count ] ||
20877                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20878                 error "stripe count $default_count != $stripe_count for $dir"
20879
20880                 stripe_index=$($LFS getdirstripe -i $dir)
20881                 [ $default_index -eq -1 ] ||
20882                         [ $stripe_index -eq $default_index ] ||
20883                         error "$stripe_index != $default_index for $dir"
20884
20885                 #check default stripe
20886                 stripe_count=$($LFS getdirstripe -D -c $dir)
20887                 [ $stripe_count -eq $default_count ] ||
20888                 error "default count $default_count != $stripe_count for $dir"
20889
20890                 stripe_index=$($LFS getdirstripe -D -i $dir)
20891                 [ $stripe_index -eq $default_index ] ||
20892                 error "default index $default_index != $stripe_index for $dir"
20893         done
20894         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20895 }
20896
20897 test_300g() {
20898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20899         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20900                 skip "Need MDS version at least 2.7.55"
20901
20902         local dir
20903         local stripe_count
20904         local stripe_index
20905
20906         mkdir $DIR/$tdir
20907         mkdir $DIR/$tdir/normal_dir
20908
20909         #Checking when client cache stripe index
20910         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20911         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20912                 error "create striped_dir failed"
20913
20914         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20915                 error "create dir0 fails"
20916         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20917         [ $stripe_index -eq 0 ] ||
20918                 error "dir0 expect index 0 got $stripe_index"
20919
20920         mkdir $DIR/$tdir/striped_dir/dir1 ||
20921                 error "create dir1 fails"
20922         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20923         [ $stripe_index -eq 1 ] ||
20924                 error "dir1 expect index 1 got $stripe_index"
20925
20926         #check default stripe count/stripe index
20927         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20928         test_300_check_default_striped_dir normal_dir 1 0
20929         test_300_check_default_striped_dir normal_dir 2 1
20930         test_300_check_default_striped_dir normal_dir 2 -1
20931
20932         #delete default stripe information
20933         echo "delete default stripeEA"
20934         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20935                 error "set default stripe on striped dir error"
20936
20937         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20938         for dir in $(find $DIR/$tdir/normal_dir/*); do
20939                 stripe_count=$($LFS getdirstripe -c $dir)
20940                 [ $stripe_count -eq 0 ] ||
20941                         error "expect 1 get $stripe_count for $dir"
20942                 stripe_index=$($LFS getdirstripe -i $dir)
20943                 [ $stripe_index -eq 0 ] ||
20944                         error "expect 0 get $stripe_index for $dir"
20945         done
20946 }
20947 run_test 300g "check default striped directory for normal directory"
20948
20949 test_300h() {
20950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20951         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20952                 skip "Need MDS version at least 2.7.55"
20953
20954         local dir
20955         local stripe_count
20956
20957         mkdir $DIR/$tdir
20958         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20959                 error "set striped dir error"
20960
20961         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20962         test_300_check_default_striped_dir striped_dir 1 0
20963         test_300_check_default_striped_dir striped_dir 2 1
20964         test_300_check_default_striped_dir striped_dir 2 -1
20965
20966         #delete default stripe information
20967         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20968                 error "set default stripe on striped dir error"
20969
20970         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20971         for dir in $(find $DIR/$tdir/striped_dir/*); do
20972                 stripe_count=$($LFS getdirstripe -c $dir)
20973                 [ $stripe_count -eq 0 ] ||
20974                         error "expect 1 get $stripe_count for $dir"
20975         done
20976 }
20977 run_test 300h "check default striped directory for striped directory"
20978
20979 test_300i() {
20980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20982         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20983                 skip "Need MDS version at least 2.7.55"
20984
20985         local stripe_count
20986         local file
20987
20988         mkdir $DIR/$tdir
20989
20990         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20991                 error "set striped dir error"
20992
20993         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20994                 error "create files under striped dir failed"
20995
20996         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
20997                 error "set striped hashdir error"
20998
20999         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21000                 error "create dir0 under hash dir failed"
21001         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21002                 error "create dir1 under hash dir failed"
21003
21004         # unfortunately, we need to umount to clear dir layout cache for now
21005         # once we fully implement dir layout, we can drop this
21006         umount_client $MOUNT || error "umount failed"
21007         mount_client $MOUNT || error "mount failed"
21008
21009         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21010         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21011         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21012
21013         #set the stripe to be unknown hash type
21014         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21015         $LCTL set_param fail_loc=0x1901
21016         for ((i = 0; i < 10; i++)); do
21017                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21018                         error "stat f-$i failed"
21019                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21020         done
21021
21022         touch $DIR/$tdir/striped_dir/f0 &&
21023                 error "create under striped dir with unknown hash should fail"
21024
21025         $LCTL set_param fail_loc=0
21026
21027         umount_client $MOUNT || error "umount failed"
21028         mount_client $MOUNT || error "mount failed"
21029
21030         return 0
21031 }
21032 run_test 300i "client handle unknown hash type striped directory"
21033
21034 test_300j() {
21035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21037         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21038                 skip "Need MDS version at least 2.7.55"
21039
21040         local stripe_count
21041         local file
21042
21043         mkdir $DIR/$tdir
21044
21045         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21046         $LCTL set_param fail_loc=0x1702
21047         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21048                 error "set striped dir error"
21049
21050         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21051                 error "create files under striped dir failed"
21052
21053         $LCTL set_param fail_loc=0
21054
21055         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21056
21057         return 0
21058 }
21059 run_test 300j "test large update record"
21060
21061 test_300k() {
21062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21063         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21064         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21065                 skip "Need MDS version at least 2.7.55"
21066
21067         # this test needs a huge transaction
21068         local kb
21069         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21070              osd*.$FSNAME-MDT0000.kbytestotal")
21071         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21072
21073         local stripe_count
21074         local file
21075
21076         mkdir $DIR/$tdir
21077
21078         #define OBD_FAIL_LARGE_STRIPE   0x1703
21079         $LCTL set_param fail_loc=0x1703
21080         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21081                 error "set striped dir error"
21082         $LCTL set_param fail_loc=0
21083
21084         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21085                 error "getstripeddir fails"
21086         rm -rf $DIR/$tdir/striped_dir ||
21087                 error "unlink striped dir fails"
21088
21089         return 0
21090 }
21091 run_test 300k "test large striped directory"
21092
21093 test_300l() {
21094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21095         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21096         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21097                 skip "Need MDS version at least 2.7.55"
21098
21099         local stripe_index
21100
21101         test_mkdir -p $DIR/$tdir/striped_dir
21102         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21103                         error "chown $RUNAS_ID failed"
21104         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21105                 error "set default striped dir failed"
21106
21107         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21108         $LCTL set_param fail_loc=0x80000158
21109         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21110
21111         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21112         [ $stripe_index -eq 1 ] ||
21113                 error "expect 1 get $stripe_index for $dir"
21114 }
21115 run_test 300l "non-root user to create dir under striped dir with stale layout"
21116
21117 test_300m() {
21118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21119         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21120         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21121                 skip "Need MDS version at least 2.7.55"
21122
21123         mkdir -p $DIR/$tdir/striped_dir
21124         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21125                 error "set default stripes dir error"
21126
21127         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21128
21129         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21130         [ $stripe_count -eq 0 ] ||
21131                         error "expect 0 get $stripe_count for a"
21132
21133         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21134                 error "set default stripes dir error"
21135
21136         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21137
21138         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21139         [ $stripe_count -eq 0 ] ||
21140                         error "expect 0 get $stripe_count for b"
21141
21142         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21143                 error "set default stripes dir error"
21144
21145         mkdir $DIR/$tdir/striped_dir/c &&
21146                 error "default stripe_index is invalid, mkdir c should fails"
21147
21148         rm -rf $DIR/$tdir || error "rmdir fails"
21149 }
21150 run_test 300m "setstriped directory on single MDT FS"
21151
21152 cleanup_300n() {
21153         local list=$(comma_list $(mdts_nodes))
21154
21155         trap 0
21156         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21157 }
21158
21159 test_300n() {
21160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21161         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21162         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21163                 skip "Need MDS version at least 2.7.55"
21164         remote_mds_nodsh && skip "remote MDS with nodsh"
21165
21166         local stripe_index
21167         local list=$(comma_list $(mdts_nodes))
21168
21169         trap cleanup_300n RETURN EXIT
21170         mkdir -p $DIR/$tdir
21171         chmod 777 $DIR/$tdir
21172         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21173                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21174                 error "create striped dir succeeds with gid=0"
21175
21176         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21177         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21178                 error "create striped dir fails with gid=-1"
21179
21180         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21181         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21182                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21183                 error "set default striped dir succeeds with gid=0"
21184
21185
21186         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21187         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21188                 error "set default striped dir fails with gid=-1"
21189
21190
21191         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21192         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21193                                         error "create test_dir fails"
21194         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21195                                         error "create test_dir1 fails"
21196         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21197                                         error "create test_dir2 fails"
21198         cleanup_300n
21199 }
21200 run_test 300n "non-root user to create dir under striped dir with default EA"
21201
21202 test_300o() {
21203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21204         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21205         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21206                 skip "Need MDS version at least 2.7.55"
21207
21208         local numfree1
21209         local numfree2
21210
21211         mkdir -p $DIR/$tdir
21212
21213         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21214         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21215         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21216                 skip "not enough free inodes $numfree1 $numfree2"
21217         fi
21218
21219         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21220         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21221         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21222                 skip "not enough free space $numfree1 $numfree2"
21223         fi
21224
21225         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21226                 error "setdirstripe fails"
21227
21228         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21229                 error "create dirs fails"
21230
21231         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21232         ls $DIR/$tdir/striped_dir > /dev/null ||
21233                 error "ls striped dir fails"
21234         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21235                 error "unlink big striped dir fails"
21236 }
21237 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21238
21239 test_300p() {
21240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21242         remote_mds_nodsh && skip "remote MDS with nodsh"
21243
21244         mkdir -p $DIR/$tdir
21245
21246         #define OBD_FAIL_OUT_ENOSPC     0x1704
21247         do_facet mds2 lctl set_param fail_loc=0x80001704
21248         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21249                  && error "create striped directory should fail"
21250
21251         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21252
21253         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21254         true
21255 }
21256 run_test 300p "create striped directory without space"
21257
21258 test_300q() {
21259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21261
21262         local fd=$(free_fd)
21263         local cmd="exec $fd<$tdir"
21264         cd $DIR
21265         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21266         eval $cmd
21267         cmd="exec $fd<&-"
21268         trap "eval $cmd" EXIT
21269         cd $tdir || error "cd $tdir fails"
21270         rmdir  ../$tdir || error "rmdir $tdir fails"
21271         mkdir local_dir && error "create dir succeeds"
21272         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21273         eval $cmd
21274         return 0
21275 }
21276 run_test 300q "create remote directory under orphan directory"
21277
21278 test_300r() {
21279         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21280                 skip "Need MDS version at least 2.7.55" && return
21281         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21282
21283         mkdir $DIR/$tdir
21284
21285         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21286                 error "set striped dir error"
21287
21288         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21289                 error "getstripeddir fails"
21290
21291         local stripe_count
21292         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21293                       awk '/lmv_stripe_count:/ { print $2 }')
21294
21295         [ $MDSCOUNT -ne $stripe_count ] &&
21296                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21297
21298         rm -rf $DIR/$tdir/striped_dir ||
21299                 error "unlink striped dir fails"
21300 }
21301 run_test 300r "test -1 striped directory"
21302
21303 prepare_remote_file() {
21304         mkdir $DIR/$tdir/src_dir ||
21305                 error "create remote source failed"
21306
21307         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21308                  error "cp to remote source failed"
21309         touch $DIR/$tdir/src_dir/a
21310
21311         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21312                 error "create remote target dir failed"
21313
21314         touch $DIR/$tdir/tgt_dir/b
21315
21316         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21317                 error "rename dir cross MDT failed!"
21318
21319         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21320                 error "src_child still exists after rename"
21321
21322         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21323                 error "missing file(a) after rename"
21324
21325         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21326                 error "diff after rename"
21327 }
21328
21329 test_310a() {
21330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21332
21333         local remote_file=$DIR/$tdir/tgt_dir/b
21334
21335         mkdir -p $DIR/$tdir
21336
21337         prepare_remote_file || error "prepare remote file failed"
21338
21339         #open-unlink file
21340         $OPENUNLINK $remote_file $remote_file ||
21341                 error "openunlink $remote_file failed"
21342         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21343 }
21344 run_test 310a "open unlink remote file"
21345
21346 test_310b() {
21347         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21349
21350         local remote_file=$DIR/$tdir/tgt_dir/b
21351
21352         mkdir -p $DIR/$tdir
21353
21354         prepare_remote_file || error "prepare remote file failed"
21355
21356         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21357         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21358         $CHECKSTAT -t file $remote_file || error "check file failed"
21359 }
21360 run_test 310b "unlink remote file with multiple links while open"
21361
21362 test_310c() {
21363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21364         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21365
21366         local remote_file=$DIR/$tdir/tgt_dir/b
21367
21368         mkdir -p $DIR/$tdir
21369
21370         prepare_remote_file || error "prepare remote file failed"
21371
21372         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21373         multiop_bg_pause $remote_file O_uc ||
21374                         error "mulitop failed for remote file"
21375         MULTIPID=$!
21376         $MULTIOP $DIR/$tfile Ouc
21377         kill -USR1 $MULTIPID
21378         wait $MULTIPID
21379 }
21380 run_test 310c "open-unlink remote file with multiple links"
21381
21382 #LU-4825
21383 test_311() {
21384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21385         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21386         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21387                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21388         remote_mds_nodsh && skip "remote MDS with nodsh"
21389
21390         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21391         local mdts=$(comma_list $(mdts_nodes))
21392
21393         mkdir -p $DIR/$tdir
21394         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21395         createmany -o $DIR/$tdir/$tfile. 1000
21396
21397         # statfs data is not real time, let's just calculate it
21398         old_iused=$((old_iused + 1000))
21399
21400         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21401                         osp.*OST0000*MDT0000.create_count")
21402         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21403                                 osp.*OST0000*MDT0000.max_create_count")
21404         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21405
21406         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21407         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21408         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21409
21410         unlinkmany $DIR/$tdir/$tfile. 1000
21411
21412         do_nodes $mdts "$LCTL set_param -n \
21413                         osp.*OST0000*.max_create_count=$max_count"
21414         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21415                 do_nodes $mdts "$LCTL set_param -n \
21416                                 osp.*OST0000*.create_count=$count"
21417         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21418                         grep "=0" && error "create_count is zero"
21419
21420         local new_iused
21421         for i in $(seq 120); do
21422                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21423                 # system may be too busy to destroy all objs in time, use
21424                 # a somewhat small value to not fail autotest
21425                 [ $((old_iused - new_iused)) -gt 400 ] && break
21426                 sleep 1
21427         done
21428
21429         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21430         [ $((old_iused - new_iused)) -gt 400 ] ||
21431                 error "objs not destroyed after unlink"
21432 }
21433 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21434
21435 zfs_oid_to_objid()
21436 {
21437         local ost=$1
21438         local objid=$2
21439
21440         local vdevdir=$(dirname $(facet_vdevice $ost))
21441         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21442         local zfs_zapid=$(do_facet $ost $cmd |
21443                           grep -w "/O/0/d$((objid%32))" -C 5 |
21444                           awk '/Object/{getline; print $1}')
21445         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21446                           awk "/$objid = /"'{printf $3}')
21447
21448         echo $zfs_objid
21449 }
21450
21451 zfs_object_blksz() {
21452         local ost=$1
21453         local objid=$2
21454
21455         local vdevdir=$(dirname $(facet_vdevice $ost))
21456         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21457         local blksz=$(do_facet $ost $cmd $objid |
21458                       awk '/dblk/{getline; printf $4}')
21459
21460         case "${blksz: -1}" in
21461                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21462                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21463                 *) ;;
21464         esac
21465
21466         echo $blksz
21467 }
21468
21469 test_312() { # LU-4856
21470         remote_ost_nodsh && skip "remote OST with nodsh"
21471         [ "$ost1_FSTYPE" = "zfs" ] ||
21472                 skip_env "the test only applies to zfs"
21473
21474         local max_blksz=$(do_facet ost1 \
21475                           $ZFS get -p recordsize $(facet_device ost1) |
21476                           awk '!/VALUE/{print $3}')
21477
21478         # to make life a little bit easier
21479         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21480         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21481
21482         local tf=$DIR/$tdir/$tfile
21483         touch $tf
21484         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21485
21486         # Get ZFS object id
21487         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21488         # block size change by sequential overwrite
21489         local bs
21490
21491         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21492                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21493
21494                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21495                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21496         done
21497         rm -f $tf
21498
21499         # block size change by sequential append write
21500         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21501         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21502         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21503         local count
21504
21505         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21506                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21507                         oflag=sync conv=notrunc
21508
21509                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21510                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21511                         error "blksz error, actual $blksz, " \
21512                                 "expected: 2 * $count * $PAGE_SIZE"
21513         done
21514         rm -f $tf
21515
21516         # random write
21517         touch $tf
21518         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21519         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21520
21521         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21522         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21523         [ $blksz -eq $PAGE_SIZE ] ||
21524                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21525
21526         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21527         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21528         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21529
21530         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21531         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21532         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21533 }
21534 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21535
21536 test_313() {
21537         remote_ost_nodsh && skip "remote OST with nodsh"
21538
21539         local file=$DIR/$tfile
21540
21541         rm -f $file
21542         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21543
21544         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21545         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21546         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21547                 error "write should failed"
21548         do_facet ost1 "$LCTL set_param fail_loc=0"
21549         rm -f $file
21550 }
21551 run_test 313 "io should fail after last_rcvd update fail"
21552
21553 test_314() {
21554         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21555
21556         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21557         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21558         rm -f $DIR/$tfile
21559         wait_delete_completed
21560         do_facet ost1 "$LCTL set_param fail_loc=0"
21561 }
21562 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21563
21564 test_315() { # LU-618
21565         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21566
21567         local file=$DIR/$tfile
21568         rm -f $file
21569
21570         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21571                 error "multiop file write failed"
21572         $MULTIOP $file oO_RDONLY:r4063232_c &
21573         PID=$!
21574
21575         sleep 2
21576
21577         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21578         kill -USR1 $PID
21579
21580         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21581         rm -f $file
21582 }
21583 run_test 315 "read should be accounted"
21584
21585 test_316() {
21586         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21587         large_xattr_enabled || skip_env "ea_inode feature disabled"
21588
21589         rm -rf $DIR/$tdir/d
21590         mkdir -p $DIR/$tdir/d
21591         chown nobody $DIR/$tdir/d
21592         touch $DIR/$tdir/d/file
21593
21594         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21595 }
21596 run_test 316 "lfs mv"
21597
21598 test_317() {
21599         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21600                 skip "Need MDS version at least 2.11.53"
21601         if [ "$ost1_FSTYPE" == "zfs" ]; then
21602                 skip "LU-10370: no implementation for ZFS"
21603         fi
21604
21605         local trunc_sz
21606         local grant_blk_size
21607
21608         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21609                         awk '/grant_block_size:/ { print $2; exit; }')
21610         #
21611         # Create File of size 5M. Truncate it to below size's and verify
21612         # blocks count.
21613         #
21614         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21615                 error "Create file $DIR/$tfile failed"
21616         stack_trap "rm -f $DIR/$tfile" EXIT
21617
21618         for trunc_sz in 2097152 4097 4000 509 0; do
21619                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21620                         error "truncate $tfile to $trunc_sz failed"
21621                 local sz=$(stat --format=%s $DIR/$tfile)
21622                 local blk=$(stat --format=%b $DIR/$tfile)
21623                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21624                                      grant_blk_size) * 8))
21625
21626                 if [[ $blk -ne $trunc_blk ]]; then
21627                         $(which stat) $DIR/$tfile
21628                         error "Expected Block $trunc_blk got $blk for $tfile"
21629                 fi
21630
21631                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21632                         error "Expected Size $trunc_sz got $sz for $tfile"
21633         done
21634
21635         #
21636         # sparse file test
21637         # Create file with a hole and write actual two blocks. Block count
21638         # must be 16.
21639         #
21640         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21641                 conv=fsync || error "Create file : $DIR/$tfile"
21642
21643         # Calculate the final truncate size.
21644         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21645
21646         #
21647         # truncate to size $trunc_sz bytes. Strip the last block
21648         # The block count must drop to 8
21649         #
21650         $TRUNCATE $DIR/$tfile $trunc_sz ||
21651                 error "truncate $tfile to $trunc_sz failed"
21652
21653         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21654         sz=$(stat --format=%s $DIR/$tfile)
21655         blk=$(stat --format=%b $DIR/$tfile)
21656
21657         if [[ $blk -ne $trunc_bsz ]]; then
21658                 $(which stat) $DIR/$tfile
21659                 error "Expected Block $trunc_bsz got $blk for $tfile"
21660         fi
21661
21662         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21663                 error "Expected Size $trunc_sz got $sz for $tfile"
21664 }
21665 run_test 317 "Verify blocks get correctly update after truncate"
21666
21667 test_318() {
21668         local old_max_active=$($LCTL get_param -n \
21669                             llite.*.max_read_ahead_async_active 2>/dev/null)
21670
21671         $LCTL set_param llite.*.max_read_ahead_async_active=256
21672         local max_active=$($LCTL get_param -n \
21673                            llite.*.max_read_ahead_async_active 2>/dev/null)
21674         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21675
21676         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21677                 error "set max_read_ahead_async_active should succeed"
21678
21679         $LCTL set_param llite.*.max_read_ahead_async_active=512
21680         max_active=$($LCTL get_param -n \
21681                      llite.*.max_read_ahead_async_active 2>/dev/null)
21682         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21683
21684         # restore @max_active
21685         [ $old_max_active -ne 0 ] && $LCTL set_param \
21686                 llite.*.max_read_ahead_async_active=$old_max_active
21687
21688         local old_threshold=$($LCTL get_param -n \
21689                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21690         local max_per_file_mb=$($LCTL get_param -n \
21691                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21692
21693         local invalid=$(($max_per_file_mb + 1))
21694         $LCTL set_param \
21695                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21696                         && error "set $invalid should fail"
21697
21698         local valid=$(($invalid - 1))
21699         $LCTL set_param \
21700                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21701                         error "set $valid should succeed"
21702         local threshold=$($LCTL get_param -n \
21703                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21704         [ $threshold -eq $valid ] || error \
21705                 "expect threshold $valid got $threshold"
21706         $LCTL set_param \
21707                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21708 }
21709 run_test 318 "Verify async readahead tunables"
21710
21711 test_319() {
21712         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21713
21714         local before=$(date +%s)
21715         local evict
21716         local mdir=$DIR/$tdir
21717         local file=$mdir/xxx
21718
21719         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21720         touch $file
21721
21722 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21723         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21724         $LFS mv -m1 $file &
21725
21726         sleep 1
21727         dd if=$file of=/dev/null
21728         wait
21729         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21730           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21731
21732         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21733 }
21734 run_test 319 "lost lease lock on migrate error"
21735
21736 test_398a() { # LU-4198
21737         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21738         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21739
21740         # request a new lock on client
21741         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21742
21743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21744         local lock_count=$($LCTL get_param -n \
21745                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21746         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21747
21748         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21749
21750         # no lock cached, should use lockless IO and not enqueue new lock
21751         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21752         lock_count=$($LCTL get_param -n \
21753                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21754         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21755 }
21756 run_test 398a "direct IO should cancel lock otherwise lockless"
21757
21758 test_398b() { # LU-4198
21759         which fio || skip_env "no fio installed"
21760         $LFS setstripe -c -1 $DIR/$tfile
21761
21762         local size=12
21763         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21764
21765         local njobs=4
21766         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21767         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21768                 --numjobs=$njobs --fallocate=none \
21769                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21770                 --filename=$DIR/$tfile &
21771         bg_pid=$!
21772
21773         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21774         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21775                 --numjobs=$njobs --fallocate=none \
21776                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21777                 --filename=$DIR/$tfile || true
21778         wait $bg_pid
21779
21780         rm -rf $DIR/$tfile
21781 }
21782 run_test 398b "DIO and buffer IO race"
21783
21784 test_398c() { # LU-4198
21785         which fio || skip_env "no fio installed"
21786
21787         saved_debug=$($LCTL get_param -n debug)
21788         $LCTL set_param debug=0
21789
21790         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21791         ((size /= 1024)) # by megabytes
21792         ((size /= 2)) # write half of the OST at most
21793         [ $size -gt 40 ] && size=40 #reduce test time anyway
21794
21795         $LFS setstripe -c 1 $DIR/$tfile
21796
21797         # it seems like ldiskfs reserves more space than necessary if the
21798         # writing blocks are not mapped, so it extends the file firstly
21799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21800         cancel_lru_locks osc
21801
21802         # clear and verify rpc_stats later
21803         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21804
21805         local njobs=4
21806         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21807         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21808                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21809                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21810                 --filename=$DIR/$tfile
21811         [ $? -eq 0 ] || error "fio write error"
21812
21813         [ $($LCTL get_param -n \
21814          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21815                 error "Locks were requested while doing AIO"
21816
21817         # get the percentage of 1-page I/O
21818         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21819                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21820                 awk '{print $7}')
21821         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21822
21823         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21824         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21825                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21826                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21827                 --filename=$DIR/$tfile
21828         [ $? -eq 0 ] || error "fio mixed read write error"
21829
21830         rm -rf $DIR/$tfile
21831         $LCTL set_param debug="$saved_debug"
21832 }
21833 run_test 398c "run fio to test AIO"
21834
21835 test_fake_rw() {
21836         local read_write=$1
21837         if [ "$read_write" = "write" ]; then
21838                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21839         elif [ "$read_write" = "read" ]; then
21840                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21841         else
21842                 error "argument error"
21843         fi
21844
21845         # turn off debug for performance testing
21846         local saved_debug=$($LCTL get_param -n debug)
21847         $LCTL set_param debug=0
21848
21849         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21850
21851         # get ost1 size - $FSNAME-OST0000
21852         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21853         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21854         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21855
21856         if [ "$read_write" = "read" ]; then
21857                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21858         fi
21859
21860         local start_time=$(date +%s.%N)
21861         $dd_cmd bs=1M count=$blocks oflag=sync ||
21862                 error "real dd $read_write error"
21863         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21864
21865         if [ "$read_write" = "write" ]; then
21866                 rm -f $DIR/$tfile
21867         fi
21868
21869         # define OBD_FAIL_OST_FAKE_RW           0x238
21870         do_facet ost1 $LCTL set_param fail_loc=0x238
21871
21872         local start_time=$(date +%s.%N)
21873         $dd_cmd bs=1M count=$blocks oflag=sync ||
21874                 error "fake dd $read_write error"
21875         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21876
21877         if [ "$read_write" = "write" ]; then
21878                 # verify file size
21879                 cancel_lru_locks osc
21880                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21881                         error "$tfile size not $blocks MB"
21882         fi
21883         do_facet ost1 $LCTL set_param fail_loc=0
21884
21885         echo "fake $read_write $duration_fake vs. normal $read_write" \
21886                 "$duration in seconds"
21887         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21888                 error_not_in_vm "fake write is slower"
21889
21890         $LCTL set_param -n debug="$saved_debug"
21891         rm -f $DIR/$tfile
21892 }
21893 test_399a() { # LU-7655 for OST fake write
21894         remote_ost_nodsh && skip "remote OST with nodsh"
21895
21896         test_fake_rw write
21897 }
21898 run_test 399a "fake write should not be slower than normal write"
21899
21900 test_399b() { # LU-8726 for OST fake read
21901         remote_ost_nodsh && skip "remote OST with nodsh"
21902         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21903                 skip_env "ldiskfs only test"
21904         fi
21905
21906         test_fake_rw read
21907 }
21908 run_test 399b "fake read should not be slower than normal read"
21909
21910 test_400a() { # LU-1606, was conf-sanity test_74
21911         if ! which $CC > /dev/null 2>&1; then
21912                 skip_env "$CC is not installed"
21913         fi
21914
21915         local extra_flags=''
21916         local out=$TMP/$tfile
21917         local prefix=/usr/include/lustre
21918         local prog
21919
21920         # Oleg removes c files in his test rig so test if any c files exist
21921         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21922                 skip_env "Needed c test files are missing"
21923
21924         if ! [[ -d $prefix ]]; then
21925                 # Assume we're running in tree and fixup the include path.
21926                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21927                 extra_flags+=" -L$LUSTRE/utils/.lib"
21928         fi
21929
21930         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21931                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21932                         error "client api broken"
21933         done
21934         rm -f $out
21935 }
21936 run_test 400a "Lustre client api program can compile and link"
21937
21938 test_400b() { # LU-1606, LU-5011
21939         local header
21940         local out=$TMP/$tfile
21941         local prefix=/usr/include/linux/lustre
21942
21943         # We use a hard coded prefix so that this test will not fail
21944         # when run in tree. There are headers in lustre/include/lustre/
21945         # that are not packaged (like lustre_idl.h) and have more
21946         # complicated include dependencies (like config.h and lnet/types.h).
21947         # Since this test about correct packaging we just skip them when
21948         # they don't exist (see below) rather than try to fixup cppflags.
21949
21950         if ! which $CC > /dev/null 2>&1; then
21951                 skip_env "$CC is not installed"
21952         fi
21953
21954         for header in $prefix/*.h; do
21955                 if ! [[ -f "$header" ]]; then
21956                         continue
21957                 fi
21958
21959                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
21960                         continue # lustre_ioctl.h is internal header
21961                 fi
21962
21963                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
21964                         error "cannot compile '$header'"
21965         done
21966         rm -f $out
21967 }
21968 run_test 400b "packaged headers can be compiled"
21969
21970 test_401a() { #LU-7437
21971         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
21972         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
21973
21974         #count the number of parameters by "list_param -R"
21975         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
21976         #count the number of parameters by listing proc files
21977         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
21978         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
21979         echo "proc_dirs='$proc_dirs'"
21980         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
21981         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
21982                       sort -u | wc -l)
21983
21984         [ $params -eq $procs ] ||
21985                 error "found $params parameters vs. $procs proc files"
21986
21987         # test the list_param -D option only returns directories
21988         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
21989         #count the number of parameters by listing proc directories
21990         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
21991                 sort -u | wc -l)
21992
21993         [ $params -eq $procs ] ||
21994                 error "found $params parameters vs. $procs proc files"
21995 }
21996 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
21997
21998 test_401b() {
21999         local save=$($LCTL get_param -n jobid_var)
22000         local tmp=testing
22001
22002         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22003                 error "no error returned when setting bad parameters"
22004
22005         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22006         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22007
22008         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22009         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22010         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22011 }
22012 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22013
22014 test_401c() {
22015         local jobid_var_old=$($LCTL get_param -n jobid_var)
22016         local jobid_var_new
22017
22018         $LCTL set_param jobid_var= &&
22019                 error "no error returned for 'set_param a='"
22020
22021         jobid_var_new=$($LCTL get_param -n jobid_var)
22022         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22023                 error "jobid_var was changed by setting without value"
22024
22025         $LCTL set_param jobid_var &&
22026                 error "no error returned for 'set_param a'"
22027
22028         jobid_var_new=$($LCTL get_param -n jobid_var)
22029         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22030                 error "jobid_var was changed by setting without value"
22031 }
22032 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22033
22034 test_401d() {
22035         local jobid_var_old=$($LCTL get_param -n jobid_var)
22036         local jobid_var_new
22037         local new_value="foo=bar"
22038
22039         $LCTL set_param jobid_var=$new_value ||
22040                 error "'set_param a=b' did not accept a value containing '='"
22041
22042         jobid_var_new=$($LCTL get_param -n jobid_var)
22043         [[ "$jobid_var_new" == "$new_value" ]] ||
22044                 error "'set_param a=b' failed on a value containing '='"
22045
22046         # Reset the jobid_var to test the other format
22047         $LCTL set_param jobid_var=$jobid_var_old
22048         jobid_var_new=$($LCTL get_param -n jobid_var)
22049         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22050                 error "failed to reset jobid_var"
22051
22052         $LCTL set_param jobid_var $new_value ||
22053                 error "'set_param a b' did not accept a value containing '='"
22054
22055         jobid_var_new=$($LCTL get_param -n jobid_var)
22056         [[ "$jobid_var_new" == "$new_value" ]] ||
22057                 error "'set_param a b' failed on a value containing '='"
22058
22059         $LCTL set_param jobid_var $jobid_var_old
22060         jobid_var_new=$($LCTL get_param -n jobid_var)
22061         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22062                 error "failed to reset jobid_var"
22063 }
22064 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22065
22066 test_402() {
22067         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22068         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22069                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22070         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22071                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22072                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22073         remote_mds_nodsh && skip "remote MDS with nodsh"
22074
22075         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22076 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22077         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22078         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22079                 echo "Touch failed - OK"
22080 }
22081 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22082
22083 test_403() {
22084         local file1=$DIR/$tfile.1
22085         local file2=$DIR/$tfile.2
22086         local tfile=$TMP/$tfile
22087
22088         rm -f $file1 $file2 $tfile
22089
22090         touch $file1
22091         ln $file1 $file2
22092
22093         # 30 sec OBD_TIMEOUT in ll_getattr()
22094         # right before populating st_nlink
22095         $LCTL set_param fail_loc=0x80001409
22096         stat -c %h $file1 > $tfile &
22097
22098         # create an alias, drop all locks and reclaim the dentry
22099         < $file2
22100         cancel_lru_locks mdc
22101         cancel_lru_locks osc
22102         sysctl -w vm.drop_caches=2
22103
22104         wait
22105
22106         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22107
22108         rm -f $tfile $file1 $file2
22109 }
22110 run_test 403 "i_nlink should not drop to zero due to aliasing"
22111
22112 test_404() { # LU-6601
22113         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22114                 skip "Need server version newer than 2.8.52"
22115         remote_mds_nodsh && skip "remote MDS with nodsh"
22116
22117         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22118                 awk '/osp .*-osc-MDT/ { print $4}')
22119
22120         local osp
22121         for osp in $mosps; do
22122                 echo "Deactivate: " $osp
22123                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22124                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22125                         awk -vp=$osp '$4 == p { print $2 }')
22126                 [ $stat = IN ] || {
22127                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22128                         error "deactivate error"
22129                 }
22130                 echo "Activate: " $osp
22131                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22132                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22133                         awk -vp=$osp '$4 == p { print $2 }')
22134                 [ $stat = UP ] || {
22135                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22136                         error "activate error"
22137                 }
22138         done
22139 }
22140 run_test 404 "validate manual {de}activated works properly for OSPs"
22141
22142 test_405() {
22143         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22144         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22145                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22146                         skip "Layout swap lock is not supported"
22147
22148         check_swap_layouts_support
22149
22150         test_mkdir $DIR/$tdir
22151         swap_lock_test -d $DIR/$tdir ||
22152                 error "One layout swap locked test failed"
22153 }
22154 run_test 405 "Various layout swap lock tests"
22155
22156 test_406() {
22157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22158         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22159         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22161         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22162                 skip "Need MDS version at least 2.8.50"
22163
22164         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22165         local test_pool=$TESTNAME
22166
22167         pool_add $test_pool || error "pool_add failed"
22168         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22169                 error "pool_add_targets failed"
22170
22171         save_layout_restore_at_exit $MOUNT
22172
22173         # parent set default stripe count only, child will stripe from both
22174         # parent and fs default
22175         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22176                 error "setstripe $MOUNT failed"
22177         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22178         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22179         for i in $(seq 10); do
22180                 local f=$DIR/$tdir/$tfile.$i
22181                 touch $f || error "touch failed"
22182                 local count=$($LFS getstripe -c $f)
22183                 [ $count -eq $OSTCOUNT ] ||
22184                         error "$f stripe count $count != $OSTCOUNT"
22185                 local offset=$($LFS getstripe -i $f)
22186                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22187                 local size=$($LFS getstripe -S $f)
22188                 [ $size -eq $((def_stripe_size * 2)) ] ||
22189                         error "$f stripe size $size != $((def_stripe_size * 2))"
22190                 local pool=$($LFS getstripe -p $f)
22191                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22192         done
22193
22194         # change fs default striping, delete parent default striping, now child
22195         # will stripe from new fs default striping only
22196         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22197                 error "change $MOUNT default stripe failed"
22198         $LFS setstripe -c 0 $DIR/$tdir ||
22199                 error "delete $tdir default stripe failed"
22200         for i in $(seq 11 20); do
22201                 local f=$DIR/$tdir/$tfile.$i
22202                 touch $f || error "touch $f failed"
22203                 local count=$($LFS getstripe -c $f)
22204                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22205                 local offset=$($LFS getstripe -i $f)
22206                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22207                 local size=$($LFS getstripe -S $f)
22208                 [ $size -eq $def_stripe_size ] ||
22209                         error "$f stripe size $size != $def_stripe_size"
22210                 local pool=$($LFS getstripe -p $f)
22211                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22212         done
22213
22214         unlinkmany $DIR/$tdir/$tfile. 1 20
22215
22216         local f=$DIR/$tdir/$tfile
22217         pool_remove_all_targets $test_pool $f
22218         pool_remove $test_pool $f
22219 }
22220 run_test 406 "DNE support fs default striping"
22221
22222 test_407() {
22223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22224         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22225                 skip "Need MDS version at least 2.8.55"
22226         remote_mds_nodsh && skip "remote MDS with nodsh"
22227
22228         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22229                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22230         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22231                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22232         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22233
22234         #define OBD_FAIL_DT_TXN_STOP    0x2019
22235         for idx in $(seq $MDSCOUNT); do
22236                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22237         done
22238         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22239         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22240                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22241         true
22242 }
22243 run_test 407 "transaction fail should cause operation fail"
22244
22245 test_408() {
22246         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22247
22248         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22249         lctl set_param fail_loc=0x8000040a
22250         # let ll_prepare_partial_page() fail
22251         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22252
22253         rm -f $DIR/$tfile
22254
22255         # create at least 100 unused inodes so that
22256         # shrink_icache_memory(0) should not return 0
22257         touch $DIR/$tfile-{0..100}
22258         rm -f $DIR/$tfile-{0..100}
22259         sync
22260
22261         echo 2 > /proc/sys/vm/drop_caches
22262 }
22263 run_test 408 "drop_caches should not hang due to page leaks"
22264
22265 test_409()
22266 {
22267         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22268
22269         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22270         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22271         touch $DIR/$tdir/guard || error "(2) Fail to create"
22272
22273         local PREFIX=$(str_repeat 'A' 128)
22274         echo "Create 1K hard links start at $(date)"
22275         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22276                 error "(3) Fail to hard link"
22277
22278         echo "Links count should be right although linkEA overflow"
22279         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22280         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22281         [ $linkcount -eq 1001 ] ||
22282                 error "(5) Unexpected hard links count: $linkcount"
22283
22284         echo "List all links start at $(date)"
22285         ls -l $DIR/$tdir/foo > /dev/null ||
22286                 error "(6) Fail to list $DIR/$tdir/foo"
22287
22288         echo "Unlink hard links start at $(date)"
22289         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22290                 error "(7) Fail to unlink"
22291         echo "Unlink hard links finished at $(date)"
22292 }
22293 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22294
22295 test_410()
22296 {
22297         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22298                 skip "Need client version at least 2.9.59"
22299
22300         # Create a file, and stat it from the kernel
22301         local testfile=$DIR/$tfile
22302         touch $testfile
22303
22304         local run_id=$RANDOM
22305         local my_ino=$(stat --format "%i" $testfile)
22306
22307         # Try to insert the module. This will always fail as the
22308         # module is designed to not be inserted.
22309         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22310             &> /dev/null
22311
22312         # Anything but success is a test failure
22313         dmesg | grep -q \
22314             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22315             error "no inode match"
22316 }
22317 run_test 410 "Test inode number returned from kernel thread"
22318
22319 cleanup_test411_cgroup() {
22320         trap 0
22321         rmdir "$1"
22322 }
22323
22324 test_411() {
22325         local cg_basedir=/sys/fs/cgroup/memory
22326         # LU-9966
22327         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22328                 skip "no setup for cgroup"
22329
22330         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22331                 error "test file creation failed"
22332         cancel_lru_locks osc
22333
22334         # Create a very small memory cgroup to force a slab allocation error
22335         local cgdir=$cg_basedir/osc_slab_alloc
22336         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22337         trap "cleanup_test411_cgroup $cgdir" EXIT
22338         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22339         echo 1M > $cgdir/memory.limit_in_bytes
22340
22341         # Should not LBUG, just be killed by oom-killer
22342         # dd will return 0 even allocation failure in some environment.
22343         # So don't check return value
22344         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22345         cleanup_test411_cgroup $cgdir
22346
22347         return 0
22348 }
22349 run_test 411 "Slab allocation error with cgroup does not LBUG"
22350
22351 test_412() {
22352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22353         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22354                 skip "Need server version at least 2.10.55"
22355         fi
22356
22357         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22358                 error "mkdir failed"
22359         $LFS getdirstripe $DIR/$tdir
22360         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22361         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22362                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22363         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22364         [ $stripe_count -eq 2 ] ||
22365                 error "expect 2 get $stripe_count"
22366 }
22367 run_test 412 "mkdir on specific MDTs"
22368
22369 test_qos_mkdir() {
22370         local mkdir_cmd=$1
22371         local stripe_count=$2
22372         local mdts=$(comma_list $(mdts_nodes))
22373
22374         local testdir
22375         local lmv_qos_prio_free
22376         local lmv_qos_threshold_rr
22377         local lmv_qos_maxage
22378         local lod_qos_prio_free
22379         local lod_qos_threshold_rr
22380         local lod_qos_maxage
22381         local count
22382         local i
22383
22384         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22385         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22386         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22387                 head -n1)
22388         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22389         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22390         stack_trap "$LCTL set_param \
22391                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22392         stack_trap "$LCTL set_param \
22393                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22394         stack_trap "$LCTL set_param \
22395                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22396
22397         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22398                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22399         lod_qos_prio_free=${lod_qos_prio_free%%%}
22400         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22401                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22402         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22403         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22404                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22405         stack_trap "do_nodes $mdts $LCTL set_param \
22406                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22407         stack_trap "do_nodes $mdts $LCTL set_param \
22408                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22409                 EXIT
22410         stack_trap "do_nodes $mdts $LCTL set_param \
22411                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22412
22413         echo
22414         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22415
22416         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22417         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22418
22419         testdir=$DIR/$tdir-s$stripe_count/rr
22420
22421         for i in $(seq $((100 * MDSCOUNT))); do
22422                 eval $mkdir_cmd $testdir/subdir$i ||
22423                         error "$mkdir_cmd subdir$i failed"
22424         done
22425
22426         for i in $(seq $MDSCOUNT); do
22427                 count=$($LFS getdirstripe -i $testdir/* |
22428                                 grep ^$((i - 1))$ | wc -l)
22429                 echo "$count directories created on MDT$((i - 1))"
22430                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22431
22432                 if [ $stripe_count -gt 1 ]; then
22433                         count=$($LFS getdirstripe $testdir/* |
22434                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22435                         echo "$count stripes created on MDT$((i - 1))"
22436                         # deviation should < 5% of average
22437                         [ $count -lt $((95 * stripe_count)) ] ||
22438                         [ $count -gt $((105 * stripe_count)) ] &&
22439                                 error "stripes are not evenly distributed"
22440                 fi
22441         done
22442
22443         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22444         do_nodes $mdts $LCTL set_param \
22445                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22446
22447         echo
22448         echo "Check for uneven MDTs: "
22449
22450         local ffree
22451         local bavail
22452         local max
22453         local min
22454         local max_index
22455         local min_index
22456         local tmp
22457
22458         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22459         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22460         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22461
22462         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22463         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22464         max_index=0
22465         min_index=0
22466         for ((i = 1; i < ${#ffree[@]}; i++)); do
22467                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22468                 if [ $tmp -gt $max ]; then
22469                         max=$tmp
22470                         max_index=$i
22471                 fi
22472                 if [ $tmp -lt $min ]; then
22473                         min=$tmp
22474                         min_index=$i
22475                 fi
22476         done
22477
22478         [ ${ffree[min_index]} -eq 0 ] &&
22479                 skip "no free files in MDT$min_index"
22480         [ ${ffree[min_index]} -gt 100000000 ] &&
22481                 skip "too much free files in MDT$min_index"
22482
22483         # Check if we need to generate uneven MDTs
22484         local threshold=50
22485         local diff=$(((max - min) * 100 / min))
22486         local value="$(generate_string 1024)"
22487
22488         while [ $diff -lt $threshold ]; do
22489                 # generate uneven MDTs, create till $threshold% diff
22490                 echo -n "weight diff=$diff% must be > $threshold% ..."
22491                 count=$((${ffree[min_index]} / 10))
22492                 # 50 sec per 10000 files in vm
22493                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22494                         skip "$count files to create"
22495                 echo "Fill MDT$min_index with $count files"
22496                 [ -d $DIR/$tdir-MDT$min_index ] ||
22497                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22498                         error "mkdir $tdir-MDT$min_index failed"
22499                 for i in $(seq $count); do
22500                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22501                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22502                                 error "create f$j_$i failed"
22503                         setfattr -n user.413b -v $value \
22504                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22505                                 error "setfattr f$j_$i failed"
22506                 done
22507
22508                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22509                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22510                 max=$(((${ffree[max_index]} >> 8) * \
22511                         (${bavail[max_index]} * bsize >> 16)))
22512                 min=$(((${ffree[min_index]} >> 8) * \
22513                         (${bavail[min_index]} * bsize >> 16)))
22514                 diff=$(((max - min) * 100 / min))
22515         done
22516
22517         echo "MDT filesfree available: ${ffree[@]}"
22518         echo "MDT blocks available: ${bavail[@]}"
22519         echo "weight diff=$diff%"
22520
22521         echo
22522         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22523
22524         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22525         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22526         # decrease statfs age, so that it can be updated in time
22527         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22528         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22529
22530         sleep 1
22531
22532         testdir=$DIR/$tdir-s$stripe_count/qos
22533
22534         for i in $(seq $((100 * MDSCOUNT))); do
22535                 eval $mkdir_cmd $testdir/subdir$i ||
22536                         error "$mkdir_cmd subdir$i failed"
22537         done
22538
22539         for i in $(seq $MDSCOUNT); do
22540                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22541                         wc -l)
22542                 echo "$count directories created on MDT$((i - 1))"
22543
22544                 if [ $stripe_count -gt 1 ]; then
22545                         count=$($LFS getdirstripe $testdir/* |
22546                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22547                         echo "$count stripes created on MDT$((i - 1))"
22548                 fi
22549         done
22550
22551         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22552         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22553
22554         # D-value should > 10% of averge
22555         [ $((max - min)) -lt 10 ] &&
22556                 error "subdirs shouldn't be evenly distributed"
22557
22558         # ditto
22559         if [ $stripe_count -gt 1 ]; then
22560                 max=$($LFS getdirstripe $testdir/* |
22561                         grep -P "^\s+$max_index\t" | wc -l)
22562                 min=$($LFS getdirstripe $testdir/* |
22563                         grep -P "^\s+$min_index\t" | wc -l)
22564                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22565                         error "stripes shouldn't be evenly distributed"|| true
22566         fi
22567 }
22568
22569 test_413a() {
22570         [ $MDSCOUNT -lt 2 ] &&
22571                 skip "We need at least 2 MDTs for this test"
22572
22573         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22574                 skip "Need server version at least 2.12.52"
22575
22576         local stripe_count
22577
22578         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22579                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22580                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22581                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22582                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22583         done
22584 }
22585 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22586
22587 test_413b() {
22588         [ $MDSCOUNT -lt 2 ] &&
22589                 skip "We need at least 2 MDTs for this test"
22590
22591         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22592                 skip "Need server version at least 2.12.52"
22593
22594         local stripe_count
22595
22596         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22597                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22598                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22599                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22600                 $LFS setdirstripe -D -c $stripe_count \
22601                         $DIR/$tdir-s$stripe_count/rr ||
22602                         error "setdirstripe failed"
22603                 $LFS setdirstripe -D -c $stripe_count \
22604                         $DIR/$tdir-s$stripe_count/qos ||
22605                         error "setdirstripe failed"
22606                 test_qos_mkdir "mkdir" $stripe_count
22607         done
22608 }
22609 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22610
22611 test_414() {
22612 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22613         $LCTL set_param fail_loc=0x80000521
22614         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22615         rm -f $DIR/$tfile
22616 }
22617 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22618
22619 test_415() {
22620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22621         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22622                 skip "Need server version at least 2.11.52"
22623
22624         # LU-11102
22625         local total
22626         local setattr_pid
22627         local start_time
22628         local end_time
22629         local duration
22630
22631         total=500
22632         # this test may be slow on ZFS
22633         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22634
22635         # though this test is designed for striped directory, let's test normal
22636         # directory too since lock is always saved as CoS lock.
22637         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22638         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22639
22640         (
22641                 while true; do
22642                         touch $DIR/$tdir
22643                 done
22644         ) &
22645         setattr_pid=$!
22646
22647         start_time=$(date +%s)
22648         for i in $(seq $total); do
22649                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22650                         > /dev/null
22651         done
22652         end_time=$(date +%s)
22653         duration=$((end_time - start_time))
22654
22655         kill -9 $setattr_pid
22656
22657         echo "rename $total files took $duration sec"
22658         [ $duration -lt 100 ] || error "rename took $duration sec"
22659 }
22660 run_test 415 "lock revoke is not missing"
22661
22662 test_416() {
22663         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22664                 skip "Need server version at least 2.11.55"
22665
22666         # define OBD_FAIL_OSD_TXN_START    0x19a
22667         do_facet mds1 lctl set_param fail_loc=0x19a
22668
22669         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22670
22671         true
22672 }
22673 run_test 416 "transaction start failure won't cause system hung"
22674
22675 cleanup_417() {
22676         trap 0
22677         do_nodes $(comma_list $(mdts_nodes)) \
22678                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22679         do_nodes $(comma_list $(mdts_nodes)) \
22680                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22681         do_nodes $(comma_list $(mdts_nodes)) \
22682                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22683 }
22684
22685 test_417() {
22686         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22687         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22688                 skip "Need MDS version at least 2.11.56"
22689
22690         trap cleanup_417 RETURN EXIT
22691
22692         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22693         do_nodes $(comma_list $(mdts_nodes)) \
22694                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22695         $LFS migrate -m 0 $DIR/$tdir.1 &&
22696                 error "migrate dir $tdir.1 should fail"
22697
22698         do_nodes $(comma_list $(mdts_nodes)) \
22699                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22700         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22701                 error "create remote dir $tdir.2 should fail"
22702
22703         do_nodes $(comma_list $(mdts_nodes)) \
22704                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22705         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22706                 error "create striped dir $tdir.3 should fail"
22707         true
22708 }
22709 run_test 417 "disable remote dir, striped dir and dir migration"
22710
22711 # Checks that the outputs of df [-i] and lfs df [-i] match
22712 #
22713 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22714 check_lfs_df() {
22715         local dir=$2
22716         local inodes
22717         local df_out
22718         local lfs_df_out
22719         local count
22720         local passed=false
22721
22722         # blocks or inodes
22723         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22724
22725         for count in {1..100}; do
22726                 cancel_lru_locks
22727                 sync; sleep 0.2
22728
22729                 # read the lines of interest
22730                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22731                         error "df $inodes $dir | tail -n +2 failed"
22732                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22733                         error "lfs df $inodes $dir | grep summary: failed"
22734
22735                 # skip first substrings of each output as they are different
22736                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22737                 # compare the two outputs
22738                 passed=true
22739                 for i in {1..5}; do
22740                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22741                 done
22742                 $passed && break
22743         done
22744
22745         if ! $passed; then
22746                 df -P $inodes $dir
22747                 echo
22748                 lfs df $inodes $dir
22749                 error "df and lfs df $1 output mismatch: "      \
22750                       "df ${inodes}: ${df_out[*]}, "            \
22751                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22752         fi
22753 }
22754
22755 test_418() {
22756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22757
22758         local dir=$DIR/$tdir
22759         local numfiles=$((RANDOM % 4096 + 2))
22760         local numblocks=$((RANDOM % 256 + 1))
22761
22762         wait_delete_completed
22763         test_mkdir $dir
22764
22765         # check block output
22766         check_lfs_df blocks $dir
22767         # check inode output
22768         check_lfs_df inodes $dir
22769
22770         # create a single file and retest
22771         echo "Creating a single file and testing"
22772         createmany -o $dir/$tfile- 1 &>/dev/null ||
22773                 error "creating 1 file in $dir failed"
22774         check_lfs_df blocks $dir
22775         check_lfs_df inodes $dir
22776
22777         # create a random number of files
22778         echo "Creating $((numfiles - 1)) files and testing"
22779         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22780                 error "creating $((numfiles - 1)) files in $dir failed"
22781
22782         # write a random number of blocks to the first test file
22783         echo "Writing $numblocks 4K blocks and testing"
22784         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22785                 count=$numblocks &>/dev/null ||
22786                 error "dd to $dir/${tfile}-0 failed"
22787
22788         # retest
22789         check_lfs_df blocks $dir
22790         check_lfs_df inodes $dir
22791
22792         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22793                 error "unlinking $numfiles files in $dir failed"
22794 }
22795 run_test 418 "df and lfs df outputs match"
22796
22797 test_419()
22798 {
22799         local dir=$DIR/$tdir
22800
22801         mkdir -p $dir
22802         touch $dir/file
22803
22804         cancel_lru_locks mdc
22805
22806         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22807         $LCTL set_param fail_loc=0x1410
22808         cat $dir/file
22809         $LCTL set_param fail_loc=0
22810         rm -rf $dir
22811 }
22812 run_test 419 "Verify open file by name doesn't crash kernel"
22813
22814 test_420()
22815 {
22816         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22817                 skip "Need MDS version at least 2.12.53"
22818
22819         local SAVE_UMASK=$(umask)
22820         local dir=$DIR/$tdir
22821         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22822
22823         mkdir -p $dir
22824         umask 0000
22825         mkdir -m03777 $dir/testdir
22826         ls -dn $dir/testdir
22827         # Need to remove trailing '.' when SELinux is enabled
22828         local dirperms=$(ls -dn $dir/testdir |
22829                          awk '{ sub(/\.$/, "", $1); print $1}')
22830         [ $dirperms == "drwxrwsrwt" ] ||
22831                 error "incorrect perms on $dir/testdir"
22832
22833         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22834                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22835         ls -n $dir/testdir/testfile
22836         local fileperms=$(ls -n $dir/testdir/testfile |
22837                           awk '{ sub(/\.$/, "", $1); print $1}')
22838         [ $fileperms == "-rwxr-xr-x" ] ||
22839                 error "incorrect perms on $dir/testdir/testfile"
22840
22841         umask $SAVE_UMASK
22842 }
22843 run_test 420 "clear SGID bit on non-directories for non-members"
22844
22845 test_421a() {
22846         local cnt
22847         local fid1
22848         local fid2
22849
22850         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22851                 skip "Need MDS version at least 2.12.54"
22852
22853         test_mkdir $DIR/$tdir
22854         createmany -o $DIR/$tdir/f 3
22855         cnt=$(ls -1 $DIR/$tdir | wc -l)
22856         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22857
22858         fid1=$(lfs path2fid $DIR/$tdir/f1)
22859         fid2=$(lfs path2fid $DIR/$tdir/f2)
22860         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22861
22862         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22863         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22864
22865         cnt=$(ls -1 $DIR/$tdir | wc -l)
22866         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22867
22868         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22869         createmany -o $DIR/$tdir/f 3
22870         cnt=$(ls -1 $DIR/$tdir | wc -l)
22871         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22872
22873         fid1=$(lfs path2fid $DIR/$tdir/f1)
22874         fid2=$(lfs path2fid $DIR/$tdir/f2)
22875         echo "remove using fsname $FSNAME"
22876         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22877
22878         cnt=$(ls -1 $DIR/$tdir | wc -l)
22879         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22880 }
22881 run_test 421a "simple rm by fid"
22882
22883 test_421b() {
22884         local cnt
22885         local FID1
22886         local FID2
22887
22888         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22889                 skip "Need MDS version at least 2.12.54"
22890
22891         test_mkdir $DIR/$tdir
22892         createmany -o $DIR/$tdir/f 3
22893         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22894         MULTIPID=$!
22895
22896         FID1=$(lfs path2fid $DIR/$tdir/f1)
22897         FID2=$(lfs path2fid $DIR/$tdir/f2)
22898         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22899
22900         kill -USR1 $MULTIPID
22901         wait
22902
22903         cnt=$(ls $DIR/$tdir | wc -l)
22904         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22905 }
22906 run_test 421b "rm by fid on open file"
22907
22908 test_421c() {
22909         local cnt
22910         local FIDS
22911
22912         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22913                 skip "Need MDS version at least 2.12.54"
22914
22915         test_mkdir $DIR/$tdir
22916         createmany -o $DIR/$tdir/f 3
22917         touch $DIR/$tdir/$tfile
22918         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22919         cnt=$(ls -1 $DIR/$tdir | wc -l)
22920         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22921
22922         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22923         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22924
22925         cnt=$(ls $DIR/$tdir | wc -l)
22926         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22927 }
22928 run_test 421c "rm by fid against hardlinked files"
22929
22930 test_421d() {
22931         local cnt
22932         local FIDS
22933
22934         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22935                 skip "Need MDS version at least 2.12.54"
22936
22937         test_mkdir $DIR/$tdir
22938         createmany -o $DIR/$tdir/f 4097
22939         cnt=$(ls -1 $DIR/$tdir | wc -l)
22940         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22941
22942         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22943         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22944
22945         cnt=$(ls $DIR/$tdir | wc -l)
22946         rm -rf $DIR/$tdir
22947         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22948 }
22949 run_test 421d "rmfid en masse"
22950
22951 test_421e() {
22952         local cnt
22953         local FID
22954
22955         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22956         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22957                 skip "Need MDS version at least 2.12.54"
22958
22959         mkdir -p $DIR/$tdir
22960         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22961         createmany -o $DIR/$tdir/striped_dir/f 512
22962         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22963         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22964
22965         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22966                 sed "s/[/][^:]*://g")
22967         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22968
22969         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22970         rm -rf $DIR/$tdir
22971         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22972 }
22973 run_test 421e "rmfid in DNE"
22974
22975 test_421f() {
22976         local cnt
22977         local FID
22978
22979         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22980                 skip "Need MDS version at least 2.12.54"
22981
22982         test_mkdir $DIR/$tdir
22983         touch $DIR/$tdir/f
22984         cnt=$(ls -1 $DIR/$tdir | wc -l)
22985         [ $cnt != 1 ] && error "unexpected #files: $cnt"
22986
22987         FID=$(lfs path2fid $DIR/$tdir/f)
22988         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
22989         # rmfid should fail
22990         cnt=$(ls -1 $DIR/$tdir | wc -l)
22991         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
22992
22993         chmod a+rw $DIR/$tdir
22994         ls -la $DIR/$tdir
22995         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
22996         # rmfid should fail
22997         cnt=$(ls -1 $DIR/$tdir | wc -l)
22998         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
22999
23000         rm -f $DIR/$tdir/f
23001         $RUNAS touch $DIR/$tdir/f
23002         FID=$(lfs path2fid $DIR/$tdir/f)
23003         echo "rmfid as root"
23004         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23005         cnt=$(ls -1 $DIR/$tdir | wc -l)
23006         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23007
23008         rm -f $DIR/$tdir/f
23009         $RUNAS touch $DIR/$tdir/f
23010         cnt=$(ls -1 $DIR/$tdir | wc -l)
23011         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23012         FID=$(lfs path2fid $DIR/$tdir/f)
23013         # rmfid w/o user_fid2path mount option should fail
23014         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23015         cnt=$(ls -1 $DIR/$tdir | wc -l)
23016         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23017
23018         umount_client $MOUNT || error "failed to umount client"
23019         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23020                 error "failed to mount client'"
23021
23022         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23023         # rmfid should succeed
23024         cnt=$(ls -1 $DIR/$tdir | wc -l)
23025         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23026
23027         # rmfid shouldn't allow to remove files due to dir's permission
23028         chmod a+rwx $DIR/$tdir
23029         touch $DIR/$tdir/f
23030         ls -la $DIR/$tdir
23031         FID=$(lfs path2fid $DIR/$tdir/f)
23032         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23033
23034         umount_client $MOUNT || error "failed to umount client"
23035         mount_client $MOUNT "$MOUNT_OPTS" ||
23036                 error "failed to mount client'"
23037
23038 }
23039 run_test 421f "rmfid checks permissions"
23040
23041 test_421g() {
23042         local cnt
23043         local FIDS
23044
23045         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23046         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23047                 skip "Need MDS version at least 2.12.54"
23048
23049         mkdir -p $DIR/$tdir
23050         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23051         createmany -o $DIR/$tdir/striped_dir/f 512
23052         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23053         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23054
23055         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23056                 sed "s/[/][^:]*://g")
23057
23058         rm -f $DIR/$tdir/striped_dir/f1*
23059         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23060         removed=$((512 - cnt))
23061
23062         # few files have been just removed, so we expect
23063         # rmfid to fail on their fids
23064         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23065         [ $removed != $errors ] && error "$errors != $removed"
23066
23067         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23068         rm -rf $DIR/$tdir
23069         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23070 }
23071 run_test 421g "rmfid to return errors properly"
23072
23073 test_422() {
23074         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23075         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23076         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23077         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23078         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23079
23080         local amc=$(at_max_get client)
23081         local amo=$(at_max_get mds1)
23082         local timeout=`lctl get_param -n timeout`
23083
23084         at_max_set 0 client
23085         at_max_set 0 mds1
23086
23087 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23088         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23089                         fail_val=$(((2*timeout + 10)*1000))
23090         touch $DIR/$tdir/d3/file &
23091         sleep 2
23092 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23093         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23094                         fail_val=$((2*timeout + 5))
23095         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23096         local pid=$!
23097         sleep 1
23098         kill -9 $pid
23099         sleep $((2 * timeout))
23100         echo kill $pid
23101         kill -9 $pid
23102         lctl mark touch
23103         touch $DIR/$tdir/d2/file3
23104         touch $DIR/$tdir/d2/file4
23105         touch $DIR/$tdir/d2/file5
23106
23107         wait
23108         at_max_set $amc client
23109         at_max_set $amo mds1
23110
23111         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23112         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23113                 error "Watchdog is always throttled"
23114 }
23115 run_test 422 "kill a process with RPC in progress"
23116
23117 stat_test() {
23118     df -h $MOUNT &
23119     df -h $MOUNT &
23120     df -h $MOUNT &
23121     df -h $MOUNT &
23122     df -h $MOUNT &
23123     df -h $MOUNT &
23124 }
23125
23126 test_423() {
23127     local _stats
23128     # ensure statfs cache is expired
23129     sleep 2;
23130
23131     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23132     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23133
23134     return 0
23135 }
23136 run_test 423 "statfs should return a right data"
23137
23138 test_424() {
23139 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23140         $LCTL set_param fail_loc=0x80000522
23141         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23142         rm -f $DIR/$tfile
23143 }
23144 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23145
23146 prep_801() {
23147         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23148         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23149                 skip "Need server version at least 2.9.55"
23150
23151         start_full_debug_logging
23152 }
23153
23154 post_801() {
23155         stop_full_debug_logging
23156 }
23157
23158 barrier_stat() {
23159         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23160                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23161                            awk '/The barrier for/ { print $7 }')
23162                 echo $st
23163         else
23164                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23165                 echo \'$st\'
23166         fi
23167 }
23168
23169 barrier_expired() {
23170         local expired
23171
23172         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23173                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23174                           awk '/will be expired/ { print $7 }')
23175         else
23176                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23177         fi
23178
23179         echo $expired
23180 }
23181
23182 test_801a() {
23183         prep_801
23184
23185         echo "Start barrier_freeze at: $(date)"
23186         #define OBD_FAIL_BARRIER_DELAY          0x2202
23187         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23188         # Do not reduce barrier time - See LU-11873
23189         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23190
23191         sleep 2
23192         local b_status=$(barrier_stat)
23193         echo "Got barrier status at: $(date)"
23194         [ "$b_status" = "'freezing_p1'" ] ||
23195                 error "(1) unexpected barrier status $b_status"
23196
23197         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23198         wait
23199         b_status=$(barrier_stat)
23200         [ "$b_status" = "'frozen'" ] ||
23201                 error "(2) unexpected barrier status $b_status"
23202
23203         local expired=$(barrier_expired)
23204         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23205         sleep $((expired + 3))
23206
23207         b_status=$(barrier_stat)
23208         [ "$b_status" = "'expired'" ] ||
23209                 error "(3) unexpected barrier status $b_status"
23210
23211         # Do not reduce barrier time - See LU-11873
23212         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23213                 error "(4) fail to freeze barrier"
23214
23215         b_status=$(barrier_stat)
23216         [ "$b_status" = "'frozen'" ] ||
23217                 error "(5) unexpected barrier status $b_status"
23218
23219         echo "Start barrier_thaw at: $(date)"
23220         #define OBD_FAIL_BARRIER_DELAY          0x2202
23221         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23222         do_facet mgs $LCTL barrier_thaw $FSNAME &
23223
23224         sleep 2
23225         b_status=$(barrier_stat)
23226         echo "Got barrier status at: $(date)"
23227         [ "$b_status" = "'thawing'" ] ||
23228                 error "(6) unexpected barrier status $b_status"
23229
23230         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23231         wait
23232         b_status=$(barrier_stat)
23233         [ "$b_status" = "'thawed'" ] ||
23234                 error "(7) unexpected barrier status $b_status"
23235
23236         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23237         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23238         do_facet mgs $LCTL barrier_freeze $FSNAME
23239
23240         b_status=$(barrier_stat)
23241         [ "$b_status" = "'failed'" ] ||
23242                 error "(8) unexpected barrier status $b_status"
23243
23244         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23245         do_facet mgs $LCTL barrier_thaw $FSNAME
23246
23247         post_801
23248 }
23249 run_test 801a "write barrier user interfaces and stat machine"
23250
23251 test_801b() {
23252         prep_801
23253
23254         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23255         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23256         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23257         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23258         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23259
23260         cancel_lru_locks mdc
23261
23262         # 180 seconds should be long enough
23263         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23264
23265         local b_status=$(barrier_stat)
23266         [ "$b_status" = "'frozen'" ] ||
23267                 error "(6) unexpected barrier status $b_status"
23268
23269         mkdir $DIR/$tdir/d0/d10 &
23270         mkdir_pid=$!
23271
23272         touch $DIR/$tdir/d1/f13 &
23273         touch_pid=$!
23274
23275         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23276         ln_pid=$!
23277
23278         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23279         mv_pid=$!
23280
23281         rm -f $DIR/$tdir/d4/f12 &
23282         rm_pid=$!
23283
23284         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23285
23286         # To guarantee taht the 'stat' is not blocked
23287         b_status=$(barrier_stat)
23288         [ "$b_status" = "'frozen'" ] ||
23289                 error "(8) unexpected barrier status $b_status"
23290
23291         # let above commands to run at background
23292         sleep 5
23293
23294         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23295         ps -p $touch_pid || error "(10) touch should be blocked"
23296         ps -p $ln_pid || error "(11) link should be blocked"
23297         ps -p $mv_pid || error "(12) rename should be blocked"
23298         ps -p $rm_pid || error "(13) unlink should be blocked"
23299
23300         b_status=$(barrier_stat)
23301         [ "$b_status" = "'frozen'" ] ||
23302                 error "(14) unexpected barrier status $b_status"
23303
23304         do_facet mgs $LCTL barrier_thaw $FSNAME
23305         b_status=$(barrier_stat)
23306         [ "$b_status" = "'thawed'" ] ||
23307                 error "(15) unexpected barrier status $b_status"
23308
23309         wait $mkdir_pid || error "(16) mkdir should succeed"
23310         wait $touch_pid || error "(17) touch should succeed"
23311         wait $ln_pid || error "(18) link should succeed"
23312         wait $mv_pid || error "(19) rename should succeed"
23313         wait $rm_pid || error "(20) unlink should succeed"
23314
23315         post_801
23316 }
23317 run_test 801b "modification will be blocked by write barrier"
23318
23319 test_801c() {
23320         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23321
23322         prep_801
23323
23324         stop mds2 || error "(1) Fail to stop mds2"
23325
23326         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23327
23328         local b_status=$(barrier_stat)
23329         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23330                 do_facet mgs $LCTL barrier_thaw $FSNAME
23331                 error "(2) unexpected barrier status $b_status"
23332         }
23333
23334         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23335                 error "(3) Fail to rescan barrier bitmap"
23336
23337         # Do not reduce barrier time - See LU-11873
23338         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23339
23340         b_status=$(barrier_stat)
23341         [ "$b_status" = "'frozen'" ] ||
23342                 error "(4) unexpected barrier status $b_status"
23343
23344         do_facet mgs $LCTL barrier_thaw $FSNAME
23345         b_status=$(barrier_stat)
23346         [ "$b_status" = "'thawed'" ] ||
23347                 error "(5) unexpected barrier status $b_status"
23348
23349         local devname=$(mdsdevname 2)
23350
23351         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23352
23353         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23354                 error "(7) Fail to rescan barrier bitmap"
23355
23356         post_801
23357 }
23358 run_test 801c "rescan barrier bitmap"
23359
23360 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23361 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23362 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23363 saved_MOUNT_OPTS=$MOUNT_OPTS
23364
23365 cleanup_802a() {
23366         trap 0
23367
23368         stopall
23369         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23370         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23371         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23372         MOUNT_OPTS=$saved_MOUNT_OPTS
23373         setupall
23374 }
23375
23376 test_802a() {
23377         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23378         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23379         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23380                 skip "Need server version at least 2.9.55"
23381
23382         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23383
23384         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23385
23386         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23387                 error "(2) Fail to copy"
23388
23389         trap cleanup_802a EXIT
23390
23391         # sync by force before remount as readonly
23392         sync; sync_all_data; sleep 3; sync_all_data
23393
23394         stopall
23395
23396         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23397         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23398         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23399
23400         echo "Mount the server as read only"
23401         setupall server_only || error "(3) Fail to start servers"
23402
23403         echo "Mount client without ro should fail"
23404         mount_client $MOUNT &&
23405                 error "(4) Mount client without 'ro' should fail"
23406
23407         echo "Mount client with ro should succeed"
23408         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23409         mount_client $MOUNT ||
23410                 error "(5) Mount client with 'ro' should succeed"
23411
23412         echo "Modify should be refused"
23413         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23414
23415         echo "Read should be allowed"
23416         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23417                 error "(7) Read should succeed under ro mode"
23418
23419         cleanup_802a
23420 }
23421 run_test 802a "simulate readonly device"
23422
23423 test_802b() {
23424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23425         remote_mds_nodsh && skip "remote MDS with nodsh"
23426
23427         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23428                 skip "readonly option not available"
23429
23430         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23431
23432         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23433                 error "(2) Fail to copy"
23434
23435         # write back all cached data before setting MDT to readonly
23436         cancel_lru_locks
23437         sync_all_data
23438
23439         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23440         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23441
23442         echo "Modify should be refused"
23443         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23444
23445         echo "Read should be allowed"
23446         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23447                 error "(7) Read should succeed under ro mode"
23448
23449         # disable readonly
23450         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23451 }
23452 run_test 802b "be able to set MDTs to readonly"
23453
23454 test_803() {
23455         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23456         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23457                 skip "MDS needs to be newer than 2.10.54"
23458
23459         mkdir -p $DIR/$tdir
23460         # Create some objects on all MDTs to trigger related logs objects
23461         for idx in $(seq $MDSCOUNT); do
23462                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23463                         $DIR/$tdir/dir${idx} ||
23464                         error "Fail to create $DIR/$tdir/dir${idx}"
23465         done
23466
23467         sync; sleep 3
23468         wait_delete_completed # ensure old test cleanups are finished
23469         echo "before create:"
23470         $LFS df -i $MOUNT
23471         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23472
23473         for i in {1..10}; do
23474                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23475                         error "Fail to create $DIR/$tdir/foo$i"
23476         done
23477
23478         sync; sleep 3
23479         echo "after create:"
23480         $LFS df -i $MOUNT
23481         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23482
23483         # allow for an llog to be cleaned up during the test
23484         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23485                 error "before ($before_used) + 10 > after ($after_used)"
23486
23487         for i in {1..10}; do
23488                 rm -rf $DIR/$tdir/foo$i ||
23489                         error "Fail to remove $DIR/$tdir/foo$i"
23490         done
23491
23492         sleep 3 # avoid MDT return cached statfs
23493         wait_delete_completed
23494         echo "after unlink:"
23495         $LFS df -i $MOUNT
23496         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23497
23498         # allow for an llog to be created during the test
23499         [ $after_used -le $((before_used + 1)) ] ||
23500                 error "after ($after_used) > before ($before_used) + 1"
23501 }
23502 run_test 803 "verify agent object for remote object"
23503
23504 test_804() {
23505         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23506         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23507                 skip "MDS needs to be newer than 2.10.54"
23508         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23509
23510         mkdir -p $DIR/$tdir
23511         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23512                 error "Fail to create $DIR/$tdir/dir0"
23513
23514         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23515         local dev=$(mdsdevname 2)
23516
23517         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23518                 grep ${fid} || error "NOT found agent entry for dir0"
23519
23520         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23521                 error "Fail to create $DIR/$tdir/dir1"
23522
23523         touch $DIR/$tdir/dir1/foo0 ||
23524                 error "Fail to create $DIR/$tdir/dir1/foo0"
23525         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23526         local rc=0
23527
23528         for idx in $(seq $MDSCOUNT); do
23529                 dev=$(mdsdevname $idx)
23530                 do_facet mds${idx} \
23531                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23532                         grep ${fid} && rc=$idx
23533         done
23534
23535         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23536                 error "Fail to rename foo0 to foo1"
23537         if [ $rc -eq 0 ]; then
23538                 for idx in $(seq $MDSCOUNT); do
23539                         dev=$(mdsdevname $idx)
23540                         do_facet mds${idx} \
23541                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23542                         grep ${fid} && rc=$idx
23543                 done
23544         fi
23545
23546         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23547                 error "Fail to rename foo1 to foo2"
23548         if [ $rc -eq 0 ]; then
23549                 for idx in $(seq $MDSCOUNT); do
23550                         dev=$(mdsdevname $idx)
23551                         do_facet mds${idx} \
23552                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23553                         grep ${fid} && rc=$idx
23554                 done
23555         fi
23556
23557         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23558
23559         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23560                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23561         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23562                 error "Fail to rename foo2 to foo0"
23563         unlink $DIR/$tdir/dir1/foo0 ||
23564                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23565         rm -rf $DIR/$tdir/dir0 ||
23566                 error "Fail to rm $DIR/$tdir/dir0"
23567
23568         for idx in $(seq $MDSCOUNT); do
23569                 dev=$(mdsdevname $idx)
23570                 rc=0
23571
23572                 stop mds${idx}
23573                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23574                         rc=$?
23575                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23576                         error "mount mds$idx failed"
23577                 df $MOUNT > /dev/null 2>&1
23578
23579                 # e2fsck should not return error
23580                 [ $rc -eq 0 ] ||
23581                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23582         done
23583 }
23584 run_test 804 "verify agent entry for remote entry"
23585
23586 cleanup_805() {
23587         do_facet $SINGLEMDS zfs set quota=$old $fsset
23588         unlinkmany $DIR/$tdir/f- 1000000
23589         trap 0
23590 }
23591
23592 test_805() {
23593         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23594         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23595         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23596                 skip "netfree not implemented before 0.7"
23597         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23598                 skip "Need MDS version at least 2.10.57"
23599
23600         local fsset
23601         local freekb
23602         local usedkb
23603         local old
23604         local quota
23605         local pref="osd-zfs.$FSNAME-MDT0000."
23606
23607         # limit available space on MDS dataset to meet nospace issue
23608         # quickly. then ZFS 0.7.2 can use reserved space if asked
23609         # properly (using netfree flag in osd_declare_destroy()
23610         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23611         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23612                 gawk '{print $3}')
23613         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23614         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23615         let "usedkb=usedkb-freekb"
23616         let "freekb=freekb/2"
23617         if let "freekb > 5000"; then
23618                 let "freekb=5000"
23619         fi
23620         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23621         trap cleanup_805 EXIT
23622         mkdir $DIR/$tdir
23623         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23624                 error "Can't set PFL layout"
23625         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23626         rm -rf $DIR/$tdir || error "not able to remove"
23627         do_facet $SINGLEMDS zfs set quota=$old $fsset
23628         trap 0
23629 }
23630 run_test 805 "ZFS can remove from full fs"
23631
23632 # Size-on-MDS test
23633 check_lsom_data()
23634 {
23635         local file=$1
23636         local size=$($LFS getsom -s $file)
23637         local expect=$(stat -c %s $file)
23638
23639         [[ $size == $expect ]] ||
23640                 error "$file expected size: $expect, got: $size"
23641
23642         local blocks=$($LFS getsom -b $file)
23643         expect=$(stat -c %b $file)
23644         [[ $blocks == $expect ]] ||
23645                 error "$file expected blocks: $expect, got: $blocks"
23646 }
23647
23648 check_lsom_size()
23649 {
23650         local size=$($LFS getsom -s $1)
23651         local expect=$2
23652
23653         [[ $size == $expect ]] ||
23654                 error "$file expected size: $expect, got: $size"
23655 }
23656
23657 test_806() {
23658         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23659                 skip "Need MDS version at least 2.11.52"
23660
23661         local bs=1048576
23662
23663         touch $DIR/$tfile || error "touch $tfile failed"
23664
23665         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23666         save_lustre_params client "llite.*.xattr_cache" > $save
23667         lctl set_param llite.*.xattr_cache=0
23668         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23669
23670         # single-threaded write
23671         echo "Test SOM for single-threaded write"
23672         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23673                 error "write $tfile failed"
23674         check_lsom_size $DIR/$tfile $bs
23675
23676         local num=32
23677         local size=$(($num * $bs))
23678         local offset=0
23679         local i
23680
23681         echo "Test SOM for single client multi-threaded($num) write"
23682         $TRUNCATE $DIR/$tfile 0
23683         for ((i = 0; i < $num; i++)); do
23684                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23685                 local pids[$i]=$!
23686                 offset=$((offset + $bs))
23687         done
23688         for (( i=0; i < $num; i++ )); do
23689                 wait ${pids[$i]}
23690         done
23691         check_lsom_size $DIR/$tfile $size
23692
23693         $TRUNCATE $DIR/$tfile 0
23694         for ((i = 0; i < $num; i++)); do
23695                 offset=$((offset - $bs))
23696                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23697                 local pids[$i]=$!
23698         done
23699         for (( i=0; i < $num; i++ )); do
23700                 wait ${pids[$i]}
23701         done
23702         check_lsom_size $DIR/$tfile $size
23703
23704         # multi-client writes
23705         num=$(get_node_count ${CLIENTS//,/ })
23706         size=$(($num * $bs))
23707         offset=0
23708         i=0
23709
23710         echo "Test SOM for multi-client ($num) writes"
23711         $TRUNCATE $DIR/$tfile 0
23712         for client in ${CLIENTS//,/ }; do
23713                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23714                 local pids[$i]=$!
23715                 i=$((i + 1))
23716                 offset=$((offset + $bs))
23717         done
23718         for (( i=0; i < $num; i++ )); do
23719                 wait ${pids[$i]}
23720         done
23721         check_lsom_size $DIR/$tfile $offset
23722
23723         i=0
23724         $TRUNCATE $DIR/$tfile 0
23725         for client in ${CLIENTS//,/ }; do
23726                 offset=$((offset - $bs))
23727                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23728                 local pids[$i]=$!
23729                 i=$((i + 1))
23730         done
23731         for (( i=0; i < $num; i++ )); do
23732                 wait ${pids[$i]}
23733         done
23734         check_lsom_size $DIR/$tfile $size
23735
23736         # verify truncate
23737         echo "Test SOM for truncate"
23738         $TRUNCATE $DIR/$tfile 1048576
23739         check_lsom_size $DIR/$tfile 1048576
23740         $TRUNCATE $DIR/$tfile 1234
23741         check_lsom_size $DIR/$tfile 1234
23742
23743         # verify SOM blocks count
23744         echo "Verify SOM block count"
23745         $TRUNCATE $DIR/$tfile 0
23746         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23747                 error "failed to write file $tfile"
23748         check_lsom_data $DIR/$tfile
23749 }
23750 run_test 806 "Verify Lazy Size on MDS"
23751
23752 test_807() {
23753         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23754         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23755                 skip "Need MDS version at least 2.11.52"
23756
23757         # Registration step
23758         changelog_register || error "changelog_register failed"
23759         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23760         changelog_users $SINGLEMDS | grep -q $cl_user ||
23761                 error "User $cl_user not found in changelog_users"
23762
23763         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23764         save_lustre_params client "llite.*.xattr_cache" > $save
23765         lctl set_param llite.*.xattr_cache=0
23766         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23767
23768         rm -rf $DIR/$tdir || error "rm $tdir failed"
23769         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23770         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23771         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23772         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23773                 error "truncate $tdir/trunc failed"
23774
23775         local bs=1048576
23776         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23777                 error "write $tfile failed"
23778
23779         # multi-client wirtes
23780         local num=$(get_node_count ${CLIENTS//,/ })
23781         local offset=0
23782         local i=0
23783
23784         echo "Test SOM for multi-client ($num) writes"
23785         touch $DIR/$tfile || error "touch $tfile failed"
23786         $TRUNCATE $DIR/$tfile 0
23787         for client in ${CLIENTS//,/ }; do
23788                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23789                 local pids[$i]=$!
23790                 i=$((i + 1))
23791                 offset=$((offset + $bs))
23792         done
23793         for (( i=0; i < $num; i++ )); do
23794                 wait ${pids[$i]}
23795         done
23796
23797         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23798         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23799         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23800         check_lsom_data $DIR/$tdir/trunc
23801         check_lsom_data $DIR/$tdir/single_dd
23802         check_lsom_data $DIR/$tfile
23803
23804         rm -rf $DIR/$tdir
23805         # Deregistration step
23806         changelog_deregister || error "changelog_deregister failed"
23807 }
23808 run_test 807 "verify LSOM syncing tool"
23809
23810 check_som_nologged()
23811 {
23812         local lines=$($LFS changelog $FSNAME-MDT0000 |
23813                 grep 'x=trusted.som' | wc -l)
23814         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23815 }
23816
23817 test_808() {
23818         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23819                 skip "Need MDS version at least 2.11.55"
23820
23821         # Registration step
23822         changelog_register || error "changelog_register failed"
23823
23824         touch $DIR/$tfile || error "touch $tfile failed"
23825         check_som_nologged
23826
23827         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23828                 error "write $tfile failed"
23829         check_som_nologged
23830
23831         $TRUNCATE $DIR/$tfile 1234
23832         check_som_nologged
23833
23834         $TRUNCATE $DIR/$tfile 1048576
23835         check_som_nologged
23836
23837         # Deregistration step
23838         changelog_deregister || error "changelog_deregister failed"
23839 }
23840 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23841
23842 check_som_nodata()
23843 {
23844         $LFS getsom $1
23845         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23846 }
23847
23848 test_809() {
23849         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23850                 skip "Need MDS version at least 2.11.56"
23851
23852         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23853                 error "failed to create DoM-only file $DIR/$tfile"
23854         touch $DIR/$tfile || error "touch $tfile failed"
23855         check_som_nodata $DIR/$tfile
23856
23857         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23858                 error "write $tfile failed"
23859         check_som_nodata $DIR/$tfile
23860
23861         $TRUNCATE $DIR/$tfile 1234
23862         check_som_nodata $DIR/$tfile
23863
23864         $TRUNCATE $DIR/$tfile 4097
23865         check_som_nodata $DIR/$file
23866 }
23867 run_test 809 "Verify no SOM xattr store for DoM-only files"
23868
23869 test_810() {
23870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23871         $GSS && skip_env "could not run with gss"
23872         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23873                 skip "OST < 2.12.58 doesn't align checksum"
23874
23875         set_checksums 1
23876         stack_trap "set_checksums $ORIG_CSUM" EXIT
23877         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23878
23879         local csum
23880         local before
23881         local after
23882         for csum in $CKSUM_TYPES; do
23883                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23884                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23885                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23886                         eval set -- $i
23887                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23888                         before=$(md5sum $DIR/$tfile)
23889                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23890                         after=$(md5sum $DIR/$tfile)
23891                         [ "$before" == "$after" ] ||
23892                                 error "$csum: $before != $after bs=$1 seek=$2"
23893                 done
23894         done
23895 }
23896 run_test 810 "partial page writes on ZFS (LU-11663)"
23897
23898 test_812a() {
23899         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23900                 skip "OST < 2.12.51 doesn't support this fail_loc"
23901         [ "$SHARED_KEY" = true ] &&
23902                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23903
23904         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23905         # ensure ost1 is connected
23906         stat $DIR/$tfile >/dev/null || error "can't stat"
23907         wait_osc_import_state client ost1 FULL
23908         # no locks, no reqs to let the connection idle
23909         cancel_lru_locks osc
23910
23911         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23912 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23913         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23914         wait_osc_import_state client ost1 CONNECTING
23915         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23916
23917         stat $DIR/$tfile >/dev/null || error "can't stat file"
23918 }
23919 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23920
23921 test_812b() { # LU-12378
23922         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23923                 skip "OST < 2.12.51 doesn't support this fail_loc"
23924         [ "$SHARED_KEY" = true ] &&
23925                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23926
23927         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23928         # ensure ost1 is connected
23929         stat $DIR/$tfile >/dev/null || error "can't stat"
23930         wait_osc_import_state client ost1 FULL
23931         # no locks, no reqs to let the connection idle
23932         cancel_lru_locks osc
23933
23934         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23935 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23936         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23937         wait_osc_import_state client ost1 CONNECTING
23938         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23939
23940         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23941         wait_osc_import_state client ost1 IDLE
23942 }
23943 run_test 812b "do not drop no resend request for idle connect"
23944
23945 test_813() {
23946         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23947         [ -z "$file_heat_sav" ] && skip "no file heat support"
23948
23949         local readsample
23950         local writesample
23951         local readbyte
23952         local writebyte
23953         local readsample1
23954         local writesample1
23955         local readbyte1
23956         local writebyte1
23957
23958         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23959         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
23960
23961         $LCTL set_param -n llite.*.file_heat=1
23962         echo "Turn on file heat"
23963         echo "Period second: $period_second, Decay percentage: $decay_pct"
23964
23965         echo "QQQQ" > $DIR/$tfile
23966         echo "QQQQ" > $DIR/$tfile
23967         echo "QQQQ" > $DIR/$tfile
23968         cat $DIR/$tfile > /dev/null
23969         cat $DIR/$tfile > /dev/null
23970         cat $DIR/$tfile > /dev/null
23971         cat $DIR/$tfile > /dev/null
23972
23973         local out=$($LFS heat_get $DIR/$tfile)
23974
23975         $LFS heat_get $DIR/$tfile
23976         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23977         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23978         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23979         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23980
23981         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
23982         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
23983         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
23984         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
23985
23986         sleep $((period_second + 3))
23987         echo "Sleep $((period_second + 3)) seconds..."
23988         # The recursion formula to calculate the heat of the file f is as
23989         # follow:
23990         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
23991         # Where Hi is the heat value in the period between time points i*I and
23992         # (i+1)*I; Ci is the access count in the period; the symbol P refers
23993         # to the weight of Ci.
23994         out=$($LFS heat_get $DIR/$tfile)
23995         $LFS heat_get $DIR/$tfile
23996         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23997         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23998         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23999         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24000
24001         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24002                 error "read sample ($readsample) is wrong"
24003         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24004                 error "write sample ($writesample) is wrong"
24005         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24006                 error "read bytes ($readbyte) is wrong"
24007         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24008                 error "write bytes ($writebyte) is wrong"
24009
24010         echo "QQQQ" > $DIR/$tfile
24011         echo "QQQQ" > $DIR/$tfile
24012         echo "QQQQ" > $DIR/$tfile
24013         cat $DIR/$tfile > /dev/null
24014         cat $DIR/$tfile > /dev/null
24015         cat $DIR/$tfile > /dev/null
24016         cat $DIR/$tfile > /dev/null
24017
24018         sleep $((period_second + 3))
24019         echo "Sleep $((period_second + 3)) seconds..."
24020
24021         out=$($LFS heat_get $DIR/$tfile)
24022         $LFS heat_get $DIR/$tfile
24023         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24024         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24025         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24026         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24027
24028         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24029                 4 * $decay_pct) / 100") -eq 1 ] ||
24030                 error "read sample ($readsample1) is wrong"
24031         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24032                 3 * $decay_pct) / 100") -eq 1 ] ||
24033                 error "write sample ($writesample1) is wrong"
24034         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24035                 20 * $decay_pct) / 100") -eq 1 ] ||
24036                 error "read bytes ($readbyte1) is wrong"
24037         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24038                 15 * $decay_pct) / 100") -eq 1 ] ||
24039                 error "write bytes ($writebyte1) is wrong"
24040
24041         echo "Turn off file heat for the file $DIR/$tfile"
24042         $LFS heat_set -o $DIR/$tfile
24043
24044         echo "QQQQ" > $DIR/$tfile
24045         echo "QQQQ" > $DIR/$tfile
24046         echo "QQQQ" > $DIR/$tfile
24047         cat $DIR/$tfile > /dev/null
24048         cat $DIR/$tfile > /dev/null
24049         cat $DIR/$tfile > /dev/null
24050         cat $DIR/$tfile > /dev/null
24051
24052         out=$($LFS heat_get $DIR/$tfile)
24053         $LFS heat_get $DIR/$tfile
24054         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24055         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24056         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24057         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24058
24059         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24060         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24061         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24062         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24063
24064         echo "Trun on file heat for the file $DIR/$tfile"
24065         $LFS heat_set -O $DIR/$tfile
24066
24067         echo "QQQQ" > $DIR/$tfile
24068         echo "QQQQ" > $DIR/$tfile
24069         echo "QQQQ" > $DIR/$tfile
24070         cat $DIR/$tfile > /dev/null
24071         cat $DIR/$tfile > /dev/null
24072         cat $DIR/$tfile > /dev/null
24073         cat $DIR/$tfile > /dev/null
24074
24075         out=$($LFS heat_get $DIR/$tfile)
24076         $LFS heat_get $DIR/$tfile
24077         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24078         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24079         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24080         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24081
24082         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24083         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24084         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24085         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24086
24087         $LFS heat_set -c $DIR/$tfile
24088         $LCTL set_param -n llite.*.file_heat=0
24089         echo "Turn off file heat support for the Lustre filesystem"
24090
24091         echo "QQQQ" > $DIR/$tfile
24092         echo "QQQQ" > $DIR/$tfile
24093         echo "QQQQ" > $DIR/$tfile
24094         cat $DIR/$tfile > /dev/null
24095         cat $DIR/$tfile > /dev/null
24096         cat $DIR/$tfile > /dev/null
24097         cat $DIR/$tfile > /dev/null
24098
24099         out=$($LFS heat_get $DIR/$tfile)
24100         $LFS heat_get $DIR/$tfile
24101         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24102         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24103         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24104         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24105
24106         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24107         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24108         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24109         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24110
24111         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24112         rm -f $DIR/$tfile
24113 }
24114 run_test 813 "File heat verfication"
24115
24116 test_814()
24117 {
24118         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24119         echo -n y >> $DIR/$tfile
24120         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24121         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24122 }
24123 run_test 814 "sparse cp works as expected (LU-12361)"
24124
24125 test_815()
24126 {
24127         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24128         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24129 }
24130 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24131
24132 test_816() {
24133         [ "$SHARED_KEY" = true ] &&
24134                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24135
24136         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24137         # ensure ost1 is connected
24138         stat $DIR/$tfile >/dev/null || error "can't stat"
24139         wait_osc_import_state client ost1 FULL
24140         # no locks, no reqs to let the connection idle
24141         cancel_lru_locks osc
24142         lru_resize_disable osc
24143         local before
24144         local now
24145         before=$($LCTL get_param -n \
24146                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24147
24148         wait_osc_import_state client ost1 IDLE
24149         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24150         now=$($LCTL get_param -n \
24151               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24152         [ $before == $now ] || error "lru_size changed $before != $now"
24153 }
24154 run_test 816 "do not reset lru_resize on idle reconnect"
24155
24156 cleanup_817() {
24157         umount $tmpdir
24158         exportfs -u localhost:$DIR/nfsexp
24159         rm -rf $DIR/nfsexp
24160 }
24161
24162 test_817() {
24163         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24164
24165         mkdir -p $DIR/nfsexp
24166         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24167                 error "failed to export nfs"
24168
24169         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24170         stack_trap cleanup_817 EXIT
24171
24172         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24173                 error "failed to mount nfs to $tmpdir"
24174
24175         cp /bin/true $tmpdir
24176         $DIR/nfsexp/true || error "failed to execute 'true' command"
24177 }
24178 run_test 817 "nfsd won't cache write lock for exec file"
24179
24180 test_818() {
24181         mkdir $DIR/$tdir
24182         $LFS setstripe -c1 -i0 $DIR/$tfile
24183         $LFS setstripe -c1 -i1 $DIR/$tfile
24184         stop $SINGLEMDS
24185         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24186         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24187         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24188                 error "start $SINGLEMDS failed"
24189         rm -rf $DIR/$tdir
24190 }
24191 run_test 818 "unlink with failed llog"
24192
24193 test_819a() {
24194         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24195         cancel_lru_locks osc
24196         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24197         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24198         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24199         rm -f $TDIR/$tfile
24200 }
24201 run_test 819a "too big niobuf in read"
24202
24203 test_819b() {
24204         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24205         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24207         cancel_lru_locks osc
24208         sleep 1
24209         rm -f $TDIR/$tfile
24210 }
24211 run_test 819b "too big niobuf in write"
24212
24213
24214 function test_820_start_ost() {
24215         sleep 5
24216
24217         for num in $(seq $OSTCOUNT); do
24218                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24219         done
24220 }
24221
24222 test_820() {
24223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24224
24225         mkdir $DIR/$tdir
24226         umount_client $MOUNT || error "umount failed"
24227         for num in $(seq $OSTCOUNT); do
24228                 stop ost$num
24229         done
24230
24231         # mount client with no active OSTs
24232         # so that the client can't initialize max LOV EA size
24233         # from OSC notifications
24234         mount_client $MOUNT || error "mount failed"
24235         # delay OST starting to keep this 0 max EA size for a while
24236         test_820_start_ost &
24237
24238         # create a directory on MDS2
24239         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24240                 error "Failed to create directory"
24241         # open intent should update default EA size
24242         # see mdc_update_max_ea_from_body()
24243         # notice this is the very first RPC to MDS2
24244         cp /etc/services $DIR/$tdir/mds2 ||
24245                 error "Failed to copy files to mds$n"
24246 }
24247 run_test 820 "update max EA from open intent"
24248
24249 #
24250 # tests that do cleanup/setup should be run at the end
24251 #
24252
24253 test_900() {
24254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24255         local ls
24256
24257         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24258         $LCTL set_param fail_loc=0x903
24259
24260         cancel_lru_locks MGC
24261
24262         FAIL_ON_ERROR=true cleanup
24263         FAIL_ON_ERROR=true setup
24264 }
24265 run_test 900 "umount should not race with any mgc requeue thread"
24266
24267 # LUS-6253/LU-11185
24268 test_901() {
24269         local oldc
24270         local newc
24271         local olds
24272         local news
24273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24274
24275         # some get_param have a bug to handle dot in param name
24276         cancel_lru_locks MGC
24277         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24278         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24279         umount_client $MOUNT || error "umount failed"
24280         mount_client $MOUNT || error "mount failed"
24281         cancel_lru_locks MGC
24282         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24283         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24284
24285         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24286         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24287
24288         return 0
24289 }
24290 run_test 901 "don't leak a mgc lock on client umount"
24291
24292 # LU-13377
24293 test_902() {
24294         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24295                 skip "client does not have LU-13377 fix"
24296         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24297         $LCTL set_param fail_loc=0x1415
24298         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24299         cancel_lru_locks osc
24300         rm -f $DIR/$tfile
24301 }
24302 run_test 902 "test short write doesn't hang lustre"
24303
24304 complete $SECONDS
24305 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24306 check_and_cleanup_lustre
24307 if [ "$I_MOUNTED" != "yes" ]; then
24308         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24309 fi
24310 exit_status