Whamcloud - gitweb
LU-13063 tests: stop running sanity test 411
[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_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-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          (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         # skip long symlink name for rhel6.5.
560         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
561         grep -q '6.5' /etc/redhat-release &>/dev/null &&
562                 TESTS="59 60 61 4062 4063"
563
564         for i in $TESTS; do
565                 local SYMNAME=$(str_repeat 'x' $i)
566                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
567                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
568         done
569 }
570 run_test 17g "symlinks: really long symlink name and inode boundaries"
571
572 test_17h() { #bug 17378
573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
574         remote_mds_nodsh && skip "remote MDS with nodsh"
575
576         local mdt_idx
577
578         test_mkdir $DIR/$tdir
579         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
580         $LFS setstripe -c -1 $DIR/$tdir
581         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
582         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
583         touch $DIR/$tdir/$tfile || true
584 }
585 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
586
587 test_17i() { #bug 20018
588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
589         remote_mds_nodsh && skip "remote MDS with nodsh"
590
591         local foo=$DIR/$tdir/$tfile
592         local mdt_idx
593
594         test_mkdir -c1 $DIR/$tdir
595         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
596         ln -s $foo $foo || error "create symlink failed"
597 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
598         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
599         ls -l $foo && error "error not detected"
600         return 0
601 }
602 run_test 17i "don't panic on short symlink (should return error)"
603
604 test_17k() { #bug 22301
605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
606         [[ -z "$(which rsync 2>/dev/null)" ]] &&
607                 skip "no rsync command"
608         rsync --help | grep -q xattr ||
609                 skip_env "$(rsync --version | head -n1) does not support xattrs"
610         test_mkdir $DIR/$tdir
611         test_mkdir $DIR/$tdir.new
612         touch $DIR/$tdir/$tfile
613         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
614         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
615                 error "rsync failed with xattrs enabled"
616 }
617 run_test 17k "symlinks: rsync with xattrs enabled"
618
619 test_17l() { # LU-279
620         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
621                 skip "no getfattr command"
622
623         test_mkdir $DIR/$tdir
624         touch $DIR/$tdir/$tfile
625         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
626         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
627                 # -h to not follow symlinks. -m '' to list all the xattrs.
628                 # grep to remove first line: '# file: $path'.
629                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
630                 do
631                         lgetxattr_size_check $path $xattr ||
632                                 error "lgetxattr_size_check $path $xattr failed"
633                 done
634         done
635 }
636 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
637
638 # LU-1540
639 test_17m() {
640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
641         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
642         remote_mds_nodsh && skip "remote MDS with nodsh"
643         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
644         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
645                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
646
647         local short_sym="0123456789"
648         local wdir=$DIR/$tdir
649         local i
650
651         test_mkdir $wdir
652         long_sym=$short_sym
653         # create a long symlink file
654         for ((i = 0; i < 4; ++i)); do
655                 long_sym=${long_sym}${long_sym}
656         done
657
658         echo "create 512 short and long symlink files under $wdir"
659         for ((i = 0; i < 256; ++i)); do
660                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
661                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
662         done
663
664         echo "erase them"
665         rm -f $wdir/*
666         sync
667         wait_delete_completed
668
669         echo "recreate the 512 symlink files with a shorter string"
670         for ((i = 0; i < 512; ++i)); do
671                 # rewrite the symlink file with a shorter string
672                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
673                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
674         done
675
676         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
677         local devname=$(mdsdevname $mds_index)
678
679         echo "stop and checking mds${mds_index}:"
680         # e2fsck should not return error
681         stop mds${mds_index}
682         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
683         rc=$?
684
685         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
686                 error "start mds${mds_index} failed"
687         df $MOUNT > /dev/null 2>&1
688         [ $rc -eq 0 ] ||
689                 error "e2fsck detected error for short/long symlink: rc=$rc"
690         rm -f $wdir/*
691 }
692 run_test 17m "run e2fsck against MDT which contains short/long symlink"
693
694 check_fs_consistency_17n() {
695         local mdt_index
696         local rc=0
697
698         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
699         # so it only check MDT1/MDT2 instead of all of MDTs.
700         for mdt_index in 1 2; do
701                 local devname=$(mdsdevname $mdt_index)
702                 # e2fsck should not return error
703                 stop mds${mdt_index}
704                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
705                         rc=$((rc + $?))
706
707                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
708                         error "mount mds$mdt_index failed"
709                 df $MOUNT > /dev/null 2>&1
710         done
711         return $rc
712 }
713
714 test_17n() {
715         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
717         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
718         remote_mds_nodsh && skip "remote MDS with nodsh"
719         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
720         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
721                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
722
723         local i
724
725         test_mkdir $DIR/$tdir
726         for ((i=0; i<10; i++)); do
727                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
728                         error "create remote dir error $i"
729                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
730                         error "create files under remote dir failed $i"
731         done
732
733         check_fs_consistency_17n ||
734                 error "e2fsck report error after create files under remote dir"
735
736         for ((i = 0; i < 10; i++)); do
737                 rm -rf $DIR/$tdir/remote_dir_${i} ||
738                         error "destroy remote dir error $i"
739         done
740
741         check_fs_consistency_17n ||
742                 error "e2fsck report error after unlink files under remote dir"
743
744         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
745                 skip "lustre < 2.4.50 does not support migrate mv"
746
747         for ((i = 0; i < 10; i++)); do
748                 mkdir -p $DIR/$tdir/remote_dir_${i}
749                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
750                         error "create files under remote dir failed $i"
751                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
752                         error "migrate remote dir error $i"
753         done
754         check_fs_consistency_17n || error "e2fsck report error after migration"
755
756         for ((i = 0; i < 10; i++)); do
757                 rm -rf $DIR/$tdir/remote_dir_${i} ||
758                         error "destroy remote dir error $i"
759         done
760
761         check_fs_consistency_17n || error "e2fsck report error after unlink"
762 }
763 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
764
765 test_17o() {
766         remote_mds_nodsh && skip "remote MDS with nodsh"
767         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
768                 skip "Need MDS version at least 2.3.64"
769
770         local wdir=$DIR/${tdir}o
771         local mdt_index
772         local rc=0
773
774         test_mkdir $wdir
775         touch $wdir/$tfile
776         mdt_index=$($LFS getstripe -m $wdir/$tfile)
777         mdt_index=$((mdt_index + 1))
778
779         cancel_lru_locks mdc
780         #fail mds will wait the failover finish then set
781         #following fail_loc to avoid interfer the recovery process.
782         fail mds${mdt_index}
783
784         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
785         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
786         ls -l $wdir/$tfile && rc=1
787         do_facet mds${mdt_index} lctl set_param fail_loc=0
788         [[ $rc -eq 0 ]] || error "stat file should fail"
789 }
790 run_test 17o "stat file with incompat LMA feature"
791
792 test_18() {
793         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
794         ls $DIR || error "Failed to ls $DIR: $?"
795 }
796 run_test 18 "touch .../f ; ls ... =============================="
797
798 test_19a() {
799         touch $DIR/$tfile
800         ls -l $DIR
801         rm $DIR/$tfile
802         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
803 }
804 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
805
806 test_19b() {
807         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
808 }
809 run_test 19b "ls -l .../f19 (should return error) =============="
810
811 test_19c() {
812         [ $RUNAS_ID -eq $UID ] &&
813                 skip_env "RUNAS_ID = UID = $UID -- skipping"
814
815         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
816 }
817 run_test 19c "$RUNAS touch .../f19 (should return error) =="
818
819 test_19d() {
820         cat $DIR/f19 && error || true
821 }
822 run_test 19d "cat .../f19 (should return error) =============="
823
824 test_20() {
825         touch $DIR/$tfile
826         rm $DIR/$tfile
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
832 }
833 run_test 20 "touch .../f ; ls -l ..."
834
835 test_21() {
836         test_mkdir $DIR/$tdir
837         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
838         ln -s dangle $DIR/$tdir/link
839         echo foo >> $DIR/$tdir/link
840         cat $DIR/$tdir/dangle
841         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
842         $CHECKSTAT -f -t file $DIR/$tdir/link ||
843                 error "$tdir/link not linked to a file"
844 }
845 run_test 21 "write to dangling link"
846
847 test_22() {
848         local wdir=$DIR/$tdir
849         test_mkdir $wdir
850         chown $RUNAS_ID:$RUNAS_GID $wdir
851         (cd $wdir || error "cd $wdir failed";
852                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
853                 $RUNAS tar xf -)
854         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
855         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
856         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
857                 error "checkstat -u failed"
858 }
859 run_test 22 "unpack tar archive as non-root user"
860
861 # was test_23
862 test_23a() {
863         test_mkdir $DIR/$tdir
864         local file=$DIR/$tdir/$tfile
865
866         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
867         openfile -f O_CREAT:O_EXCL $file &&
868                 error "$file recreate succeeded" || true
869 }
870 run_test 23a "O_CREAT|O_EXCL in subdir"
871
872 test_23b() { # bug 18988
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         rm -f $file
877         echo foo > $file || error "write filed"
878         echo bar >> $file || error "append filed"
879         $CHECKSTAT -s 8 $file || error "wrong size"
880         rm $file
881 }
882 run_test 23b "O_APPEND check"
883
884 # LU-9409, size with O_APPEND and tiny writes
885 test_23c() {
886         local file=$DIR/$tfile
887
888         # single dd
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
890         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
891         rm -f $file
892
893         # racing tiny writes
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
896         wait
897         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
898         rm -f $file
899
900         #racing tiny & normal writes
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
902         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
903         wait
904         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
905         rm -f $file
906
907         #racing tiny & normal writes 2, ugly numbers
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
909         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
910         wait
911         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
912         rm -f $file
913 }
914 run_test 23c "O_APPEND size checks for tiny writes"
915
916 # LU-11069 file offset is correct after appending writes
917 test_23d() {
918         local file=$DIR/$tfile
919         local offset
920
921         echo CentaurHauls > $file
922         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
923         if ((offset != 26)); then
924                 error "wrong offset, expected 26, got '$offset'"
925         fi
926 }
927 run_test 23d "file offset is correct after appending writes"
928
929 # rename sanity
930 test_24a() {
931         echo '-- same directory rename'
932         test_mkdir $DIR/$tdir
933         touch $DIR/$tdir/$tfile.1
934         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
935         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
936 }
937 run_test 24a "rename file to non-existent target"
938
939 test_24b() {
940         test_mkdir $DIR/$tdir
941         touch $DIR/$tdir/$tfile.{1,2}
942         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
943         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
944         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
945 }
946 run_test 24b "rename file to existing target"
947
948 test_24c() {
949         test_mkdir $DIR/$tdir
950         test_mkdir $DIR/$tdir/d$testnum.1
951         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
952         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
953         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
954 }
955 run_test 24c "rename directory to non-existent target"
956
957 test_24d() {
958         test_mkdir -c1 $DIR/$tdir
959         test_mkdir -c1 $DIR/$tdir/d$testnum.1
960         test_mkdir -c1 $DIR/$tdir/d$testnum.2
961         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24d "rename directory to existing target"
966
967 test_24e() {
968         echo '-- cross directory renames --'
969         test_mkdir $DIR/R5a
970         test_mkdir $DIR/R5b
971         touch $DIR/R5a/f
972         mv $DIR/R5a/f $DIR/R5b/g
973         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
974         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
975 }
976 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
977
978 test_24f() {
979         test_mkdir $DIR/R6a
980         test_mkdir $DIR/R6b
981         touch $DIR/R6a/f $DIR/R6b/g
982         mv $DIR/R6a/f $DIR/R6b/g
983         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
984         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
985 }
986 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
987
988 test_24g() {
989         test_mkdir $DIR/R7a
990         test_mkdir $DIR/R7b
991         test_mkdir $DIR/R7a/d
992         mv $DIR/R7a/d $DIR/R7b/e
993         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
994         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
995 }
996 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
997
998 test_24h() {
999         test_mkdir -c1 $DIR/R8a
1000         test_mkdir -c1 $DIR/R8b
1001         test_mkdir -c1 $DIR/R8a/d
1002         test_mkdir -c1 $DIR/R8b/e
1003         mrename $DIR/R8a/d $DIR/R8b/e
1004         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1005         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1006 }
1007 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1008
1009 test_24i() {
1010         echo "-- rename error cases"
1011         test_mkdir $DIR/R9
1012         test_mkdir $DIR/R9/a
1013         touch $DIR/R9/f
1014         mrename $DIR/R9/f $DIR/R9/a
1015         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1016         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1017         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1018 }
1019 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1020
1021 test_24j() {
1022         test_mkdir $DIR/R10
1023         mrename $DIR/R10/f $DIR/R10/g
1024         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1025         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1026         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1027 }
1028 run_test 24j "source does not exist ============================"
1029
1030 test_24k() {
1031         test_mkdir $DIR/R11a
1032         test_mkdir $DIR/R11a/d
1033         touch $DIR/R11a/f
1034         mv $DIR/R11a/f $DIR/R11a/d
1035         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1036         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1037 }
1038 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1039
1040 # bug 2429 - rename foo foo foo creates invalid file
1041 test_24l() {
1042         f="$DIR/f24l"
1043         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1044 }
1045 run_test 24l "Renaming a file to itself ========================"
1046
1047 test_24m() {
1048         f="$DIR/f24m"
1049         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1050         # on ext3 this does not remove either the source or target files
1051         # though the "expected" operation would be to remove the source
1052         $CHECKSTAT -t file ${f} || error "${f} missing"
1053         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1054 }
1055 run_test 24m "Renaming a file to a hard link to itself ========="
1056
1057 test_24n() {
1058     f="$DIR/f24n"
1059     # this stats the old file after it was renamed, so it should fail
1060     touch ${f}
1061     $CHECKSTAT ${f} || error "${f} missing"
1062     mv ${f} ${f}.rename
1063     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1064     $CHECKSTAT -a ${f} || error "${f} exists"
1065 }
1066 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1067
1068 test_24o() {
1069         test_mkdir $DIR/$tdir
1070         rename_many -s random -v -n 10 $DIR/$tdir
1071 }
1072 run_test 24o "rename of files during htree split"
1073
1074 test_24p() {
1075         test_mkdir $DIR/R12a
1076         test_mkdir $DIR/R12b
1077         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1078         mrename $DIR/R12a $DIR/R12b
1079         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1080         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1081         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1082         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1083 }
1084 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1085
1086 cleanup_multiop_pause() {
1087         trap 0
1088         kill -USR1 $MULTIPID
1089 }
1090
1091 test_24q() {
1092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1093
1094         test_mkdir $DIR/R13a
1095         test_mkdir $DIR/R13b
1096         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1097         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1098         MULTIPID=$!
1099
1100         trap cleanup_multiop_pause EXIT
1101         mrename $DIR/R13a $DIR/R13b
1102         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1103         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1104         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1105         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1106         cleanup_multiop_pause
1107         wait $MULTIPID || error "multiop close failed"
1108 }
1109 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1110
1111 test_24r() { #bug 3789
1112         test_mkdir $DIR/R14a
1113         test_mkdir $DIR/R14a/b
1114         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1115         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1116         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1117 }
1118 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1119
1120 test_24s() {
1121         test_mkdir $DIR/R15a
1122         test_mkdir $DIR/R15a/b
1123         test_mkdir $DIR/R15a/b/c
1124         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1126         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1127 }
1128 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1129 test_24t() {
1130         test_mkdir $DIR/R16a
1131         test_mkdir $DIR/R16a/b
1132         test_mkdir $DIR/R16a/b/c
1133         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1134         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1135         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1136 }
1137 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1138
1139 test_24u() { # bug12192
1140         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1141         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1142 }
1143 run_test 24u "create stripe file"
1144
1145 simple_cleanup_common() {
1146         local rc=0
1147         trap 0
1148         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1149
1150         local start=$SECONDS
1151         rm -rf $DIR/$tdir
1152         rc=$?
1153         wait_delete_completed
1154         echo "cleanup time $((SECONDS - start))"
1155         return $rc
1156 }
1157
1158 max_pages_per_rpc() {
1159         local mdtname="$(printf "MDT%04x" ${1:-0})"
1160         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1161 }
1162
1163 test_24v() {
1164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1165
1166         local nrfiles=${COUNT:-100000}
1167         local fname="$DIR/$tdir/$tfile"
1168
1169         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1170         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1171
1172         test_mkdir "$(dirname $fname)"
1173         # assume MDT0000 has the fewest inodes
1174         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1175         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1176         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1177
1178         trap simple_cleanup_common EXIT
1179
1180         createmany -m "$fname" $nrfiles
1181
1182         cancel_lru_locks mdc
1183         lctl set_param mdc.*.stats clear
1184
1185         # was previously test_24D: LU-6101
1186         # readdir() returns correct number of entries after cursor reload
1187         local num_ls=$(ls $DIR/$tdir | wc -l)
1188         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1189         local num_all=$(ls -a $DIR/$tdir | wc -l)
1190         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1191                 [ $num_all -ne $((nrfiles + 2)) ]; then
1192                         error "Expected $nrfiles files, got $num_ls " \
1193                                 "($num_uniq unique $num_all .&..)"
1194         fi
1195         # LU-5 large readdir
1196         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1197         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1198         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1199         # take into account of overhead in lu_dirpage header and end mark in
1200         # each page, plus one in rpc_num calculation.
1201         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1202         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1203         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1204         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1205         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1206         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1207         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1208         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1209                 error "large readdir doesn't take effect: " \
1210                       "$mds_readpage should be about $rpc_max"
1211
1212         simple_cleanup_common
1213 }
1214 run_test 24v "list large directory (test hash collision, b=17560)"
1215
1216 test_24w() { # bug21506
1217         SZ1=234852
1218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1219         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1220         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1221         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1222         [[ "$SZ1" -eq "$SZ2" ]] ||
1223                 error "Error reading at the end of the file $tfile"
1224 }
1225 run_test 24w "Reading a file larger than 4Gb"
1226
1227 test_24x() {
1228         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1230         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1231                 skip "Need MDS version at least 2.7.56"
1232
1233         local MDTIDX=1
1234         local remote_dir=$DIR/$tdir/remote_dir
1235
1236         test_mkdir $DIR/$tdir
1237         $LFS mkdir -i $MDTIDX $remote_dir ||
1238                 error "create remote directory failed"
1239
1240         test_mkdir $DIR/$tdir/src_dir
1241         touch $DIR/$tdir/src_file
1242         test_mkdir $remote_dir/tgt_dir
1243         touch $remote_dir/tgt_file
1244
1245         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1246                 error "rename dir cross MDT failed!"
1247
1248         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1249                 error "rename file cross MDT failed!"
1250
1251         touch $DIR/$tdir/ln_file
1252         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1253                 error "ln file cross MDT failed"
1254
1255         rm -rf $DIR/$tdir || error "Can not delete directories"
1256 }
1257 run_test 24x "cross MDT rename/link"
1258
1259 test_24y() {
1260         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1262
1263         local remote_dir=$DIR/$tdir/remote_dir
1264         local mdtidx=1
1265
1266         test_mkdir $DIR/$tdir
1267         $LFS mkdir -i $mdtidx $remote_dir ||
1268                 error "create remote directory failed"
1269
1270         test_mkdir $remote_dir/src_dir
1271         touch $remote_dir/src_file
1272         test_mkdir $remote_dir/tgt_dir
1273         touch $remote_dir/tgt_file
1274
1275         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1276                 error "rename subdir in the same remote dir failed!"
1277
1278         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1279                 error "rename files in the same remote dir failed!"
1280
1281         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1282                 error "link files in the same remote dir failed!"
1283
1284         rm -rf $DIR/$tdir || error "Can not delete directories"
1285 }
1286 run_test 24y "rename/link on the same dir should succeed"
1287
1288 test_24z() {
1289         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1290         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1291                 skip "Need MDS version at least 2.12.51"
1292
1293         local index
1294
1295         for index in 0 1; do
1296                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1297                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1298         done
1299
1300         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1301
1302         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1303         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1304
1305         local mdts=$(comma_list $(mdts_nodes))
1306
1307         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1308         stack_trap "do_nodes $mdts $LCTL \
1309                 set_param mdt.*.enable_remote_rename=1" EXIT
1310
1311         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1312
1313         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1314         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1315 }
1316 run_test 24z "cross-MDT rename is done as cp"
1317
1318 test_24A() { # LU-3182
1319         local NFILES=5000
1320
1321         rm -rf $DIR/$tdir
1322         test_mkdir $DIR/$tdir
1323         trap simple_cleanup_common EXIT
1324         createmany -m $DIR/$tdir/$tfile $NFILES
1325         local t=$(ls $DIR/$tdir | wc -l)
1326         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1327         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1328         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1329            [ $v -ne $((NFILES + 2)) ] ; then
1330                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1331         fi
1332
1333         simple_cleanup_common || error "Can not delete directories"
1334 }
1335 run_test 24A "readdir() returns correct number of entries."
1336
1337 test_24B() { # LU-4805
1338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1339
1340         local count
1341
1342         test_mkdir $DIR/$tdir
1343         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1344                 error "create striped dir failed"
1345
1346         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1347         [ $count -eq 2 ] || error "Expected 2, got $count"
1348
1349         touch $DIR/$tdir/striped_dir/a
1350
1351         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1352         [ $count -eq 3 ] || error "Expected 3, got $count"
1353
1354         touch $DIR/$tdir/striped_dir/.f
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 4 ] || error "Expected 4, got $count"
1358
1359         rm -rf $DIR/$tdir || error "Can not delete directories"
1360 }
1361 run_test 24B "readdir for striped dir return correct number of entries"
1362
1363 test_24C() {
1364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1365
1366         mkdir $DIR/$tdir
1367         mkdir $DIR/$tdir/d0
1368         mkdir $DIR/$tdir/d1
1369
1370         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1371                 error "create striped dir failed"
1372
1373         cd $DIR/$tdir/d0/striped_dir
1374
1375         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1376         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1377         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1378
1379         [ "$d0_ino" = "$parent_ino" ] ||
1380                 error ".. wrong, expect $d0_ino, get $parent_ino"
1381
1382         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1383                 error "mv striped dir failed"
1384
1385         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1386
1387         [ "$d1_ino" = "$parent_ino" ] ||
1388                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1389 }
1390 run_test 24C "check .. in striped dir"
1391
1392 test_24E() {
1393         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1395
1396         mkdir -p $DIR/$tdir
1397         mkdir $DIR/$tdir/src_dir
1398         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1399                 error "create remote source failed"
1400
1401         touch $DIR/$tdir/src_dir/src_child/a
1402
1403         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1404                 error "create remote target dir failed"
1405
1406         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1407                 error "create remote target child failed"
1408
1409         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1410                 error "rename dir cross MDT failed!"
1411
1412         find $DIR/$tdir
1413
1414         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1415                 error "src_child still exists after rename"
1416
1417         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1418                 error "missing file(a) after rename"
1419
1420         rm -rf $DIR/$tdir || error "Can not delete directories"
1421 }
1422 run_test 24E "cross MDT rename/link"
1423
1424 test_24F () {
1425         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1426
1427         local repeats=1000
1428         [ "$SLOW" = "no" ] && repeats=100
1429
1430         mkdir -p $DIR/$tdir
1431
1432         echo "$repeats repeats"
1433         for ((i = 0; i < repeats; i++)); do
1434                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1435                 touch $DIR/$tdir/test/a || error "touch fails"
1436                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1437                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1438         done
1439
1440         true
1441 }
1442 run_test 24F "hash order vs readdir (LU-11330)"
1443
1444 test_25a() {
1445         echo '== symlink sanity ============================================='
1446
1447         test_mkdir $DIR/d25
1448         ln -s d25 $DIR/s25
1449         touch $DIR/s25/foo ||
1450                 error "File creation in symlinked directory failed"
1451 }
1452 run_test 25a "create file in symlinked directory ==============="
1453
1454 test_25b() {
1455         [ ! -d $DIR/d25 ] && test_25a
1456         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1457 }
1458 run_test 25b "lookup file in symlinked directory ==============="
1459
1460 test_26a() {
1461         test_mkdir $DIR/d26
1462         test_mkdir $DIR/d26/d26-2
1463         ln -s d26/d26-2 $DIR/s26
1464         touch $DIR/s26/foo || error "File creation failed"
1465 }
1466 run_test 26a "multiple component symlink ======================="
1467
1468 test_26b() {
1469         test_mkdir -p $DIR/$tdir/d26-2
1470         ln -s $tdir/d26-2/foo $DIR/s26-2
1471         touch $DIR/s26-2 || error "File creation failed"
1472 }
1473 run_test 26b "multiple component symlink at end of lookup ======"
1474
1475 test_26c() {
1476         test_mkdir $DIR/d26.2
1477         touch $DIR/d26.2/foo
1478         ln -s d26.2 $DIR/s26.2-1
1479         ln -s s26.2-1 $DIR/s26.2-2
1480         ln -s s26.2-2 $DIR/s26.2-3
1481         chmod 0666 $DIR/s26.2-3/foo
1482 }
1483 run_test 26c "chain of symlinks"
1484
1485 # recursive symlinks (bug 439)
1486 test_26d() {
1487         ln -s d26-3/foo $DIR/d26-3
1488 }
1489 run_test 26d "create multiple component recursive symlink"
1490
1491 test_26e() {
1492         [ ! -h $DIR/d26-3 ] && test_26d
1493         rm $DIR/d26-3
1494 }
1495 run_test 26e "unlink multiple component recursive symlink"
1496
1497 # recursive symlinks (bug 7022)
1498 test_26f() {
1499         test_mkdir $DIR/$tdir
1500         test_mkdir $DIR/$tdir/$tfile
1501         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1502         test_mkdir -p lndir/bar1
1503         test_mkdir $DIR/$tdir/$tfile/$tfile
1504         cd $tfile                || error "cd $tfile failed"
1505         ln -s .. dotdot          || error "ln dotdot failed"
1506         ln -s dotdot/lndir lndir || error "ln lndir failed"
1507         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1508         output=`ls $tfile/$tfile/lndir/bar1`
1509         [ "$output" = bar1 ] && error "unexpected output"
1510         rm -r $tfile             || error "rm $tfile failed"
1511         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1512 }
1513 run_test 26f "rm -r of a directory which has recursive symlink"
1514
1515 test_27a() {
1516         test_mkdir $DIR/$tdir
1517         $LFS getstripe $DIR/$tdir
1518         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1519         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1520         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1521 }
1522 run_test 27a "one stripe file"
1523
1524 test_27b() {
1525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1526
1527         test_mkdir $DIR/$tdir
1528         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1529         $LFS getstripe -c $DIR/$tdir/$tfile
1530         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1531                 error "two-stripe file doesn't have two stripes"
1532
1533         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1534 }
1535 run_test 27b "create and write to two stripe file"
1536
1537 # 27c family tests specific striping, setstripe -o
1538 test_27ca() {
1539         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1540         test_mkdir -p $DIR/$tdir
1541         local osts="1"
1542
1543         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1544         $LFS getstripe -i $DIR/$tdir/$tfile
1545         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1546                 error "stripe not on specified OST"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27ca "one stripe on specified OST"
1551
1552 test_27cb() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         test_mkdir -p $DIR/$tdir
1555         local osts="1,0"
1556         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1557         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1558         echo "$getstripe"
1559
1560         # Strip getstripe output to a space separated list of OSTs
1561         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1562                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1563         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1564                 error "stripes not on specified OSTs"
1565
1566         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1567 }
1568 run_test 27cb "two stripes on specified OSTs"
1569
1570 test_27cc() {
1571         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1572         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1573                 skip "server does not support overstriping"
1574
1575         test_mkdir -p $DIR/$tdir
1576         local osts="0,0"
1577         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1578         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1579         echo "$getstripe"
1580
1581         # Strip getstripe output to a space separated list of OSTs
1582         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1583                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1584         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1585                 error "stripes not on specified OSTs"
1586
1587         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1588 }
1589 run_test 27cc "two stripes on the same OST"
1590
1591 test_27cd() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1594                 skip "server does not support overstriping"
1595         test_mkdir -p $DIR/$tdir
1596         local osts="0,1,1,0"
1597         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1598         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1599         echo "$getstripe"
1600
1601         # Strip getstripe output to a space separated list of OSTs
1602         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1603                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1604         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1605                 error "stripes not on specified OSTs"
1606
1607         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1608 }
1609 run_test 27cd "four stripes on two OSTs"
1610
1611 test_27ce() {
1612         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1613                 skip_env "too many osts, skipping"
1614         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1615                 skip "server does not support overstriping"
1616         # We do one more stripe than we have OSTs
1617         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1618                 skip_env "ea_inode feature disabled"
1619
1620         test_mkdir -p $DIR/$tdir
1621         local osts=""
1622         for i in $(seq 0 $OSTCOUNT);
1623         do
1624                 osts=$osts"0"
1625                 if [ $i -ne $OSTCOUNT ]; then
1626                         osts=$osts","
1627                 fi
1628         done
1629         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1630         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1631         echo "$getstripe"
1632
1633         # Strip getstripe output to a space separated list of OSTs
1634         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1635                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1636         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1637                 error "stripes not on specified OSTs"
1638
1639         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1640 }
1641 run_test 27ce "more stripes than OSTs with -o"
1642
1643 test_27d() {
1644         test_mkdir $DIR/$tdir
1645         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1646                 error "setstripe failed"
1647         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1648         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1649 }
1650 run_test 27d "create file with default settings"
1651
1652 test_27e() {
1653         # LU-5839 adds check for existed layout before setting it
1654         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1655                 skip "Need MDS version at least 2.7.56"
1656
1657         test_mkdir $DIR/$tdir
1658         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1659         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1660         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1661 }
1662 run_test 27e "setstripe existing file (should return error)"
1663
1664 test_27f() {
1665         test_mkdir $DIR/$tdir
1666         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1667                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1668         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1669                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1670         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1671         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1672 }
1673 run_test 27f "setstripe with bad stripe size (should return error)"
1674
1675 test_27g() {
1676         test_mkdir $DIR/$tdir
1677         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1678         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1679                 error "$DIR/$tdir/$tfile has object"
1680 }
1681 run_test 27g "$LFS getstripe with no objects"
1682
1683 test_27ga() {
1684         test_mkdir $DIR/$tdir
1685         touch $DIR/$tdir/$tfile || error "touch failed"
1686         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1687         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1688         local rc=$?
1689         (( rc == 2 )) || error "getstripe did not return ENOENT"
1690 }
1691 run_test 27ga "$LFS getstripe with missing file (should return error)"
1692
1693 test_27i() {
1694         test_mkdir $DIR/$tdir
1695         touch $DIR/$tdir/$tfile || error "touch failed"
1696         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1697                 error "missing objects"
1698 }
1699 run_test 27i "$LFS getstripe with some objects"
1700
1701 test_27j() {
1702         test_mkdir $DIR/$tdir
1703         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1704                 error "setstripe failed" || true
1705 }
1706 run_test 27j "setstripe with bad stripe offset (should return error)"
1707
1708 test_27k() { # bug 2844
1709         test_mkdir $DIR/$tdir
1710         local file=$DIR/$tdir/$tfile
1711         local ll_max_blksize=$((4 * 1024 * 1024))
1712         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1713         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1714         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1715         dd if=/dev/zero of=$file bs=4k count=1
1716         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1717         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1718 }
1719 run_test 27k "limit i_blksize for broken user apps"
1720
1721 test_27l() {
1722         mcreate $DIR/$tfile || error "creating file"
1723         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1724                 error "setstripe should have failed" || true
1725 }
1726 run_test 27l "check setstripe permissions (should return error)"
1727
1728 test_27m() {
1729         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1730
1731         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1732                 skip_env "multiple clients -- skipping"
1733
1734         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1735                    head -n1)
1736         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1737                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1738         fi
1739         trap simple_cleanup_common EXIT
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1742         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1743                 error "dd should fill OST0"
1744         i=2
1745         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1746                 i=$((i + 1))
1747                 [ $i -gt 256 ] && break
1748         done
1749         i=$((i + 1))
1750         touch $DIR/$tdir/$tfile.$i
1751         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1752             awk '{print $1}'| grep -w "0") ] &&
1753                 error "OST0 was full but new created file still use it"
1754         i=$((i + 1))
1755         touch $DIR/$tdir/$tfile.$i
1756         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1757             awk '{print $1}'| grep -w "0") ] &&
1758                 error "OST0 was full but new created file still use it"
1759         simple_cleanup_common
1760 }
1761 run_test 27m "create file while OST0 was full"
1762
1763 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1764 # if the OST isn't full anymore.
1765 reset_enospc() {
1766         local OSTIDX=${1:-""}
1767
1768         local list=$(comma_list $(osts_nodes))
1769         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1770
1771         do_nodes $list lctl set_param fail_loc=0
1772         sync    # initiate all OST_DESTROYs from MDS to OST
1773         sleep_maxage
1774 }
1775
1776 exhaust_precreations() {
1777         local OSTIDX=$1
1778         local FAILLOC=$2
1779         local FAILIDX=${3:-$OSTIDX}
1780         local ofacet=ost$((OSTIDX + 1))
1781
1782         test_mkdir -p -c1 $DIR/$tdir
1783         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1784         local mfacet=mds$((mdtidx + 1))
1785         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1786
1787         local OST=$(ostname_from_index $OSTIDX)
1788
1789         # on the mdt's osc
1790         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1791         local last_id=$(do_facet $mfacet lctl get_param -n \
1792                         osp.$mdtosc_proc1.prealloc_last_id)
1793         local next_id=$(do_facet $mfacet lctl get_param -n \
1794                         osp.$mdtosc_proc1.prealloc_next_id)
1795
1796         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1797         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1798
1799         test_mkdir -p $DIR/$tdir/${OST}
1800         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1801 #define OBD_FAIL_OST_ENOSPC              0x215
1802         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1803         echo "Creating to objid $last_id on ost $OST..."
1804         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1805         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1806         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1807         sleep_maxage
1808 }
1809
1810 exhaust_all_precreations() {
1811         local i
1812         for (( i=0; i < OSTCOUNT; i++ )) ; do
1813                 exhaust_precreations $i $1 -1
1814         done
1815 }
1816
1817 test_27n() {
1818         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1820         remote_mds_nodsh && skip "remote MDS with nodsh"
1821         remote_ost_nodsh && skip "remote OST with nodsh"
1822
1823         reset_enospc
1824         rm -f $DIR/$tdir/$tfile
1825         exhaust_precreations 0 0x80000215
1826         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1827         touch $DIR/$tdir/$tfile || error "touch failed"
1828         $LFS getstripe $DIR/$tdir/$tfile
1829         reset_enospc
1830 }
1831 run_test 27n "create file with some full OSTs"
1832
1833 test_27o() {
1834         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1836         remote_mds_nodsh && skip "remote MDS with nodsh"
1837         remote_ost_nodsh && skip "remote OST with nodsh"
1838
1839         reset_enospc
1840         rm -f $DIR/$tdir/$tfile
1841         exhaust_all_precreations 0x215
1842
1843         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1844
1845         reset_enospc
1846         rm -rf $DIR/$tdir/*
1847 }
1848 run_test 27o "create file with all full OSTs (should error)"
1849
1850 test_27p() {
1851         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1853         remote_mds_nodsh && skip "remote MDS with nodsh"
1854         remote_ost_nodsh && skip "remote OST with nodsh"
1855
1856         reset_enospc
1857         rm -f $DIR/$tdir/$tfile
1858         test_mkdir $DIR/$tdir
1859
1860         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1861         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1862         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1863
1864         exhaust_precreations 0 0x80000215
1865         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1866         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1867         $LFS getstripe $DIR/$tdir/$tfile
1868
1869         reset_enospc
1870 }
1871 run_test 27p "append to a truncated file with some full OSTs"
1872
1873 test_27q() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881
1882         test_mkdir $DIR/$tdir
1883         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1884         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1885                 error "truncate $DIR/$tdir/$tfile failed"
1886         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1887
1888         exhaust_all_precreations 0x215
1889
1890         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1891         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1892
1893         reset_enospc
1894 }
1895 run_test 27q "append to truncated file with all OSTs full (should error)"
1896
1897 test_27r() {
1898         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1900         remote_mds_nodsh && skip "remote MDS with nodsh"
1901         remote_ost_nodsh && skip "remote OST with nodsh"
1902
1903         reset_enospc
1904         rm -f $DIR/$tdir/$tfile
1905         exhaust_precreations 0 0x80000215
1906
1907         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1908
1909         reset_enospc
1910 }
1911 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1912
1913 test_27s() { # bug 10725
1914         test_mkdir $DIR/$tdir
1915         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1916         local stripe_count=0
1917         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1918         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1919                 error "stripe width >= 2^32 succeeded" || true
1920
1921 }
1922 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1923
1924 test_27t() { # bug 10864
1925         WDIR=$(pwd)
1926         WLFS=$(which lfs)
1927         cd $DIR
1928         touch $tfile
1929         $WLFS getstripe $tfile
1930         cd $WDIR
1931 }
1932 run_test 27t "check that utils parse path correctly"
1933
1934 test_27u() { # bug 4900
1935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937
1938         local index
1939         local list=$(comma_list $(mdts_nodes))
1940
1941 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1942         do_nodes $list $LCTL set_param fail_loc=0x139
1943         test_mkdir -p $DIR/$tdir
1944         trap simple_cleanup_common EXIT
1945         createmany -o $DIR/$tdir/t- 1000
1946         do_nodes $list $LCTL set_param fail_loc=0
1947
1948         TLOG=$TMP/$tfile.getstripe
1949         $LFS getstripe $DIR/$tdir > $TLOG
1950         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1951         unlinkmany $DIR/$tdir/t- 1000
1952         trap 0
1953         [[ $OBJS -gt 0 ]] &&
1954                 error "$OBJS objects created on OST-0. See $TLOG" ||
1955                 rm -f $TLOG
1956 }
1957 run_test 27u "skip object creation on OSC w/o objects"
1958
1959 test_27v() { # bug 4900
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         exhaust_all_precreations 0x215
1966         reset_enospc
1967
1968         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1969
1970         touch $DIR/$tdir/$tfile
1971         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1972         # all except ost1
1973         for (( i=1; i < OSTCOUNT; i++ )); do
1974                 do_facet ost$i lctl set_param fail_loc=0x705
1975         done
1976         local START=`date +%s`
1977         createmany -o $DIR/$tdir/$tfile 32
1978
1979         local FINISH=`date +%s`
1980         local TIMEOUT=`lctl get_param -n timeout`
1981         local PROCESS=$((FINISH - START))
1982         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1983                error "$FINISH - $START >= $TIMEOUT / 2"
1984         sleep $((TIMEOUT / 2 - PROCESS))
1985         reset_enospc
1986 }
1987 run_test 27v "skip object creation on slow OST"
1988
1989 test_27w() { # bug 10997
1990         test_mkdir $DIR/$tdir
1991         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1992         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1993                 error "stripe size $size != 65536" || true
1994         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1995                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1996 }
1997 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1998
1999 test_27wa() {
2000         [[ $OSTCOUNT -lt 2 ]] &&
2001                 skip_env "skipping multiple stripe count/offset test"
2002
2003         test_mkdir $DIR/$tdir
2004         for i in $(seq 1 $OSTCOUNT); do
2005                 offset=$((i - 1))
2006                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2007                         error "setstripe -c $i -i $offset failed"
2008                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2009                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2010                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2011                 [ $index -ne $offset ] &&
2012                         error "stripe offset $index != $offset" || true
2013         done
2014 }
2015 run_test 27wa "check $LFS setstripe -c -i options"
2016
2017 test_27x() {
2018         remote_ost_nodsh && skip "remote OST with nodsh"
2019         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2021
2022         OFFSET=$(($OSTCOUNT - 1))
2023         OSTIDX=0
2024         local OST=$(ostname_from_index $OSTIDX)
2025
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2028         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2029         sleep_maxage
2030         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2031         for i in $(seq 0 $OFFSET); do
2032                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2033                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2034                 error "OST0 was degraded but new created file still use it"
2035         done
2036         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2037 }
2038 run_test 27x "create files while OST0 is degraded"
2039
2040 test_27y() {
2041         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2042         remote_mds_nodsh && skip "remote MDS with nodsh"
2043         remote_ost_nodsh && skip "remote OST with nodsh"
2044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2045
2046         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2047         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2048                 osp.$mdtosc.prealloc_last_id)
2049         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2050                 osp.$mdtosc.prealloc_next_id)
2051         local fcount=$((last_id - next_id))
2052         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2053         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2054
2055         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2056                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2057         local OST_DEACTIVE_IDX=-1
2058         local OSC
2059         local OSTIDX
2060         local OST
2061
2062         for OSC in $MDS_OSCS; do
2063                 OST=$(osc_to_ost $OSC)
2064                 OSTIDX=$(index_from_ostuuid $OST)
2065                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2066                         OST_DEACTIVE_IDX=$OSTIDX
2067                 fi
2068                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2069                         echo $OSC "is Deactivated:"
2070                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2071                 fi
2072         done
2073
2074         OSTIDX=$(index_from_ostuuid $OST)
2075         test_mkdir $DIR/$tdir
2076         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2077
2078         for OSC in $MDS_OSCS; do
2079                 OST=$(osc_to_ost $OSC)
2080                 OSTIDX=$(index_from_ostuuid $OST)
2081                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2082                         echo $OST "is degraded:"
2083                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2084                                                 obdfilter.$OST.degraded=1
2085                 fi
2086         done
2087
2088         sleep_maxage
2089         createmany -o $DIR/$tdir/$tfile $fcount
2090
2091         for OSC in $MDS_OSCS; do
2092                 OST=$(osc_to_ost $OSC)
2093                 OSTIDX=$(index_from_ostuuid $OST)
2094                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2095                         echo $OST "is recovered from degraded:"
2096                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2097                                                 obdfilter.$OST.degraded=0
2098                 else
2099                         do_facet $SINGLEMDS lctl --device %$OSC activate
2100                 fi
2101         done
2102
2103         # all osp devices get activated, hence -1 stripe count restored
2104         local stripe_count=0
2105
2106         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2107         # devices get activated.
2108         sleep_maxage
2109         $LFS setstripe -c -1 $DIR/$tfile
2110         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2111         rm -f $DIR/$tfile
2112         [ $stripe_count -ne $OSTCOUNT ] &&
2113                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2114         return 0
2115 }
2116 run_test 27y "create files while OST0 is degraded and the rest inactive"
2117
2118 check_seq_oid()
2119 {
2120         log "check file $1"
2121
2122         lmm_count=$($LFS getstripe -c $1)
2123         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2124         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2125
2126         local old_ifs="$IFS"
2127         IFS=$'[:]'
2128         fid=($($LFS path2fid $1))
2129         IFS="$old_ifs"
2130
2131         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2132         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2133
2134         # compare lmm_seq and lu_fid->f_seq
2135         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2136         # compare lmm_object_id and lu_fid->oid
2137         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2138
2139         # check the trusted.fid attribute of the OST objects of the file
2140         local have_obdidx=false
2141         local stripe_nr=0
2142         $LFS getstripe $1 | while read obdidx oid hex seq; do
2143                 # skip lines up to and including "obdidx"
2144                 [ -z "$obdidx" ] && break
2145                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2146                 $have_obdidx || continue
2147
2148                 local ost=$((obdidx + 1))
2149                 local dev=$(ostdevname $ost)
2150                 local oid_hex
2151
2152                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2153
2154                 seq=$(echo $seq | sed -e "s/^0x//g")
2155                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2156                         oid_hex=$(echo $oid)
2157                 else
2158                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2159                 fi
2160                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2161
2162                 local ff=""
2163                 #
2164                 # Don't unmount/remount the OSTs if we don't need to do that.
2165                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2166                 # update too, until that use mount/ll_decode_filter_fid/mount.
2167                 # Re-enable when debugfs will understand new filter_fid.
2168                 #
2169                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2170                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2171                                 $dev 2>/dev/null" | grep "parent=")
2172                 fi
2173                 if [ -z "$ff" ]; then
2174                         stop ost$ost
2175                         mount_fstype ost$ost
2176                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2177                                 $(facet_mntpt ost$ost)/$obj_file)
2178                         unmount_fstype ost$ost
2179                         start ost$ost $dev $OST_MOUNT_OPTS
2180                         clients_up
2181                 fi
2182
2183                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2184
2185                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2186
2187                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2188                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2189                 #
2190                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2191                 #       stripe_size=1048576 component_id=1 component_start=0 \
2192                 #       component_end=33554432
2193                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2194                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2195                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2196                 local ff_pstripe
2197                 if grep -q 'stripe=' <<<$ff; then
2198                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2199                 else
2200                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2201                         # into f_ver in this case.  See comment on ff_parent.
2202                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2203                 fi
2204
2205                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2206                 [ $ff_pseq = $lmm_seq ] ||
2207                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2208                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2209                 [ $ff_poid = $lmm_oid ] ||
2210                         error "FF parent OID $ff_poid != $lmm_oid"
2211                 (($ff_pstripe == $stripe_nr)) ||
2212                         error "FF stripe $ff_pstripe != $stripe_nr"
2213
2214                 stripe_nr=$((stripe_nr + 1))
2215                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2216                         continue
2217                 if grep -q 'stripe_count=' <<<$ff; then
2218                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2219                                             -e 's/ .*//' <<<$ff)
2220                         [ $lmm_count = $ff_scnt ] ||
2221                                 error "FF stripe count $lmm_count != $ff_scnt"
2222                 fi
2223         done
2224 }
2225
2226 test_27z() {
2227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2228         remote_ost_nodsh && skip "remote OST with nodsh"
2229
2230         test_mkdir $DIR/$tdir
2231         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2232                 { error "setstripe -c -1 failed"; return 1; }
2233         # We need to send a write to every object to get parent FID info set.
2234         # This _should_ also work for setattr, but does not currently.
2235         # touch $DIR/$tdir/$tfile-1 ||
2236         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2237                 { error "dd $tfile-1 failed"; return 2; }
2238         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2239                 { error "setstripe -c -1 failed"; return 3; }
2240         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2241                 { error "dd $tfile-2 failed"; return 4; }
2242
2243         # make sure write RPCs have been sent to OSTs
2244         sync; sleep 5; sync
2245
2246         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2247         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2248 }
2249 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2250
2251 test_27A() { # b=19102
2252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2253
2254         save_layout_restore_at_exit $MOUNT
2255         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2256         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2257                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2258         local default_size=$($LFS getstripe -S $MOUNT)
2259         local default_offset=$($LFS getstripe -i $MOUNT)
2260         local dsize=$(do_facet $SINGLEMDS \
2261                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2262         [ $default_size -eq $dsize ] ||
2263                 error "stripe size $default_size != $dsize"
2264         [ $default_offset -eq -1 ] ||
2265                 error "stripe offset $default_offset != -1"
2266 }
2267 run_test 27A "check filesystem-wide default LOV EA values"
2268
2269 test_27B() { # LU-2523
2270         test_mkdir $DIR/$tdir
2271         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2272         touch $DIR/$tdir/f0
2273         # open f1 with O_LOV_DELAY_CREATE
2274         # rename f0 onto f1
2275         # call setstripe ioctl on open file descriptor for f1
2276         # close
2277         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2278                 $DIR/$tdir/f0
2279
2280         rm -f $DIR/$tdir/f1
2281         # open f1 with O_LOV_DELAY_CREATE
2282         # unlink f1
2283         # call setstripe ioctl on open file descriptor for f1
2284         # close
2285         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2286
2287         # Allow multiop to fail in imitation of NFS's busted semantics.
2288         true
2289 }
2290 run_test 27B "call setstripe on open unlinked file/rename victim"
2291
2292 # 27C family tests full striping and overstriping
2293 test_27Ca() { #LU-2871
2294         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2295
2296         declare -a ost_idx
2297         local index
2298         local found
2299         local i
2300         local j
2301
2302         test_mkdir $DIR/$tdir
2303         cd $DIR/$tdir
2304         for i in $(seq 0 $((OSTCOUNT - 1))); do
2305                 # set stripe across all OSTs starting from OST$i
2306                 $LFS setstripe -i $i -c -1 $tfile$i
2307                 # get striping information
2308                 ost_idx=($($LFS getstripe $tfile$i |
2309                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2310                 echo ${ost_idx[@]}
2311
2312                 # check the layout
2313                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2314                         error "${#ost_idx[@]} != $OSTCOUNT"
2315
2316                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2317                         found=0
2318                         for j in $(echo ${ost_idx[@]}); do
2319                                 if [ $index -eq $j ]; then
2320                                         found=1
2321                                         break
2322                                 fi
2323                         done
2324                         [ $found = 1 ] ||
2325                                 error "Can not find $index in ${ost_idx[@]}"
2326                 done
2327         done
2328 }
2329 run_test 27Ca "check full striping across all OSTs"
2330
2331 test_27Cb() {
2332         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2333                 skip "server does not support overstriping"
2334         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2335                 skip_env "too many osts, skipping"
2336
2337         test_mkdir -p $DIR/$tdir
2338         local setcount=$(($OSTCOUNT * 2))
2339         [ $setcount -ge 160 ] || large_xattr_enabled ||
2340                 skip_env "ea_inode feature disabled"
2341
2342         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2343                 error "setstripe failed"
2344
2345         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2346         [ $count -eq $setcount ] ||
2347                 error "stripe count $count, should be $setcount"
2348
2349         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2350                 error "overstriped should be set in pattern"
2351
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2353                 error "dd failed"
2354 }
2355 run_test 27Cb "more stripes than OSTs with -C"
2356
2357 test_27Cc() {
2358         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2359                 skip "server does not support overstriping"
2360         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2361
2362         test_mkdir -p $DIR/$tdir
2363         local setcount=$(($OSTCOUNT - 1))
2364
2365         [ $setcount -ge 160 ] || large_xattr_enabled ||
2366                 skip_env "ea_inode feature disabled"
2367
2368         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2369                 error "setstripe failed"
2370
2371         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2372         [ $count -eq $setcount ] ||
2373                 error "stripe count $count, should be $setcount"
2374
2375         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2376                 error "overstriped should not be set in pattern"
2377
2378         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2379                 error "dd failed"
2380 }
2381 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2382
2383 test_27Cd() {
2384         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2385                 skip "server does not support overstriping"
2386         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2387         large_xattr_enabled || skip_env "ea_inode feature disabled"
2388
2389         test_mkdir -p $DIR/$tdir
2390         local setcount=$LOV_MAX_STRIPE_COUNT
2391
2392         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2393                 error "setstripe failed"
2394
2395         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2396         [ $count -eq $setcount ] ||
2397                 error "stripe count $count, should be $setcount"
2398
2399         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2400                 error "overstriped should be set in pattern"
2401
2402         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2403                 error "dd failed"
2404
2405         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2406 }
2407 run_test 27Cd "test maximum stripe count"
2408
2409 test_27Ce() {
2410         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2411                 skip "server does not support overstriping"
2412         test_mkdir -p $DIR/$tdir
2413
2414         pool_add $TESTNAME || error "Pool creation failed"
2415         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2416
2417         local setcount=8
2418
2419         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2420                 error "setstripe failed"
2421
2422         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2423         [ $count -eq $setcount ] ||
2424                 error "stripe count $count, should be $setcount"
2425
2426         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2427                 error "overstriped should be set in pattern"
2428
2429         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2430                 error "dd failed"
2431
2432         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2433 }
2434 run_test 27Ce "test pool with overstriping"
2435
2436 test_27Cf() {
2437         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2438                 skip "server does not support overstriping"
2439         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2440                 skip_env "too many osts, skipping"
2441
2442         test_mkdir -p $DIR/$tdir
2443
2444         local setcount=$(($OSTCOUNT * 2))
2445         [ $setcount -ge 160 ] || large_xattr_enabled ||
2446                 skip_env "ea_inode feature disabled"
2447
2448         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2449                 error "setstripe failed"
2450
2451         echo 1 > $DIR/$tdir/$tfile
2452
2453         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2454         [ $count -eq $setcount ] ||
2455                 error "stripe count $count, should be $setcount"
2456
2457         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2458                 error "overstriped should be set in pattern"
2459
2460         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2461                 error "dd failed"
2462
2463         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2464 }
2465 run_test 27Cf "test default inheritance with overstriping"
2466
2467 test_27D() {
2468         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2469         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2470         remote_mds_nodsh && skip "remote MDS with nodsh"
2471
2472         local POOL=${POOL:-testpool}
2473         local first_ost=0
2474         local last_ost=$(($OSTCOUNT - 1))
2475         local ost_step=1
2476         local ost_list=$(seq $first_ost $ost_step $last_ost)
2477         local ost_range="$first_ost $last_ost $ost_step"
2478
2479         test_mkdir $DIR/$tdir
2480         pool_add $POOL || error "pool_add failed"
2481         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2482
2483         local skip27D
2484         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2485                 skip27D+="-s 29"
2486         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2487                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2488                         skip27D+=" -s 30,31"
2489         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2490           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2491                 skip27D+=" -s 32,33"
2492         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2493                 skip27D+=" -s 34"
2494         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2495                 error "llapi_layout_test failed"
2496
2497         destroy_test_pools || error "destroy test pools failed"
2498 }
2499 run_test 27D "validate llapi_layout API"
2500
2501 # Verify that default_easize is increased from its initial value after
2502 # accessing a widely striped file.
2503 test_27E() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2506                 skip "client does not have LU-3338 fix"
2507
2508         # 72 bytes is the minimum space required to store striping
2509         # information for a file striped across one OST:
2510         # (sizeof(struct lov_user_md_v3) +
2511         #  sizeof(struct lov_user_ost_data_v1))
2512         local min_easize=72
2513         $LCTL set_param -n llite.*.default_easize $min_easize ||
2514                 error "lctl set_param failed"
2515         local easize=$($LCTL get_param -n llite.*.default_easize)
2516
2517         [ $easize -eq $min_easize ] ||
2518                 error "failed to set default_easize"
2519
2520         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2521                 error "setstripe failed"
2522         # In order to ensure stat() call actually talks to MDS we need to
2523         # do something drastic to this file to shake off all lock, e.g.
2524         # rename it (kills lookup lock forcing cache cleaning)
2525         mv $DIR/$tfile $DIR/${tfile}-1
2526         ls -l $DIR/${tfile}-1
2527         rm $DIR/${tfile}-1
2528
2529         easize=$($LCTL get_param -n llite.*.default_easize)
2530
2531         [ $easize -gt $min_easize ] ||
2532                 error "default_easize not updated"
2533 }
2534 run_test 27E "check that default extended attribute size properly increases"
2535
2536 test_27F() { # LU-5346/LU-7975
2537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2538         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2539         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2540                 skip "Need MDS version at least 2.8.51"
2541         remote_ost_nodsh && skip "remote OST with nodsh"
2542
2543         test_mkdir $DIR/$tdir
2544         rm -f $DIR/$tdir/f0
2545         $LFS setstripe -c 2 $DIR/$tdir
2546
2547         # stop all OSTs to reproduce situation for LU-7975 ticket
2548         for num in $(seq $OSTCOUNT); do
2549                 stop ost$num
2550         done
2551
2552         # open/create f0 with O_LOV_DELAY_CREATE
2553         # truncate f0 to a non-0 size
2554         # close
2555         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2556
2557         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2558         # open/write it again to force delayed layout creation
2559         cat /etc/hosts > $DIR/$tdir/f0 &
2560         catpid=$!
2561
2562         # restart OSTs
2563         for num in $(seq $OSTCOUNT); do
2564                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2565                         error "ost$num failed to start"
2566         done
2567
2568         wait $catpid || error "cat failed"
2569
2570         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2571         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2572                 error "wrong stripecount"
2573
2574 }
2575 run_test 27F "Client resend delayed layout creation with non-zero size"
2576
2577 test_27G() { #LU-10629
2578         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2579                 skip "Need MDS version at least 2.11.51"
2580         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2581         remote_mds_nodsh && skip "remote MDS with nodsh"
2582         local POOL=${POOL:-testpool}
2583         local ostrange="0 0 1"
2584
2585         test_mkdir $DIR/$tdir
2586         pool_add $POOL || error "pool_add failed"
2587         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2588         $LFS setstripe -p $POOL $DIR/$tdir
2589
2590         local pool=$($LFS getstripe -p $DIR/$tdir)
2591
2592         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2593
2594         $LFS setstripe -d $DIR/$tdir
2595
2596         pool=$($LFS getstripe -p $DIR/$tdir)
2597
2598         rmdir $DIR/$tdir
2599
2600         [ -z "$pool" ] || error "'$pool' is not empty"
2601 }
2602 run_test 27G "Clear OST pool from stripe"
2603
2604 test_27H() {
2605         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2606                 skip "Need MDS version newer than 2.11.54"
2607         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2608         test_mkdir $DIR/$tdir
2609         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2610         touch $DIR/$tdir/$tfile
2611         $LFS getstripe -c $DIR/$tdir/$tfile
2612         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2613                 error "two-stripe file doesn't have two stripes"
2614
2615         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2616         $LFS getstripe -y $DIR/$tdir/$tfile
2617         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2618              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2619                 error "expected l_ost_idx: [02]$ not matched"
2620
2621         # make sure ost list has been cleared
2622         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2623         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2624                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2625         touch $DIR/$tdir/f3
2626         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2627 }
2628 run_test 27H "Set specific OSTs stripe"
2629
2630 test_27I() {
2631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2632         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2633         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2634                 skip "Need MDS version newer than 2.12.52"
2635         local pool=$TESTNAME
2636         local ostrange="1 1 1"
2637
2638         save_layout_restore_at_exit $MOUNT
2639         $LFS setstripe -c 2 -i 0 $MOUNT
2640         pool_add $pool || error "pool_add failed"
2641         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2642         test_mkdir $DIR/$tdir
2643         $LFS setstripe -p $pool $DIR/$tdir
2644         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2645         $LFS getstripe $DIR/$tdir/$tfile
2646 }
2647 run_test 27I "check that root dir striping does not break parent dir one"
2648
2649 test_27J() {
2650         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2651                 skip "Need MDS version newer than 2.12.51"
2652
2653         test_mkdir $DIR/$tdir
2654         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2655         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2656
2657         # create foreign file (raw way)
2658         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2659                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2660
2661         # verify foreign file (raw way)
2662         parse_foreign_file -f $DIR/$tdir/$tfile |
2663                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2664                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2665         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2666                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2667         parse_foreign_file -f $DIR/$tdir/$tfile |
2668                 grep "lov_foreign_size: 73" ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2670         parse_foreign_file -f $DIR/$tdir/$tfile |
2671                 grep "lov_foreign_type: 1" ||
2672                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2673         parse_foreign_file -f $DIR/$tdir/$tfile |
2674                 grep "lov_foreign_flags: 0x0000DA08" ||
2675                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2676         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2677                 grep "lov_foreign_value: 0x" |
2678                 sed -e 's/lov_foreign_value: 0x//')
2679         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2680         [[ $lov = ${lov2// /} ]] ||
2681                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2682
2683         # create foreign file (lfs + API)
2684         $LFS setstripe --foreign=daos --flags 0xda08 \
2685                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2686                 error "$DIR/$tdir/${tfile}2: create failed"
2687
2688         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2689                 grep "lfm_magic:.*0x0BD70BD0" ||
2690                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2691         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2692         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2693                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2694         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2695                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2696         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2697                 grep "lfm_flags:.*0x0000DA08" ||
2698                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2699         $LFS getstripe $DIR/$tdir/${tfile}2 |
2700                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2701                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2702
2703         # modify striping should fail
2704         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2705                 error "$DIR/$tdir/$tfile: setstripe should fail"
2706         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2707                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2708
2709         # R/W should fail
2710         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2711         cat $DIR/$tdir/${tfile}2 &&
2712                 error "$DIR/$tdir/${tfile}2: read should fail"
2713         cat /etc/passwd > $DIR/$tdir/$tfile &&
2714                 error "$DIR/$tdir/$tfile: write should fail"
2715         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2716                 error "$DIR/$tdir/${tfile}2: write should fail"
2717
2718         # chmod should work
2719         chmod 222 $DIR/$tdir/$tfile ||
2720                 error "$DIR/$tdir/$tfile: chmod failed"
2721         chmod 222 $DIR/$tdir/${tfile}2 ||
2722                 error "$DIR/$tdir/${tfile}2: chmod failed"
2723
2724         # chown should work
2725         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2726                 error "$DIR/$tdir/$tfile: chown failed"
2727         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2728                 error "$DIR/$tdir/${tfile}2: chown failed"
2729
2730         # rename should work
2731         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2732                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2733         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2734                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2735
2736         #remove foreign file
2737         rm $DIR/$tdir/${tfile}.new ||
2738                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2739         rm $DIR/$tdir/${tfile}2.new ||
2740                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2741 }
2742 run_test 27J "basic ops on file with foreign LOV"
2743
2744 test_27K() {
2745         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2746                 skip "Need MDS version newer than 2.12.49"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign dir (raw way)
2753         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2754                 error "create_foreign_dir FAILED"
2755
2756         # verify foreign dir (raw way)
2757         parse_foreign_dir -d $DIR/$tdir/$tdir |
2758                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2759                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2760         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2761                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2762         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2763                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2764         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2765                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2766         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2767                 grep "lmv_foreign_value: 0x" |
2768                 sed 's/lmv_foreign_value: 0x//')
2769         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2770                 sed 's/ //g')
2771         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2772
2773         # create foreign dir (lfs + API)
2774         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2775                 $DIR/$tdir/${tdir}2 ||
2776                 error "$DIR/$tdir/${tdir}2: create failed"
2777
2778         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2779                 grep "lfm_magic:.*0x0CD50CD0" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2781         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2782         # - sizeof(lfm_type) - sizeof(lfm_flags)
2783         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2784                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2785         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2786                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2787         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2788                 grep "lfm_flags:.*0x0000DA05" ||
2789                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2790         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2791                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2792                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2793
2794         # file create in dir should fail
2795         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2796         touch $DIR/$tdir/${tdir}2/$tfile &&
2797                 "$DIR/${tdir}2: file create should fail"
2798
2799         # chmod should work
2800         chmod 777 $DIR/$tdir/$tdir ||
2801                 error "$DIR/$tdir: chmod failed"
2802         chmod 777 $DIR/$tdir/${tdir}2 ||
2803                 error "$DIR/${tdir}2: chmod failed"
2804
2805         # chown should work
2806         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2807                 error "$DIR/$tdir: chown failed"
2808         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2809                 error "$DIR/${tdir}2: chown failed"
2810
2811         # rename should work
2812         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2813                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2814         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2815                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2816
2817         #remove foreign dir
2818         rmdir $DIR/$tdir/${tdir}.new ||
2819                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2820         rmdir $DIR/$tdir/${tdir}2.new ||
2821                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2822 }
2823 run_test 27K "basic ops on dir with foreign LMV"
2824
2825 test_27L() {
2826         remote_mds_nodsh && skip "remote MDS with nodsh"
2827
2828         local POOL=${POOL:-$TESTNAME}
2829
2830         pool_add $POOL || error "pool_add failed"
2831
2832         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2833                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2834                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2835 }
2836 run_test 27L "lfs pool_list gives correct pool name"
2837
2838 test_27M() {
2839         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2840                 skip "Need MDS version >= than 2.12.57"
2841         remote_mds_nodsh && skip "remote MDS with nodsh"
2842         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2843
2844         test_mkdir $DIR/$tdir
2845
2846         # Set default striping on directory
2847         $LFS setstripe -C 4 $DIR/$tdir
2848
2849         echo 1 > $DIR/$tdir/${tfile}.1
2850         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2851         local setcount=4
2852         [ $count -eq $setcount ] ||
2853                 error "(1) stripe count $count, should be $setcount"
2854
2855         # Capture existing append_stripe_count setting for restore
2856         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2857         local mdts=$(comma_list $(mdts_nodes))
2858         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2859
2860         local appendcount=$orig_count
2861         echo 1 >> $DIR/$tdir/${tfile}.2_append
2862         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2863         [ $count -eq $appendcount ] ||
2864                 error "(2)stripe count $count, should be $appendcount for append"
2865
2866         # Disable O_APPEND striping, verify it works
2867         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2868
2869         # Should now get the default striping, which is 4
2870         setcount=4
2871         echo 1 >> $DIR/$tdir/${tfile}.3_append
2872         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2873         [ $count -eq $setcount ] ||
2874                 error "(3) stripe count $count, should be $setcount"
2875
2876         # Try changing the stripe count for append files
2877         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2878
2879         # Append striping is now 2 (directory default is still 4)
2880         appendcount=2
2881         echo 1 >> $DIR/$tdir/${tfile}.4_append
2882         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2883         [ $count -eq $appendcount ] ||
2884                 error "(4) stripe count $count, should be $appendcount for append"
2885
2886         # Test append stripe count of -1
2887         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2888         appendcount=$OSTCOUNT
2889         echo 1 >> $DIR/$tdir/${tfile}.5
2890         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2891         [ $count -eq $appendcount ] ||
2892                 error "(5) stripe count $count, should be $appendcount for append"
2893
2894         # Set append striping back to default of 1
2895         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2896
2897         # Try a new default striping, PFL + DOM
2898         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2899
2900         # Create normal DOM file, DOM returns stripe count == 0
2901         setcount=0
2902         touch $DIR/$tdir/${tfile}.6
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2904         [ $count -eq $setcount ] ||
2905                 error "(6) stripe count $count, should be $setcount"
2906
2907         # Show
2908         appendcount=1
2909         echo 1 >> $DIR/$tdir/${tfile}.7_append
2910         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2911         [ $count -eq $appendcount ] ||
2912                 error "(7) stripe count $count, should be $appendcount for append"
2913
2914         # Clean up DOM layout
2915         $LFS setstripe -d $DIR/$tdir
2916
2917         # Now test that append striping works when layout is from root
2918         $LFS setstripe -c 2 $MOUNT
2919         # Make a special directory for this
2920         mkdir $DIR/${tdir}/${tdir}.2
2921         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2922
2923         # Verify for normal file
2924         setcount=2
2925         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2926         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2927         [ $count -eq $setcount ] ||
2928                 error "(8) stripe count $count, should be $setcount"
2929
2930         appendcount=1
2931         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2932         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2933         [ $count -eq $appendcount ] ||
2934                 error "(9) stripe count $count, should be $appendcount for append"
2935
2936         # Now test O_APPEND striping with pools
2937         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2938         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2939
2940         # Create the pool
2941         pool_add $TESTNAME || error "pool creation failed"
2942         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2943
2944         echo 1 >> $DIR/$tdir/${tfile}.10_append
2945
2946         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2947         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2948
2949         # Check that count is still correct
2950         appendcount=1
2951         echo 1 >> $DIR/$tdir/${tfile}.11_append
2952         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2953         [ $count -eq $appendcount ] ||
2954                 error "(11) stripe count $count, should be $appendcount for append"
2955
2956         # Disable O_APPEND stripe count, verify pool works separately
2957         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2958
2959         echo 1 >> $DIR/$tdir/${tfile}.12_append
2960
2961         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2962         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2963
2964         # Remove pool setting, verify it's not applied
2965         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2966
2967         echo 1 >> $DIR/$tdir/${tfile}.13_append
2968
2969         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2970         [ "$pool" = "" ] || error "(13) pool found: $pool"
2971 }
2972 run_test 27M "test O_APPEND striping"
2973
2974 test_27N() {
2975         combined_mgs_mds && skip "needs separate MGS/MDT"
2976
2977         pool_add $TESTNAME || error "pool_add failed"
2978         do_facet mgs "$LCTL pool_list $FSNAME" |
2979                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2980                 error "lctl pool_list on MGS failed"
2981 }
2982 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2983
2984 # createtest also checks that device nodes are created and
2985 # then visible correctly (#2091)
2986 test_28() { # bug 2091
2987         test_mkdir $DIR/d28
2988         $CREATETEST $DIR/d28/ct || error "createtest failed"
2989 }
2990 run_test 28 "create/mknod/mkdir with bad file types ============"
2991
2992 test_29() {
2993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2994
2995         sync; sleep 1; sync # flush out any dirty pages from previous tests
2996         cancel_lru_locks
2997         test_mkdir $DIR/d29
2998         touch $DIR/d29/foo
2999         log 'first d29'
3000         ls -l $DIR/d29
3001
3002         declare -i LOCKCOUNTORIG=0
3003         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3004                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3005         done
3006         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3007
3008         declare -i LOCKUNUSEDCOUNTORIG=0
3009         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3010                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3011         done
3012
3013         log 'second d29'
3014         ls -l $DIR/d29
3015         log 'done'
3016
3017         declare -i LOCKCOUNTCURRENT=0
3018         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3019                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3020         done
3021
3022         declare -i LOCKUNUSEDCOUNTCURRENT=0
3023         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3024                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3025         done
3026
3027         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3028                 $LCTL set_param -n ldlm.dump_namespaces ""
3029                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3030                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3031                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3032                 return 2
3033         fi
3034         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3035                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3036                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3037                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3038                 return 3
3039         fi
3040 }
3041 run_test 29 "IT_GETATTR regression  ============================"
3042
3043 test_30a() { # was test_30
3044         cp $(which ls) $DIR || cp /bin/ls $DIR
3045         $DIR/ls / || error "Can't execute binary from lustre"
3046         rm $DIR/ls
3047 }
3048 run_test 30a "execute binary from Lustre (execve) =============="
3049
3050 test_30b() {
3051         cp `which ls` $DIR || cp /bin/ls $DIR
3052         chmod go+rx $DIR/ls
3053         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3054         rm $DIR/ls
3055 }
3056 run_test 30b "execute binary from Lustre as non-root ==========="
3057
3058 test_30c() { # b=22376
3059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3060
3061         cp `which ls` $DIR || cp /bin/ls $DIR
3062         chmod a-rw $DIR/ls
3063         cancel_lru_locks mdc
3064         cancel_lru_locks osc
3065         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3066         rm -f $DIR/ls
3067 }
3068 run_test 30c "execute binary from Lustre without read perms ===="
3069
3070 test_31a() {
3071         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3072         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3073 }
3074 run_test 31a "open-unlink file =================================="
3075
3076 test_31b() {
3077         touch $DIR/f31 || error "touch $DIR/f31 failed"
3078         ln $DIR/f31 $DIR/f31b || error "ln failed"
3079         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3080         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3081 }
3082 run_test 31b "unlink file with multiple links while open ======="
3083
3084 test_31c() {
3085         touch $DIR/f31 || error "touch $DIR/f31 failed"
3086         ln $DIR/f31 $DIR/f31c || error "ln failed"
3087         multiop_bg_pause $DIR/f31 O_uc ||
3088                 error "multiop_bg_pause for $DIR/f31 failed"
3089         MULTIPID=$!
3090         $MULTIOP $DIR/f31c Ouc
3091         kill -USR1 $MULTIPID
3092         wait $MULTIPID
3093 }
3094 run_test 31c "open-unlink file with multiple links ============="
3095
3096 test_31d() {
3097         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3098         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3099 }
3100 run_test 31d "remove of open directory ========================="
3101
3102 test_31e() { # bug 2904
3103         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3104 }
3105 run_test 31e "remove of open non-empty directory ==============="
3106
3107 test_31f() { # bug 4554
3108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3109
3110         set -vx
3111         test_mkdir $DIR/d31f
3112         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3113         cp /etc/hosts $DIR/d31f
3114         ls -l $DIR/d31f
3115         $LFS getstripe $DIR/d31f/hosts
3116         multiop_bg_pause $DIR/d31f D_c || return 1
3117         MULTIPID=$!
3118
3119         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3120         test_mkdir $DIR/d31f
3121         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3122         cp /etc/hosts $DIR/d31f
3123         ls -l $DIR/d31f
3124         $LFS getstripe $DIR/d31f/hosts
3125         multiop_bg_pause $DIR/d31f D_c || return 1
3126         MULTIPID2=$!
3127
3128         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3129         wait $MULTIPID || error "first opendir $MULTIPID failed"
3130
3131         sleep 6
3132
3133         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3134         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3135         set +vx
3136 }
3137 run_test 31f "remove of open directory with open-unlink file ==="
3138
3139 test_31g() {
3140         echo "-- cross directory link --"
3141         test_mkdir -c1 $DIR/${tdir}ga
3142         test_mkdir -c1 $DIR/${tdir}gb
3143         touch $DIR/${tdir}ga/f
3144         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3145         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3146         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3147         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3148         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3149 }
3150 run_test 31g "cross directory link==============="
3151
3152 test_31h() {
3153         echo "-- cross directory link --"
3154         test_mkdir -c1 $DIR/${tdir}
3155         test_mkdir -c1 $DIR/${tdir}/dir
3156         touch $DIR/${tdir}/f
3157         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3158         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3159         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3160         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3161         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3162 }
3163 run_test 31h "cross directory link under child==============="
3164
3165 test_31i() {
3166         echo "-- cross directory link --"
3167         test_mkdir -c1 $DIR/$tdir
3168         test_mkdir -c1 $DIR/$tdir/dir
3169         touch $DIR/$tdir/dir/f
3170         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3171         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3172         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3173         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3174         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3175 }
3176 run_test 31i "cross directory link under parent==============="
3177
3178 test_31j() {
3179         test_mkdir -c1 -p $DIR/$tdir
3180         test_mkdir -c1 -p $DIR/$tdir/dir1
3181         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3182         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3183         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3184         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3185         return 0
3186 }
3187 run_test 31j "link for directory==============="
3188
3189 test_31k() {
3190         test_mkdir -c1 -p $DIR/$tdir
3191         touch $DIR/$tdir/s
3192         touch $DIR/$tdir/exist
3193         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3194         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3195         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3196         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3197         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3198         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3199         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3200         return 0
3201 }
3202 run_test 31k "link to file: the same, non-existing, dir==============="
3203
3204 test_31m() {
3205         mkdir $DIR/d31m
3206         touch $DIR/d31m/s
3207         mkdir $DIR/d31m2
3208         touch $DIR/d31m2/exist
3209         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3210         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3211         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3212         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3213         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3214         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3215         return 0
3216 }
3217 run_test 31m "link to file: the same, non-existing, dir==============="
3218
3219 test_31n() {
3220         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3221         nlink=$(stat --format=%h $DIR/$tfile)
3222         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3223         local fd=$(free_fd)
3224         local cmd="exec $fd<$DIR/$tfile"
3225         eval $cmd
3226         cmd="exec $fd<&-"
3227         trap "eval $cmd" EXIT
3228         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3229         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3230         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3231         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3232         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3233         eval $cmd
3234 }
3235 run_test 31n "check link count of unlinked file"
3236
3237 link_one() {
3238         local tempfile=$(mktemp $1_XXXXXX)
3239         mlink $tempfile $1 2> /dev/null &&
3240                 echo "$BASHPID: link $tempfile to $1 succeeded"
3241         munlink $tempfile
3242 }
3243
3244 test_31o() { # LU-2901
3245         test_mkdir $DIR/$tdir
3246         for LOOP in $(seq 100); do
3247                 rm -f $DIR/$tdir/$tfile*
3248                 for THREAD in $(seq 8); do
3249                         link_one $DIR/$tdir/$tfile.$LOOP &
3250                 done
3251                 wait
3252                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3253                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3254                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3255                         break || true
3256         done
3257 }
3258 run_test 31o "duplicate hard links with same filename"
3259
3260 test_31p() {
3261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3262
3263         test_mkdir $DIR/$tdir
3264         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3265         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3266
3267         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3268                 error "open unlink test1 failed"
3269         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3270                 error "open unlink test2 failed"
3271
3272         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3273                 error "test1 still exists"
3274         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3275                 error "test2 still exists"
3276 }
3277 run_test 31p "remove of open striped directory"
3278
3279 cleanup_test32_mount() {
3280         local rc=0
3281         trap 0
3282         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3283         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3284         losetup -d $loopdev || true
3285         rm -rf $DIR/$tdir
3286         return $rc
3287 }
3288
3289 test_32a() {
3290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3291
3292         echo "== more mountpoints and symlinks ================="
3293         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3294         trap cleanup_test32_mount EXIT
3295         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3296         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3297                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3298         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3299                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3300         cleanup_test32_mount
3301 }
3302 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3303
3304 test_32b() {
3305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3306
3307         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3308         trap cleanup_test32_mount EXIT
3309         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3310         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3311                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3312         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3313                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3314         cleanup_test32_mount
3315 }
3316 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3317
3318 test_32c() {
3319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3320
3321         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3322         trap cleanup_test32_mount EXIT
3323         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3324         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3325                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3326         test_mkdir -p $DIR/$tdir/d2/test_dir
3327         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3328                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3329         cleanup_test32_mount
3330 }
3331 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3332
3333 test_32d() {
3334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3335
3336         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3337         trap cleanup_test32_mount EXIT
3338         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3339         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3340                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3341         test_mkdir -p $DIR/$tdir/d2/test_dir
3342         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3343                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3344         cleanup_test32_mount
3345 }
3346 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3347
3348 test_32e() {
3349         rm -fr $DIR/$tdir
3350         test_mkdir -p $DIR/$tdir/tmp
3351         local tmp_dir=$DIR/$tdir/tmp
3352         ln -s $DIR/$tdir $tmp_dir/symlink11
3353         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3354         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3355         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3356 }
3357 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3358
3359 test_32f() {
3360         rm -fr $DIR/$tdir
3361         test_mkdir -p $DIR/$tdir/tmp
3362         local tmp_dir=$DIR/$tdir/tmp
3363         ln -s $DIR/$tdir $tmp_dir/symlink11
3364         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3365         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3366         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3367 }
3368 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3369
3370 test_32g() {
3371         local tmp_dir=$DIR/$tdir/tmp
3372         test_mkdir -p $tmp_dir
3373         test_mkdir $DIR/${tdir}2
3374         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3375         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3376         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3377         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3378         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3379         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3380 }
3381 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3382
3383 test_32h() {
3384         rm -fr $DIR/$tdir $DIR/${tdir}2
3385         tmp_dir=$DIR/$tdir/tmp
3386         test_mkdir -p $tmp_dir
3387         test_mkdir $DIR/${tdir}2
3388         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3389         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3390         ls $tmp_dir/symlink12 || error "listing symlink12"
3391         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3392 }
3393 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3394
3395 test_32i() {
3396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3397
3398         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3399         trap cleanup_test32_mount EXIT
3400         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3401         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3402                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3403         touch $DIR/$tdir/test_file
3404         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3405                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3406         cleanup_test32_mount
3407 }
3408 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3409
3410 test_32j() {
3411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3412
3413         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3414         trap cleanup_test32_mount EXIT
3415         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3416         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3417                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3418         touch $DIR/$tdir/test_file
3419         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3420                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3421         cleanup_test32_mount
3422 }
3423 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3424
3425 test_32k() {
3426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3427
3428         rm -fr $DIR/$tdir
3429         trap cleanup_test32_mount EXIT
3430         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3431         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3432                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3433         test_mkdir -p $DIR/$tdir/d2
3434         touch $DIR/$tdir/d2/test_file || error "touch failed"
3435         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3436                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3437         cleanup_test32_mount
3438 }
3439 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3440
3441 test_32l() {
3442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3443
3444         rm -fr $DIR/$tdir
3445         trap cleanup_test32_mount EXIT
3446         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3447         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3448                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3449         test_mkdir -p $DIR/$tdir/d2
3450         touch $DIR/$tdir/d2/test_file || error "touch failed"
3451         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3452                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3453         cleanup_test32_mount
3454 }
3455 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3456
3457 test_32m() {
3458         rm -fr $DIR/d32m
3459         test_mkdir -p $DIR/d32m/tmp
3460         TMP_DIR=$DIR/d32m/tmp
3461         ln -s $DIR $TMP_DIR/symlink11
3462         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3463         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3464                 error "symlink11 not a link"
3465         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3466                 error "symlink01 not a link"
3467 }
3468 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3469
3470 test_32n() {
3471         rm -fr $DIR/d32n
3472         test_mkdir -p $DIR/d32n/tmp
3473         TMP_DIR=$DIR/d32n/tmp
3474         ln -s $DIR $TMP_DIR/symlink11
3475         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3476         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3477         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3478 }
3479 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3480
3481 test_32o() {
3482         touch $DIR/$tfile
3483         test_mkdir -p $DIR/d32o/tmp
3484         TMP_DIR=$DIR/d32o/tmp
3485         ln -s $DIR/$tfile $TMP_DIR/symlink12
3486         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3487         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3488                 error "symlink12 not a link"
3489         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3490         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3491                 error "$DIR/d32o/tmp/symlink12 not file type"
3492         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3493                 error "$DIR/d32o/symlink02 not file type"
3494 }
3495 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3496
3497 test_32p() {
3498         log 32p_1
3499         rm -fr $DIR/d32p
3500         log 32p_2
3501         rm -f $DIR/$tfile
3502         log 32p_3
3503         touch $DIR/$tfile
3504         log 32p_4
3505         test_mkdir -p $DIR/d32p/tmp
3506         log 32p_5
3507         TMP_DIR=$DIR/d32p/tmp
3508         log 32p_6
3509         ln -s $DIR/$tfile $TMP_DIR/symlink12
3510         log 32p_7
3511         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3512         log 32p_8
3513         cat $DIR/d32p/tmp/symlink12 ||
3514                 error "Can't open $DIR/d32p/tmp/symlink12"
3515         log 32p_9
3516         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3517         log 32p_10
3518 }
3519 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3520
3521 test_32q() {
3522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3523
3524         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3525         trap cleanup_test32_mount EXIT
3526         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3527         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3528         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3529                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3530         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3531         cleanup_test32_mount
3532 }
3533 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3534
3535 test_32r() {
3536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3537
3538         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3539         trap cleanup_test32_mount EXIT
3540         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3541         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3542         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3543                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3544         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3545         cleanup_test32_mount
3546 }
3547 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3548
3549 test_33aa() {
3550         rm -f $DIR/$tfile
3551         touch $DIR/$tfile
3552         chmod 444 $DIR/$tfile
3553         chown $RUNAS_ID $DIR/$tfile
3554         log 33_1
3555         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3556         log 33_2
3557 }
3558 run_test 33aa "write file with mode 444 (should return error)"
3559
3560 test_33a() {
3561         rm -fr $DIR/$tdir
3562         test_mkdir $DIR/$tdir
3563         chown $RUNAS_ID $DIR/$tdir
3564         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3565                 error "$RUNAS create $tdir/$tfile failed"
3566         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3567                 error "open RDWR" || true
3568 }
3569 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3570
3571 test_33b() {
3572         rm -fr $DIR/$tdir
3573         test_mkdir $DIR/$tdir
3574         chown $RUNAS_ID $DIR/$tdir
3575         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3576 }
3577 run_test 33b "test open file with malformed flags (No panic)"
3578
3579 test_33c() {
3580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3581         remote_ost_nodsh && skip "remote OST with nodsh"
3582
3583         local ostnum
3584         local ostname
3585         local write_bytes
3586         local all_zeros
3587
3588         all_zeros=:
3589         rm -fr $DIR/$tdir
3590         test_mkdir $DIR/$tdir
3591         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3592
3593         sync
3594         for ostnum in $(seq $OSTCOUNT); do
3595                 # test-framework's OST numbering is one-based, while Lustre's
3596                 # is zero-based
3597                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3598                 # Parsing llobdstat's output sucks; we could grep the /proc
3599                 # path, but that's likely to not be as portable as using the
3600                 # llobdstat utility.  So we parse lctl output instead.
3601                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3602                         obdfilter/$ostname/stats |
3603                         awk '/^write_bytes/ {print $7}' )
3604                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3605                 if (( ${write_bytes:-0} > 0 ))
3606                 then
3607                         all_zeros=false
3608                         break;
3609                 fi
3610         done
3611
3612         $all_zeros || return 0
3613
3614         # Write four bytes
3615         echo foo > $DIR/$tdir/bar
3616         # Really write them
3617         sync
3618
3619         # Total up write_bytes after writing.  We'd better find non-zeros.
3620         for ostnum in $(seq $OSTCOUNT); do
3621                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3622                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3623                         obdfilter/$ostname/stats |
3624                         awk '/^write_bytes/ {print $7}' )
3625                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3626                 if (( ${write_bytes:-0} > 0 ))
3627                 then
3628                         all_zeros=false
3629                         break;
3630                 fi
3631         done
3632
3633         if $all_zeros
3634         then
3635                 for ostnum in $(seq $OSTCOUNT); do
3636                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3637                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3638                         do_facet ost$ostnum lctl get_param -n \
3639                                 obdfilter/$ostname/stats
3640                 done
3641                 error "OST not keeping write_bytes stats (b22312)"
3642         fi
3643 }
3644 run_test 33c "test llobdstat and write_bytes"
3645
3646 test_33d() {
3647         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3649
3650         local MDTIDX=1
3651         local remote_dir=$DIR/$tdir/remote_dir
3652
3653         test_mkdir $DIR/$tdir
3654         $LFS mkdir -i $MDTIDX $remote_dir ||
3655                 error "create remote directory failed"
3656
3657         touch $remote_dir/$tfile
3658         chmod 444 $remote_dir/$tfile
3659         chown $RUNAS_ID $remote_dir/$tfile
3660
3661         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3662
3663         chown $RUNAS_ID $remote_dir
3664         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3665                                         error "create" || true
3666         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3667                                     error "open RDWR" || true
3668         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3669 }
3670 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3671
3672 test_33e() {
3673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3674
3675         mkdir $DIR/$tdir
3676
3677         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3678         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3679         mkdir $DIR/$tdir/local_dir
3680
3681         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3682         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3683         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3684
3685         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3686                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3687
3688         rmdir $DIR/$tdir/* || error "rmdir failed"
3689
3690         umask 777
3691         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3692         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3693         mkdir $DIR/$tdir/local_dir
3694
3695         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3696         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3697         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3698
3699         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3700                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3701
3702         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3703
3704         umask 000
3705         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3706         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3707         mkdir $DIR/$tdir/local_dir
3708
3709         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3710         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3711         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3712
3713         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3714                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3715 }
3716 run_test 33e "mkdir and striped directory should have same mode"
3717
3718 cleanup_33f() {
3719         trap 0
3720         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3721 }
3722
3723 test_33f() {
3724         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3725         remote_mds_nodsh && skip "remote MDS with nodsh"
3726
3727         mkdir $DIR/$tdir
3728         chmod go+rwx $DIR/$tdir
3729         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3730         trap cleanup_33f EXIT
3731
3732         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3733                 error "cannot create striped directory"
3734
3735         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3736                 error "cannot create files in striped directory"
3737
3738         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3739                 error "cannot remove files in striped directory"
3740
3741         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3742                 error "cannot remove striped directory"
3743
3744         cleanup_33f
3745 }
3746 run_test 33f "nonroot user can create, access, and remove a striped directory"
3747
3748 test_33g() {
3749         mkdir -p $DIR/$tdir/dir2
3750
3751         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3752         echo $err
3753         [[ $err =~ "exists" ]] || error "Not exists error"
3754 }
3755 run_test 33g "nonroot user create already existing root created file"
3756
3757 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3758 test_34a() {
3759         rm -f $DIR/f34
3760         $MCREATE $DIR/f34 || error "mcreate failed"
3761         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3762                 error "getstripe failed"
3763         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3764         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3765                 error "getstripe failed"
3766         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3767                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3768 }
3769 run_test 34a "truncate file that has not been opened ==========="
3770
3771 test_34b() {
3772         [ ! -f $DIR/f34 ] && test_34a
3773         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3774                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3775         $OPENFILE -f O_RDONLY $DIR/f34
3776         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3777                 error "getstripe failed"
3778         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3779                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3780 }
3781 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3782
3783 test_34c() {
3784         [ ! -f $DIR/f34 ] && test_34a
3785         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3786                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3787         $OPENFILE -f O_RDWR $DIR/f34
3788         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3789                 error "$LFS getstripe failed"
3790         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3791                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3792 }
3793 run_test 34c "O_RDWR opening file-with-size works =============="
3794
3795 test_34d() {
3796         [ ! -f $DIR/f34 ] && test_34a
3797         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3798                 error "dd failed"
3799         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3800                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3801         rm $DIR/f34
3802 }
3803 run_test 34d "write to sparse file ============================="
3804
3805 test_34e() {
3806         rm -f $DIR/f34e
3807         $MCREATE $DIR/f34e || error "mcreate failed"
3808         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3809         $CHECKSTAT -s 1000 $DIR/f34e ||
3810                 error "Size of $DIR/f34e not equal to 1000 bytes"
3811         $OPENFILE -f O_RDWR $DIR/f34e
3812         $CHECKSTAT -s 1000 $DIR/f34e ||
3813                 error "Size of $DIR/f34e not equal to 1000 bytes"
3814 }
3815 run_test 34e "create objects, some with size and some without =="
3816
3817 test_34f() { # bug 6242, 6243
3818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3819
3820         SIZE34F=48000
3821         rm -f $DIR/f34f
3822         $MCREATE $DIR/f34f || error "mcreate failed"
3823         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3824         dd if=$DIR/f34f of=$TMP/f34f
3825         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3826         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3827         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3828         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3829         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3830 }
3831 run_test 34f "read from a file with no objects until EOF ======="
3832
3833 test_34g() {
3834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3835
3836         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3837                 error "dd failed"
3838         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3839         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3840                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3841         cancel_lru_locks osc
3842         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3843                 error "wrong size after lock cancel"
3844
3845         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3846         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3847                 error "expanding truncate failed"
3848         cancel_lru_locks osc
3849         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3850                 error "wrong expanded size after lock cancel"
3851 }
3852 run_test 34g "truncate long file ==============================="
3853
3854 test_34h() {
3855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3856
3857         local gid=10
3858         local sz=1000
3859
3860         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3861         sync # Flush the cache so that multiop below does not block on cache
3862              # flush when getting the group lock
3863         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3864         MULTIPID=$!
3865
3866         # Since just timed wait is not good enough, let's do a sync write
3867         # that way we are sure enough time for a roundtrip + processing
3868         # passed + 2 seconds of extra margin.
3869         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3870         rm $DIR/${tfile}-1
3871         sleep 2
3872
3873         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3874                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3875                 kill -9 $MULTIPID
3876         fi
3877         wait $MULTIPID
3878         local nsz=`stat -c %s $DIR/$tfile`
3879         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3880 }
3881 run_test 34h "ftruncate file under grouplock should not block"
3882
3883 test_35a() {
3884         cp /bin/sh $DIR/f35a
3885         chmod 444 $DIR/f35a
3886         chown $RUNAS_ID $DIR/f35a
3887         $RUNAS $DIR/f35a && error || true
3888         rm $DIR/f35a
3889 }
3890 run_test 35a "exec file with mode 444 (should return and not leak)"
3891
3892 test_36a() {
3893         rm -f $DIR/f36
3894         utime $DIR/f36 || error "utime failed for MDS"
3895 }
3896 run_test 36a "MDS utime check (mknod, utime)"
3897
3898 test_36b() {
3899         echo "" > $DIR/f36
3900         utime $DIR/f36 || error "utime failed for OST"
3901 }
3902 run_test 36b "OST utime check (open, utime)"
3903
3904 test_36c() {
3905         rm -f $DIR/d36/f36
3906         test_mkdir $DIR/d36
3907         chown $RUNAS_ID $DIR/d36
3908         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3909 }
3910 run_test 36c "non-root MDS utime check (mknod, utime)"
3911
3912 test_36d() {
3913         [ ! -d $DIR/d36 ] && test_36c
3914         echo "" > $DIR/d36/f36
3915         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3916 }
3917 run_test 36d "non-root OST utime check (open, utime)"
3918
3919 test_36e() {
3920         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3921
3922         test_mkdir $DIR/$tdir
3923         touch $DIR/$tdir/$tfile
3924         $RUNAS utime $DIR/$tdir/$tfile &&
3925                 error "utime worked, expected failure" || true
3926 }
3927 run_test 36e "utime on non-owned file (should return error)"
3928
3929 subr_36fh() {
3930         local fl="$1"
3931         local LANG_SAVE=$LANG
3932         local LC_LANG_SAVE=$LC_LANG
3933         export LANG=C LC_LANG=C # for date language
3934
3935         DATESTR="Dec 20  2000"
3936         test_mkdir $DIR/$tdir
3937         lctl set_param fail_loc=$fl
3938         date; date +%s
3939         cp /etc/hosts $DIR/$tdir/$tfile
3940         sync & # write RPC generated with "current" inode timestamp, but delayed
3941         sleep 1
3942         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3943         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3944         cancel_lru_locks $OSC
3945         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3946         date; date +%s
3947         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3948                 echo "BEFORE: $LS_BEFORE" && \
3949                 echo "AFTER : $LS_AFTER" && \
3950                 echo "WANT  : $DATESTR" && \
3951                 error "$DIR/$tdir/$tfile timestamps changed" || true
3952
3953         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3954 }
3955
3956 test_36f() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3960         subr_36fh "0x80000214"
3961 }
3962 run_test 36f "utime on file racing with OST BRW write =========="
3963
3964 test_36g() {
3965         remote_ost_nodsh && skip "remote OST with nodsh"
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3968                 skip "Need MDS version at least 2.12.51"
3969
3970         local fmd_max_age
3971         local fmd
3972         local facet="ost1"
3973         local tgt="obdfilter"
3974
3975         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3976
3977         test_mkdir $DIR/$tdir
3978         fmd_max_age=$(do_facet $facet \
3979                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3980                 head -n 1")
3981
3982         echo "FMD max age: ${fmd_max_age}s"
3983         touch $DIR/$tdir/$tfile
3984         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3985                 gawk '{cnt=cnt+$1}  END{print cnt}')
3986         echo "FMD before: $fmd"
3987         [[ $fmd == 0 ]] &&
3988                 error "FMD wasn't create by touch"
3989         sleep $((fmd_max_age + 12))
3990         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3991                 gawk '{cnt=cnt+$1}  END{print cnt}')
3992         echo "FMD after: $fmd"
3993         [[ $fmd == 0 ]] ||
3994                 error "FMD wasn't expired by ping"
3995 }
3996 run_test 36g "FMD cache expiry ====================="
3997
3998 test_36h() {
3999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4000
4001         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4002         subr_36fh "0x80000227"
4003 }
4004 run_test 36h "utime on file racing with OST BRW write =========="
4005
4006 test_36i() {
4007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4008
4009         test_mkdir $DIR/$tdir
4010         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4011
4012         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4013         local new_mtime=$((mtime + 200))
4014
4015         #change Modify time of striped dir
4016         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4017                         error "change mtime failed"
4018
4019         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4020
4021         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4022 }
4023 run_test 36i "change mtime on striped directory"
4024
4025 # test_37 - duplicate with tests 32q 32r
4026
4027 test_38() {
4028         local file=$DIR/$tfile
4029         touch $file
4030         openfile -f O_DIRECTORY $file
4031         local RC=$?
4032         local ENOTDIR=20
4033         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4034         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4035 }
4036 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4037
4038 test_39a() { # was test_39
4039         touch $DIR/$tfile
4040         touch $DIR/${tfile}2
4041 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4042 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4043 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4044         sleep 2
4045         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4046         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4047                 echo "mtime"
4048                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4049                 echo "atime"
4050                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4051                 echo "ctime"
4052                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4053                 error "O_TRUNC didn't change timestamps"
4054         fi
4055 }
4056 run_test 39a "mtime changed on create"
4057
4058 test_39b() {
4059         test_mkdir -c1 $DIR/$tdir
4060         cp -p /etc/passwd $DIR/$tdir/fopen
4061         cp -p /etc/passwd $DIR/$tdir/flink
4062         cp -p /etc/passwd $DIR/$tdir/funlink
4063         cp -p /etc/passwd $DIR/$tdir/frename
4064         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4065
4066         sleep 1
4067         echo "aaaaaa" >> $DIR/$tdir/fopen
4068         echo "aaaaaa" >> $DIR/$tdir/flink
4069         echo "aaaaaa" >> $DIR/$tdir/funlink
4070         echo "aaaaaa" >> $DIR/$tdir/frename
4071
4072         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4073         local link_new=`stat -c %Y $DIR/$tdir/flink`
4074         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4075         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4076
4077         cat $DIR/$tdir/fopen > /dev/null
4078         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4079         rm -f $DIR/$tdir/funlink2
4080         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4081
4082         for (( i=0; i < 2; i++ )) ; do
4083                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4084                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4085                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4086                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4087
4088                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4089                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4090                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4091                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4092
4093                 cancel_lru_locks $OSC
4094                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4095         done
4096 }
4097 run_test 39b "mtime change on open, link, unlink, rename  ======"
4098
4099 # this should be set to past
4100 TEST_39_MTIME=`date -d "1 year ago" +%s`
4101
4102 # bug 11063
4103 test_39c() {
4104         touch $DIR1/$tfile
4105         sleep 2
4106         local mtime0=`stat -c %Y $DIR1/$tfile`
4107
4108         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4109         local mtime1=`stat -c %Y $DIR1/$tfile`
4110         [ "$mtime1" = $TEST_39_MTIME ] || \
4111                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4112
4113         local d1=`date +%s`
4114         echo hello >> $DIR1/$tfile
4115         local d2=`date +%s`
4116         local mtime2=`stat -c %Y $DIR1/$tfile`
4117         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4118                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4119
4120         mv $DIR1/$tfile $DIR1/$tfile-1
4121
4122         for (( i=0; i < 2; i++ )) ; do
4123                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4124                 [ "$mtime2" = "$mtime3" ] || \
4125                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4126
4127                 cancel_lru_locks $OSC
4128                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4129         done
4130 }
4131 run_test 39c "mtime change on rename ==========================="
4132
4133 # bug 21114
4134 test_39d() {
4135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4136
4137         touch $DIR1/$tfile
4138         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4139
4140         for (( i=0; i < 2; i++ )) ; do
4141                 local mtime=`stat -c %Y $DIR1/$tfile`
4142                 [ $mtime = $TEST_39_MTIME ] || \
4143                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4144
4145                 cancel_lru_locks $OSC
4146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4147         done
4148 }
4149 run_test 39d "create, utime, stat =============================="
4150
4151 # bug 21114
4152 test_39e() {
4153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4154
4155         touch $DIR1/$tfile
4156         local mtime1=`stat -c %Y $DIR1/$tfile`
4157
4158         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4159
4160         for (( i=0; i < 2; i++ )) ; do
4161                 local mtime2=`stat -c %Y $DIR1/$tfile`
4162                 [ $mtime2 = $TEST_39_MTIME ] || \
4163                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4164
4165                 cancel_lru_locks $OSC
4166                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4167         done
4168 }
4169 run_test 39e "create, stat, utime, stat ========================"
4170
4171 # bug 21114
4172 test_39f() {
4173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4174
4175         touch $DIR1/$tfile
4176         mtime1=`stat -c %Y $DIR1/$tfile`
4177
4178         sleep 2
4179         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4180
4181         for (( i=0; i < 2; i++ )) ; do
4182                 local mtime2=`stat -c %Y $DIR1/$tfile`
4183                 [ $mtime2 = $TEST_39_MTIME ] || \
4184                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4185
4186                 cancel_lru_locks $OSC
4187                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4188         done
4189 }
4190 run_test 39f "create, stat, sleep, utime, stat ================="
4191
4192 # bug 11063
4193 test_39g() {
4194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4195
4196         echo hello >> $DIR1/$tfile
4197         local mtime1=`stat -c %Y $DIR1/$tfile`
4198
4199         sleep 2
4200         chmod o+r $DIR1/$tfile
4201
4202         for (( i=0; i < 2; i++ )) ; do
4203                 local mtime2=`stat -c %Y $DIR1/$tfile`
4204                 [ "$mtime1" = "$mtime2" ] || \
4205                         error "lost mtime: $mtime2, should be $mtime1"
4206
4207                 cancel_lru_locks $OSC
4208                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4209         done
4210 }
4211 run_test 39g "write, chmod, stat ==============================="
4212
4213 # bug 11063
4214 test_39h() {
4215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4216
4217         touch $DIR1/$tfile
4218         sleep 1
4219
4220         local d1=`date`
4221         echo hello >> $DIR1/$tfile
4222         local mtime1=`stat -c %Y $DIR1/$tfile`
4223
4224         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4225         local d2=`date`
4226         if [ "$d1" != "$d2" ]; then
4227                 echo "write and touch not within one second"
4228         else
4229                 for (( i=0; i < 2; i++ )) ; do
4230                         local mtime2=`stat -c %Y $DIR1/$tfile`
4231                         [ "$mtime2" = $TEST_39_MTIME ] || \
4232                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4233
4234                         cancel_lru_locks $OSC
4235                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4236                 done
4237         fi
4238 }
4239 run_test 39h "write, utime within one second, stat ============="
4240
4241 test_39i() {
4242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4243
4244         touch $DIR1/$tfile
4245         sleep 1
4246
4247         echo hello >> $DIR1/$tfile
4248         local mtime1=`stat -c %Y $DIR1/$tfile`
4249
4250         mv $DIR1/$tfile $DIR1/$tfile-1
4251
4252         for (( i=0; i < 2; i++ )) ; do
4253                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4254
4255                 [ "$mtime1" = "$mtime2" ] || \
4256                         error "lost mtime: $mtime2, should be $mtime1"
4257
4258                 cancel_lru_locks $OSC
4259                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4260         done
4261 }
4262 run_test 39i "write, rename, stat =============================="
4263
4264 test_39j() {
4265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4266
4267         start_full_debug_logging
4268         touch $DIR1/$tfile
4269         sleep 1
4270
4271         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4272         lctl set_param fail_loc=0x80000412
4273         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4274                 error "multiop failed"
4275         local multipid=$!
4276         local mtime1=`stat -c %Y $DIR1/$tfile`
4277
4278         mv $DIR1/$tfile $DIR1/$tfile-1
4279
4280         kill -USR1 $multipid
4281         wait $multipid || error "multiop close failed"
4282
4283         for (( i=0; i < 2; i++ )) ; do
4284                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4285                 [ "$mtime1" = "$mtime2" ] ||
4286                         error "mtime is lost on close: $mtime2, " \
4287                               "should be $mtime1"
4288
4289                 cancel_lru_locks
4290                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4291         done
4292         lctl set_param fail_loc=0
4293         stop_full_debug_logging
4294 }
4295 run_test 39j "write, rename, close, stat ======================="
4296
4297 test_39k() {
4298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4299
4300         touch $DIR1/$tfile
4301         sleep 1
4302
4303         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4304         local multipid=$!
4305         local mtime1=`stat -c %Y $DIR1/$tfile`
4306
4307         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4308
4309         kill -USR1 $multipid
4310         wait $multipid || error "multiop close failed"
4311
4312         for (( i=0; i < 2; i++ )) ; do
4313                 local mtime2=`stat -c %Y $DIR1/$tfile`
4314
4315                 [ "$mtime2" = $TEST_39_MTIME ] || \
4316                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4317
4318                 cancel_lru_locks
4319                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4320         done
4321 }
4322 run_test 39k "write, utime, close, stat ========================"
4323
4324 # this should be set to future
4325 TEST_39_ATIME=`date -d "1 year" +%s`
4326
4327 test_39l() {
4328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4329         remote_mds_nodsh && skip "remote MDS with nodsh"
4330
4331         local atime_diff=$(do_facet $SINGLEMDS \
4332                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4333         rm -rf $DIR/$tdir
4334         mkdir -p $DIR/$tdir
4335
4336         # test setting directory atime to future
4337         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4338         local atime=$(stat -c %X $DIR/$tdir)
4339         [ "$atime" = $TEST_39_ATIME ] ||
4340                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4341
4342         # test setting directory atime from future to now
4343         local now=$(date +%s)
4344         touch -a -d @$now $DIR/$tdir
4345
4346         atime=$(stat -c %X $DIR/$tdir)
4347         [ "$atime" -eq "$now"  ] ||
4348                 error "atime is not updated from future: $atime, $now"
4349
4350         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4351         sleep 3
4352
4353         # test setting directory atime when now > dir atime + atime_diff
4354         local d1=$(date +%s)
4355         ls $DIR/$tdir
4356         local d2=$(date +%s)
4357         cancel_lru_locks mdc
4358         atime=$(stat -c %X $DIR/$tdir)
4359         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4360                 error "atime is not updated  : $atime, should be $d2"
4361
4362         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4363         sleep 3
4364
4365         # test not setting directory atime when now < dir atime + atime_diff
4366         ls $DIR/$tdir
4367         cancel_lru_locks mdc
4368         atime=$(stat -c %X $DIR/$tdir)
4369         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4370                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4371
4372         do_facet $SINGLEMDS \
4373                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4374 }
4375 run_test 39l "directory atime update ==========================="
4376
4377 test_39m() {
4378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4379
4380         touch $DIR1/$tfile
4381         sleep 2
4382         local far_past_mtime=$(date -d "May 29 1953" +%s)
4383         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4384
4385         touch -m -d @$far_past_mtime $DIR1/$tfile
4386         touch -a -d @$far_past_atime $DIR1/$tfile
4387
4388         for (( i=0; i < 2; i++ )) ; do
4389                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4390                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4391                         error "atime or mtime set incorrectly"
4392
4393                 cancel_lru_locks $OSC
4394                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4395         done
4396 }
4397 run_test 39m "test atime and mtime before 1970"
4398
4399 test_39n() { # LU-3832
4400         remote_mds_nodsh && skip "remote MDS with nodsh"
4401
4402         local atime_diff=$(do_facet $SINGLEMDS \
4403                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4404         local atime0
4405         local atime1
4406         local atime2
4407
4408         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4409
4410         rm -rf $DIR/$tfile
4411         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4412         atime0=$(stat -c %X $DIR/$tfile)
4413
4414         sleep 5
4415         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4416         atime1=$(stat -c %X $DIR/$tfile)
4417
4418         sleep 5
4419         cancel_lru_locks mdc
4420         cancel_lru_locks osc
4421         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4422         atime2=$(stat -c %X $DIR/$tfile)
4423
4424         do_facet $SINGLEMDS \
4425                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4426
4427         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4428         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4429 }
4430 run_test 39n "check that O_NOATIME is honored"
4431
4432 test_39o() {
4433         TESTDIR=$DIR/$tdir/$tfile
4434         [ -e $TESTDIR ] && rm -rf $TESTDIR
4435         mkdir -p $TESTDIR
4436         cd $TESTDIR
4437         links1=2
4438         ls
4439         mkdir a b
4440         ls
4441         links2=$(stat -c %h .)
4442         [ $(($links1 + 2)) != $links2 ] &&
4443                 error "wrong links count $(($links1 + 2)) != $links2"
4444         rmdir b
4445         links3=$(stat -c %h .)
4446         [ $(($links1 + 1)) != $links3 ] &&
4447                 error "wrong links count $links1 != $links3"
4448         return 0
4449 }
4450 run_test 39o "directory cached attributes updated after create"
4451
4452 test_39p() {
4453         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4454
4455         local MDTIDX=1
4456         TESTDIR=$DIR/$tdir/$tdir
4457         [ -e $TESTDIR ] && rm -rf $TESTDIR
4458         test_mkdir -p $TESTDIR
4459         cd $TESTDIR
4460         links1=2
4461         ls
4462         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4463         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4464         ls
4465         links2=$(stat -c %h .)
4466         [ $(($links1 + 2)) != $links2 ] &&
4467                 error "wrong links count $(($links1 + 2)) != $links2"
4468         rmdir remote_dir2
4469         links3=$(stat -c %h .)
4470         [ $(($links1 + 1)) != $links3 ] &&
4471                 error "wrong links count $links1 != $links3"
4472         return 0
4473 }
4474 run_test 39p "remote directory cached attributes updated after create ========"
4475
4476
4477 test_39q() { # LU-8041
4478         local testdir=$DIR/$tdir
4479         mkdir -p $testdir
4480         multiop_bg_pause $testdir D_c || error "multiop failed"
4481         local multipid=$!
4482         cancel_lru_locks mdc
4483         kill -USR1 $multipid
4484         local atime=$(stat -c %X $testdir)
4485         [ "$atime" -ne 0 ] || error "atime is zero"
4486 }
4487 run_test 39q "close won't zero out atime"
4488
4489 test_40() {
4490         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4491         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4492                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4493         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4494                 error "$tfile is not 4096 bytes in size"
4495 }
4496 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4497
4498 test_41() {
4499         # bug 1553
4500         small_write $DIR/f41 18
4501 }
4502 run_test 41 "test small file write + fstat ====================="
4503
4504 count_ost_writes() {
4505         lctl get_param -n ${OSC}.*.stats |
4506                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4507                         END { printf("%0.0f", writes) }'
4508 }
4509
4510 # decent default
4511 WRITEBACK_SAVE=500
4512 DIRTY_RATIO_SAVE=40
4513 MAX_DIRTY_RATIO=50
4514 BG_DIRTY_RATIO_SAVE=10
4515 MAX_BG_DIRTY_RATIO=25
4516
4517 start_writeback() {
4518         trap 0
4519         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4520         # dirty_ratio, dirty_background_ratio
4521         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4522                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4523                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4524                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4525         else
4526                 # if file not here, we are a 2.4 kernel
4527                 kill -CONT `pidof kupdated`
4528         fi
4529 }
4530
4531 stop_writeback() {
4532         # setup the trap first, so someone cannot exit the test at the
4533         # exact wrong time and mess up a machine
4534         trap start_writeback EXIT
4535         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4536         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4537                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4538                 sysctl -w vm.dirty_writeback_centisecs=0
4539                 sysctl -w vm.dirty_writeback_centisecs=0
4540                 # save and increase /proc/sys/vm/dirty_ratio
4541                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4542                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4543                 # save and increase /proc/sys/vm/dirty_background_ratio
4544                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4545                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4546         else
4547                 # if file not here, we are a 2.4 kernel
4548                 kill -STOP `pidof kupdated`
4549         fi
4550 }
4551
4552 # ensure that all stripes have some grant before we test client-side cache
4553 setup_test42() {
4554         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4555                 dd if=/dev/zero of=$i bs=4k count=1
4556                 rm $i
4557         done
4558 }
4559
4560 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4561 # file truncation, and file removal.
4562 test_42a() {
4563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4564
4565         setup_test42
4566         cancel_lru_locks $OSC
4567         stop_writeback
4568         sync; sleep 1; sync # just to be safe
4569         BEFOREWRITES=`count_ost_writes`
4570         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4571         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4572         AFTERWRITES=`count_ost_writes`
4573         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4574                 error "$BEFOREWRITES < $AFTERWRITES"
4575         start_writeback
4576 }
4577 run_test 42a "ensure that we don't flush on close"
4578
4579 test_42b() {
4580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4581
4582         setup_test42
4583         cancel_lru_locks $OSC
4584         stop_writeback
4585         sync
4586         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4587         BEFOREWRITES=$(count_ost_writes)
4588         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4589         AFTERWRITES=$(count_ost_writes)
4590         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4591                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4592         fi
4593         BEFOREWRITES=$(count_ost_writes)
4594         sync || error "sync: $?"
4595         AFTERWRITES=$(count_ost_writes)
4596         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4597                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4598         fi
4599         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4600         start_writeback
4601         return 0
4602 }
4603 run_test 42b "test destroy of file with cached dirty data ======"
4604
4605 # if these tests just want to test the effect of truncation,
4606 # they have to be very careful.  consider:
4607 # - the first open gets a {0,EOF}PR lock
4608 # - the first write conflicts and gets a {0, count-1}PW
4609 # - the rest of the writes are under {count,EOF}PW
4610 # - the open for truncate tries to match a {0,EOF}PR
4611 #   for the filesize and cancels the PWs.
4612 # any number of fixes (don't get {0,EOF} on open, match
4613 # composite locks, do smarter file size management) fix
4614 # this, but for now we want these tests to verify that
4615 # the cancellation with truncate intent works, so we
4616 # start the file with a full-file pw lock to match against
4617 # until the truncate.
4618 trunc_test() {
4619         test=$1
4620         file=$DIR/$test
4621         offset=$2
4622         cancel_lru_locks $OSC
4623         stop_writeback
4624         # prime the file with 0,EOF PW to match
4625         touch $file
4626         $TRUNCATE $file 0
4627         sync; sync
4628         # now the real test..
4629         dd if=/dev/zero of=$file bs=1024 count=100
4630         BEFOREWRITES=`count_ost_writes`
4631         $TRUNCATE $file $offset
4632         cancel_lru_locks $OSC
4633         AFTERWRITES=`count_ost_writes`
4634         start_writeback
4635 }
4636
4637 test_42c() {
4638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4639
4640         trunc_test 42c 1024
4641         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4642                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4643         rm $file
4644 }
4645 run_test 42c "test partial truncate of file with cached dirty data"
4646
4647 test_42d() {
4648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4649
4650         trunc_test 42d 0
4651         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4652                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4653         rm $file
4654 }
4655 run_test 42d "test complete truncate of file with cached dirty data"
4656
4657 test_42e() { # bug22074
4658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4659
4660         local TDIR=$DIR/${tdir}e
4661         local pages=16 # hardcoded 16 pages, don't change it.
4662         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4663         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4664         local max_dirty_mb
4665         local warmup_files
4666
4667         test_mkdir $DIR/${tdir}e
4668         $LFS setstripe -c 1 $TDIR
4669         createmany -o $TDIR/f $files
4670
4671         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4672
4673         # we assume that with $OSTCOUNT files, at least one of them will
4674         # be allocated on OST0.
4675         warmup_files=$((OSTCOUNT * max_dirty_mb))
4676         createmany -o $TDIR/w $warmup_files
4677
4678         # write a large amount of data into one file and sync, to get good
4679         # avail_grant number from OST.
4680         for ((i=0; i<$warmup_files; i++)); do
4681                 idx=$($LFS getstripe -i $TDIR/w$i)
4682                 [ $idx -ne 0 ] && continue
4683                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4684                 break
4685         done
4686         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4687         sync
4688         $LCTL get_param $proc_osc0/cur_dirty_bytes
4689         $LCTL get_param $proc_osc0/cur_grant_bytes
4690
4691         # create as much dirty pages as we can while not to trigger the actual
4692         # RPCs directly. but depends on the env, VFS may trigger flush during this
4693         # period, hopefully we are good.
4694         for ((i=0; i<$warmup_files; i++)); do
4695                 idx=$($LFS getstripe -i $TDIR/w$i)
4696                 [ $idx -ne 0 ] && continue
4697                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4698         done
4699         $LCTL get_param $proc_osc0/cur_dirty_bytes
4700         $LCTL get_param $proc_osc0/cur_grant_bytes
4701
4702         # perform the real test
4703         $LCTL set_param $proc_osc0/rpc_stats 0
4704         for ((;i<$files; i++)); do
4705                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4706                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4707         done
4708         sync
4709         $LCTL get_param $proc_osc0/rpc_stats
4710
4711         local percent=0
4712         local have_ppr=false
4713         $LCTL get_param $proc_osc0/rpc_stats |
4714                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4715                         # skip lines until we are at the RPC histogram data
4716                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4717                         $have_ppr || continue
4718
4719                         # we only want the percent stat for < 16 pages
4720                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4721
4722                         percent=$((percent + WPCT))
4723                         if [[ $percent -gt 15 ]]; then
4724                                 error "less than 16-pages write RPCs" \
4725                                       "$percent% > 15%"
4726                                 break
4727                         fi
4728                 done
4729         rm -rf $TDIR
4730 }
4731 run_test 42e "verify sub-RPC writes are not done synchronously"
4732
4733 test_43A() { # was test_43
4734         test_mkdir $DIR/$tdir
4735         cp -p /bin/ls $DIR/$tdir/$tfile
4736         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4737         pid=$!
4738         # give multiop a chance to open
4739         sleep 1
4740
4741         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4742         kill -USR1 $pid
4743 }
4744 run_test 43A "execution of file opened for write should return -ETXTBSY"
4745
4746 test_43a() {
4747         test_mkdir $DIR/$tdir
4748         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4749         $DIR/$tdir/sleep 60 &
4750         SLEEP_PID=$!
4751         # Make sure exec of $tdir/sleep wins race with truncate
4752         sleep 1
4753         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4754         kill $SLEEP_PID
4755 }
4756 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4757
4758 test_43b() {
4759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4760
4761         test_mkdir $DIR/$tdir
4762         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4763         $DIR/$tdir/sleep 60 &
4764         SLEEP_PID=$!
4765         # Make sure exec of $tdir/sleep wins race with truncate
4766         sleep 1
4767         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4768         kill $SLEEP_PID
4769 }
4770 run_test 43b "truncate of file being executed should return -ETXTBSY"
4771
4772 test_43c() {
4773         local testdir="$DIR/$tdir"
4774         test_mkdir $testdir
4775         cp $SHELL $testdir/
4776         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4777                 ( cd $testdir && md5sum -c )
4778 }
4779 run_test 43c "md5sum of copy into lustre"
4780
4781 test_44A() { # was test_44
4782         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4783
4784         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4785         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4786 }
4787 run_test 44A "zero length read from a sparse stripe"
4788
4789 test_44a() {
4790         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4791                 awk '{ print $2 }')
4792         [ -z "$nstripe" ] && skip "can't get stripe info"
4793         [[ $nstripe -gt $OSTCOUNT ]] &&
4794                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4795
4796         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4797                 awk '{ print $2 }')
4798         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4799                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4800                         awk '{ print $2 }')
4801         fi
4802
4803         OFFSETS="0 $((stride/2)) $((stride-1))"
4804         for offset in $OFFSETS; do
4805                 for i in $(seq 0 $((nstripe-1))); do
4806                         local GLOBALOFFSETS=""
4807                         # size in Bytes
4808                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4809                         local myfn=$DIR/d44a-$size
4810                         echo "--------writing $myfn at $size"
4811                         ll_sparseness_write $myfn $size ||
4812                                 error "ll_sparseness_write"
4813                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4814                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4815                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4816
4817                         for j in $(seq 0 $((nstripe-1))); do
4818                                 # size in Bytes
4819                                 size=$((((j + $nstripe )*$stride + $offset)))
4820                                 ll_sparseness_write $myfn $size ||
4821                                         error "ll_sparseness_write"
4822                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4823                         done
4824                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4825                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4826                         rm -f $myfn
4827                 done
4828         done
4829 }
4830 run_test 44a "test sparse pwrite ==============================="
4831
4832 dirty_osc_total() {
4833         tot=0
4834         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4835                 tot=$(($tot + $d))
4836         done
4837         echo $tot
4838 }
4839 do_dirty_record() {
4840         before=`dirty_osc_total`
4841         echo executing "\"$*\""
4842         eval $*
4843         after=`dirty_osc_total`
4844         echo before $before, after $after
4845 }
4846 test_45() {
4847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4848
4849         f="$DIR/f45"
4850         # Obtain grants from OST if it supports it
4851         echo blah > ${f}_grant
4852         stop_writeback
4853         sync
4854         do_dirty_record "echo blah > $f"
4855         [[ $before -eq $after ]] && error "write wasn't cached"
4856         do_dirty_record "> $f"
4857         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4858         do_dirty_record "echo blah > $f"
4859         [[ $before -eq $after ]] && error "write wasn't cached"
4860         do_dirty_record "sync"
4861         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4862         do_dirty_record "echo blah > $f"
4863         [[ $before -eq $after ]] && error "write wasn't cached"
4864         do_dirty_record "cancel_lru_locks osc"
4865         [[ $before -gt $after ]] ||
4866                 error "lock cancellation didn't lower dirty count"
4867         start_writeback
4868 }
4869 run_test 45 "osc io page accounting ============================"
4870
4871 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4872 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4873 # objects offset and an assert hit when an rpc was built with 1023's mapped
4874 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4875 test_46() {
4876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4877
4878         f="$DIR/f46"
4879         stop_writeback
4880         sync
4881         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4882         sync
4883         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4884         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4885         sync
4886         start_writeback
4887 }
4888 run_test 46 "dirtying a previously written page ================"
4889
4890 # test_47 is removed "Device nodes check" is moved to test_28
4891
4892 test_48a() { # bug 2399
4893         [ "$mds1_FSTYPE" = "zfs" ] &&
4894         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4895                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4896
4897         test_mkdir $DIR/$tdir
4898         cd $DIR/$tdir
4899         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4900         test_mkdir $DIR/$tdir
4901         touch foo || error "'touch foo' failed after recreating cwd"
4902         test_mkdir bar
4903         touch .foo || error "'touch .foo' failed after recreating cwd"
4904         test_mkdir .bar
4905         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4906         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4907         cd . || error "'cd .' failed after recreating cwd"
4908         mkdir . && error "'mkdir .' worked after recreating cwd"
4909         rmdir . && error "'rmdir .' worked after recreating cwd"
4910         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4911         cd .. || error "'cd ..' failed after recreating cwd"
4912 }
4913 run_test 48a "Access renamed working dir (should return errors)="
4914
4915 test_48b() { # bug 2399
4916         rm -rf $DIR/$tdir
4917         test_mkdir $DIR/$tdir
4918         cd $DIR/$tdir
4919         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4920         touch foo && error "'touch foo' worked after removing cwd"
4921         mkdir foo && error "'mkdir foo' worked after removing cwd"
4922         touch .foo && error "'touch .foo' worked after removing cwd"
4923         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4924         ls . > /dev/null && error "'ls .' worked after removing cwd"
4925         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4926         mkdir . && error "'mkdir .' worked after removing cwd"
4927         rmdir . && error "'rmdir .' worked after removing cwd"
4928         ln -s . foo && error "'ln -s .' worked after removing cwd"
4929         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4930 }
4931 run_test 48b "Access removed working dir (should return errors)="
4932
4933 test_48c() { # bug 2350
4934         #lctl set_param debug=-1
4935         #set -vx
4936         rm -rf $DIR/$tdir
4937         test_mkdir -p $DIR/$tdir/dir
4938         cd $DIR/$tdir/dir
4939         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4940         $TRACE touch foo && error "touch foo worked after removing cwd"
4941         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4942         touch .foo && error "touch .foo worked after removing cwd"
4943         mkdir .foo && error "mkdir .foo worked after removing cwd"
4944         $TRACE ls . && error "'ls .' worked after removing cwd"
4945         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4946         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4947         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4948         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4949         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4950 }
4951 run_test 48c "Access removed working subdir (should return errors)"
4952
4953 test_48d() { # bug 2350
4954         #lctl set_param debug=-1
4955         #set -vx
4956         rm -rf $DIR/$tdir
4957         test_mkdir -p $DIR/$tdir/dir
4958         cd $DIR/$tdir/dir
4959         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4960         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4961         $TRACE touch foo && error "'touch foo' worked after removing parent"
4962         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4963         touch .foo && error "'touch .foo' worked after removing parent"
4964         mkdir .foo && error "mkdir .foo worked after removing parent"
4965         $TRACE ls . && error "'ls .' worked after removing parent"
4966         $TRACE ls .. && error "'ls ..' worked after removing parent"
4967         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4968         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4969         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4970         true
4971 }
4972 run_test 48d "Access removed parent subdir (should return errors)"
4973
4974 test_48e() { # bug 4134
4975         #lctl set_param debug=-1
4976         #set -vx
4977         rm -rf $DIR/$tdir
4978         test_mkdir -p $DIR/$tdir/dir
4979         cd $DIR/$tdir/dir
4980         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4981         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4982         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4983         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4984         # On a buggy kernel addition of "touch foo" after cd .. will
4985         # produce kernel oops in lookup_hash_it
4986         touch ../foo && error "'cd ..' worked after recreate parent"
4987         cd $DIR
4988         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4989 }
4990 run_test 48e "Access to recreated parent subdir (should return errors)"
4991
4992 test_49() { # LU-1030
4993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4994         remote_ost_nodsh && skip "remote OST with nodsh"
4995
4996         # get ost1 size - $FSNAME-OST0000
4997         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4998                 awk '{ print $4 }')
4999         # write 800M at maximum
5000         [[ $ost1_size -lt 2 ]] && ost1_size=2
5001         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5002
5003         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5004         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5005         local dd_pid=$!
5006
5007         # change max_pages_per_rpc while writing the file
5008         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5009         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5010         # loop until dd process exits
5011         while ps ax -opid | grep -wq $dd_pid; do
5012                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5013                 sleep $((RANDOM % 5 + 1))
5014         done
5015         # restore original max_pages_per_rpc
5016         $LCTL set_param $osc1_mppc=$orig_mppc
5017         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5018 }
5019 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5020
5021 test_50() {
5022         # bug 1485
5023         test_mkdir $DIR/$tdir
5024         cd $DIR/$tdir
5025         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5026 }
5027 run_test 50 "special situations: /proc symlinks  ==============="
5028
5029 test_51a() {    # was test_51
5030         # bug 1516 - create an empty entry right after ".." then split dir
5031         test_mkdir -c1 $DIR/$tdir
5032         touch $DIR/$tdir/foo
5033         $MCREATE $DIR/$tdir/bar
5034         rm $DIR/$tdir/foo
5035         createmany -m $DIR/$tdir/longfile 201
5036         FNUM=202
5037         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5038                 $MCREATE $DIR/$tdir/longfile$FNUM
5039                 FNUM=$(($FNUM + 1))
5040                 echo -n "+"
5041         done
5042         echo
5043         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5044 }
5045 run_test 51a "special situations: split htree with empty entry =="
5046
5047 cleanup_print_lfs_df () {
5048         trap 0
5049         $LFS df
5050         $LFS df -i
5051 }
5052
5053 test_51b() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055
5056         local dir=$DIR/$tdir
5057         local nrdirs=$((65536 + 100))
5058
5059         # cleanup the directory
5060         rm -fr $dir
5061
5062         test_mkdir -c1 $dir
5063
5064         $LFS df
5065         $LFS df -i
5066         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5067         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5068         [[ $numfree -lt $nrdirs ]] &&
5069                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5070
5071         # need to check free space for the directories as well
5072         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5073         numfree=$(( blkfree / $(fs_inode_ksize) ))
5074         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5075
5076         trap cleanup_print_lfs_df EXIT
5077
5078         # create files
5079         createmany -d $dir/d $nrdirs || {
5080                 unlinkmany $dir/d $nrdirs
5081                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5082         }
5083
5084         # really created :
5085         nrdirs=$(ls -U $dir | wc -l)
5086
5087         # unlink all but 100 subdirectories, then check it still works
5088         local left=100
5089         local delete=$((nrdirs - left))
5090
5091         $LFS df
5092         $LFS df -i
5093
5094         # for ldiskfs the nlink count should be 1, but this is OSD specific
5095         # and so this is listed for informational purposes only
5096         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5097         unlinkmany -d $dir/d $delete ||
5098                 error "unlink of first $delete subdirs failed"
5099
5100         echo "nlink between: $(stat -c %h $dir)"
5101         local found=$(ls -U $dir | wc -l)
5102         [ $found -ne $left ] &&
5103                 error "can't find subdirs: found only $found, expected $left"
5104
5105         unlinkmany -d $dir/d $delete $left ||
5106                 error "unlink of second $left subdirs failed"
5107         # regardless of whether the backing filesystem tracks nlink accurately
5108         # or not, the nlink count shouldn't be more than "." and ".." here
5109         local after=$(stat -c %h $dir)
5110         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5111                 echo "nlink after: $after"
5112
5113         cleanup_print_lfs_df
5114 }
5115 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5116
5117 test_51d() {
5118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5119         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5120
5121         test_mkdir $DIR/$tdir
5122         createmany -o $DIR/$tdir/t- 1000
5123         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5124         for N in $(seq 0 $((OSTCOUNT - 1))); do
5125                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5126                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5127                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5128                         '($1 == '$N') { objs += 1 } \
5129                         END { printf("%0.0f", objs) }')
5130                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5131         done
5132         unlinkmany $DIR/$tdir/t- 1000
5133
5134         NLAST=0
5135         for N in $(seq 1 $((OSTCOUNT - 1))); do
5136                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5137                         error "OST $N has less objects vs OST $NLAST" \
5138                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5139                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5140                         error "OST $N has less objects vs OST $NLAST" \
5141                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5142
5143                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5144                         error "OST $N has less #0 objects vs OST $NLAST" \
5145                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5146                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5147                         error "OST $N has less #0 objects vs OST $NLAST" \
5148                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5149                 NLAST=$N
5150         done
5151         rm -f $TMP/$tfile
5152 }
5153 run_test 51d "check object distribution"
5154
5155 test_51e() {
5156         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5157                 skip_env "ldiskfs only test"
5158         fi
5159
5160         test_mkdir -c1 $DIR/$tdir
5161         test_mkdir -c1 $DIR/$tdir/d0
5162
5163         touch $DIR/$tdir/d0/foo
5164         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5165                 error "file exceed 65000 nlink limit!"
5166         unlinkmany $DIR/$tdir/d0/f- 65001
5167         return 0
5168 }
5169 run_test 51e "check file nlink limit"
5170
5171 test_51f() {
5172         test_mkdir $DIR/$tdir
5173
5174         local max=100000
5175         local ulimit_old=$(ulimit -n)
5176         local spare=20 # number of spare fd's for scripts/libraries, etc.
5177         local mdt=$($LFS getstripe -m $DIR/$tdir)
5178         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5179
5180         echo "MDT$mdt numfree=$numfree, max=$max"
5181         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5182         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5183                 while ! ulimit -n $((numfree + spare)); do
5184                         numfree=$((numfree * 3 / 4))
5185                 done
5186                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5187         else
5188                 echo "left ulimit at $ulimit_old"
5189         fi
5190
5191         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5192                 unlinkmany $DIR/$tdir/f $numfree
5193                 error "create+open $numfree files in $DIR/$tdir failed"
5194         }
5195         ulimit -n $ulimit_old
5196
5197         # if createmany exits at 120s there will be fewer than $numfree files
5198         unlinkmany $DIR/$tdir/f $numfree || true
5199 }
5200 run_test 51f "check many open files limit"
5201
5202 test_52a() {
5203         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5204         test_mkdir $DIR/$tdir
5205         touch $DIR/$tdir/foo
5206         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5207         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5208         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5209         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5210         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5211                                         error "link worked"
5212         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5213         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5214         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5215                                                      error "lsattr"
5216         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5217         cp -r $DIR/$tdir $TMP/
5218         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5219 }
5220 run_test 52a "append-only flag test (should return errors)"
5221
5222 test_52b() {
5223         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5224         test_mkdir $DIR/$tdir
5225         touch $DIR/$tdir/foo
5226         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5227         cat test > $DIR/$tdir/foo && error "cat test worked"
5228         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5229         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5230         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5231                                         error "link worked"
5232         echo foo >> $DIR/$tdir/foo && error "echo worked"
5233         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5234         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5235         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5236         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5237                                                         error "lsattr"
5238         chattr -i $DIR/$tdir/foo || error "chattr failed"
5239
5240         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5241 }
5242 run_test 52b "immutable flag test (should return errors) ======="
5243
5244 test_53() {
5245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5246         remote_mds_nodsh && skip "remote MDS with nodsh"
5247         remote_ost_nodsh && skip "remote OST with nodsh"
5248
5249         local param
5250         local param_seq
5251         local ostname
5252         local mds_last
5253         local mds_last_seq
5254         local ost_last
5255         local ost_last_seq
5256         local ost_last_id
5257         local ostnum
5258         local node
5259         local found=false
5260         local support_last_seq=true
5261
5262         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5263                 support_last_seq=false
5264
5265         # only test MDT0000
5266         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5267         local value
5268         for value in $(do_facet $SINGLEMDS \
5269                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5270                 param=$(echo ${value[0]} | cut -d "=" -f1)
5271                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5272
5273                 if $support_last_seq; then
5274                         param_seq=$(echo $param |
5275                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5276                         mds_last_seq=$(do_facet $SINGLEMDS \
5277                                        $LCTL get_param -n $param_seq)
5278                 fi
5279                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5280
5281                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5282                 node=$(facet_active_host ost$((ostnum+1)))
5283                 param="obdfilter.$ostname.last_id"
5284                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5285                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5286                         ost_last_id=$ost_last
5287
5288                         if $support_last_seq; then
5289                                 ost_last_id=$(echo $ost_last |
5290                                               awk -F':' '{print $2}' |
5291                                               sed -e "s/^0x//g")
5292                                 ost_last_seq=$(echo $ost_last |
5293                                                awk -F':' '{print $1}')
5294                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5295                         fi
5296
5297                         if [[ $ost_last_id != $mds_last ]]; then
5298                                 error "$ost_last_id != $mds_last"
5299                         else
5300                                 found=true
5301                                 break
5302                         fi
5303                 done
5304         done
5305         $found || error "can not match last_seq/last_id for $mdtosc"
5306         return 0
5307 }
5308 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5309
5310 test_54a() {
5311         perl -MSocket -e ';' || skip "no Socket perl module installed"
5312
5313         $SOCKETSERVER $DIR/socket ||
5314                 error "$SOCKETSERVER $DIR/socket failed: $?"
5315         $SOCKETCLIENT $DIR/socket ||
5316                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5317         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5318 }
5319 run_test 54a "unix domain socket test =========================="
5320
5321 test_54b() {
5322         f="$DIR/f54b"
5323         mknod $f c 1 3
5324         chmod 0666 $f
5325         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5326 }
5327 run_test 54b "char device works in lustre ======================"
5328
5329 find_loop_dev() {
5330         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5331         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5332         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5333
5334         for i in $(seq 3 7); do
5335                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5336                 LOOPDEV=$LOOPBASE$i
5337                 LOOPNUM=$i
5338                 break
5339         done
5340 }
5341
5342 cleanup_54c() {
5343         local rc=0
5344         loopdev="$DIR/loop54c"
5345
5346         trap 0
5347         $UMOUNT $DIR/$tdir || rc=$?
5348         losetup -d $loopdev || true
5349         losetup -d $LOOPDEV || true
5350         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5351         return $rc
5352 }
5353
5354 test_54c() {
5355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5356
5357         loopdev="$DIR/loop54c"
5358
5359         find_loop_dev
5360         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5361         trap cleanup_54c EXIT
5362         mknod $loopdev b 7 $LOOPNUM
5363         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5364         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5365         losetup $loopdev $DIR/$tfile ||
5366                 error "can't set up $loopdev for $DIR/$tfile"
5367         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5368         test_mkdir $DIR/$tdir
5369         mount -t ext2 $loopdev $DIR/$tdir ||
5370                 error "error mounting $loopdev on $DIR/$tdir"
5371         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5372                 error "dd write"
5373         df $DIR/$tdir
5374         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5375                 error "dd read"
5376         cleanup_54c
5377 }
5378 run_test 54c "block device works in lustre ====================="
5379
5380 test_54d() {
5381         f="$DIR/f54d"
5382         string="aaaaaa"
5383         mknod $f p
5384         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5385 }
5386 run_test 54d "fifo device works in lustre ======================"
5387
5388 test_54e() {
5389         f="$DIR/f54e"
5390         string="aaaaaa"
5391         cp -aL /dev/console $f
5392         echo $string > $f || error "echo $string to $f failed"
5393 }
5394 run_test 54e "console/tty device works in lustre ======================"
5395
5396 test_56a() {
5397         local numfiles=3
5398         local dir=$DIR/$tdir
5399
5400         rm -rf $dir
5401         test_mkdir -p $dir/dir
5402         for i in $(seq $numfiles); do
5403                 touch $dir/file$i
5404                 touch $dir/dir/file$i
5405         done
5406
5407         local numcomp=$($LFS getstripe --component-count $dir)
5408
5409         [[ $numcomp == 0 ]] && numcomp=1
5410
5411         # test lfs getstripe with --recursive
5412         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5413
5414         [[ $filenum -eq $((numfiles * 2)) ]] ||
5415                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5416         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5417         [[ $filenum -eq $numfiles ]] ||
5418                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5419         echo "$LFS getstripe showed obdidx or l_ost_idx"
5420
5421         # test lfs getstripe with file instead of dir
5422         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5423         [[ $filenum -eq 1 ]] ||
5424                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5425         echo "$LFS getstripe file1 passed"
5426
5427         #test lfs getstripe with --verbose
5428         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5429         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5430                 error "$LFS getstripe --verbose $dir: "\
5431                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5432         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5433                 error "$LFS getstripe $dir: showed lmm_magic"
5434
5435         #test lfs getstripe with -v prints lmm_fid
5436         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5437         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5438                 error "$LFS getstripe -v $dir: "\
5439                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5440         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5441                 error "$LFS getstripe $dir: showed lmm_fid by default"
5442         echo "$LFS getstripe --verbose passed"
5443
5444         #check for FID information
5445         local fid1=$($LFS getstripe --fid $dir/file1)
5446         local fid2=$($LFS getstripe --verbose $dir/file1 |
5447                      awk '/lmm_fid: / { print $2; exit; }')
5448         local fid3=$($LFS path2fid $dir/file1)
5449
5450         [ "$fid1" != "$fid2" ] &&
5451                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5452         [ "$fid1" != "$fid3" ] &&
5453                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5454         echo "$LFS getstripe --fid passed"
5455
5456         #test lfs getstripe with --obd
5457         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5458                 error "$LFS getstripe --obd wrong_uuid: should return error"
5459
5460         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5461
5462         local ostidx=1
5463         local obduuid=$(ostuuid_from_index $ostidx)
5464         local found=$($LFS getstripe -r --obd $obduuid $dir |
5465                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5466
5467         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5468         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5469                 ((filenum--))
5470         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5471                 ((filenum--))
5472
5473         [[ $found -eq $filenum ]] ||
5474                 error "$LFS getstripe --obd: found $found expect $filenum"
5475         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5476                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5477                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5478                 error "$LFS getstripe --obd: should not show file on other obd"
5479         echo "$LFS getstripe --obd passed"
5480 }
5481 run_test 56a "check $LFS getstripe"
5482
5483 test_56b() {
5484         local dir=$DIR/$tdir
5485         local numdirs=3
5486
5487         test_mkdir $dir
5488         for i in $(seq $numdirs); do
5489                 test_mkdir $dir/dir$i
5490         done
5491
5492         # test lfs getdirstripe default mode is non-recursion, which is
5493         # different from lfs getstripe
5494         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5495
5496         [[ $dircnt -eq 1 ]] ||
5497                 error "$LFS getdirstripe: found $dircnt, not 1"
5498         dircnt=$($LFS getdirstripe --recursive $dir |
5499                 grep -c lmv_stripe_count)
5500         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5501                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5502 }
5503 run_test 56b "check $LFS getdirstripe"
5504
5505 test_56c() {
5506         remote_ost_nodsh && skip "remote OST with nodsh"
5507
5508         local ost_idx=0
5509         local ost_name=$(ostname_from_index $ost_idx)
5510         local old_status=$(ost_dev_status $ost_idx)
5511
5512         [[ -z "$old_status" ]] ||
5513                 skip_env "OST $ost_name is in $old_status status"
5514
5515         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5516         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5517                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5518         sleep_maxage
5519
5520         local new_status=$(ost_dev_status $ost_idx)
5521
5522         [[ "$new_status" =~ "D" ]] ||
5523                 error "$ost_name status is '$new_status', missing 'D'"
5524         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5525                 [[ "$new_status" =~ "N" ]] ||
5526                         error "$ost_name status is '$new_status', missing 'N'"
5527         fi
5528
5529         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5530         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5531                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5532         sleep_maxage
5533
5534         new_status=$(ost_dev_status $ost_idx)
5535         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5536                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5537 }
5538 run_test 56c "check 'lfs df' showing device status"
5539
5540 NUMFILES=3
5541 NUMDIRS=3
5542 setup_56() {
5543         local local_tdir="$1"
5544         local local_numfiles="$2"
5545         local local_numdirs="$3"
5546         local dir_params="$4"
5547         local dir_stripe_params="$5"
5548
5549         if [ ! -d "$local_tdir" ] ; then
5550                 test_mkdir -p $dir_stripe_params $local_tdir
5551                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5552                 for i in $(seq $local_numfiles) ; do
5553                         touch $local_tdir/file$i
5554                 done
5555                 for i in $(seq $local_numdirs) ; do
5556                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5557                         for j in $(seq $local_numfiles) ; do
5558                                 touch $local_tdir/dir$i/file$j
5559                         done
5560                 done
5561         fi
5562 }
5563
5564 setup_56_special() {
5565         local local_tdir=$1
5566         local local_numfiles=$2
5567         local local_numdirs=$3
5568
5569         setup_56 $local_tdir $local_numfiles $local_numdirs
5570
5571         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5572                 for i in $(seq $local_numfiles) ; do
5573                         mknod $local_tdir/loop${i}b b 7 $i
5574                         mknod $local_tdir/null${i}c c 1 3
5575                         ln -s $local_tdir/file1 $local_tdir/link${i}
5576                 done
5577                 for i in $(seq $local_numdirs) ; do
5578                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5579                         mknod $local_tdir/dir$i/null${i}c c 1 3
5580                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5581                 done
5582         fi
5583 }
5584
5585 test_56g() {
5586         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5587         local expected=$(($NUMDIRS + 2))
5588
5589         setup_56 $dir $NUMFILES $NUMDIRS
5590
5591         # test lfs find with -name
5592         for i in $(seq $NUMFILES) ; do
5593                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5594
5595                 [ $nums -eq $expected ] ||
5596                         error "lfs find -name '*$i' $dir wrong: "\
5597                               "found $nums, expected $expected"
5598         done
5599 }
5600 run_test 56g "check lfs find -name"
5601
5602 test_56h() {
5603         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5604         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5605
5606         setup_56 $dir $NUMFILES $NUMDIRS
5607
5608         # test lfs find with ! -name
5609         for i in $(seq $NUMFILES) ; do
5610                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5611
5612                 [ $nums -eq $expected ] ||
5613                         error "lfs find ! -name '*$i' $dir wrong: "\
5614                               "found $nums, expected $expected"
5615         done
5616 }
5617 run_test 56h "check lfs find ! -name"
5618
5619 test_56i() {
5620         local dir=$DIR/$tdir
5621
5622         test_mkdir $dir
5623
5624         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5625         local out=$($cmd)
5626
5627         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5628 }
5629 run_test 56i "check 'lfs find -ost UUID' skips directories"
5630
5631 test_56j() {
5632         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5633
5634         setup_56_special $dir $NUMFILES $NUMDIRS
5635
5636         local expected=$((NUMDIRS + 1))
5637         local cmd="$LFS find -type d $dir"
5638         local nums=$($cmd | wc -l)
5639
5640         [ $nums -eq $expected ] ||
5641                 error "'$cmd' wrong: found $nums, expected $expected"
5642 }
5643 run_test 56j "check lfs find -type d"
5644
5645 test_56k() {
5646         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5647
5648         setup_56_special $dir $NUMFILES $NUMDIRS
5649
5650         local expected=$(((NUMDIRS + 1) * NUMFILES))
5651         local cmd="$LFS find -type f $dir"
5652         local nums=$($cmd | wc -l)
5653
5654         [ $nums -eq $expected ] ||
5655                 error "'$cmd' wrong: found $nums, expected $expected"
5656 }
5657 run_test 56k "check lfs find -type f"
5658
5659 test_56l() {
5660         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5661
5662         setup_56_special $dir $NUMFILES $NUMDIRS
5663
5664         local expected=$((NUMDIRS + NUMFILES))
5665         local cmd="$LFS find -type b $dir"
5666         local nums=$($cmd | wc -l)
5667
5668         [ $nums -eq $expected ] ||
5669                 error "'$cmd' wrong: found $nums, expected $expected"
5670 }
5671 run_test 56l "check lfs find -type b"
5672
5673 test_56m() {
5674         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5675
5676         setup_56_special $dir $NUMFILES $NUMDIRS
5677
5678         local expected=$((NUMDIRS + NUMFILES))
5679         local cmd="$LFS find -type c $dir"
5680         local nums=$($cmd | wc -l)
5681         [ $nums -eq $expected ] ||
5682                 error "'$cmd' wrong: found $nums, expected $expected"
5683 }
5684 run_test 56m "check lfs find -type c"
5685
5686 test_56n() {
5687         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5688         setup_56_special $dir $NUMFILES $NUMDIRS
5689
5690         local expected=$((NUMDIRS + NUMFILES))
5691         local cmd="$LFS find -type l $dir"
5692         local nums=$($cmd | wc -l)
5693
5694         [ $nums -eq $expected ] ||
5695                 error "'$cmd' wrong: found $nums, expected $expected"
5696 }
5697 run_test 56n "check lfs find -type l"
5698
5699 test_56o() {
5700         local dir=$DIR/$tdir
5701
5702         setup_56 $dir $NUMFILES $NUMDIRS
5703         utime $dir/file1 > /dev/null || error "utime (1)"
5704         utime $dir/file2 > /dev/null || error "utime (2)"
5705         utime $dir/dir1 > /dev/null || error "utime (3)"
5706         utime $dir/dir2 > /dev/null || error "utime (4)"
5707         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5708         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5709
5710         local expected=4
5711         local nums=$($LFS find -mtime +0 $dir | wc -l)
5712
5713         [ $nums -eq $expected ] ||
5714                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5715
5716         expected=12
5717         cmd="$LFS find -mtime 0 $dir"
5718         nums=$($cmd | wc -l)
5719         [ $nums -eq $expected ] ||
5720                 error "'$cmd' wrong: found $nums, expected $expected"
5721 }
5722 run_test 56o "check lfs find -mtime for old files"
5723
5724 test_56ob() {
5725         local dir=$DIR/$tdir
5726         local expected=1
5727         local count=0
5728
5729         # just to make sure there is something that won't be found
5730         test_mkdir $dir
5731         touch $dir/$tfile.now
5732
5733         for age in year week day hour min; do
5734                 count=$((count + 1))
5735
5736                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5737                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5738                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5739
5740                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5741                 local nums=$($cmd | wc -l)
5742                 [ $nums -eq $expected ] ||
5743                         error "'$cmd' wrong: found $nums, expected $expected"
5744
5745                 cmd="$LFS find $dir -atime $count${age:0:1}"
5746                 nums=$($cmd | wc -l)
5747                 [ $nums -eq $expected ] ||
5748                         error "'$cmd' wrong: found $nums, expected $expected"
5749         done
5750
5751         sleep 2
5752         cmd="$LFS find $dir -ctime +1s -type f"
5753         nums=$($cmd | wc -l)
5754         (( $nums == $count * 2 + 1)) ||
5755                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5756 }
5757 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5758
5759 test_newerXY_base() {
5760         local x=$1
5761         local y=$2
5762         local dir=$DIR/$tdir
5763         local ref
5764         local negref
5765
5766         if [ $y == "t" ]; then
5767                 ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5768         else
5769                 ref=$DIR/$tfile.newer
5770                 touch $ref || error "touch $ref failed"
5771         fi
5772         sleep 2
5773         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5774         sleep 2
5775         if [ $y == "t" ]; then
5776                 negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5777         else
5778                 negref=$DIR/$tfile.newerneg
5779                 touch $negref || error "touch $negref failed"
5780         fi
5781
5782         local cmd="$LFS find $dir -newer$x$y $ref"
5783         local nums=$(eval $cmd | wc -l)
5784         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5785
5786         [ $nums -eq $expected ] ||
5787                 error "'$cmd' wrong: found $nums, expected $expected"
5788
5789         cmd="$LFS find $dir ! -newer$x$y $negref"
5790         nums=$(eval $cmd | wc -l)
5791         [ $nums -eq $expected ] ||
5792                 error "'$cmd' wrong: found $nums, expected $expected"
5793
5794         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5795         nums=$(eval $cmd | wc -l)
5796         [ $nums -eq $expected ] ||
5797                 error "'$cmd' wrong: found $nums, expected $expected"
5798
5799         rm -rf $DIR/*
5800 }
5801
5802 test_56oc() {
5803         test_newerXY_base "a" "a"
5804         test_newerXY_base "a" "m"
5805         test_newerXY_base "a" "c"
5806         test_newerXY_base "m" "a"
5807         test_newerXY_base "m" "m"
5808         test_newerXY_base "m" "c"
5809         test_newerXY_base "c" "a"
5810         test_newerXY_base "c" "m"
5811         test_newerXY_base "c" "c"
5812         test_newerXY_base "a" "t"
5813         test_newerXY_base "m" "t"
5814         test_newerXY_base "c" "t"
5815 }
5816 run_test 56oc "check lfs find -newerXY work"
5817
5818 test_56p() {
5819         [ $RUNAS_ID -eq $UID ] &&
5820                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5821
5822         local dir=$DIR/$tdir
5823
5824         setup_56 $dir $NUMFILES $NUMDIRS
5825         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5826
5827         local expected=$NUMFILES
5828         local cmd="$LFS find -uid $RUNAS_ID $dir"
5829         local nums=$($cmd | wc -l)
5830
5831         [ $nums -eq $expected ] ||
5832                 error "'$cmd' wrong: found $nums, expected $expected"
5833
5834         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5835         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5836         nums=$($cmd | wc -l)
5837         [ $nums -eq $expected ] ||
5838                 error "'$cmd' wrong: found $nums, expected $expected"
5839 }
5840 run_test 56p "check lfs find -uid and ! -uid"
5841
5842 test_56q() {
5843         [ $RUNAS_ID -eq $UID ] &&
5844                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5845
5846         local dir=$DIR/$tdir
5847
5848         setup_56 $dir $NUMFILES $NUMDIRS
5849         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5850
5851         local expected=$NUMFILES
5852         local cmd="$LFS find -gid $RUNAS_GID $dir"
5853         local nums=$($cmd | wc -l)
5854
5855         [ $nums -eq $expected ] ||
5856                 error "'$cmd' wrong: found $nums, expected $expected"
5857
5858         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5859         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5860         nums=$($cmd | wc -l)
5861         [ $nums -eq $expected ] ||
5862                 error "'$cmd' wrong: found $nums, expected $expected"
5863 }
5864 run_test 56q "check lfs find -gid and ! -gid"
5865
5866 test_56r() {
5867         local dir=$DIR/$tdir
5868
5869         setup_56 $dir $NUMFILES $NUMDIRS
5870
5871         local expected=12
5872         local cmd="$LFS find -size 0 -type f -lazy $dir"
5873         local nums=$($cmd | wc -l)
5874
5875         [ $nums -eq $expected ] ||
5876                 error "'$cmd' wrong: found $nums, expected $expected"
5877         cmd="$LFS find -size 0 -type f $dir"
5878         nums=$($cmd | wc -l)
5879         [ $nums -eq $expected ] ||
5880                 error "'$cmd' wrong: found $nums, expected $expected"
5881
5882         expected=0
5883         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5884         nums=$($cmd | wc -l)
5885         [ $nums -eq $expected ] ||
5886                 error "'$cmd' wrong: found $nums, expected $expected"
5887         cmd="$LFS find ! -size 0 -type f $dir"
5888         nums=$($cmd | wc -l)
5889         [ $nums -eq $expected ] ||
5890                 error "'$cmd' wrong: found $nums, expected $expected"
5891
5892         echo "test" > $dir/$tfile
5893         echo "test2" > $dir/$tfile.2 && sync
5894         expected=1
5895         cmd="$LFS find -size 5 -type f -lazy $dir"
5896         nums=$($cmd | wc -l)
5897         [ $nums -eq $expected ] ||
5898                 error "'$cmd' wrong: found $nums, expected $expected"
5899         cmd="$LFS find -size 5 -type f $dir"
5900         nums=$($cmd | wc -l)
5901         [ $nums -eq $expected ] ||
5902                 error "'$cmd' wrong: found $nums, expected $expected"
5903
5904         expected=1
5905         cmd="$LFS find -size +5 -type f -lazy $dir"
5906         nums=$($cmd | wc -l)
5907         [ $nums -eq $expected ] ||
5908                 error "'$cmd' wrong: found $nums, expected $expected"
5909         cmd="$LFS find -size +5 -type f $dir"
5910         nums=$($cmd | wc -l)
5911         [ $nums -eq $expected ] ||
5912                 error "'$cmd' wrong: found $nums, expected $expected"
5913
5914         expected=2
5915         cmd="$LFS find -size +0 -type f -lazy $dir"
5916         nums=$($cmd | wc -l)
5917         [ $nums -eq $expected ] ||
5918                 error "'$cmd' wrong: found $nums, expected $expected"
5919         cmd="$LFS find -size +0 -type f $dir"
5920         nums=$($cmd | wc -l)
5921         [ $nums -eq $expected ] ||
5922                 error "'$cmd' wrong: found $nums, expected $expected"
5923
5924         expected=2
5925         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5926         nums=$($cmd | wc -l)
5927         [ $nums -eq $expected ] ||
5928                 error "'$cmd' wrong: found $nums, expected $expected"
5929         cmd="$LFS find ! -size -5 -type f $dir"
5930         nums=$($cmd | wc -l)
5931         [ $nums -eq $expected ] ||
5932                 error "'$cmd' wrong: found $nums, expected $expected"
5933
5934         expected=12
5935         cmd="$LFS find -size -5 -type f -lazy $dir"
5936         nums=$($cmd | wc -l)
5937         [ $nums -eq $expected ] ||
5938                 error "'$cmd' wrong: found $nums, expected $expected"
5939         cmd="$LFS find -size -5 -type f $dir"
5940         nums=$($cmd | wc -l)
5941         [ $nums -eq $expected ] ||
5942                 error "'$cmd' wrong: found $nums, expected $expected"
5943 }
5944 run_test 56r "check lfs find -size works"
5945
5946 test_56ra() {
5947         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
5948                 skip "MDS < 2.12.58 doesn't return LSOM data"
5949         local dir=$DIR/$tdir
5950
5951         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5952
5953         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5954
5955         cancel_lru_locks $OSC
5956
5957         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5958         local expected=12
5959         local cmd="$LFS find -size 0 -type f -lazy $dir"
5960         local nums=$($cmd | wc -l)
5961
5962         [ $nums -eq $expected ] ||
5963                 error "'$cmd' wrong: found $nums, expected $expected"
5964
5965         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5966         [ $rpcs_before -eq $rpcs_after ] ||
5967                 error "'$cmd' should not send glimpse RPCs to OST"
5968         cmd="$LFS find -size 0 -type f $dir"
5969         nums=$($cmd | wc -l)
5970         [ $nums -eq $expected ] ||
5971                 error "'$cmd' wrong: found $nums, expected $expected"
5972         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5973         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5974         $LCTL get_param osc.*.stats
5975         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5976                 error "'$cmd' should send 12 glimpse RPCs to OST"
5977
5978         cancel_lru_locks $OSC
5979         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5980         expected=0
5981         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5982         nums=$($cmd | wc -l)
5983         [ $nums -eq $expected ] ||
5984                 error "'$cmd' wrong: found $nums, expected $expected"
5985         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5986         $LCTL get_param mdc.*.stats
5987         [ $rpcs_before -eq $rpcs_after ] ||
5988                 error "'$cmd' should not send glimpse RPCs to OST"
5989         cmd="$LFS find ! -size 0 -type f $dir"
5990         nums=$($cmd | wc -l)
5991         [ $nums -eq $expected ] ||
5992                 error "'$cmd' wrong: found $nums, expected $expected"
5993         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5994         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5995         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5996                 error "'$cmd' should send 12 glimpse RPCs to OST"
5997
5998         echo "test" > $dir/$tfile
5999         echo "test2" > $dir/$tfile.2 && sync
6000         cancel_lru_locks $OSC
6001         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6002         expected=1
6003         cmd="$LFS find -size 5 -type f -lazy $dir"
6004         nums=$($cmd | wc -l)
6005         [ $nums -eq $expected ] ||
6006                 error "'$cmd' wrong: found $nums, expected $expected"
6007         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6008         [ $rpcs_before -eq $rpcs_after ] ||
6009                 error "'$cmd' should not send glimpse RPCs to OST"
6010         cmd="$LFS find -size 5 -type f $dir"
6011         nums=$($cmd | wc -l)
6012         [ $nums -eq $expected ] ||
6013                 error "'$cmd' wrong: found $nums, expected $expected"
6014         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6015         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6016         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6017                 error "'$cmd' should send 14 glimpse RPCs to OST"
6018
6019         cancel_lru_locks $OSC
6020         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6021         expected=1
6022         cmd="$LFS find -size +5 -type f -lazy $dir"
6023         nums=$($cmd | wc -l)
6024         [ $nums -eq $expected ] ||
6025                 error "'$cmd' wrong: found $nums, expected $expected"
6026         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6027         [ $rpcs_before -eq $rpcs_after ] ||
6028                 error "'$cmd' should not send glimpse RPCs to OST"
6029         cmd="$LFS find -size +5 -type f $dir"
6030         nums=$($cmd | wc -l)
6031         [ $nums -eq $expected ] ||
6032                 error "'$cmd' wrong: found $nums, expected $expected"
6033         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6034         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6035         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6036                 error "'$cmd' should send 14 glimpse RPCs to OST"
6037
6038         cancel_lru_locks $OSC
6039         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6040         expected=2
6041         cmd="$LFS find -size +0 -type f -lazy $dir"
6042         nums=$($cmd | wc -l)
6043         [ $nums -eq $expected ] ||
6044                 error "'$cmd' wrong: found $nums, expected $expected"
6045         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6046         [ $rpcs_before -eq $rpcs_after ] ||
6047                 error "'$cmd' should not send glimpse RPCs to OST"
6048         cmd="$LFS find -size +0 -type f $dir"
6049         nums=$($cmd | wc -l)
6050         [ $nums -eq $expected ] ||
6051                 error "'$cmd' wrong: found $nums, expected $expected"
6052         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6053         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6054         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6055                 error "'$cmd' should send 14 glimpse RPCs to OST"
6056
6057         cancel_lru_locks $OSC
6058         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6059         expected=2
6060         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6061         nums=$($cmd | wc -l)
6062         [ $nums -eq $expected ] ||
6063                 error "'$cmd' wrong: found $nums, expected $expected"
6064         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6065         [ $rpcs_before -eq $rpcs_after ] ||
6066                 error "'$cmd' should not send glimpse RPCs to OST"
6067         cmd="$LFS find ! -size -5 -type f $dir"
6068         nums=$($cmd | wc -l)
6069         [ $nums -eq $expected ] ||
6070                 error "'$cmd' wrong: found $nums, expected $expected"
6071         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6072         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6073         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6074                 error "'$cmd' should send 14 glimpse RPCs to OST"
6075
6076         cancel_lru_locks $OSC
6077         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6078         expected=12
6079         cmd="$LFS find -size -5 -type f -lazy $dir"
6080         nums=$($cmd | wc -l)
6081         [ $nums -eq $expected ] ||
6082                 error "'$cmd' wrong: found $nums, expected $expected"
6083         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6084         [ $rpcs_before -eq $rpcs_after ] ||
6085                 error "'$cmd' should not send glimpse RPCs to OST"
6086         cmd="$LFS find -size -5 -type f $dir"
6087         nums=$($cmd | wc -l)
6088         [ $nums -eq $expected ] ||
6089                 error "'$cmd' wrong: found $nums, expected $expected"
6090         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6091         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6092         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6093                 error "'$cmd' should send 14 glimpse RPCs to OST"
6094 }
6095 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6096
6097 test_56s() { # LU-611 #LU-9369
6098         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6099
6100         local dir=$DIR/$tdir
6101         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6102
6103         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6104         for i in $(seq $NUMDIRS); do
6105                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6106         done
6107
6108         local expected=$NUMDIRS
6109         local cmd="$LFS find -c $OSTCOUNT $dir"
6110         local nums=$($cmd | wc -l)
6111
6112         [ $nums -eq $expected ] || {
6113                 $LFS getstripe -R $dir
6114                 error "'$cmd' wrong: found $nums, expected $expected"
6115         }
6116
6117         expected=$((NUMDIRS + onestripe))
6118         cmd="$LFS find -stripe-count +0 -type f $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] || {
6121                 $LFS getstripe -R $dir
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123         }
6124
6125         expected=$onestripe
6126         cmd="$LFS find -stripe-count 1 -type f $dir"
6127         nums=$($cmd | wc -l)
6128         [ $nums -eq $expected ] || {
6129                 $LFS getstripe -R $dir
6130                 error "'$cmd' wrong: found $nums, expected $expected"
6131         }
6132
6133         cmd="$LFS find -stripe-count -2 -type f $dir"
6134         nums=$($cmd | wc -l)
6135         [ $nums -eq $expected ] || {
6136                 $LFS getstripe -R $dir
6137                 error "'$cmd' wrong: found $nums, expected $expected"
6138         }
6139
6140         expected=0
6141         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6142         nums=$($cmd | wc -l)
6143         [ $nums -eq $expected ] || {
6144                 $LFS getstripe -R $dir
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146         }
6147 }
6148 run_test 56s "check lfs find -stripe-count works"
6149
6150 test_56t() { # LU-611 #LU-9369
6151         local dir=$DIR/$tdir
6152
6153         setup_56 $dir 0 $NUMDIRS
6154         for i in $(seq $NUMDIRS); do
6155                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6156         done
6157
6158         local expected=$NUMDIRS
6159         local cmd="$LFS find -S 8M $dir"
6160         local nums=$($cmd | wc -l)
6161
6162         [ $nums -eq $expected ] || {
6163                 $LFS getstripe -R $dir
6164                 error "'$cmd' wrong: found $nums, expected $expected"
6165         }
6166         rm -rf $dir
6167
6168         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6169
6170         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6171
6172         expected=$(((NUMDIRS + 1) * NUMFILES))
6173         cmd="$LFS find -stripe-size 512k -type f $dir"
6174         nums=$($cmd | wc -l)
6175         [ $nums -eq $expected ] ||
6176                 error "'$cmd' wrong: found $nums, expected $expected"
6177
6178         cmd="$LFS find -stripe-size +320k -type f $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182
6183         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6184         cmd="$LFS find -stripe-size +200k -type f $dir"
6185         nums=$($cmd | wc -l)
6186         [ $nums -eq $expected ] ||
6187                 error "'$cmd' wrong: found $nums, expected $expected"
6188
6189         cmd="$LFS find -stripe-size -640k -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         expected=4
6195         cmd="$LFS find -stripe-size 256k -type f $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199
6200         cmd="$LFS find -stripe-size -320k -type f $dir"
6201         nums=$($cmd | wc -l)
6202         [ $nums -eq $expected ] ||
6203                 error "'$cmd' wrong: found $nums, expected $expected"
6204
6205         expected=0
6206         cmd="$LFS find -stripe-size 1024k -type f $dir"
6207         nums=$($cmd | wc -l)
6208         [ $nums -eq $expected ] ||
6209                 error "'$cmd' wrong: found $nums, expected $expected"
6210 }
6211 run_test 56t "check lfs find -stripe-size works"
6212
6213 test_56u() { # LU-611
6214         local dir=$DIR/$tdir
6215
6216         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6217
6218         if [[ $OSTCOUNT -gt 1 ]]; then
6219                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6220                 onestripe=4
6221         else
6222                 onestripe=0
6223         fi
6224
6225         local expected=$(((NUMDIRS + 1) * NUMFILES))
6226         local cmd="$LFS find -stripe-index 0 -type f $dir"
6227         local nums=$($cmd | wc -l)
6228
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231
6232         expected=$onestripe
6233         cmd="$LFS find -stripe-index 1 -type f $dir"
6234         nums=$($cmd | wc -l)
6235         [ $nums -eq $expected ] ||
6236                 error "'$cmd' wrong: found $nums, expected $expected"
6237
6238         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6239         nums=$($cmd | wc -l)
6240         [ $nums -eq $expected ] ||
6241                 error "'$cmd' wrong: found $nums, expected $expected"
6242
6243         expected=0
6244         # This should produce an error and not return any files
6245         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6246         nums=$($cmd 2>/dev/null | wc -l)
6247         [ $nums -eq $expected ] ||
6248                 error "'$cmd' wrong: found $nums, expected $expected"
6249
6250         if [[ $OSTCOUNT -gt 1 ]]; then
6251                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6252                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6253                 nums=$($cmd | wc -l)
6254                 [ $nums -eq $expected ] ||
6255                         error "'$cmd' wrong: found $nums, expected $expected"
6256         fi
6257 }
6258 run_test 56u "check lfs find -stripe-index works"
6259
6260 test_56v() {
6261         local mdt_idx=0
6262         local dir=$DIR/$tdir
6263
6264         setup_56 $dir $NUMFILES $NUMDIRS
6265
6266         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6267         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6268
6269         for file in $($LFS find -m $UUID $dir); do
6270                 file_midx=$($LFS getstripe -m $file)
6271                 [ $file_midx -eq $mdt_idx ] ||
6272                         error "lfs find -m $UUID != getstripe -m $file_midx"
6273         done
6274 }
6275 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6276
6277 test_56w() {
6278         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6280
6281         local dir=$DIR/$tdir
6282
6283         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6284
6285         local stripe_size=$($LFS getstripe -S -d $dir) ||
6286                 error "$LFS getstripe -S -d $dir failed"
6287         stripe_size=${stripe_size%% *}
6288
6289         local file_size=$((stripe_size * OSTCOUNT))
6290         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6291         local required_space=$((file_num * file_size))
6292         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6293                            head -n1)
6294         [[ $free_space -le $((required_space / 1024)) ]] &&
6295                 skip_env "need $required_space, have $free_space kbytes"
6296
6297         local dd_bs=65536
6298         local dd_count=$((file_size / dd_bs))
6299
6300         # write data into the files
6301         local i
6302         local j
6303         local file
6304
6305         for i in $(seq $NUMFILES); do
6306                 file=$dir/file$i
6307                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6308                         error "write data into $file failed"
6309         done
6310         for i in $(seq $NUMDIRS); do
6311                 for j in $(seq $NUMFILES); do
6312                         file=$dir/dir$i/file$j
6313                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6314                                 error "write data into $file failed"
6315                 done
6316         done
6317
6318         # $LFS_MIGRATE will fail if hard link migration is unsupported
6319         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6320                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6321                         error "creating links to $dir/dir1/file1 failed"
6322         fi
6323
6324         local expected=-1
6325
6326         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6327
6328         # lfs_migrate file
6329         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6330
6331         echo "$cmd"
6332         eval $cmd || error "$cmd failed"
6333
6334         check_stripe_count $dir/file1 $expected
6335
6336         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6337         then
6338                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6339                 # OST 1 if it is on OST 0. This file is small enough to
6340                 # be on only one stripe.
6341                 file=$dir/migr_1_ost
6342                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6343                         error "write data into $file failed"
6344                 local obdidx=$($LFS getstripe -i $file)
6345                 local oldmd5=$(md5sum $file)
6346                 local newobdidx=0
6347
6348                 [[ $obdidx -eq 0 ]] && newobdidx=1
6349                 cmd="$LFS migrate -i $newobdidx $file"
6350                 echo $cmd
6351                 eval $cmd || error "$cmd failed"
6352
6353                 local realobdix=$($LFS getstripe -i $file)
6354                 local newmd5=$(md5sum $file)
6355
6356                 [[ $newobdidx -ne $realobdix ]] &&
6357                         error "new OST is different (was=$obdidx, "\
6358                               "wanted=$newobdidx, got=$realobdix)"
6359                 [[ "$oldmd5" != "$newmd5" ]] &&
6360                         error "md5sum differ: $oldmd5, $newmd5"
6361         fi
6362
6363         # lfs_migrate dir
6364         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6365         echo "$cmd"
6366         eval $cmd || error "$cmd failed"
6367
6368         for j in $(seq $NUMFILES); do
6369                 check_stripe_count $dir/dir1/file$j $expected
6370         done
6371
6372         # lfs_migrate works with lfs find
6373         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6374              $LFS_MIGRATE -y -c $expected"
6375         echo "$cmd"
6376         eval $cmd || error "$cmd failed"
6377
6378         for i in $(seq 2 $NUMFILES); do
6379                 check_stripe_count $dir/file$i $expected
6380         done
6381         for i in $(seq 2 $NUMDIRS); do
6382                 for j in $(seq $NUMFILES); do
6383                 check_stripe_count $dir/dir$i/file$j $expected
6384                 done
6385         done
6386 }
6387 run_test 56w "check lfs_migrate -c stripe_count works"
6388
6389 test_56wb() {
6390         local file1=$DIR/$tdir/file1
6391         local create_pool=false
6392         local initial_pool=$($LFS getstripe -p $DIR)
6393         local pool_list=()
6394         local pool=""
6395
6396         echo -n "Creating test dir..."
6397         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6398         echo "done."
6399
6400         echo -n "Creating test file..."
6401         touch $file1 || error "cannot create file"
6402         echo "done."
6403
6404         echo -n "Detecting existing pools..."
6405         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6406
6407         if [ ${#pool_list[@]} -gt 0 ]; then
6408                 echo "${pool_list[@]}"
6409                 for thispool in "${pool_list[@]}"; do
6410                         if [[ -z "$initial_pool" ||
6411                               "$initial_pool" != "$thispool" ]]; then
6412                                 pool="$thispool"
6413                                 echo "Using existing pool '$pool'"
6414                                 break
6415                         fi
6416                 done
6417         else
6418                 echo "none detected."
6419         fi
6420         if [ -z "$pool" ]; then
6421                 pool=${POOL:-testpool}
6422                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6423                 echo -n "Creating pool '$pool'..."
6424                 create_pool=true
6425                 pool_add $pool &> /dev/null ||
6426                         error "pool_add failed"
6427                 echo "done."
6428
6429                 echo -n "Adding target to pool..."
6430                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6431                         error "pool_add_targets failed"
6432                 echo "done."
6433         fi
6434
6435         echo -n "Setting pool using -p option..."
6436         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6437                 error "migrate failed rc = $?"
6438         echo "done."
6439
6440         echo -n "Verifying test file is in pool after migrating..."
6441         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6442                 error "file was not migrated to pool $pool"
6443         echo "done."
6444
6445         echo -n "Removing test file from pool '$pool'..."
6446         $LFS migrate $file1 &> /dev/null ||
6447                 error "cannot remove from pool"
6448         [ "$($LFS getstripe -p $file1)" ] &&
6449                 error "pool still set"
6450         echo "done."
6451
6452         echo -n "Setting pool using --pool option..."
6453         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6454                 error "migrate failed rc = $?"
6455         echo "done."
6456
6457         # Clean up
6458         rm -f $file1
6459         if $create_pool; then
6460                 destroy_test_pools 2> /dev/null ||
6461                         error "destroy test pools failed"
6462         fi
6463 }
6464 run_test 56wb "check lfs_migrate pool support"
6465
6466 test_56wc() {
6467         local file1="$DIR/$tdir/file1"
6468
6469         echo -n "Creating test dir..."
6470         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6471         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6472         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6473                 error "cannot set stripe"
6474         echo "done"
6475
6476         echo -n "Setting initial stripe for test file..."
6477         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6478                 error "cannot set stripe"
6479         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6480                 error "stripe size not set"
6481         echo "done."
6482
6483         # File currently set to -S 512K -c 1
6484
6485         # Ensure -c and -S options are rejected when -R is set
6486         echo -n "Verifying incompatible options are detected..."
6487         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6488                 error "incompatible -c and -R options not detected"
6489         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6490                 error "incompatible -S and -R options not detected"
6491         echo "done."
6492
6493         # Ensure unrecognized options are passed through to 'lfs migrate'
6494         echo -n "Verifying -S option is passed through to lfs migrate..."
6495         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6496                 error "migration failed"
6497         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6498                 error "file was not restriped"
6499         echo "done."
6500
6501         # File currently set to -S 1M -c 1
6502
6503         # Ensure long options are supported
6504         echo -n "Verifying long options supported..."
6505         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6506                 error "long option without argument not supported"
6507         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6508                 error "long option with argument not supported"
6509         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6510                 error "file not restriped with --stripe-size option"
6511         echo "done."
6512
6513         # File currently set to -S 512K -c 1
6514
6515         if [ "$OSTCOUNT" -gt 1 ]; then
6516                 echo -n "Verifying explicit stripe count can be set..."
6517                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6518                         error "migrate failed"
6519                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6520                         error "file not restriped to explicit count"
6521                 echo "done."
6522         fi
6523
6524         # File currently set to -S 512K -c 1 or -S 512K -c 2
6525
6526         # Ensure parent striping is used if -R is set, and no stripe
6527         # count or size is specified
6528         echo -n "Setting stripe for parent directory..."
6529         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6530                 error "cannot set stripe"
6531         echo "done."
6532
6533         echo -n "Verifying restripe option uses parent stripe settings..."
6534         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6535                 error "migrate failed"
6536         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6537                 error "file not restriped to parent settings"
6538         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6539                 error "file not restriped to parent settings"
6540         echo "done."
6541
6542         # File currently set to -S 1M -c 1
6543
6544         # Ensure striping is preserved if -R is not set, and no stripe
6545         # count or size is specified
6546         echo -n "Verifying striping size preserved when not specified..."
6547         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6548         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6549                 error "cannot set stripe on parent directory"
6550         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6551                 error "migrate failed"
6552         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6553                 error "file was restriped"
6554         echo "done."
6555
6556         # Ensure file name properly detected when final option has no argument
6557         echo -n "Verifying file name properly detected..."
6558         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6559                 error "file name interpreted as option argument"
6560         echo "done."
6561
6562         # Clean up
6563         rm -f "$file1"
6564 }
6565 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6566
6567 test_56wd() {
6568         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6569
6570         local file1=$DIR/$tdir/file1
6571
6572         echo -n "Creating test dir..."
6573         test_mkdir $DIR/$tdir || error "cannot create dir"
6574         echo "done."
6575
6576         echo -n "Creating test file..."
6577         touch $file1
6578         echo "done."
6579
6580         # Ensure 'lfs migrate' will fail by using a non-existent option,
6581         # and make sure rsync is not called to recover
6582         echo -n "Make sure --no-rsync option works..."
6583         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6584                 grep -q 'refusing to fall back to rsync' ||
6585                 error "rsync was called with --no-rsync set"
6586         echo "done."
6587
6588         # Ensure rsync is called without trying 'lfs migrate' first
6589         echo -n "Make sure --rsync option works..."
6590         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6591                 grep -q 'falling back to rsync' &&
6592                 error "lfs migrate was called with --rsync set"
6593         echo "done."
6594
6595         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6596         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6597                 grep -q 'at the same time' ||
6598                 error "--rsync and --no-rsync accepted concurrently"
6599         echo "done."
6600
6601         # Clean up
6602         rm -f $file1
6603 }
6604 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6605
6606 test_56x() {
6607         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6608         check_swap_layouts_support
6609
6610         local dir=$DIR/$tdir
6611         local ref1=/etc/passwd
6612         local file1=$dir/file1
6613
6614         test_mkdir $dir || error "creating dir $dir"
6615         $LFS setstripe -c 2 $file1
6616         cp $ref1 $file1
6617         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6618         stripe=$($LFS getstripe -c $file1)
6619         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6620         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6621
6622         # clean up
6623         rm -f $file1
6624 }
6625 run_test 56x "lfs migration support"
6626
6627 test_56xa() {
6628         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6629         check_swap_layouts_support
6630
6631         local dir=$DIR/$tdir/$testnum
6632
6633         test_mkdir -p $dir
6634
6635         local ref1=/etc/passwd
6636         local file1=$dir/file1
6637
6638         $LFS setstripe -c 2 $file1
6639         cp $ref1 $file1
6640         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6641
6642         local stripe=$($LFS getstripe -c $file1)
6643
6644         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6645         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6646
6647         # clean up
6648         rm -f $file1
6649 }
6650 run_test 56xa "lfs migration --block support"
6651
6652 check_migrate_links() {
6653         local dir="$1"
6654         local file1="$dir/file1"
6655         local begin="$2"
6656         local count="$3"
6657         local runas="$4"
6658         local total_count=$(($begin + $count - 1))
6659         local symlink_count=10
6660         local uniq_count=10
6661
6662         if [ ! -f "$file1" ]; then
6663                 echo -n "creating initial file..."
6664                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6665                         error "cannot setstripe initial file"
6666                 echo "done"
6667
6668                 echo -n "creating symlinks..."
6669                 for s in $(seq 1 $symlink_count); do
6670                         ln -s "$file1" "$dir/slink$s" ||
6671                                 error "cannot create symlinks"
6672                 done
6673                 echo "done"
6674
6675                 echo -n "creating nonlinked files..."
6676                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6677                         error "cannot create nonlinked files"
6678                 echo "done"
6679         fi
6680
6681         # create hard links
6682         if [ ! -f "$dir/file$total_count" ]; then
6683                 echo -n "creating hard links $begin:$total_count..."
6684                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6685                         /dev/null || error "cannot create hard links"
6686                 echo "done"
6687         fi
6688
6689         echo -n "checking number of hard links listed in xattrs..."
6690         local fid=$($LFS getstripe -F "$file1")
6691         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6692
6693         echo "${#paths[*]}"
6694         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6695                         skip "hard link list has unexpected size, skipping test"
6696         fi
6697         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6698                         error "link names should exceed xattrs size"
6699         fi
6700
6701         echo -n "migrating files..."
6702         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6703         local rc=$?
6704         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6705         echo "done"
6706
6707         # make sure all links have been properly migrated
6708         echo -n "verifying files..."
6709         fid=$($LFS getstripe -F "$file1") ||
6710                 error "cannot get fid for file $file1"
6711         for i in $(seq 2 $total_count); do
6712                 local fid2=$($LFS getstripe -F $dir/file$i)
6713
6714                 [ "$fid2" == "$fid" ] ||
6715                         error "migrated hard link has mismatched FID"
6716         done
6717
6718         # make sure hard links were properly detected, and migration was
6719         # performed only once for the entire link set; nonlinked files should
6720         # also be migrated
6721         local actual=$(grep -c 'done' <<< "$migrate_out")
6722         local expected=$(($uniq_count + 1))
6723
6724         [ "$actual" -eq  "$expected" ] ||
6725                 error "hard links individually migrated ($actual != $expected)"
6726
6727         # make sure the correct number of hard links are present
6728         local hardlinks=$(stat -c '%h' "$file1")
6729
6730         [ $hardlinks -eq $total_count ] ||
6731                 error "num hard links $hardlinks != $total_count"
6732         echo "done"
6733
6734         return 0
6735 }
6736
6737 test_56xb() {
6738         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6739                 skip "Need MDS version at least 2.10.55"
6740
6741         local dir="$DIR/$tdir"
6742
6743         test_mkdir "$dir" || error "cannot create dir $dir"
6744
6745         echo "testing lfs migrate mode when all links fit within xattrs"
6746         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6747
6748         echo "testing rsync mode when all links fit within xattrs"
6749         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6750
6751         echo "testing lfs migrate mode when all links do not fit within xattrs"
6752         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6753
6754         echo "testing rsync mode when all links do not fit within xattrs"
6755         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6756
6757         chown -R $RUNAS_ID $dir
6758         echo "testing non-root lfs migrate mode when not all links are in xattr"
6759         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6760
6761         # clean up
6762         rm -rf $dir
6763 }
6764 run_test 56xb "lfs migration hard link support"
6765
6766 test_56xc() {
6767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6768
6769         local dir="$DIR/$tdir"
6770
6771         test_mkdir "$dir" || error "cannot create dir $dir"
6772
6773         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6774         echo -n "Setting initial stripe for 20MB test file..."
6775         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6776                 error "cannot setstripe 20MB file"
6777         echo "done"
6778         echo -n "Sizing 20MB test file..."
6779         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6780         echo "done"
6781         echo -n "Verifying small file autostripe count is 1..."
6782         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6783                 error "cannot migrate 20MB file"
6784         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6785                 error "cannot get stripe for $dir/20mb"
6786         [ $stripe_count -eq 1 ] ||
6787                 error "unexpected stripe count $stripe_count for 20MB file"
6788         rm -f "$dir/20mb"
6789         echo "done"
6790
6791         # Test 2: File is small enough to fit within the available space on
6792         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6793         # have at least an additional 1KB for each desired stripe for test 3
6794         echo -n "Setting stripe for 1GB test file..."
6795         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6796         echo "done"
6797         echo -n "Sizing 1GB test file..."
6798         # File size is 1GB + 3KB
6799         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6800         echo "done"
6801
6802         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6803         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6804         if (( avail > 524288 * OSTCOUNT )); then
6805                 echo -n "Migrating 1GB file..."
6806                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6807                         error "cannot migrate 1GB file"
6808                 echo "done"
6809                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6810                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6811                         error "cannot getstripe for 1GB file"
6812                 [ $stripe_count -eq 2 ] ||
6813                         error "unexpected stripe count $stripe_count != 2"
6814                 echo "done"
6815         fi
6816
6817         # Test 3: File is too large to fit within the available space on
6818         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6819         if [ $OSTCOUNT -ge 3 ]; then
6820                 # The required available space is calculated as
6821                 # file size (1GB + 3KB) / OST count (3).
6822                 local kb_per_ost=349526
6823
6824                 echo -n "Migrating 1GB file with limit..."
6825                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6826                         error "cannot migrate 1GB file with limit"
6827                 echo "done"
6828
6829                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6830                 echo -n "Verifying 1GB autostripe count with limited space..."
6831                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6832                         error "unexpected stripe count $stripe_count (min 3)"
6833                 echo "done"
6834         fi
6835
6836         # clean up
6837         rm -rf $dir
6838 }
6839 run_test 56xc "lfs migration autostripe"
6840
6841 test_56y() {
6842         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6843                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6844
6845         local res=""
6846         local dir=$DIR/$tdir
6847         local f1=$dir/file1
6848         local f2=$dir/file2
6849
6850         test_mkdir -p $dir || error "creating dir $dir"
6851         touch $f1 || error "creating std file $f1"
6852         $MULTIOP $f2 H2c || error "creating released file $f2"
6853
6854         # a directory can be raid0, so ask only for files
6855         res=$($LFS find $dir -L raid0 -type f | wc -l)
6856         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6857
6858         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6859         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6860
6861         # only files can be released, so no need to force file search
6862         res=$($LFS find $dir -L released)
6863         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6864
6865         res=$($LFS find $dir -type f \! -L released)
6866         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6867 }
6868 run_test 56y "lfs find -L raid0|released"
6869
6870 test_56z() { # LU-4824
6871         # This checks to make sure 'lfs find' continues after errors
6872         # There are two classes of errors that should be caught:
6873         # - If multiple paths are provided, all should be searched even if one
6874         #   errors out
6875         # - If errors are encountered during the search, it should not terminate
6876         #   early
6877         local dir=$DIR/$tdir
6878         local i
6879
6880         test_mkdir $dir
6881         for i in d{0..9}; do
6882                 test_mkdir $dir/$i
6883                 touch $dir/$i/$tfile
6884         done
6885         $LFS find $DIR/non_existent_dir $dir &&
6886                 error "$LFS find did not return an error"
6887         # Make a directory unsearchable. This should NOT be the last entry in
6888         # directory order.  Arbitrarily pick the 6th entry
6889         chmod 700 $($LFS find $dir -type d | sed '6!d')
6890
6891         $RUNAS $LFS find $DIR/non_existent $dir
6892         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6893
6894         # The user should be able to see 10 directories and 9 files
6895         (( count == 19 )) ||
6896                 error "$LFS find found $count != 19 entries after error"
6897 }
6898 run_test 56z "lfs find should continue after an error"
6899
6900 test_56aa() { # LU-5937
6901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6902
6903         local dir=$DIR/$tdir
6904
6905         mkdir $dir
6906         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6907
6908         createmany -o $dir/striped_dir/${tfile}- 1024
6909         local dirs=$($LFS find --size +8k $dir/)
6910
6911         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6912 }
6913 run_test 56aa "lfs find --size under striped dir"
6914
6915 test_56ab() { # LU-10705
6916         test_mkdir $DIR/$tdir
6917         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6918         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6919         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6920         # Flush writes to ensure valid blocks.  Need to be more thorough for
6921         # ZFS, since blocks are not allocated/returned to client immediately.
6922         sync_all_data
6923         wait_zfs_commit ost1 2
6924         cancel_lru_locks osc
6925         ls -ls $DIR/$tdir
6926
6927         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6928
6929         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6930
6931         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6932         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6933
6934         rm -f $DIR/$tdir/$tfile.[123]
6935 }
6936 run_test 56ab "lfs find --blocks"
6937
6938 test_56ba() {
6939         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6940                 skip "Need MDS version at least 2.10.50"
6941
6942         # Create composite files with one component
6943         local dir=$DIR/$tdir
6944
6945         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6946         # Create composite files with three components
6947         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6948         # Create non-composite files
6949         createmany -o $dir/${tfile}- 10
6950
6951         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6952
6953         [[ $nfiles == 10 ]] ||
6954                 error "lfs find -E 1M found $nfiles != 10 files"
6955
6956         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6957         [[ $nfiles == 25 ]] ||
6958                 error "lfs find ! -E 1M found $nfiles != 25 files"
6959
6960         # All files have a component that starts at 0
6961         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6962         [[ $nfiles == 35 ]] ||
6963                 error "lfs find --component-start 0 - $nfiles != 35 files"
6964
6965         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6966         [[ $nfiles == 15 ]] ||
6967                 error "lfs find --component-start 2M - $nfiles != 15 files"
6968
6969         # All files created here have a componenet that does not starts at 2M
6970         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6971         [[ $nfiles == 35 ]] ||
6972                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6973
6974         # Find files with a specified number of components
6975         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6976         [[ $nfiles == 15 ]] ||
6977                 error "lfs find --component-count 3 - $nfiles != 15 files"
6978
6979         # Remember non-composite files have a component count of zero
6980         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6981         [[ $nfiles == 10 ]] ||
6982                 error "lfs find --component-count 0 - $nfiles != 10 files"
6983
6984         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6985         [[ $nfiles == 20 ]] ||
6986                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6987
6988         # All files have a flag called "init"
6989         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6990         [[ $nfiles == 35 ]] ||
6991                 error "lfs find --component-flags init - $nfiles != 35 files"
6992
6993         # Multi-component files will have a component not initialized
6994         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6995         [[ $nfiles == 15 ]] ||
6996                 error "lfs find !--component-flags init - $nfiles != 15 files"
6997
6998         rm -rf $dir
6999
7000 }
7001 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7002
7003 test_56ca() {
7004         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7005                 skip "Need MDS version at least 2.10.57"
7006
7007         local td=$DIR/$tdir
7008         local tf=$td/$tfile
7009         local dir
7010         local nfiles
7011         local cmd
7012         local i
7013         local j
7014
7015         # create mirrored directories and mirrored files
7016         mkdir $td || error "mkdir $td failed"
7017         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7018         createmany -o $tf- 10 || error "create $tf- failed"
7019
7020         for i in $(seq 2); do
7021                 dir=$td/dir$i
7022                 mkdir $dir || error "mkdir $dir failed"
7023                 $LFS mirror create -N$((3 + i)) $dir ||
7024                         error "create mirrored dir $dir failed"
7025                 createmany -o $dir/$tfile- 10 ||
7026                         error "create $dir/$tfile- failed"
7027         done
7028
7029         # change the states of some mirrored files
7030         echo foo > $tf-6
7031         for i in $(seq 2); do
7032                 dir=$td/dir$i
7033                 for j in $(seq 4 9); do
7034                         echo foo > $dir/$tfile-$j
7035                 done
7036         done
7037
7038         # find mirrored files with specific mirror count
7039         cmd="$LFS find --mirror-count 3 --type f $td"
7040         nfiles=$($cmd | wc -l)
7041         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7042
7043         cmd="$LFS find ! --mirror-count 3 --type f $td"
7044         nfiles=$($cmd | wc -l)
7045         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7046
7047         cmd="$LFS find --mirror-count +2 --type f $td"
7048         nfiles=$($cmd | wc -l)
7049         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7050
7051         cmd="$LFS find --mirror-count -6 --type f $td"
7052         nfiles=$($cmd | wc -l)
7053         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7054
7055         # find mirrored files with specific file state
7056         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7057         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7058
7059         cmd="$LFS find --mirror-state=ro --type f $td"
7060         nfiles=$($cmd | wc -l)
7061         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7062
7063         cmd="$LFS find ! --mirror-state=ro --type f $td"
7064         nfiles=$($cmd | wc -l)
7065         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7066
7067         cmd="$LFS find --mirror-state=wp --type f $td"
7068         nfiles=$($cmd | wc -l)
7069         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7070
7071         cmd="$LFS find ! --mirror-state=sp --type f $td"
7072         nfiles=$($cmd | wc -l)
7073         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7074 }
7075 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7076
7077 test_57a() {
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079         # note test will not do anything if MDS is not local
7080         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7081                 skip_env "ldiskfs only test"
7082         fi
7083         remote_mds_nodsh && skip "remote MDS with nodsh"
7084
7085         local MNTDEV="osd*.*MDT*.mntdev"
7086         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7087         [ -z "$DEV" ] && error "can't access $MNTDEV"
7088         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7089                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7090                         error "can't access $DEV"
7091                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7092                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7093                 rm $TMP/t57a.dump
7094         done
7095 }
7096 run_test 57a "verify MDS filesystem created with large inodes =="
7097
7098 test_57b() {
7099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7100         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7101                 skip_env "ldiskfs only test"
7102         fi
7103         remote_mds_nodsh && skip "remote MDS with nodsh"
7104
7105         local dir=$DIR/$tdir
7106         local filecount=100
7107         local file1=$dir/f1
7108         local fileN=$dir/f$filecount
7109
7110         rm -rf $dir || error "removing $dir"
7111         test_mkdir -c1 $dir
7112         local mdtidx=$($LFS getstripe -m $dir)
7113         local mdtname=MDT$(printf %04x $mdtidx)
7114         local facet=mds$((mdtidx + 1))
7115
7116         echo "mcreating $filecount files"
7117         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7118
7119         # verify that files do not have EAs yet
7120         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7121                 error "$file1 has an EA"
7122         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7123                 error "$fileN has an EA"
7124
7125         sync
7126         sleep 1
7127         df $dir  #make sure we get new statfs data
7128         local mdsfree=$(do_facet $facet \
7129                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7130         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7131         local file
7132
7133         echo "opening files to create objects/EAs"
7134         for file in $(seq -f $dir/f%g 1 $filecount); do
7135                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7136                         error "opening $file"
7137         done
7138
7139         # verify that files have EAs now
7140         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7141         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7142
7143         sleep 1  #make sure we get new statfs data
7144         df $dir
7145         local mdsfree2=$(do_facet $facet \
7146                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7147         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7148
7149         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7150                 if [ "$mdsfree" != "$mdsfree2" ]; then
7151                         error "MDC before $mdcfree != after $mdcfree2"
7152                 else
7153                         echo "MDC before $mdcfree != after $mdcfree2"
7154                         echo "unable to confirm if MDS has large inodes"
7155                 fi
7156         fi
7157         rm -rf $dir
7158 }
7159 run_test 57b "default LOV EAs are stored inside large inodes ==="
7160
7161 test_58() {
7162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7163         [ -z "$(which wiretest 2>/dev/null)" ] &&
7164                         skip_env "could not find wiretest"
7165
7166         wiretest
7167 }
7168 run_test 58 "verify cross-platform wire constants =============="
7169
7170 test_59() {
7171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7172
7173         echo "touch 130 files"
7174         createmany -o $DIR/f59- 130
7175         echo "rm 130 files"
7176         unlinkmany $DIR/f59- 130
7177         sync
7178         # wait for commitment of removal
7179         wait_delete_completed
7180 }
7181 run_test 59 "verify cancellation of llog records async ========="
7182
7183 TEST60_HEAD="test_60 run $RANDOM"
7184 test_60a() {
7185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7186         remote_mgs_nodsh && skip "remote MGS with nodsh"
7187         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7188                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7189                         skip_env "missing subtest run-llog.sh"
7190
7191         log "$TEST60_HEAD - from kernel mode"
7192         do_facet mgs "$LCTL dk > /dev/null"
7193         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7194         do_facet mgs $LCTL dk > $TMP/$tfile
7195
7196         # LU-6388: test llog_reader
7197         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7198         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7199         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7200                         skip_env "missing llog_reader"
7201         local fstype=$(facet_fstype mgs)
7202         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7203                 skip_env "Only for ldiskfs or zfs type mgs"
7204
7205         local mntpt=$(facet_mntpt mgs)
7206         local mgsdev=$(mgsdevname 1)
7207         local fid_list
7208         local fid
7209         local rec_list
7210         local rec
7211         local rec_type
7212         local obj_file
7213         local path
7214         local seq
7215         local oid
7216         local pass=true
7217
7218         #get fid and record list
7219         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7220                 tail -n 4))
7221         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7222                 tail -n 4))
7223         #remount mgs as ldiskfs or zfs type
7224         stop mgs || error "stop mgs failed"
7225         mount_fstype mgs || error "remount mgs failed"
7226         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7227                 fid=${fid_list[i]}
7228                 rec=${rec_list[i]}
7229                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7230                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7231                 oid=$((16#$oid))
7232
7233                 case $fstype in
7234                         ldiskfs )
7235                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7236                         zfs )
7237                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7238                 esac
7239                 echo "obj_file is $obj_file"
7240                 do_facet mgs $llog_reader $obj_file
7241
7242                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7243                         awk '{ print $3 }' | sed -e "s/^type=//g")
7244                 if [ $rec_type != $rec ]; then
7245                         echo "FAILED test_60a wrong record type $rec_type," \
7246                               "should be $rec"
7247                         pass=false
7248                         break
7249                 fi
7250
7251                 #check obj path if record type is LLOG_LOGID_MAGIC
7252                 if [ "$rec" == "1064553b" ]; then
7253                         path=$(do_facet mgs $llog_reader $obj_file |
7254                                 grep "path=" | awk '{ print $NF }' |
7255                                 sed -e "s/^path=//g")
7256                         if [ $obj_file != $mntpt/$path ]; then
7257                                 echo "FAILED test_60a wrong obj path" \
7258                                       "$montpt/$path, should be $obj_file"
7259                                 pass=false
7260                                 break
7261                         fi
7262                 fi
7263         done
7264         rm -f $TMP/$tfile
7265         #restart mgs before "error", otherwise it will block the next test
7266         stop mgs || error "stop mgs failed"
7267         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7268         $pass || error "test failed, see FAILED test_60a messages for specifics"
7269 }
7270 run_test 60a "llog_test run from kernel module and test llog_reader"
7271
7272 test_60b() { # bug 6411
7273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7274
7275         dmesg > $DIR/$tfile
7276         LLOG_COUNT=$(do_facet mgs dmesg |
7277                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7278                           /llog_[a-z]*.c:[0-9]/ {
7279                                 if (marker)
7280                                         from_marker++
7281                                 from_begin++
7282                           }
7283                           END {
7284                                 if (marker)
7285                                         print from_marker
7286                                 else
7287                                         print from_begin
7288                           }")
7289
7290         [[ $LLOG_COUNT -gt 120 ]] &&
7291                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7292 }
7293 run_test 60b "limit repeated messages from CERROR/CWARN"
7294
7295 test_60c() {
7296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7297
7298         echo "create 5000 files"
7299         createmany -o $DIR/f60c- 5000
7300 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7301         lctl set_param fail_loc=0x80000137
7302         unlinkmany $DIR/f60c- 5000
7303         lctl set_param fail_loc=0
7304 }
7305 run_test 60c "unlink file when mds full"
7306
7307 test_60d() {
7308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7309
7310         SAVEPRINTK=$(lctl get_param -n printk)
7311         # verify "lctl mark" is even working"
7312         MESSAGE="test message ID $RANDOM $$"
7313         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7314         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7315
7316         lctl set_param printk=0 || error "set lnet.printk failed"
7317         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7318         MESSAGE="new test message ID $RANDOM $$"
7319         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7320         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7321         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7322
7323         lctl set_param -n printk="$SAVEPRINTK"
7324 }
7325 run_test 60d "test printk console message masking"
7326
7327 test_60e() {
7328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7329         remote_mds_nodsh && skip "remote MDS with nodsh"
7330
7331         touch $DIR/$tfile
7332 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7333         do_facet mds1 lctl set_param fail_loc=0x15b
7334         rm $DIR/$tfile
7335 }
7336 run_test 60e "no space while new llog is being created"
7337
7338 test_60g() {
7339         local pid
7340         local i
7341
7342         test_mkdir -c $MDSCOUNT $DIR/$tdir
7343
7344         (
7345                 local index=0
7346                 while true; do
7347                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7348                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7349                                 2>/dev/null
7350                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7351                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7352                         index=$((index + 1))
7353                 done
7354         ) &
7355
7356         pid=$!
7357
7358         for i in {0..100}; do
7359                 # define OBD_FAIL_OSD_TXN_START    0x19a
7360                 local index=$((i % MDSCOUNT + 1))
7361
7362                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7363                         > /dev/null
7364                 usleep 100
7365         done
7366
7367         kill -9 $pid
7368
7369         for i in $(seq $MDSCOUNT); do
7370                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7371         done
7372
7373         mkdir $DIR/$tdir/new || error "mkdir failed"
7374         rmdir $DIR/$tdir/new || error "rmdir failed"
7375
7376         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7377                 -t namespace
7378         for i in $(seq $MDSCOUNT); do
7379                 wait_update_facet mds$i "$LCTL get_param -n \
7380                         mdd.$(facet_svc mds$i).lfsck_namespace |
7381                         awk '/^status/ { print \\\$2 }'" "completed"
7382         done
7383
7384         ls -R $DIR/$tdir || error "ls failed"
7385         rm -rf $DIR/$tdir || error "rmdir failed"
7386 }
7387 run_test 60g "transaction abort won't cause MDT hung"
7388
7389 test_60h() {
7390         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7391                 skip "Need MDS version at least 2.12.52"
7392         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7393
7394         local f
7395
7396         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7397         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7398         for fail_loc in 0x80000188 0x80000189; do
7399                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7400                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7401                         error "mkdir $dir-$fail_loc failed"
7402                 for i in {0..10}; do
7403                         # create may fail on missing stripe
7404                         echo $i > $DIR/$tdir-$fail_loc/$i
7405                 done
7406                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7407                         error "getdirstripe $tdir-$fail_loc failed"
7408                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7409                         error "migrate $tdir-$fail_loc failed"
7410                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7411                         error "getdirstripe $tdir-$fail_loc failed"
7412                 pushd $DIR/$tdir-$fail_loc
7413                 for f in *; do
7414                         echo $f | cmp $f - || error "$f data mismatch"
7415                 done
7416                 popd
7417                 rm -rf $DIR/$tdir-$fail_loc
7418         done
7419 }
7420 run_test 60h "striped directory with missing stripes can be accessed"
7421
7422 test_61a() {
7423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7424
7425         f="$DIR/f61"
7426         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7427         cancel_lru_locks osc
7428         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7429         sync
7430 }
7431 run_test 61a "mmap() writes don't make sync hang ================"
7432
7433 test_61b() {
7434         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7435 }
7436 run_test 61b "mmap() of unstriped file is successful"
7437
7438 # bug 2330 - insufficient obd_match error checking causes LBUG
7439 test_62() {
7440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7441
7442         f="$DIR/f62"
7443         echo foo > $f
7444         cancel_lru_locks osc
7445         lctl set_param fail_loc=0x405
7446         cat $f && error "cat succeeded, expect -EIO"
7447         lctl set_param fail_loc=0
7448 }
7449 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7450 # match every page all of the time.
7451 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7452
7453 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7454 # Though this test is irrelevant anymore, it helped to reveal some
7455 # other grant bugs (LU-4482), let's keep it.
7456 test_63a() {   # was test_63
7457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7458
7459         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7460
7461         for i in `seq 10` ; do
7462                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7463                 sleep 5
7464                 kill $!
7465                 sleep 1
7466         done
7467
7468         rm -f $DIR/f63 || true
7469 }
7470 run_test 63a "Verify oig_wait interruption does not crash ======="
7471
7472 # bug 2248 - async write errors didn't return to application on sync
7473 # bug 3677 - async write errors left page locked
7474 test_63b() {
7475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7476
7477         debugsave
7478         lctl set_param debug=-1
7479
7480         # ensure we have a grant to do async writes
7481         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7482         rm $DIR/$tfile
7483
7484         sync    # sync lest earlier test intercept the fail_loc
7485
7486         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7487         lctl set_param fail_loc=0x80000406
7488         $MULTIOP $DIR/$tfile Owy && \
7489                 error "sync didn't return ENOMEM"
7490         sync; sleep 2; sync     # do a real sync this time to flush page
7491         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7492                 error "locked page left in cache after async error" || true
7493         debugrestore
7494 }
7495 run_test 63b "async write errors should be returned to fsync ==="
7496
7497 test_64a () {
7498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7499
7500         df $DIR
7501         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7502 }
7503 run_test 64a "verify filter grant calculations (in kernel) ====="
7504
7505 test_64b () {
7506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7507
7508         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7509 }
7510 run_test 64b "check out-of-space detection on client"
7511
7512 test_64c() {
7513         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7514 }
7515 run_test 64c "verify grant shrink"
7516
7517 # this does exactly what osc_request.c:osc_announce_cached() does in
7518 # order to calculate max amount of grants to ask from server
7519 want_grant() {
7520         local tgt=$1
7521
7522         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7523         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7524
7525         ((rpc_in_flight ++));
7526         nrpages=$((nrpages * rpc_in_flight))
7527
7528         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7529
7530         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7531
7532         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7533         local undirty=$((nrpages * PAGE_SIZE))
7534
7535         local max_extent_pages
7536         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7537             grep grant_max_extent_size | awk '{print $2}')
7538         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7539         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7540         local grant_extent_tax
7541         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7542             grep grant_extent_tax | awk '{print $2}')
7543
7544         undirty=$((undirty + nrextents * grant_extent_tax))
7545
7546         echo $undirty
7547 }
7548
7549 # this is size of unit for grant allocation. It should be equal to
7550 # what tgt_grant.c:tgt_grant_chunk() calculates
7551 grant_chunk() {
7552         local tgt=$1
7553         local max_brw_size
7554         local grant_extent_tax
7555
7556         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7557             grep max_brw_size | awk '{print $2}')
7558
7559         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7560             grep grant_extent_tax | awk '{print $2}')
7561
7562         echo $(((max_brw_size + grant_extent_tax) * 2))
7563 }
7564
7565 test_64d() {
7566         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7567                 skip "OST < 2.10.55 doesn't limit grants enough"
7568
7569         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7570         local file=$DIR/$tfile
7571
7572         [[ $($LCTL get_param osc.${tgt}.import |
7573              grep "connect_flags:.*grant_param") ]] ||
7574                 skip "no grant_param connect flag"
7575
7576         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7577
7578         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7579
7580         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7581         stack_trap "rm -f $file" EXIT
7582
7583         $LFS setstripe $file -i 0 -c 1
7584         dd if=/dev/zero of=$file bs=1M count=1000 &
7585         ddpid=$!
7586
7587         while true
7588         do
7589                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7590                 if [[ $cur_grant -gt $max_cur_granted ]]
7591                 then
7592                         kill $ddpid
7593                         error "cur_grant $cur_grant > $max_cur_granted"
7594                 fi
7595                 kill -0 $ddpid
7596                 [[ $? -ne 0 ]] && break;
7597                 sleep 2
7598         done
7599
7600         rm -f $DIR/$tfile
7601         wait_delete_completed
7602         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7603 }
7604 run_test 64d "check grant limit exceed"
7605
7606 # bug 1414 - set/get directories' stripe info
7607 test_65a() {
7608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7609
7610         test_mkdir $DIR/$tdir
7611         touch $DIR/$tdir/f1
7612         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7613 }
7614 run_test 65a "directory with no stripe info"
7615
7616 test_65b() {
7617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7618
7619         test_mkdir $DIR/$tdir
7620         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7621
7622         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7623                                                 error "setstripe"
7624         touch $DIR/$tdir/f2
7625         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7626 }
7627 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7628
7629 test_65c() {
7630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7631         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7632
7633         test_mkdir $DIR/$tdir
7634         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7635
7636         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7637                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7638         touch $DIR/$tdir/f3
7639         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7640 }
7641 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7642
7643 test_65d() {
7644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7645
7646         test_mkdir $DIR/$tdir
7647         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7648         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7649
7650         if [[ $STRIPECOUNT -le 0 ]]; then
7651                 sc=1
7652         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7653                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7654                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7655         else
7656                 sc=$(($STRIPECOUNT - 1))
7657         fi
7658         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7659         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7660         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7661                 error "lverify failed"
7662 }
7663 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7664
7665 test_65e() {
7666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7667
7668         test_mkdir $DIR/$tdir
7669
7670         $LFS setstripe $DIR/$tdir || error "setstripe"
7671         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7672                                         error "no stripe info failed"
7673         touch $DIR/$tdir/f6
7674         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7675 }
7676 run_test 65e "directory setstripe defaults"
7677
7678 test_65f() {
7679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7680
7681         test_mkdir $DIR/${tdir}f
7682         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7683                 error "setstripe succeeded" || true
7684 }
7685 run_test 65f "dir setstripe permission (should return error) ==="
7686
7687 test_65g() {
7688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7689
7690         test_mkdir $DIR/$tdir
7691         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7692
7693         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7694                 error "setstripe -S failed"
7695         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7696         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7697                 error "delete default stripe failed"
7698 }
7699 run_test 65g "directory setstripe -d"
7700
7701 test_65h() {
7702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7703
7704         test_mkdir $DIR/$tdir
7705         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7706
7707         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7708                 error "setstripe -S failed"
7709         test_mkdir $DIR/$tdir/dd1
7710         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7711                 error "stripe info inherit failed"
7712 }
7713 run_test 65h "directory stripe info inherit ===================="
7714
7715 test_65i() {
7716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7717
7718         save_layout_restore_at_exit $MOUNT
7719
7720         # bug6367: set non-default striping on root directory
7721         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7722
7723         # bug12836: getstripe on -1 default directory striping
7724         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7725
7726         # bug12836: getstripe -v on -1 default directory striping
7727         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7728
7729         # bug12836: new find on -1 default directory striping
7730         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7731 }
7732 run_test 65i "various tests to set root directory striping"
7733
7734 test_65j() { # bug6367
7735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7736
7737         sync; sleep 1
7738
7739         # if we aren't already remounting for each test, do so for this test
7740         if [ "$I_MOUNTED" = "yes" ]; then
7741                 cleanup || error "failed to unmount"
7742                 setup
7743         fi
7744
7745         save_layout_restore_at_exit $MOUNT
7746
7747         $LFS setstripe -d $MOUNT || error "setstripe failed"
7748 }
7749 run_test 65j "set default striping on root directory (bug 6367)="
7750
7751 cleanup_65k() {
7752         rm -rf $DIR/$tdir
7753         wait_delete_completed
7754         do_facet $SINGLEMDS "lctl set_param -n \
7755                 osp.$ost*MDT0000.max_create_count=$max_count"
7756         do_facet $SINGLEMDS "lctl set_param -n \
7757                 osp.$ost*MDT0000.create_count=$count"
7758         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7759         echo $INACTIVE_OSC "is Activate"
7760
7761         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7762 }
7763
7764 test_65k() { # bug11679
7765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7767         remote_mds_nodsh && skip "remote MDS with nodsh"
7768
7769         local disable_precreate=true
7770         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7771                 disable_precreate=false
7772
7773         echo "Check OST status: "
7774         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7775                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7776
7777         for OSC in $MDS_OSCS; do
7778                 echo $OSC "is active"
7779                 do_facet $SINGLEMDS lctl --device %$OSC activate
7780         done
7781
7782         for INACTIVE_OSC in $MDS_OSCS; do
7783                 local ost=$(osc_to_ost $INACTIVE_OSC)
7784                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7785                                lov.*md*.target_obd |
7786                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7787
7788                 mkdir -p $DIR/$tdir
7789                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7790                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7791
7792                 echo "Deactivate: " $INACTIVE_OSC
7793                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7794
7795                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7796                               osp.$ost*MDT0000.create_count")
7797                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7798                                   osp.$ost*MDT0000.max_create_count")
7799                 $disable_precreate &&
7800                         do_facet $SINGLEMDS "lctl set_param -n \
7801                                 osp.$ost*MDT0000.max_create_count=0"
7802
7803                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7804                         [ -f $DIR/$tdir/$idx ] && continue
7805                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7806                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7807                                 { cleanup_65k;
7808                                   error "setstripe $idx should succeed"; }
7809                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7810                 done
7811                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7812                 rmdir $DIR/$tdir
7813
7814                 do_facet $SINGLEMDS "lctl set_param -n \
7815                         osp.$ost*MDT0000.max_create_count=$max_count"
7816                 do_facet $SINGLEMDS "lctl set_param -n \
7817                         osp.$ost*MDT0000.create_count=$count"
7818                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7819                 echo $INACTIVE_OSC "is Activate"
7820
7821                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7822         done
7823 }
7824 run_test 65k "validate manual striping works properly with deactivated OSCs"
7825
7826 test_65l() { # bug 12836
7827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7828
7829         test_mkdir -p $DIR/$tdir/test_dir
7830         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7831         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7832 }
7833 run_test 65l "lfs find on -1 stripe dir ========================"
7834
7835 test_65m() {
7836         local layout=$(save_layout $MOUNT)
7837         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7838                 restore_layout $MOUNT $layout
7839                 error "setstripe should fail by non-root users"
7840         }
7841         true
7842 }
7843 run_test 65m "normal user can't set filesystem default stripe"
7844
7845 test_65n() {
7846         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7847         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7848                 skip "Need MDS version at least 2.12.50"
7849         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7850
7851         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7852         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7853         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7854
7855         local root_layout=$(save_layout $MOUNT)
7856         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7857
7858         # new subdirectory under root directory should not inherit
7859         # the default layout from root
7860         local dir1=$MOUNT/$tdir-1
7861         mkdir $dir1 || error "mkdir $dir1 failed"
7862         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7863                 error "$dir1 shouldn't have LOV EA"
7864
7865         # delete the default layout on root directory
7866         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7867
7868         local dir2=$MOUNT/$tdir-2
7869         mkdir $dir2 || error "mkdir $dir2 failed"
7870         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7871                 error "$dir2 shouldn't have LOV EA"
7872
7873         # set a new striping pattern on root directory
7874         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7875         local new_def_stripe_size=$((def_stripe_size * 2))
7876         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7877                 error "set stripe size on $MOUNT failed"
7878
7879         # new file created in $dir2 should inherit the new stripe size from
7880         # the filesystem default
7881         local file2=$dir2/$tfile-2
7882         touch $file2 || error "touch $file2 failed"
7883
7884         local file2_stripe_size=$($LFS getstripe -S $file2)
7885         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7886                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7887
7888         local dir3=$MOUNT/$tdir-3
7889         mkdir $dir3 || error "mkdir $dir3 failed"
7890         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
7891         # the root layout, which is the actual default layout that will be used
7892         # when new files are created in $dir3.
7893         local dir3_layout=$(get_layout_param $dir3)
7894         local root_dir_layout=$(get_layout_param $MOUNT)
7895         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
7896                 error "$dir3 should show the default layout from $MOUNT"
7897
7898         # set OST pool on root directory
7899         local pool=$TESTNAME
7900         pool_add $pool || error "add $pool failed"
7901         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7902                 error "add targets to $pool failed"
7903
7904         $LFS setstripe -p $pool $MOUNT ||
7905                 error "set OST pool on $MOUNT failed"
7906
7907         # new file created in $dir3 should inherit the pool from
7908         # the filesystem default
7909         local file3=$dir3/$tfile-3
7910         touch $file3 || error "touch $file3 failed"
7911
7912         local file3_pool=$($LFS getstripe -p $file3)
7913         [[ "$file3_pool" = "$pool" ]] ||
7914                 error "$file3 didn't inherit OST pool $pool"
7915
7916         local dir4=$MOUNT/$tdir-4
7917         mkdir $dir4 || error "mkdir $dir4 failed"
7918         local dir4_layout=$(get_layout_param $dir4)
7919         root_dir_layout=$(get_layout_param $MOUNT)
7920         echo "$LFS getstripe -d $dir4"
7921         $LFS getstripe -d $dir4
7922         echo "$LFS getstripe -d $MOUNT"
7923         $LFS getstripe -d $MOUNT
7924         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
7925                 error "$dir4 should show the default layout from $MOUNT"
7926
7927         # new file created in $dir4 should inherit the pool from
7928         # the filesystem default
7929         local file4=$dir4/$tfile-4
7930         touch $file4 || error "touch $file4 failed"
7931
7932         local file4_pool=$($LFS getstripe -p $file4)
7933         [[ "$file4_pool" = "$pool" ]] ||
7934                 error "$file4 didn't inherit OST pool $pool"
7935
7936         # new subdirectory under non-root directory should inherit
7937         # the default layout from its parent directory
7938         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7939                 error "set directory layout on $dir4 failed"
7940
7941         local dir5=$dir4/$tdir-5
7942         mkdir $dir5 || error "mkdir $dir5 failed"
7943
7944         dir4_layout=$(get_layout_param $dir4)
7945         local dir5_layout=$(get_layout_param $dir5)
7946         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7947                 error "$dir5 should inherit the default layout from $dir4"
7948
7949         # though subdir under ROOT doesn't inherit default layout, but
7950         # its sub dir/file should be created with default layout.
7951         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
7952         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
7953                 skip "Need MDS version at least 2.12.59"
7954
7955         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
7956         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
7957         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
7958
7959         if [ $default_lmv_hash == "none" ]; then
7960                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
7961         else
7962                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
7963                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
7964         fi
7965
7966         $LFS setdirstripe -D -c 2 $MOUNT ||
7967                 error "setdirstripe -D -c 2 failed"
7968         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
7969         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
7970         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
7971 }
7972 run_test 65n "don't inherit default layout from root for new subdirectories"
7973
7974 # bug 2543 - update blocks count on client
7975 test_66() {
7976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7977
7978         COUNT=${COUNT:-8}
7979         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7980         sync; sync_all_data; sync; sync_all_data
7981         cancel_lru_locks osc
7982         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7983         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7984 }
7985 run_test 66 "update inode blocks count on client ==============="
7986
7987 meminfo() {
7988         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7989 }
7990
7991 swap_used() {
7992         swapon -s | awk '($1 == "'$1'") { print $4 }'
7993 }
7994
7995 # bug5265, obdfilter oa2dentry return -ENOENT
7996 # #define OBD_FAIL_SRV_ENOENT 0x217
7997 test_69() {
7998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7999         remote_ost_nodsh && skip "remote OST with nodsh"
8000
8001         f="$DIR/$tfile"
8002         $LFS setstripe -c 1 -i 0 $f
8003
8004         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8005
8006         do_facet ost1 lctl set_param fail_loc=0x217
8007         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8008         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8009
8010         do_facet ost1 lctl set_param fail_loc=0
8011         $DIRECTIO write $f 0 2 || error "write error"
8012
8013         cancel_lru_locks osc
8014         $DIRECTIO read $f 0 1 || error "read error"
8015
8016         do_facet ost1 lctl set_param fail_loc=0x217
8017         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8018
8019         do_facet ost1 lctl set_param fail_loc=0
8020         rm -f $f
8021 }
8022 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8023
8024 test_71() {
8025         test_mkdir $DIR/$tdir
8026         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8027         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8028 }
8029 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8030
8031 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8033         [ "$RUNAS_ID" = "$UID" ] &&
8034                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8035         # Check that testing environment is properly set up. Skip if not
8036         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8037                 skip_env "User $RUNAS_ID does not exist - skipping"
8038
8039         touch $DIR/$tfile
8040         chmod 777 $DIR/$tfile
8041         chmod ug+s $DIR/$tfile
8042         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8043                 error "$RUNAS dd $DIR/$tfile failed"
8044         # See if we are still setuid/sgid
8045         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8046                 error "S/gid is not dropped on write"
8047         # Now test that MDS is updated too
8048         cancel_lru_locks mdc
8049         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8050                 error "S/gid is not dropped on MDS"
8051         rm -f $DIR/$tfile
8052 }
8053 run_test 72a "Test that remove suid works properly (bug5695) ===="
8054
8055 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8056         local perm
8057
8058         [ "$RUNAS_ID" = "$UID" ] &&
8059                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8060         [ "$RUNAS_ID" -eq 0 ] &&
8061                 skip_env "RUNAS_ID = 0 -- skipping"
8062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8063         # Check that testing environment is properly set up. Skip if not
8064         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8065                 skip_env "User $RUNAS_ID does not exist - skipping"
8066
8067         touch $DIR/${tfile}-f{g,u}
8068         test_mkdir $DIR/${tfile}-dg
8069         test_mkdir $DIR/${tfile}-du
8070         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8071         chmod g+s $DIR/${tfile}-{f,d}g
8072         chmod u+s $DIR/${tfile}-{f,d}u
8073         for perm in 777 2777 4777; do
8074                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8075                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8076                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8077                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8078         done
8079         true
8080 }
8081 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8082
8083 # bug 3462 - multiple simultaneous MDC requests
8084 test_73() {
8085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8086
8087         test_mkdir $DIR/d73-1
8088         test_mkdir $DIR/d73-2
8089         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8090         pid1=$!
8091
8092         lctl set_param fail_loc=0x80000129
8093         $MULTIOP $DIR/d73-1/f73-2 Oc &
8094         sleep 1
8095         lctl set_param fail_loc=0
8096
8097         $MULTIOP $DIR/d73-2/f73-3 Oc &
8098         pid3=$!
8099
8100         kill -USR1 $pid1
8101         wait $pid1 || return 1
8102
8103         sleep 25
8104
8105         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8106         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8107         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8108
8109         rm -rf $DIR/d73-*
8110 }
8111 run_test 73 "multiple MDC requests (should not deadlock)"
8112
8113 test_74a() { # bug 6149, 6184
8114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8115
8116         touch $DIR/f74a
8117         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8118         #
8119         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8120         # will spin in a tight reconnection loop
8121         $LCTL set_param fail_loc=0x8000030e
8122         # get any lock that won't be difficult - lookup works.
8123         ls $DIR/f74a
8124         $LCTL set_param fail_loc=0
8125         rm -f $DIR/f74a
8126         true
8127 }
8128 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8129
8130 test_74b() { # bug 13310
8131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8132
8133         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8134         #
8135         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8136         # will spin in a tight reconnection loop
8137         $LCTL set_param fail_loc=0x8000030e
8138         # get a "difficult" lock
8139         touch $DIR/f74b
8140         $LCTL set_param fail_loc=0
8141         rm -f $DIR/f74b
8142         true
8143 }
8144 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8145
8146 test_74c() {
8147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8148
8149         #define OBD_FAIL_LDLM_NEW_LOCK
8150         $LCTL set_param fail_loc=0x319
8151         touch $DIR/$tfile && error "touch successful"
8152         $LCTL set_param fail_loc=0
8153         true
8154 }
8155 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8156
8157 num_inodes() {
8158         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8159 }
8160
8161 test_76() { # Now for bug 20433, added originally in bug 1443
8162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8163
8164         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8165
8166         cancel_lru_locks osc
8167         BEFORE_INODES=$(num_inodes)
8168         echo "before inodes: $BEFORE_INODES"
8169         local COUNT=1000
8170         [ "$SLOW" = "no" ] && COUNT=100
8171         for i in $(seq $COUNT); do
8172                 touch $DIR/$tfile
8173                 rm -f $DIR/$tfile
8174         done
8175         cancel_lru_locks osc
8176         AFTER_INODES=$(num_inodes)
8177         echo "after inodes: $AFTER_INODES"
8178         local wait=0
8179         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8180                 sleep 2
8181                 AFTER_INODES=$(num_inodes)
8182                 wait=$((wait+2))
8183                 echo "wait $wait seconds inodes: $AFTER_INODES"
8184                 if [ $wait -gt 30 ]; then
8185                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8186                 fi
8187         done
8188 }
8189 run_test 76 "confirm clients recycle inodes properly ===="
8190
8191
8192 export ORIG_CSUM=""
8193 set_checksums()
8194 {
8195         # Note: in sptlrpc modes which enable its own bulk checksum, the
8196         # original crc32_le bulk checksum will be automatically disabled,
8197         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8198         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8199         # In this case set_checksums() will not be no-op, because sptlrpc
8200         # bulk checksum will be enabled all through the test.
8201
8202         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8203         lctl set_param -n osc.*.checksums $1
8204         return 0
8205 }
8206
8207 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8208                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8209 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8210                              tr -d [] | head -n1)}
8211 set_checksum_type()
8212 {
8213         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8214         rc=$?
8215         log "set checksum type to $1, rc = $rc"
8216         return $rc
8217 }
8218
8219 get_osc_checksum_type()
8220 {
8221         # arugment 1: OST name, like OST0000
8222         ost=$1
8223         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8224                         sed 's/.*\[\(.*\)\].*/\1/g')
8225         rc=$?
8226         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8227         echo $checksum_type
8228 }
8229
8230 F77_TMP=$TMP/f77-temp
8231 F77SZ=8
8232 setup_f77() {
8233         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8234                 error "error writing to $F77_TMP"
8235 }
8236
8237 test_77a() { # bug 10889
8238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8239         $GSS && skip_env "could not run with gss"
8240
8241         [ ! -f $F77_TMP ] && setup_f77
8242         set_checksums 1
8243         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8244         set_checksums 0
8245         rm -f $DIR/$tfile
8246 }
8247 run_test 77a "normal checksum read/write operation"
8248
8249 test_77b() { # bug 10889
8250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8251         $GSS && skip_env "could not run with gss"
8252
8253         [ ! -f $F77_TMP ] && setup_f77
8254         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8255         $LCTL set_param fail_loc=0x80000409
8256         set_checksums 1
8257
8258         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8259                 error "dd error: $?"
8260         $LCTL set_param fail_loc=0
8261
8262         for algo in $CKSUM_TYPES; do
8263                 cancel_lru_locks osc
8264                 set_checksum_type $algo
8265                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8266                 $LCTL set_param fail_loc=0x80000408
8267                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8268                 $LCTL set_param fail_loc=0
8269         done
8270         set_checksums 0
8271         set_checksum_type $ORIG_CSUM_TYPE
8272         rm -f $DIR/$tfile
8273 }
8274 run_test 77b "checksum error on client write, read"
8275
8276 cleanup_77c() {
8277         trap 0
8278         set_checksums 0
8279         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8280         $check_ost &&
8281                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8282         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8283         $check_ost && [ -n "$ost_file_prefix" ] &&
8284                 do_facet ost1 rm -f ${ost_file_prefix}\*
8285 }
8286
8287 test_77c() {
8288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8289         $GSS && skip_env "could not run with gss"
8290         remote_ost_nodsh && skip "remote OST with nodsh"
8291
8292         local bad1
8293         local osc_file_prefix
8294         local osc_file
8295         local check_ost=false
8296         local ost_file_prefix
8297         local ost_file
8298         local orig_cksum
8299         local dump_cksum
8300         local fid
8301
8302         # ensure corruption will occur on first OSS/OST
8303         $LFS setstripe -i 0 $DIR/$tfile
8304
8305         [ ! -f $F77_TMP ] && setup_f77
8306         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8307                 error "dd write error: $?"
8308         fid=$($LFS path2fid $DIR/$tfile)
8309
8310         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8311         then
8312                 check_ost=true
8313                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8314                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8315         else
8316                 echo "OSS do not support bulk pages dump upon error"
8317         fi
8318
8319         osc_file_prefix=$($LCTL get_param -n debug_path)
8320         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8321
8322         trap cleanup_77c EXIT
8323
8324         set_checksums 1
8325         # enable bulk pages dump upon error on Client
8326         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8327         # enable bulk pages dump upon error on OSS
8328         $check_ost &&
8329                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8330
8331         # flush Client cache to allow next read to reach OSS
8332         cancel_lru_locks osc
8333
8334         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8335         $LCTL set_param fail_loc=0x80000408
8336         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8337         $LCTL set_param fail_loc=0
8338
8339         rm -f $DIR/$tfile
8340
8341         # check cksum dump on Client
8342         osc_file=$(ls ${osc_file_prefix}*)
8343         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8344         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8345         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8346         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8347         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8348                      cksum)
8349         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8350         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8351                 error "dump content does not match on Client"
8352
8353         $check_ost || skip "No need to check cksum dump on OSS"
8354
8355         # check cksum dump on OSS
8356         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8357         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8358         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8359         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8360         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8361                 error "dump content does not match on OSS"
8362
8363         cleanup_77c
8364 }
8365 run_test 77c "checksum error on client read with debug"
8366
8367 test_77d() { # bug 10889
8368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8369         $GSS && skip_env "could not run with gss"
8370
8371         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8372         $LCTL set_param fail_loc=0x80000409
8373         set_checksums 1
8374         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8375                 error "direct write: rc=$?"
8376         $LCTL set_param fail_loc=0
8377         set_checksums 0
8378
8379         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8380         $LCTL set_param fail_loc=0x80000408
8381         set_checksums 1
8382         cancel_lru_locks osc
8383         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8384                 error "direct read: rc=$?"
8385         $LCTL set_param fail_loc=0
8386         set_checksums 0
8387 }
8388 run_test 77d "checksum error on OST direct write, read"
8389
8390 test_77f() { # bug 10889
8391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8392         $GSS && skip_env "could not run with gss"
8393
8394         set_checksums 1
8395         for algo in $CKSUM_TYPES; do
8396                 cancel_lru_locks osc
8397                 set_checksum_type $algo
8398                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8399                 $LCTL set_param fail_loc=0x409
8400                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8401                         error "direct write succeeded"
8402                 $LCTL set_param fail_loc=0
8403         done
8404         set_checksum_type $ORIG_CSUM_TYPE
8405         set_checksums 0
8406 }
8407 run_test 77f "repeat checksum error on write (expect error)"
8408
8409 test_77g() { # bug 10889
8410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8411         $GSS && skip_env "could not run with gss"
8412         remote_ost_nodsh && skip "remote OST with nodsh"
8413
8414         [ ! -f $F77_TMP ] && setup_f77
8415
8416         local file=$DIR/$tfile
8417         stack_trap "rm -f $file" EXIT
8418
8419         $LFS setstripe -c 1 -i 0 $file
8420         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8421         do_facet ost1 lctl set_param fail_loc=0x8000021a
8422         set_checksums 1
8423         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8424                 error "write error: rc=$?"
8425         do_facet ost1 lctl set_param fail_loc=0
8426         set_checksums 0
8427
8428         cancel_lru_locks osc
8429         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8430         do_facet ost1 lctl set_param fail_loc=0x8000021b
8431         set_checksums 1
8432         cmp $F77_TMP $file || error "file compare failed"
8433         do_facet ost1 lctl set_param fail_loc=0
8434         set_checksums 0
8435 }
8436 run_test 77g "checksum error on OST write, read"
8437
8438 test_77k() { # LU-10906
8439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8440         $GSS && skip_env "could not run with gss"
8441
8442         local cksum_param="osc.$FSNAME*.checksums"
8443         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8444         local checksum
8445         local i
8446
8447         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8448         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8449         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8450                 EXIT
8451
8452         for i in 0 1; do
8453                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8454                         error "failed to set checksum=$i on MGS"
8455                 wait_update $HOSTNAME "$get_checksum" $i
8456                 #remount
8457                 echo "remount client, checksum should be $i"
8458                 remount_client $MOUNT || error "failed to remount client"
8459                 checksum=$(eval $get_checksum)
8460                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8461         done
8462         # remove persistent param to avoid races with checksum mountopt below
8463         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8464                 error "failed to delete checksum on MGS"
8465
8466         for opt in "checksum" "nochecksum"; do
8467                 #remount with mount option
8468                 echo "remount client with option $opt, checksum should be $i"
8469                 umount_client $MOUNT || error "failed to umount client"
8470                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8471                         error "failed to mount client with option '$opt'"
8472                 checksum=$(eval $get_checksum)
8473                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8474                 i=$((i - 1))
8475         done
8476
8477         remount_client $MOUNT || error "failed to remount client"
8478 }
8479 run_test 77k "enable/disable checksum correctly"
8480
8481 test_77l() {
8482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8483         $GSS && skip_env "could not run with gss"
8484
8485         set_checksums 1
8486         stack_trap "set_checksums $ORIG_CSUM" EXIT
8487         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8488
8489         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8490
8491         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8492         for algo in $CKSUM_TYPES; do
8493                 set_checksum_type $algo || error "fail to set checksum type $algo"
8494                 osc_algo=$(get_osc_checksum_type OST0000)
8495                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8496
8497                 # no locks, no reqs to let the connection idle
8498                 cancel_lru_locks osc
8499                 lru_resize_disable osc
8500                 wait_osc_import_state client ost1 IDLE
8501
8502                 # ensure ost1 is connected
8503                 stat $DIR/$tfile >/dev/null || error "can't stat"
8504                 wait_osc_import_state client ost1 FULL
8505
8506                 osc_algo=$(get_osc_checksum_type OST0000)
8507                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8508         done
8509         return 0
8510 }
8511 run_test 77l "preferred checksum type is remembered after reconnected"
8512
8513 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8514 rm -f $F77_TMP
8515 unset F77_TMP
8516
8517 cleanup_test_78() {
8518         trap 0
8519         rm -f $DIR/$tfile
8520 }
8521
8522 test_78() { # bug 10901
8523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8524         remote_ost || skip_env "local OST"
8525
8526         NSEQ=5
8527         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8528         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8529         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8530         echo "MemTotal: $MEMTOTAL"
8531
8532         # reserve 256MB of memory for the kernel and other running processes,
8533         # and then take 1/2 of the remaining memory for the read/write buffers.
8534         if [ $MEMTOTAL -gt 512 ] ;then
8535                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8536         else
8537                 # for those poor memory-starved high-end clusters...
8538                 MEMTOTAL=$((MEMTOTAL / 2))
8539         fi
8540         echo "Mem to use for directio: $MEMTOTAL"
8541
8542         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8543         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8544         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8545         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8546                 head -n1)
8547         echo "Smallest OST: $SMALLESTOST"
8548         [[ $SMALLESTOST -lt 10240 ]] &&
8549                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8550
8551         trap cleanup_test_78 EXIT
8552
8553         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8554                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8555
8556         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8557         echo "File size: $F78SIZE"
8558         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8559         for i in $(seq 1 $NSEQ); do
8560                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8561                 echo directIO rdwr round $i of $NSEQ
8562                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8563         done
8564
8565         cleanup_test_78
8566 }
8567 run_test 78 "handle large O_DIRECT writes correctly ============"
8568
8569 test_79() { # bug 12743
8570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8571
8572         wait_delete_completed
8573
8574         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8575         BKFREE=$(calc_osc_kbytes kbytesfree)
8576         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8577
8578         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8579         DFTOTAL=`echo $STRING | cut -d, -f1`
8580         DFUSED=`echo $STRING  | cut -d, -f2`
8581         DFAVAIL=`echo $STRING | cut -d, -f3`
8582         DFFREE=$(($DFTOTAL - $DFUSED))
8583
8584         ALLOWANCE=$((64 * $OSTCOUNT))
8585
8586         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8587            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8588                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8589         fi
8590         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8591            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8592                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8593         fi
8594         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8595            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8596                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8597         fi
8598 }
8599 run_test 79 "df report consistency check ======================="
8600
8601 test_80() { # bug 10718
8602         remote_ost_nodsh && skip "remote OST with nodsh"
8603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8604
8605         # relax strong synchronous semantics for slow backends like ZFS
8606         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8607                 local soc="obdfilter.*.sync_lock_cancel"
8608                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8609
8610                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8611                 if [ -z "$save" ]; then
8612                         soc="obdfilter.*.sync_on_lock_cancel"
8613                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8614                 fi
8615
8616                 if [ "$save" != "never" ]; then
8617                         local hosts=$(comma_list $(osts_nodes))
8618
8619                         do_nodes $hosts $LCTL set_param $soc=never
8620                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8621                 fi
8622         fi
8623
8624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8625         sync; sleep 1; sync
8626         local before=$(date +%s)
8627         cancel_lru_locks osc
8628         local after=$(date +%s)
8629         local diff=$((after - before))
8630         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8631
8632         rm -f $DIR/$tfile
8633 }
8634 run_test 80 "Page eviction is equally fast at high offsets too"
8635
8636 test_81a() { # LU-456
8637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8638         remote_ost_nodsh && skip "remote OST with nodsh"
8639
8640         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8641         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8642         do_facet ost1 lctl set_param fail_loc=0x80000228
8643
8644         # write should trigger a retry and success
8645         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8646         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8647         RC=$?
8648         if [ $RC -ne 0 ] ; then
8649                 error "write should success, but failed for $RC"
8650         fi
8651 }
8652 run_test 81a "OST should retry write when get -ENOSPC ==============="
8653
8654 test_81b() { # LU-456
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656         remote_ost_nodsh && skip "remote OST with nodsh"
8657
8658         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8659         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8660         do_facet ost1 lctl set_param fail_loc=0x228
8661
8662         # write should retry several times and return -ENOSPC finally
8663         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8664         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8665         RC=$?
8666         ENOSPC=28
8667         if [ $RC -ne $ENOSPC ] ; then
8668                 error "dd should fail for -ENOSPC, but succeed."
8669         fi
8670 }
8671 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8672
8673 test_82() { # LU-1031
8674         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8675         local gid1=14091995
8676         local gid2=16022000
8677
8678         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8679         local MULTIPID1=$!
8680         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8681         local MULTIPID2=$!
8682         kill -USR1 $MULTIPID2
8683         sleep 2
8684         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8685                 error "First grouplock does not block second one"
8686         else
8687                 echo "Second grouplock blocks first one"
8688         fi
8689         kill -USR1 $MULTIPID1
8690         wait $MULTIPID1
8691         wait $MULTIPID2
8692 }
8693 run_test 82 "Basic grouplock test"
8694
8695 test_99() {
8696         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8697
8698         test_mkdir $DIR/$tdir.cvsroot
8699         chown $RUNAS_ID $DIR/$tdir.cvsroot
8700
8701         cd $TMP
8702         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8703
8704         cd /etc/init.d
8705         # some versions of cvs import exit(1) when asked to import links or
8706         # files they can't read.  ignore those files.
8707         local toignore=$(find . -type l -printf '-I %f\n' -o \
8708                          ! -perm /4 -printf '-I %f\n')
8709         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8710                 $tdir.reposname vtag rtag
8711
8712         cd $DIR
8713         test_mkdir $DIR/$tdir.reposname
8714         chown $RUNAS_ID $DIR/$tdir.reposname
8715         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8716
8717         cd $DIR/$tdir.reposname
8718         $RUNAS touch foo99
8719         $RUNAS cvs add -m 'addmsg' foo99
8720         $RUNAS cvs update
8721         $RUNAS cvs commit -m 'nomsg' foo99
8722         rm -fr $DIR/$tdir.cvsroot
8723 }
8724 run_test 99 "cvs strange file/directory operations"
8725
8726 test_100() {
8727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8728         [[ "$NETTYPE" =~ tcp ]] ||
8729                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8730         remote_ost_nodsh && skip "remote OST with nodsh"
8731         remote_mds_nodsh && skip "remote MDS with nodsh"
8732         remote_servers ||
8733                 skip "useless for local single node setup"
8734
8735         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8736                 [ "$PROT" != "tcp" ] && continue
8737                 RPORT=$(echo $REMOTE | cut -d: -f2)
8738                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8739
8740                 rc=0
8741                 LPORT=`echo $LOCAL | cut -d: -f2`
8742                 if [ $LPORT -ge 1024 ]; then
8743                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8744                         netstat -tna
8745                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8746                 fi
8747         done
8748         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8749 }
8750 run_test 100 "check local port using privileged port ==========="
8751
8752 function get_named_value()
8753 {
8754     local tag
8755
8756     tag=$1
8757     while read ;do
8758         line=$REPLY
8759         case $line in
8760         $tag*)
8761             echo $line | sed "s/^$tag[ ]*//"
8762             break
8763             ;;
8764         esac
8765     done
8766 }
8767
8768 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8769                    awk '/^max_cached_mb/ { print $2 }')
8770
8771 cleanup_101a() {
8772         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8773         trap 0
8774 }
8775
8776 test_101a() {
8777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8778
8779         local s
8780         local discard
8781         local nreads=10000
8782         local cache_limit=32
8783
8784         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8785         trap cleanup_101a EXIT
8786         $LCTL set_param -n llite.*.read_ahead_stats 0
8787         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8788
8789         #
8790         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8791         #
8792         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8793         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8794
8795         discard=0
8796         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8797                 get_named_value 'read but discarded' | cut -d" " -f1); do
8798                         discard=$(($discard + $s))
8799         done
8800         cleanup_101a
8801
8802         $LCTL get_param osc.*-osc*.rpc_stats
8803         $LCTL get_param llite.*.read_ahead_stats
8804
8805         # Discard is generally zero, but sometimes a few random reads line up
8806         # and trigger larger readahead, which is wasted & leads to discards.
8807         if [[ $(($discard)) -gt $nreads ]]; then
8808                 error "too many ($discard) discarded pages"
8809         fi
8810         rm -f $DIR/$tfile || true
8811 }
8812 run_test 101a "check read-ahead for random reads"
8813
8814 setup_test101bc() {
8815         test_mkdir $DIR/$tdir
8816         local ssize=$1
8817         local FILE_LENGTH=$2
8818         STRIPE_OFFSET=0
8819
8820         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8821
8822         local list=$(comma_list $(osts_nodes))
8823         set_osd_param $list '' read_cache_enable 0
8824         set_osd_param $list '' writethrough_cache_enable 0
8825
8826         trap cleanup_test101bc EXIT
8827         # prepare the read-ahead file
8828         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8829
8830         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8831                                 count=$FILE_SIZE_MB 2> /dev/null
8832
8833 }
8834
8835 cleanup_test101bc() {
8836         trap 0
8837         rm -rf $DIR/$tdir
8838         rm -f $DIR/$tfile
8839
8840         local list=$(comma_list $(osts_nodes))
8841         set_osd_param $list '' read_cache_enable 1
8842         set_osd_param $list '' writethrough_cache_enable 1
8843 }
8844
8845 calc_total() {
8846         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8847 }
8848
8849 ra_check_101() {
8850         local READ_SIZE=$1
8851         local STRIPE_SIZE=$2
8852         local FILE_LENGTH=$3
8853         local RA_INC=1048576
8854         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8855         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8856                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8857         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8858                         get_named_value 'read but discarded' |
8859                         cut -d" " -f1 | calc_total)
8860         if [[ $DISCARD -gt $discard_limit ]]; then
8861                 $LCTL get_param llite.*.read_ahead_stats
8862                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8863         else
8864                 echo "Read-ahead success for size ${READ_SIZE}"
8865         fi
8866 }
8867
8868 test_101b() {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8871
8872         local STRIPE_SIZE=1048576
8873         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8874
8875         if [ $SLOW == "yes" ]; then
8876                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8877         else
8878                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8879         fi
8880
8881         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8882
8883         # prepare the read-ahead file
8884         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8885         cancel_lru_locks osc
8886         for BIDX in 2 4 8 16 32 64 128 256
8887         do
8888                 local BSIZE=$((BIDX*4096))
8889                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8890                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8891                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8892                 $LCTL set_param -n llite.*.read_ahead_stats 0
8893                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8894                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8895                 cancel_lru_locks osc
8896                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8897         done
8898         cleanup_test101bc
8899         true
8900 }
8901 run_test 101b "check stride-io mode read-ahead ================="
8902
8903 test_101c() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905
8906         local STRIPE_SIZE=1048576
8907         local FILE_LENGTH=$((STRIPE_SIZE*100))
8908         local nreads=10000
8909         local rsize=65536
8910         local osc_rpc_stats
8911
8912         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8913
8914         cancel_lru_locks osc
8915         $LCTL set_param osc.*.rpc_stats 0
8916         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8917         $LCTL get_param osc.*.rpc_stats
8918         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8919                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8920                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8921                 local size
8922
8923                 if [ $lines -le 20 ]; then
8924                         echo "continue debug"
8925                         continue
8926                 fi
8927                 for size in 1 2 4 8; do
8928                         local rpc=$(echo "$stats" |
8929                                     awk '($1 == "'$size':") {print $2; exit; }')
8930                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8931                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8932                 done
8933                 echo "$osc_rpc_stats check passed!"
8934         done
8935         cleanup_test101bc
8936         true
8937 }
8938 run_test 101c "check stripe_size aligned read-ahead ================="
8939
8940 set_read_ahead() {
8941         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8942         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8943 }
8944
8945 test_101d() {
8946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8947
8948         local file=$DIR/$tfile
8949         local sz_MB=${FILESIZE_101d:-500}
8950         local ra_MB=${READAHEAD_MB:-40}
8951
8952         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8953         [ $free_MB -lt $sz_MB ] &&
8954                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8955
8956         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8957         $LFS setstripe -c -1 $file || error "setstripe failed"
8958
8959         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8960         echo Cancel LRU locks on lustre client to flush the client cache
8961         cancel_lru_locks osc
8962
8963         echo Disable read-ahead
8964         local old_READAHEAD=$(set_read_ahead 0)
8965
8966         echo Reading the test file $file with read-ahead disabled
8967         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8968
8969         echo Cancel LRU locks on lustre client to flush the client cache
8970         cancel_lru_locks osc
8971         echo Enable read-ahead with ${ra_MB}MB
8972         set_read_ahead $ra_MB
8973
8974         echo Reading the test file $file with read-ahead enabled
8975         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8976
8977         echo "read-ahead disabled time read $raOFF"
8978         echo "read-ahead enabled  time read $raON"
8979
8980         set_read_ahead $old_READAHEAD
8981         rm -f $file
8982         wait_delete_completed
8983
8984         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8985                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8986 }
8987 run_test 101d "file read with and without read-ahead enabled"
8988
8989 test_101e() {
8990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8991
8992         local file=$DIR/$tfile
8993         local size_KB=500  #KB
8994         local count=100
8995         local bsize=1024
8996
8997         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8998         local need_KB=$((count * size_KB))
8999         [[ $free_KB -le $need_KB ]] &&
9000                 skip_env "Need free space $need_KB, have $free_KB"
9001
9002         echo "Creating $count ${size_KB}K test files"
9003         for ((i = 0; i < $count; i++)); do
9004                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9005         done
9006
9007         echo "Cancel LRU locks on lustre client to flush the client cache"
9008         cancel_lru_locks $OSC
9009
9010         echo "Reset readahead stats"
9011         $LCTL set_param -n llite.*.read_ahead_stats 0
9012
9013         for ((i = 0; i < $count; i++)); do
9014                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9015         done
9016
9017         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9018                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9019
9020         for ((i = 0; i < $count; i++)); do
9021                 rm -rf $file.$i 2>/dev/null
9022         done
9023
9024         #10000 means 20% reads are missing in readahead
9025         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9026 }
9027 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9028
9029 test_101f() {
9030         which iozone || skip_env "no iozone installed"
9031
9032         local old_debug=$($LCTL get_param debug)
9033         old_debug=${old_debug#*=}
9034         $LCTL set_param debug="reada mmap"
9035
9036         # create a test file
9037         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9038
9039         echo Cancel LRU locks on lustre client to flush the client cache
9040         cancel_lru_locks osc
9041
9042         echo Reset readahead stats
9043         $LCTL set_param -n llite.*.read_ahead_stats 0
9044
9045         echo mmap read the file with small block size
9046         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9047                 > /dev/null 2>&1
9048
9049         echo checking missing pages
9050         $LCTL get_param llite.*.read_ahead_stats
9051         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9052                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9053
9054         $LCTL set_param debug="$old_debug"
9055         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9056         rm -f $DIR/$tfile
9057 }
9058 run_test 101f "check mmap read performance"
9059
9060 test_101g_brw_size_test() {
9061         local mb=$1
9062         local pages=$((mb * 1048576 / PAGE_SIZE))
9063         local file=$DIR/$tfile
9064
9065         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9066                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9067         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9068                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9069                         return 2
9070         done
9071
9072         stack_trap "rm -f $file" EXIT
9073         $LCTL set_param -n osc.*.rpc_stats=0
9074
9075         # 10 RPCs should be enough for the test
9076         local count=10
9077         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9078                 { error "dd write ${mb} MB blocks failed"; return 3; }
9079         cancel_lru_locks osc
9080         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9081                 { error "dd write ${mb} MB blocks failed"; return 4; }
9082
9083         # calculate number of full-sized read and write RPCs
9084         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9085                 sed -n '/pages per rpc/,/^$/p' |
9086                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9087                 END { print reads,writes }'))
9088         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9089                 return 5
9090         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9091                 return 6
9092
9093         return 0
9094 }
9095
9096 test_101g() {
9097         remote_ost_nodsh && skip "remote OST with nodsh"
9098
9099         local rpcs
9100         local osts=$(get_facets OST)
9101         local list=$(comma_list $(osts_nodes))
9102         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9103         local brw_size="obdfilter.*.brw_size"
9104
9105         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9106
9107         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9108
9109         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9110                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9111                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9112            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9113                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9114                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9115
9116                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9117                         suffix="M"
9118
9119                 if [[ $orig_mb -lt 16 ]]; then
9120                         save_lustre_params $osts "$brw_size" > $p
9121                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9122                                 error "set 16MB RPC size failed"
9123
9124                         echo "remount client to enable new RPC size"
9125                         remount_client $MOUNT || error "remount_client failed"
9126                 fi
9127
9128                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9129                 # should be able to set brw_size=12, but no rpc_stats for that
9130                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9131         fi
9132
9133         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9134
9135         if [[ $orig_mb -lt 16 ]]; then
9136                 restore_lustre_params < $p
9137                 remount_client $MOUNT || error "remount_client restore failed"
9138         fi
9139
9140         rm -f $p $DIR/$tfile
9141 }
9142 run_test 101g "Big bulk(4/16 MiB) readahead"
9143
9144 test_101h() {
9145         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9146
9147         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9148                 error "dd 70M file failed"
9149         echo Cancel LRU locks on lustre client to flush the client cache
9150         cancel_lru_locks osc
9151
9152         echo "Reset readahead stats"
9153         $LCTL set_param -n llite.*.read_ahead_stats 0
9154
9155         echo "Read 10M of data but cross 64M bundary"
9156         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9157         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9158                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9159         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9160         rm -f $p $DIR/$tfile
9161 }
9162 run_test 101h "Readahead should cover current read window"
9163
9164 setup_test102() {
9165         test_mkdir $DIR/$tdir
9166         chown $RUNAS_ID $DIR/$tdir
9167         STRIPE_SIZE=65536
9168         STRIPE_OFFSET=1
9169         STRIPE_COUNT=$OSTCOUNT
9170         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9171
9172         trap cleanup_test102 EXIT
9173         cd $DIR
9174         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9175         cd $DIR/$tdir
9176         for num in 1 2 3 4; do
9177                 for count in $(seq 1 $STRIPE_COUNT); do
9178                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9179                                 local size=`expr $STRIPE_SIZE \* $num`
9180                                 local file=file"$num-$idx-$count"
9181                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9182                         done
9183                 done
9184         done
9185
9186         cd $DIR
9187         $1 tar cf $TMP/f102.tar $tdir --xattrs
9188 }
9189
9190 cleanup_test102() {
9191         trap 0
9192         rm -f $TMP/f102.tar
9193         rm -rf $DIR/d0.sanity/d102
9194 }
9195
9196 test_102a() {
9197         [ "$UID" != 0 ] && skip "must run as root"
9198         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9199                 skip_env "must have user_xattr"
9200
9201         [ -z "$(which setfattr 2>/dev/null)" ] &&
9202                 skip_env "could not find setfattr"
9203
9204         local testfile=$DIR/$tfile
9205
9206         touch $testfile
9207         echo "set/get xattr..."
9208         setfattr -n trusted.name1 -v value1 $testfile ||
9209                 error "setfattr -n trusted.name1=value1 $testfile failed"
9210         getfattr -n trusted.name1 $testfile 2> /dev/null |
9211           grep "trusted.name1=.value1" ||
9212                 error "$testfile missing trusted.name1=value1"
9213
9214         setfattr -n user.author1 -v author1 $testfile ||
9215                 error "setfattr -n user.author1=author1 $testfile failed"
9216         getfattr -n user.author1 $testfile 2> /dev/null |
9217           grep "user.author1=.author1" ||
9218                 error "$testfile missing trusted.author1=author1"
9219
9220         echo "listxattr..."
9221         setfattr -n trusted.name2 -v value2 $testfile ||
9222                 error "$testfile unable to set trusted.name2"
9223         setfattr -n trusted.name3 -v value3 $testfile ||
9224                 error "$testfile unable to set trusted.name3"
9225         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9226             grep "trusted.name" | wc -l) -eq 3 ] ||
9227                 error "$testfile missing 3 trusted.name xattrs"
9228
9229         setfattr -n user.author2 -v author2 $testfile ||
9230                 error "$testfile unable to set user.author2"
9231         setfattr -n user.author3 -v author3 $testfile ||
9232                 error "$testfile unable to set user.author3"
9233         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9234             grep "user.author" | wc -l) -eq 3 ] ||
9235                 error "$testfile missing 3 user.author xattrs"
9236
9237         echo "remove xattr..."
9238         setfattr -x trusted.name1 $testfile ||
9239                 error "$testfile error deleting trusted.name1"
9240         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9241                 error "$testfile did not delete trusted.name1 xattr"
9242
9243         setfattr -x user.author1 $testfile ||
9244                 error "$testfile error deleting user.author1"
9245         echo "set lustre special xattr ..."
9246         $LFS setstripe -c1 $testfile
9247         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9248                 awk -F "=" '/trusted.lov/ { print $2 }' )
9249         setfattr -n "trusted.lov" -v $lovea $testfile ||
9250                 error "$testfile doesn't ignore setting trusted.lov again"
9251         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9252                 error "$testfile allow setting invalid trusted.lov"
9253         rm -f $testfile
9254 }
9255 run_test 102a "user xattr test =================================="
9256
9257 test_102b() {
9258         [ -z "$(which setfattr 2>/dev/null)" ] &&
9259                 skip_env "could not find setfattr"
9260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9261
9262         # b10930: get/set/list trusted.lov xattr
9263         echo "get/set/list trusted.lov xattr ..."
9264         local testfile=$DIR/$tfile
9265         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9266                 error "setstripe failed"
9267         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9268                 error "getstripe failed"
9269         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9270                 error "can't get trusted.lov from $testfile"
9271
9272         local testfile2=${testfile}2
9273         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9274                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9275
9276         $MCREATE $testfile2
9277         setfattr -n trusted.lov -v $value $testfile2
9278         local stripe_size=$($LFS getstripe -S $testfile2)
9279         local stripe_count=$($LFS getstripe -c $testfile2)
9280         [[ $stripe_size -eq 65536 ]] ||
9281                 error "stripe size $stripe_size != 65536"
9282         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9283                 error "stripe count $stripe_count != $STRIPECOUNT"
9284         rm -f $DIR/$tfile
9285 }
9286 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9287
9288 test_102c() {
9289         [ -z "$(which setfattr 2>/dev/null)" ] &&
9290                 skip_env "could not find setfattr"
9291         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9292
9293         # b10930: get/set/list lustre.lov xattr
9294         echo "get/set/list lustre.lov xattr ..."
9295         test_mkdir $DIR/$tdir
9296         chown $RUNAS_ID $DIR/$tdir
9297         local testfile=$DIR/$tdir/$tfile
9298         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9299                 error "setstripe failed"
9300         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9301                 error "getstripe failed"
9302         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9303         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9304
9305         local testfile2=${testfile}2
9306         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9307                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9308
9309         $RUNAS $MCREATE $testfile2
9310         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9311         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9312         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9313         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9314         [ $stripe_count -eq $STRIPECOUNT ] ||
9315                 error "stripe count $stripe_count != $STRIPECOUNT"
9316 }
9317 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9318
9319 compare_stripe_info1() {
9320         local stripe_index_all_zero=true
9321
9322         for num in 1 2 3 4; do
9323                 for count in $(seq 1 $STRIPE_COUNT); do
9324                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9325                                 local size=$((STRIPE_SIZE * num))
9326                                 local file=file"$num-$offset-$count"
9327                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9328                                 [[ $stripe_size -ne $size ]] &&
9329                                     error "$file: size $stripe_size != $size"
9330                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9331                                 # allow fewer stripes to be created, ORI-601
9332                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9333                                     error "$file: count $stripe_count != $count"
9334                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9335                                 [[ $stripe_index -ne 0 ]] &&
9336                                         stripe_index_all_zero=false
9337                         done
9338                 done
9339         done
9340         $stripe_index_all_zero &&
9341                 error "all files are being extracted starting from OST index 0"
9342         return 0
9343 }
9344
9345 have_xattrs_include() {
9346         tar --help | grep -q xattrs-include &&
9347                 echo --xattrs-include="lustre.*"
9348 }
9349
9350 test_102d() {
9351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9353
9354         XINC=$(have_xattrs_include)
9355         setup_test102
9356         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9357         cd $DIR/$tdir/$tdir
9358         compare_stripe_info1
9359 }
9360 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9361
9362 test_102f() {
9363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9364         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9365
9366         XINC=$(have_xattrs_include)
9367         setup_test102
9368         test_mkdir $DIR/$tdir.restore
9369         cd $DIR
9370         tar cf - --xattrs $tdir | tar xf - \
9371                 -C $DIR/$tdir.restore --xattrs $XINC
9372         cd $DIR/$tdir.restore/$tdir
9373         compare_stripe_info1
9374 }
9375 run_test 102f "tar copy files, not keep osts"
9376
9377 grow_xattr() {
9378         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9379                 skip "must have user_xattr"
9380         [ -z "$(which setfattr 2>/dev/null)" ] &&
9381                 skip_env "could not find setfattr"
9382         [ -z "$(which getfattr 2>/dev/null)" ] &&
9383                 skip_env "could not find getfattr"
9384
9385         local xsize=${1:-1024}  # in bytes
9386         local file=$DIR/$tfile
9387         local value="$(generate_string $xsize)"
9388         local xbig=trusted.big
9389         local toobig=$2
9390
9391         touch $file
9392         log "save $xbig on $file"
9393         if [ -z "$toobig" ]
9394         then
9395                 setfattr -n $xbig -v $value $file ||
9396                         error "saving $xbig on $file failed"
9397         else
9398                 setfattr -n $xbig -v $value $file &&
9399                         error "saving $xbig on $file succeeded"
9400                 return 0
9401         fi
9402
9403         local orig=$(get_xattr_value $xbig $file)
9404         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9405
9406         local xsml=trusted.sml
9407         log "save $xsml on $file"
9408         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9409
9410         local new=$(get_xattr_value $xbig $file)
9411         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9412
9413         log "grow $xsml on $file"
9414         setfattr -n $xsml -v "$value" $file ||
9415                 error "growing $xsml on $file failed"
9416
9417         new=$(get_xattr_value $xbig $file)
9418         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9419         log "$xbig still valid after growing $xsml"
9420
9421         rm -f $file
9422 }
9423
9424 test_102h() { # bug 15777
9425         grow_xattr 1024
9426 }
9427 run_test 102h "grow xattr from inside inode to external block"
9428
9429 test_102ha() {
9430         large_xattr_enabled || skip_env "ea_inode feature disabled"
9431
9432         echo "setting xattr of max xattr size: $(max_xattr_size)"
9433         grow_xattr $(max_xattr_size)
9434
9435         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9436         echo "This should fail:"
9437         grow_xattr $(($(max_xattr_size) + 10)) 1
9438 }
9439 run_test 102ha "grow xattr from inside inode to external inode"
9440
9441 test_102i() { # bug 17038
9442         [ -z "$(which getfattr 2>/dev/null)" ] &&
9443                 skip "could not find getfattr"
9444
9445         touch $DIR/$tfile
9446         ln -s $DIR/$tfile $DIR/${tfile}link
9447         getfattr -n trusted.lov $DIR/$tfile ||
9448                 error "lgetxattr on $DIR/$tfile failed"
9449         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9450                 grep -i "no such attr" ||
9451                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9452         rm -f $DIR/$tfile $DIR/${tfile}link
9453 }
9454 run_test 102i "lgetxattr test on symbolic link ============"
9455
9456 test_102j() {
9457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9459
9460         XINC=$(have_xattrs_include)
9461         setup_test102 "$RUNAS"
9462         chown $RUNAS_ID $DIR/$tdir
9463         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9464         cd $DIR/$tdir/$tdir
9465         compare_stripe_info1 "$RUNAS"
9466 }
9467 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9468
9469 test_102k() {
9470         [ -z "$(which setfattr 2>/dev/null)" ] &&
9471                 skip "could not find setfattr"
9472
9473         touch $DIR/$tfile
9474         # b22187 just check that does not crash for regular file.
9475         setfattr -n trusted.lov $DIR/$tfile
9476         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9477         local test_kdir=$DIR/$tdir
9478         test_mkdir $test_kdir
9479         local default_size=$($LFS getstripe -S $test_kdir)
9480         local default_count=$($LFS getstripe -c $test_kdir)
9481         local default_offset=$($LFS getstripe -i $test_kdir)
9482         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9483                 error 'dir setstripe failed'
9484         setfattr -n trusted.lov $test_kdir
9485         local stripe_size=$($LFS getstripe -S $test_kdir)
9486         local stripe_count=$($LFS getstripe -c $test_kdir)
9487         local stripe_offset=$($LFS getstripe -i $test_kdir)
9488         [ $stripe_size -eq $default_size ] ||
9489                 error "stripe size $stripe_size != $default_size"
9490         [ $stripe_count -eq $default_count ] ||
9491                 error "stripe count $stripe_count != $default_count"
9492         [ $stripe_offset -eq $default_offset ] ||
9493                 error "stripe offset $stripe_offset != $default_offset"
9494         rm -rf $DIR/$tfile $test_kdir
9495 }
9496 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9497
9498 test_102l() {
9499         [ -z "$(which getfattr 2>/dev/null)" ] &&
9500                 skip "could not find getfattr"
9501
9502         # LU-532 trusted. xattr is invisible to non-root
9503         local testfile=$DIR/$tfile
9504
9505         touch $testfile
9506
9507         echo "listxattr as user..."
9508         chown $RUNAS_ID $testfile
9509         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9510             grep -q "trusted" &&
9511                 error "$testfile trusted xattrs are user visible"
9512
9513         return 0;
9514 }
9515 run_test 102l "listxattr size test =================================="
9516
9517 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9518         local path=$DIR/$tfile
9519         touch $path
9520
9521         listxattr_size_check $path || error "listattr_size_check $path failed"
9522 }
9523 run_test 102m "Ensure listxattr fails on small bufffer ========"
9524
9525 cleanup_test102
9526
9527 getxattr() { # getxattr path name
9528         # Return the base64 encoding of the value of xattr name on path.
9529         local path=$1
9530         local name=$2
9531
9532         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9533         # file: $path
9534         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9535         #
9536         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9537
9538         getfattr --absolute-names --encoding=base64 --name=$name $path |
9539                 awk -F= -v name=$name '$1 == name {
9540                         print substr($0, index($0, "=") + 1);
9541         }'
9542 }
9543
9544 test_102n() { # LU-4101 mdt: protect internal xattrs
9545         [ -z "$(which setfattr 2>/dev/null)" ] &&
9546                 skip "could not find setfattr"
9547         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9548         then
9549                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9550         fi
9551
9552         local file0=$DIR/$tfile.0
9553         local file1=$DIR/$tfile.1
9554         local xattr0=$TMP/$tfile.0
9555         local xattr1=$TMP/$tfile.1
9556         local namelist="lov lma lmv link fid version som hsm"
9557         local name
9558         local value
9559
9560         rm -rf $file0 $file1 $xattr0 $xattr1
9561         touch $file0 $file1
9562
9563         # Get 'before' xattrs of $file1.
9564         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9565
9566         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9567                 namelist+=" lfsck_namespace"
9568         for name in $namelist; do
9569                 # Try to copy xattr from $file0 to $file1.
9570                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9571
9572                 setfattr --name=trusted.$name --value="$value" $file1 ||
9573                         error "setxattr 'trusted.$name' failed"
9574
9575                 # Try to set a garbage xattr.
9576                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9577
9578                 if [[ x$name == "xlov" ]]; then
9579                         setfattr --name=trusted.lov --value="$value" $file1 &&
9580                         error "setxattr invalid 'trusted.lov' success"
9581                 else
9582                         setfattr --name=trusted.$name --value="$value" $file1 ||
9583                                 error "setxattr invalid 'trusted.$name' failed"
9584                 fi
9585
9586                 # Try to remove the xattr from $file1. We don't care if this
9587                 # appears to succeed or fail, we just don't want there to be
9588                 # any changes or crashes.
9589                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9590         done
9591
9592         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9593         then
9594                 name="lfsck_ns"
9595                 # Try to copy xattr from $file0 to $file1.
9596                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9597
9598                 setfattr --name=trusted.$name --value="$value" $file1 ||
9599                         error "setxattr 'trusted.$name' failed"
9600
9601                 # Try to set a garbage xattr.
9602                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9603
9604                 setfattr --name=trusted.$name --value="$value" $file1 ||
9605                         error "setxattr 'trusted.$name' failed"
9606
9607                 # Try to remove the xattr from $file1. We don't care if this
9608                 # appears to succeed or fail, we just don't want there to be
9609                 # any changes or crashes.
9610                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9611         fi
9612
9613         # Get 'after' xattrs of file1.
9614         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9615
9616         if ! diff $xattr0 $xattr1; then
9617                 error "before and after xattrs of '$file1' differ"
9618         fi
9619
9620         rm -rf $file0 $file1 $xattr0 $xattr1
9621
9622         return 0
9623 }
9624 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9625
9626 test_102p() { # LU-4703 setxattr did not check ownership
9627         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9628                 skip "MDS needs to be at least 2.5.56"
9629
9630         local testfile=$DIR/$tfile
9631
9632         touch $testfile
9633
9634         echo "setfacl as user..."
9635         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9636         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9637
9638         echo "setfattr as user..."
9639         setfacl -m "u:$RUNAS_ID:---" $testfile
9640         $RUNAS setfattr -x system.posix_acl_access $testfile
9641         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9642 }
9643 run_test 102p "check setxattr(2) correctly fails without permission"
9644
9645 test_102q() {
9646         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9647                 skip "MDS needs to be at least 2.6.92"
9648
9649         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9650 }
9651 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9652
9653 test_102r() {
9654         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9655                 skip "MDS needs to be at least 2.6.93"
9656
9657         touch $DIR/$tfile || error "touch"
9658         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9659         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9660         rm $DIR/$tfile || error "rm"
9661
9662         #normal directory
9663         mkdir -p $DIR/$tdir || error "mkdir"
9664         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9665         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9666         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9667                 error "$testfile error deleting user.author1"
9668         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9669                 grep "user.$(basename $tdir)" &&
9670                 error "$tdir did not delete user.$(basename $tdir)"
9671         rmdir $DIR/$tdir || error "rmdir"
9672
9673         #striped directory
9674         test_mkdir $DIR/$tdir
9675         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9676         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9677         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9678                 error "$testfile error deleting user.author1"
9679         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9680                 grep "user.$(basename $tdir)" &&
9681                 error "$tdir did not delete user.$(basename $tdir)"
9682         rmdir $DIR/$tdir || error "rm striped dir"
9683 }
9684 run_test 102r "set EAs with empty values"
9685
9686 test_102s() {
9687         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9688                 skip "MDS needs to be at least 2.11.52"
9689
9690         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9691
9692         save_lustre_params client "llite.*.xattr_cache" > $save
9693
9694         for cache in 0 1; do
9695                 lctl set_param llite.*.xattr_cache=$cache
9696
9697                 rm -f $DIR/$tfile
9698                 touch $DIR/$tfile || error "touch"
9699                 for prefix in lustre security system trusted user; do
9700                         # Note getxattr() may fail with 'Operation not
9701                         # supported' or 'No such attribute' depending
9702                         # on prefix and cache.
9703                         getfattr -n $prefix.n102s $DIR/$tfile &&
9704                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9705                 done
9706         done
9707
9708         restore_lustre_params < $save
9709 }
9710 run_test 102s "getting nonexistent xattrs should fail"
9711
9712 test_102t() {
9713         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9714                 skip "MDS needs to be at least 2.11.52"
9715
9716         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9717
9718         save_lustre_params client "llite.*.xattr_cache" > $save
9719
9720         for cache in 0 1; do
9721                 lctl set_param llite.*.xattr_cache=$cache
9722
9723                 for buf_size in 0 256; do
9724                         rm -f $DIR/$tfile
9725                         touch $DIR/$tfile || error "touch"
9726                         setfattr -n user.multiop $DIR/$tfile
9727                         $MULTIOP $DIR/$tfile oa$buf_size ||
9728                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9729                 done
9730         done
9731
9732         restore_lustre_params < $save
9733 }
9734 run_test 102t "zero length xattr values handled correctly"
9735
9736 run_acl_subtest()
9737 {
9738     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9739     return $?
9740 }
9741
9742 test_103a() {
9743         [ "$UID" != 0 ] && skip "must run as root"
9744         $GSS && skip_env "could not run under gss"
9745         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9746                 skip_env "must have acl enabled"
9747         [ -z "$(which setfacl 2>/dev/null)" ] &&
9748                 skip_env "could not find setfacl"
9749         remote_mds_nodsh && skip "remote MDS with nodsh"
9750
9751         gpasswd -a daemon bin                           # LU-5641
9752         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9753
9754         declare -a identity_old
9755
9756         for num in $(seq $MDSCOUNT); do
9757                 switch_identity $num true || identity_old[$num]=$?
9758         done
9759
9760         SAVE_UMASK=$(umask)
9761         umask 0022
9762         mkdir -p $DIR/$tdir
9763         cd $DIR/$tdir
9764
9765         echo "performing cp ..."
9766         run_acl_subtest cp || error "run_acl_subtest cp failed"
9767         echo "performing getfacl-noacl..."
9768         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9769         echo "performing misc..."
9770         run_acl_subtest misc || error  "misc test failed"
9771         echo "performing permissions..."
9772         run_acl_subtest permissions || error "permissions failed"
9773         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9774         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9775                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9776                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9777         then
9778                 echo "performing permissions xattr..."
9779                 run_acl_subtest permissions_xattr ||
9780                         error "permissions_xattr failed"
9781         fi
9782         echo "performing setfacl..."
9783         run_acl_subtest setfacl || error  "setfacl test failed"
9784
9785         # inheritance test got from HP
9786         echo "performing inheritance..."
9787         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9788         chmod +x make-tree || error "chmod +x failed"
9789         run_acl_subtest inheritance || error "inheritance test failed"
9790         rm -f make-tree
9791
9792         echo "LU-974 ignore umask when acl is enabled..."
9793         run_acl_subtest 974 || error "LU-974 umask test failed"
9794         if [ $MDSCOUNT -ge 2 ]; then
9795                 run_acl_subtest 974_remote ||
9796                         error "LU-974 umask test failed under remote dir"
9797         fi
9798
9799         echo "LU-2561 newly created file is same size as directory..."
9800         if [ "$mds1_FSTYPE" != "zfs" ]; then
9801                 run_acl_subtest 2561 || error "LU-2561 test failed"
9802         else
9803                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9804         fi
9805
9806         run_acl_subtest 4924 || error "LU-4924 test failed"
9807
9808         cd $SAVE_PWD
9809         umask $SAVE_UMASK
9810
9811         for num in $(seq $MDSCOUNT); do
9812                 if [ "${identity_old[$num]}" = 1 ]; then
9813                         switch_identity $num false || identity_old[$num]=$?
9814                 fi
9815         done
9816 }
9817 run_test 103a "acl test"
9818
9819 test_103b() {
9820         declare -a pids
9821         local U
9822
9823         for U in {0..511}; do
9824                 {
9825                 local O=$(printf "%04o" $U)
9826
9827                 umask $(printf "%04o" $((511 ^ $O)))
9828                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9829                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9830
9831                 (( $S == ($O & 0666) )) ||
9832                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9833
9834                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9835                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9836                 (( $S == ($O & 0666) )) ||
9837                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9838
9839                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9840                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9841                 (( $S == ($O & 0666) )) ||
9842                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9843                 rm -f $DIR/$tfile.[smp]$0
9844                 } &
9845                 local pid=$!
9846
9847                 # limit the concurrently running threads to 64. LU-11878
9848                 local idx=$((U % 64))
9849                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9850                 pids[idx]=$pid
9851         done
9852         wait
9853 }
9854 run_test 103b "umask lfs setstripe"
9855
9856 test_103c() {
9857         mkdir -p $DIR/$tdir
9858         cp -rp $DIR/$tdir $DIR/$tdir.bak
9859
9860         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9861                 error "$DIR/$tdir shouldn't contain default ACL"
9862         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9863                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9864         true
9865 }
9866 run_test 103c "'cp -rp' won't set empty acl"
9867
9868 test_104a() {
9869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9870
9871         touch $DIR/$tfile
9872         lfs df || error "lfs df failed"
9873         lfs df -ih || error "lfs df -ih failed"
9874         lfs df -h $DIR || error "lfs df -h $DIR failed"
9875         lfs df -i $DIR || error "lfs df -i $DIR failed"
9876         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9877         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9878
9879         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9880         lctl --device %$OSC deactivate
9881         lfs df || error "lfs df with deactivated OSC failed"
9882         lctl --device %$OSC activate
9883         # wait the osc back to normal
9884         wait_osc_import_ready client ost
9885
9886         lfs df || error "lfs df with reactivated OSC failed"
9887         rm -f $DIR/$tfile
9888 }
9889 run_test 104a "lfs df [-ih] [path] test ========================="
9890
9891 test_104b() {
9892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9893         [ $RUNAS_ID -eq $UID ] &&
9894                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9895
9896         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9897                         grep "Permission denied" | wc -l)))
9898         if [ $denied_cnt -ne 0 ]; then
9899                 error "lfs check servers test failed"
9900         fi
9901 }
9902 run_test 104b "$RUNAS lfs check servers test ===================="
9903
9904 test_105a() {
9905         # doesn't work on 2.4 kernels
9906         touch $DIR/$tfile
9907         if $(flock_is_enabled); then
9908                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9909         else
9910                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9911         fi
9912         rm -f $DIR/$tfile
9913 }
9914 run_test 105a "flock when mounted without -o flock test ========"
9915
9916 test_105b() {
9917         touch $DIR/$tfile
9918         if $(flock_is_enabled); then
9919                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9920         else
9921                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9922         fi
9923         rm -f $DIR/$tfile
9924 }
9925 run_test 105b "fcntl when mounted without -o flock test ========"
9926
9927 test_105c() {
9928         touch $DIR/$tfile
9929         if $(flock_is_enabled); then
9930                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9931         else
9932                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9933         fi
9934         rm -f $DIR/$tfile
9935 }
9936 run_test 105c "lockf when mounted without -o flock test"
9937
9938 test_105d() { # bug 15924
9939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9940
9941         test_mkdir $DIR/$tdir
9942         flock_is_enabled || skip_env "mount w/o flock enabled"
9943         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9944         $LCTL set_param fail_loc=0x80000315
9945         flocks_test 2 $DIR/$tdir
9946 }
9947 run_test 105d "flock race (should not freeze) ========"
9948
9949 test_105e() { # bug 22660 && 22040
9950         flock_is_enabled || skip_env "mount w/o flock enabled"
9951
9952         touch $DIR/$tfile
9953         flocks_test 3 $DIR/$tfile
9954 }
9955 run_test 105e "Two conflicting flocks from same process"
9956
9957 test_106() { #bug 10921
9958         test_mkdir $DIR/$tdir
9959         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9960         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9961 }
9962 run_test 106 "attempt exec of dir followed by chown of that dir"
9963
9964 test_107() {
9965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9966
9967         CDIR=`pwd`
9968         local file=core
9969
9970         cd $DIR
9971         rm -f $file
9972
9973         local save_pattern=$(sysctl -n kernel.core_pattern)
9974         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9975         sysctl -w kernel.core_pattern=$file
9976         sysctl -w kernel.core_uses_pid=0
9977
9978         ulimit -c unlimited
9979         sleep 60 &
9980         SLEEPPID=$!
9981
9982         sleep 1
9983
9984         kill -s 11 $SLEEPPID
9985         wait $SLEEPPID
9986         if [ -e $file ]; then
9987                 size=`stat -c%s $file`
9988                 [ $size -eq 0 ] && error "Fail to create core file $file"
9989         else
9990                 error "Fail to create core file $file"
9991         fi
9992         rm -f $file
9993         sysctl -w kernel.core_pattern=$save_pattern
9994         sysctl -w kernel.core_uses_pid=$save_uses_pid
9995         cd $CDIR
9996 }
9997 run_test 107 "Coredump on SIG"
9998
9999 test_110() {
10000         test_mkdir $DIR/$tdir
10001         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10002         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10003                 error "mkdir with 256 char should fail, but did not"
10004         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10005                 error "create with 255 char failed"
10006         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10007                 error "create with 256 char should fail, but did not"
10008
10009         ls -l $DIR/$tdir
10010         rm -rf $DIR/$tdir
10011 }
10012 run_test 110 "filename length checking"
10013
10014 #
10015 # Purpose: To verify dynamic thread (OSS) creation.
10016 #
10017 test_115() {
10018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10019         remote_ost_nodsh && skip "remote OST with nodsh"
10020
10021         # Lustre does not stop service threads once they are started.
10022         # Reset number of running threads to default.
10023         stopall
10024         setupall
10025
10026         local OSTIO_pre
10027         local save_params="$TMP/sanity-$TESTNAME.parameters"
10028
10029         # Get ll_ost_io count before I/O
10030         OSTIO_pre=$(do_facet ost1 \
10031                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10032         # Exit if lustre is not running (ll_ost_io not running).
10033         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10034
10035         echo "Starting with $OSTIO_pre threads"
10036         local thread_max=$((OSTIO_pre * 2))
10037         local rpc_in_flight=$((thread_max * 2))
10038         # Number of I/O Process proposed to be started.
10039         local nfiles
10040         local facets=$(get_facets OST)
10041
10042         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10043         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10044
10045         # Set in_flight to $rpc_in_flight
10046         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10047                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10048         nfiles=${rpc_in_flight}
10049         # Set ost thread_max to $thread_max
10050         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10051
10052         # 5 Minutes should be sufficient for max number of OSS
10053         # threads(thread_max) to be created.
10054         local timeout=300
10055
10056         # Start I/O.
10057         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10058         test_mkdir $DIR/$tdir
10059         for i in $(seq $nfiles); do
10060                 local file=$DIR/$tdir/${tfile}-$i
10061                 $LFS setstripe -c -1 -i 0 $file
10062                 ($WTL $file $timeout)&
10063         done
10064
10065         # I/O Started - Wait for thread_started to reach thread_max or report
10066         # error if thread_started is more than thread_max.
10067         echo "Waiting for thread_started to reach thread_max"
10068         local thread_started=0
10069         local end_time=$((SECONDS + timeout))
10070
10071         while [ $SECONDS -le $end_time ] ; do
10072                 echo -n "."
10073                 # Get ost i/o thread_started count.
10074                 thread_started=$(do_facet ost1 \
10075                         "$LCTL get_param \
10076                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10077                 # Break out if thread_started is equal/greater than thread_max
10078                 if [[ $thread_started -ge $thread_max ]]; then
10079                         echo ll_ost_io thread_started $thread_started, \
10080                                 equal/greater than thread_max $thread_max
10081                         break
10082                 fi
10083                 sleep 1
10084         done
10085
10086         # Cleanup - We have the numbers, Kill i/o jobs if running.
10087         jobcount=($(jobs -p))
10088         for i in $(seq 0 $((${#jobcount[@]}-1)))
10089         do
10090                 kill -9 ${jobcount[$i]}
10091                 if [ $? -ne 0 ] ; then
10092                         echo Warning: \
10093                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10094                 fi
10095         done
10096
10097         # Cleanup files left by WTL binary.
10098         for i in $(seq $nfiles); do
10099                 local file=$DIR/$tdir/${tfile}-$i
10100                 rm -rf $file
10101                 if [ $? -ne 0 ] ; then
10102                         echo "Warning: Failed to delete file $file"
10103                 fi
10104         done
10105
10106         restore_lustre_params <$save_params
10107         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10108
10109         # Error out if no new thread has started or Thread started is greater
10110         # than thread max.
10111         if [[ $thread_started -le $OSTIO_pre ||
10112                         $thread_started -gt $thread_max ]]; then
10113                 error "ll_ost_io: thread_started $thread_started" \
10114                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10115                       "No new thread started or thread started greater " \
10116                       "than thread_max."
10117         fi
10118 }
10119 run_test 115 "verify dynamic thread creation===================="
10120
10121 free_min_max () {
10122         wait_delete_completed
10123         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10124         echo "OST kbytes available: ${AVAIL[@]}"
10125         MAXV=${AVAIL[0]}
10126         MAXI=0
10127         MINV=${AVAIL[0]}
10128         MINI=0
10129         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10130                 #echo OST $i: ${AVAIL[i]}kb
10131                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10132                         MAXV=${AVAIL[i]}
10133                         MAXI=$i
10134                 fi
10135                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10136                         MINV=${AVAIL[i]}
10137                         MINI=$i
10138                 fi
10139         done
10140         echo "Min free space: OST $MINI: $MINV"
10141         echo "Max free space: OST $MAXI: $MAXV"
10142 }
10143
10144 test_116a() { # was previously test_116()
10145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10147         remote_mds_nodsh && skip "remote MDS with nodsh"
10148
10149         echo -n "Free space priority "
10150         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10151                 head -n1
10152         declare -a AVAIL
10153         free_min_max
10154
10155         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10156         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10157         trap simple_cleanup_common EXIT
10158
10159         # Check if we need to generate uneven OSTs
10160         test_mkdir -p $DIR/$tdir/OST${MINI}
10161         local FILL=$((MINV / 4))
10162         local DIFF=$((MAXV - MINV))
10163         local DIFF2=$((DIFF * 100 / MINV))
10164
10165         local threshold=$(do_facet $SINGLEMDS \
10166                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10167         threshold=${threshold%%%}
10168         echo -n "Check for uneven OSTs: "
10169         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10170
10171         if [[ $DIFF2 -gt $threshold ]]; then
10172                 echo "ok"
10173                 echo "Don't need to fill OST$MINI"
10174         else
10175                 # generate uneven OSTs. Write 2% over the QOS threshold value
10176                 echo "no"
10177                 DIFF=$((threshold - DIFF2 + 2))
10178                 DIFF2=$((MINV * DIFF / 100))
10179                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10180                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10181                         error "setstripe failed"
10182                 DIFF=$((DIFF2 / 2048))
10183                 i=0
10184                 while [ $i -lt $DIFF ]; do
10185                         i=$((i + 1))
10186                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10187                                 bs=2M count=1 2>/dev/null
10188                         echo -n .
10189                 done
10190                 echo .
10191                 sync
10192                 sleep_maxage
10193                 free_min_max
10194         fi
10195
10196         DIFF=$((MAXV - MINV))
10197         DIFF2=$((DIFF * 100 / MINV))
10198         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10199         if [ $DIFF2 -gt $threshold ]; then
10200                 echo "ok"
10201         else
10202                 echo "failed - QOS mode won't be used"
10203                 simple_cleanup_common
10204                 skip "QOS imbalance criteria not met"
10205         fi
10206
10207         MINI1=$MINI
10208         MINV1=$MINV
10209         MAXI1=$MAXI
10210         MAXV1=$MAXV
10211
10212         # now fill using QOS
10213         $LFS setstripe -c 1 $DIR/$tdir
10214         FILL=$((FILL / 200))
10215         if [ $FILL -gt 600 ]; then
10216                 FILL=600
10217         fi
10218         echo "writing $FILL files to QOS-assigned OSTs"
10219         i=0
10220         while [ $i -lt $FILL ]; do
10221                 i=$((i + 1))
10222                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10223                         count=1 2>/dev/null
10224                 echo -n .
10225         done
10226         echo "wrote $i 200k files"
10227         sync
10228         sleep_maxage
10229
10230         echo "Note: free space may not be updated, so measurements might be off"
10231         free_min_max
10232         DIFF2=$((MAXV - MINV))
10233         echo "free space delta: orig $DIFF final $DIFF2"
10234         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10235         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10236         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10237         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10238         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10239         if [[ $DIFF -gt 0 ]]; then
10240                 FILL=$((DIFF2 * 100 / DIFF - 100))
10241                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10242         fi
10243
10244         # Figure out which files were written where
10245         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10246                awk '/'$MINI1': / {print $2; exit}')
10247         echo $UUID
10248         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10249         echo "$MINC files created on smaller OST $MINI1"
10250         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10251                awk '/'$MAXI1': / {print $2; exit}')
10252         echo $UUID
10253         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10254         echo "$MAXC files created on larger OST $MAXI1"
10255         if [[ $MINC -gt 0 ]]; then
10256                 FILL=$((MAXC * 100 / MINC - 100))
10257                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10258         fi
10259         [[ $MAXC -gt $MINC ]] ||
10260                 error_ignore LU-9 "stripe QOS didn't balance free space"
10261         simple_cleanup_common
10262 }
10263 run_test 116a "stripe QOS: free space balance ==================="
10264
10265 test_116b() { # LU-2093
10266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10267         remote_mds_nodsh && skip "remote MDS with nodsh"
10268
10269 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10270         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10271                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10272         [ -z "$old_rr" ] && skip "no QOS"
10273         do_facet $SINGLEMDS lctl set_param \
10274                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10275         mkdir -p $DIR/$tdir
10276         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10277         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10278         do_facet $SINGLEMDS lctl set_param fail_loc=0
10279         rm -rf $DIR/$tdir
10280         do_facet $SINGLEMDS lctl set_param \
10281                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10282 }
10283 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10284
10285 test_117() # bug 10891
10286 {
10287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10288
10289         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10290         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10291         lctl set_param fail_loc=0x21e
10292         > $DIR/$tfile || error "truncate failed"
10293         lctl set_param fail_loc=0
10294         echo "Truncate succeeded."
10295         rm -f $DIR/$tfile
10296 }
10297 run_test 117 "verify osd extend =========="
10298
10299 NO_SLOW_RESENDCOUNT=4
10300 export OLD_RESENDCOUNT=""
10301 set_resend_count () {
10302         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10303         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10304         lctl set_param -n $PROC_RESENDCOUNT $1
10305         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10306 }
10307
10308 # for reduce test_118* time (b=14842)
10309 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10310
10311 # Reset async IO behavior after error case
10312 reset_async() {
10313         FILE=$DIR/reset_async
10314
10315         # Ensure all OSCs are cleared
10316         $LFS setstripe -c -1 $FILE
10317         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10318         sync
10319         rm $FILE
10320 }
10321
10322 test_118a() #bug 11710
10323 {
10324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10325
10326         reset_async
10327
10328         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10329         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10330         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10331
10332         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10333                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10334                 return 1;
10335         fi
10336         rm -f $DIR/$tfile
10337 }
10338 run_test 118a "verify O_SYNC works =========="
10339
10340 test_118b()
10341 {
10342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10343         remote_ost_nodsh && skip "remote OST with nodsh"
10344
10345         reset_async
10346
10347         #define OBD_FAIL_SRV_ENOENT 0x217
10348         set_nodes_failloc "$(osts_nodes)" 0x217
10349         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10350         RC=$?
10351         set_nodes_failloc "$(osts_nodes)" 0
10352         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10353         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10354                     grep -c writeback)
10355
10356         if [[ $RC -eq 0 ]]; then
10357                 error "Must return error due to dropped pages, rc=$RC"
10358                 return 1;
10359         fi
10360
10361         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10362                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10363                 return 1;
10364         fi
10365
10366         echo "Dirty pages not leaked on ENOENT"
10367
10368         # Due to the above error the OSC will issue all RPCs syncronously
10369         # until a subsequent RPC completes successfully without error.
10370         $MULTIOP $DIR/$tfile Ow4096yc
10371         rm -f $DIR/$tfile
10372
10373         return 0
10374 }
10375 run_test 118b "Reclaim dirty pages on fatal error =========="
10376
10377 test_118c()
10378 {
10379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10380
10381         # for 118c, restore the original resend count, LU-1940
10382         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10383                                 set_resend_count $OLD_RESENDCOUNT
10384         remote_ost_nodsh && skip "remote OST with nodsh"
10385
10386         reset_async
10387
10388         #define OBD_FAIL_OST_EROFS               0x216
10389         set_nodes_failloc "$(osts_nodes)" 0x216
10390
10391         # multiop should block due to fsync until pages are written
10392         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10393         MULTIPID=$!
10394         sleep 1
10395
10396         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10397                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10398         fi
10399
10400         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10401                     grep -c writeback)
10402         if [[ $WRITEBACK -eq 0 ]]; then
10403                 error "No page in writeback, writeback=$WRITEBACK"
10404         fi
10405
10406         set_nodes_failloc "$(osts_nodes)" 0
10407         wait $MULTIPID
10408         RC=$?
10409         if [[ $RC -ne 0 ]]; then
10410                 error "Multiop fsync failed, rc=$RC"
10411         fi
10412
10413         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10414         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10415                     grep -c writeback)
10416         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10417                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10418         fi
10419
10420         rm -f $DIR/$tfile
10421         echo "Dirty pages flushed via fsync on EROFS"
10422         return 0
10423 }
10424 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10425
10426 # continue to use small resend count to reduce test_118* time (b=14842)
10427 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10428
10429 test_118d()
10430 {
10431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10432         remote_ost_nodsh && skip "remote OST with nodsh"
10433
10434         reset_async
10435
10436         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10437         set_nodes_failloc "$(osts_nodes)" 0x214
10438         # multiop should block due to fsync until pages are written
10439         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10440         MULTIPID=$!
10441         sleep 1
10442
10443         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10444                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10445         fi
10446
10447         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10448                     grep -c writeback)
10449         if [[ $WRITEBACK -eq 0 ]]; then
10450                 error "No page in writeback, writeback=$WRITEBACK"
10451         fi
10452
10453         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10454         set_nodes_failloc "$(osts_nodes)" 0
10455
10456         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10457         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10458                     grep -c writeback)
10459         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10460                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10461         fi
10462
10463         rm -f $DIR/$tfile
10464         echo "Dirty pages gaurenteed flushed via fsync"
10465         return 0
10466 }
10467 run_test 118d "Fsync validation inject a delay of the bulk =========="
10468
10469 test_118f() {
10470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10471
10472         reset_async
10473
10474         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10475         lctl set_param fail_loc=0x8000040a
10476
10477         # Should simulate EINVAL error which is fatal
10478         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10479         RC=$?
10480         if [[ $RC -eq 0 ]]; then
10481                 error "Must return error due to dropped pages, rc=$RC"
10482         fi
10483
10484         lctl set_param fail_loc=0x0
10485
10486         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10487         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10488         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10489                     grep -c writeback)
10490         if [[ $LOCKED -ne 0 ]]; then
10491                 error "Locked pages remain in cache, locked=$LOCKED"
10492         fi
10493
10494         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10495                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10496         fi
10497
10498         rm -f $DIR/$tfile
10499         echo "No pages locked after fsync"
10500
10501         reset_async
10502         return 0
10503 }
10504 run_test 118f "Simulate unrecoverable OSC side error =========="
10505
10506 test_118g() {
10507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10508
10509         reset_async
10510
10511         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10512         lctl set_param fail_loc=0x406
10513
10514         # simulate local -ENOMEM
10515         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10516         RC=$?
10517
10518         lctl set_param fail_loc=0
10519         if [[ $RC -eq 0 ]]; then
10520                 error "Must return error due to dropped pages, rc=$RC"
10521         fi
10522
10523         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10524         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10525         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10526                         grep -c writeback)
10527         if [[ $LOCKED -ne 0 ]]; then
10528                 error "Locked pages remain in cache, locked=$LOCKED"
10529         fi
10530
10531         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10532                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10533         fi
10534
10535         rm -f $DIR/$tfile
10536         echo "No pages locked after fsync"
10537
10538         reset_async
10539         return 0
10540 }
10541 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10542
10543 test_118h() {
10544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10545         remote_ost_nodsh && skip "remote OST with nodsh"
10546
10547         reset_async
10548
10549         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10550         set_nodes_failloc "$(osts_nodes)" 0x20e
10551         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10552         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10553         RC=$?
10554
10555         set_nodes_failloc "$(osts_nodes)" 0
10556         if [[ $RC -eq 0 ]]; then
10557                 error "Must return error due to dropped pages, rc=$RC"
10558         fi
10559
10560         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10561         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10562         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10563                     grep -c writeback)
10564         if [[ $LOCKED -ne 0 ]]; then
10565                 error "Locked pages remain in cache, locked=$LOCKED"
10566         fi
10567
10568         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10569                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10570         fi
10571
10572         rm -f $DIR/$tfile
10573         echo "No pages locked after fsync"
10574
10575         return 0
10576 }
10577 run_test 118h "Verify timeout in handling recoverables errors  =========="
10578
10579 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10580
10581 test_118i() {
10582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10583         remote_ost_nodsh && skip "remote OST with nodsh"
10584
10585         reset_async
10586
10587         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10588         set_nodes_failloc "$(osts_nodes)" 0x20e
10589
10590         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10591         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10592         PID=$!
10593         sleep 5
10594         set_nodes_failloc "$(osts_nodes)" 0
10595
10596         wait $PID
10597         RC=$?
10598         if [[ $RC -ne 0 ]]; then
10599                 error "got error, but should be not, rc=$RC"
10600         fi
10601
10602         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10603         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10604         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10605         if [[ $LOCKED -ne 0 ]]; then
10606                 error "Locked pages remain in cache, locked=$LOCKED"
10607         fi
10608
10609         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10610                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10611         fi
10612
10613         rm -f $DIR/$tfile
10614         echo "No pages locked after fsync"
10615
10616         return 0
10617 }
10618 run_test 118i "Fix error before timeout in recoverable error  =========="
10619
10620 [ "$SLOW" = "no" ] && set_resend_count 4
10621
10622 test_118j() {
10623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10624         remote_ost_nodsh && skip "remote OST with nodsh"
10625
10626         reset_async
10627
10628         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10629         set_nodes_failloc "$(osts_nodes)" 0x220
10630
10631         # return -EIO from OST
10632         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10633         RC=$?
10634         set_nodes_failloc "$(osts_nodes)" 0x0
10635         if [[ $RC -eq 0 ]]; then
10636                 error "Must return error due to dropped pages, rc=$RC"
10637         fi
10638
10639         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10640         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10641         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10642         if [[ $LOCKED -ne 0 ]]; then
10643                 error "Locked pages remain in cache, locked=$LOCKED"
10644         fi
10645
10646         # in recoverable error on OST we want resend and stay until it finished
10647         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10648                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10649         fi
10650
10651         rm -f $DIR/$tfile
10652         echo "No pages locked after fsync"
10653
10654         return 0
10655 }
10656 run_test 118j "Simulate unrecoverable OST side error =========="
10657
10658 test_118k()
10659 {
10660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10661         remote_ost_nodsh && skip "remote OSTs with nodsh"
10662
10663         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10664         set_nodes_failloc "$(osts_nodes)" 0x20e
10665         test_mkdir $DIR/$tdir
10666
10667         for ((i=0;i<10;i++)); do
10668                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10669                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10670                 SLEEPPID=$!
10671                 sleep 0.500s
10672                 kill $SLEEPPID
10673                 wait $SLEEPPID
10674         done
10675
10676         set_nodes_failloc "$(osts_nodes)" 0
10677         rm -rf $DIR/$tdir
10678 }
10679 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10680
10681 test_118l() # LU-646
10682 {
10683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10684
10685         test_mkdir $DIR/$tdir
10686         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10687         rm -rf $DIR/$tdir
10688 }
10689 run_test 118l "fsync dir"
10690
10691 test_118m() # LU-3066
10692 {
10693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10694
10695         test_mkdir $DIR/$tdir
10696         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10697         rm -rf $DIR/$tdir
10698 }
10699 run_test 118m "fdatasync dir ========="
10700
10701 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10702
10703 test_118n()
10704 {
10705         local begin
10706         local end
10707
10708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10709         remote_ost_nodsh && skip "remote OSTs with nodsh"
10710
10711         # Sleep to avoid a cached response.
10712         #define OBD_STATFS_CACHE_SECONDS 1
10713         sleep 2
10714
10715         # Inject a 10 second delay in the OST_STATFS handler.
10716         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10717         set_nodes_failloc "$(osts_nodes)" 0x242
10718
10719         begin=$SECONDS
10720         stat --file-system $MOUNT > /dev/null
10721         end=$SECONDS
10722
10723         set_nodes_failloc "$(osts_nodes)" 0
10724
10725         if ((end - begin > 20)); then
10726             error "statfs took $((end - begin)) seconds, expected 10"
10727         fi
10728 }
10729 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10730
10731 test_119a() # bug 11737
10732 {
10733         BSIZE=$((512 * 1024))
10734         directio write $DIR/$tfile 0 1 $BSIZE
10735         # We ask to read two blocks, which is more than a file size.
10736         # directio will indicate an error when requested and actual
10737         # sizes aren't equeal (a normal situation in this case) and
10738         # print actual read amount.
10739         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10740         if [ "$NOB" != "$BSIZE" ]; then
10741                 error "read $NOB bytes instead of $BSIZE"
10742         fi
10743         rm -f $DIR/$tfile
10744 }
10745 run_test 119a "Short directIO read must return actual read amount"
10746
10747 test_119b() # bug 11737
10748 {
10749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10750
10751         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10753         sync
10754         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10755                 error "direct read failed"
10756         rm -f $DIR/$tfile
10757 }
10758 run_test 119b "Sparse directIO read must return actual read amount"
10759
10760 test_119c() # bug 13099
10761 {
10762         BSIZE=1048576
10763         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10764         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10765         rm -f $DIR/$tfile
10766 }
10767 run_test 119c "Testing for direct read hitting hole"
10768
10769 test_119d() # bug 15950
10770 {
10771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10772
10773         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10774         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10775         BSIZE=1048576
10776         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10777         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10778         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10779         lctl set_param fail_loc=0x40d
10780         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10781         pid_dio=$!
10782         sleep 1
10783         cat $DIR/$tfile > /dev/null &
10784         lctl set_param fail_loc=0
10785         pid_reads=$!
10786         wait $pid_dio
10787         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10788         sleep 2
10789         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10790         error "the read rpcs have not completed in 2s"
10791         rm -f $DIR/$tfile
10792         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10793 }
10794 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10795
10796 test_120a() {
10797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10798         remote_mds_nodsh && skip "remote MDS with nodsh"
10799         test_mkdir -i0 -c1 $DIR/$tdir
10800         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10801                 skip_env "no early lock cancel on server"
10802
10803         lru_resize_disable mdc
10804         lru_resize_disable osc
10805         cancel_lru_locks mdc
10806         # asynchronous object destroy at MDT could cause bl ast to client
10807         cancel_lru_locks osc
10808
10809         stat $DIR/$tdir > /dev/null
10810         can1=$(do_facet mds1 \
10811                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10812                awk '/ldlm_cancel/ {print $2}')
10813         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10814                awk '/ldlm_bl_callback/ {print $2}')
10815         test_mkdir -i0 -c1 $DIR/$tdir/d1
10816         can2=$(do_facet mds1 \
10817                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10818                awk '/ldlm_cancel/ {print $2}')
10819         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10820                awk '/ldlm_bl_callback/ {print $2}')
10821         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10822         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10823         lru_resize_enable mdc
10824         lru_resize_enable osc
10825 }
10826 run_test 120a "Early Lock Cancel: mkdir test"
10827
10828 test_120b() {
10829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10830         remote_mds_nodsh && skip "remote MDS with nodsh"
10831         test_mkdir $DIR/$tdir
10832         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10833                 skip_env "no early lock cancel on server"
10834
10835         lru_resize_disable mdc
10836         lru_resize_disable osc
10837         cancel_lru_locks mdc
10838         stat $DIR/$tdir > /dev/null
10839         can1=$(do_facet $SINGLEMDS \
10840                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10841                awk '/ldlm_cancel/ {print $2}')
10842         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10843                awk '/ldlm_bl_callback/ {print $2}')
10844         touch $DIR/$tdir/f1
10845         can2=$(do_facet $SINGLEMDS \
10846                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10847                awk '/ldlm_cancel/ {print $2}')
10848         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10849                awk '/ldlm_bl_callback/ {print $2}')
10850         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10851         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10852         lru_resize_enable mdc
10853         lru_resize_enable osc
10854 }
10855 run_test 120b "Early Lock Cancel: create test"
10856
10857 test_120c() {
10858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10859         remote_mds_nodsh && skip "remote MDS with nodsh"
10860         test_mkdir -i0 -c1 $DIR/$tdir
10861         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10862                 skip "no early lock cancel on server"
10863
10864         lru_resize_disable mdc
10865         lru_resize_disable osc
10866         test_mkdir -i0 -c1 $DIR/$tdir/d1
10867         test_mkdir -i0 -c1 $DIR/$tdir/d2
10868         touch $DIR/$tdir/d1/f1
10869         cancel_lru_locks mdc
10870         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10871         can1=$(do_facet mds1 \
10872                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10873                awk '/ldlm_cancel/ {print $2}')
10874         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10875                awk '/ldlm_bl_callback/ {print $2}')
10876         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10877         can2=$(do_facet mds1 \
10878                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10879                awk '/ldlm_cancel/ {print $2}')
10880         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10881                awk '/ldlm_bl_callback/ {print $2}')
10882         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10883         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10884         lru_resize_enable mdc
10885         lru_resize_enable osc
10886 }
10887 run_test 120c "Early Lock Cancel: link test"
10888
10889 test_120d() {
10890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10891         remote_mds_nodsh && skip "remote MDS with nodsh"
10892         test_mkdir -i0 -c1 $DIR/$tdir
10893         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10894                 skip_env "no early lock cancel on server"
10895
10896         lru_resize_disable mdc
10897         lru_resize_disable osc
10898         touch $DIR/$tdir
10899         cancel_lru_locks mdc
10900         stat $DIR/$tdir > /dev/null
10901         can1=$(do_facet mds1 \
10902                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10903                awk '/ldlm_cancel/ {print $2}')
10904         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10905                awk '/ldlm_bl_callback/ {print $2}')
10906         chmod a+x $DIR/$tdir
10907         can2=$(do_facet mds1 \
10908                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10909                awk '/ldlm_cancel/ {print $2}')
10910         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10911                awk '/ldlm_bl_callback/ {print $2}')
10912         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10913         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10914         lru_resize_enable mdc
10915         lru_resize_enable osc
10916 }
10917 run_test 120d "Early Lock Cancel: setattr test"
10918
10919 test_120e() {
10920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10921         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10922                 skip_env "no early lock cancel on server"
10923         remote_mds_nodsh && skip "remote MDS with nodsh"
10924
10925         local dlmtrace_set=false
10926
10927         test_mkdir -i0 -c1 $DIR/$tdir
10928         lru_resize_disable mdc
10929         lru_resize_disable osc
10930         ! $LCTL get_param debug | grep -q dlmtrace &&
10931                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10932         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10933         cancel_lru_locks mdc
10934         cancel_lru_locks osc
10935         dd if=$DIR/$tdir/f1 of=/dev/null
10936         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10937         # XXX client can not do early lock cancel of OST lock
10938         # during unlink (LU-4206), so cancel osc lock now.
10939         sleep 2
10940         cancel_lru_locks osc
10941         can1=$(do_facet mds1 \
10942                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10943                awk '/ldlm_cancel/ {print $2}')
10944         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10945                awk '/ldlm_bl_callback/ {print $2}')
10946         unlink $DIR/$tdir/f1
10947         sleep 5
10948         can2=$(do_facet mds1 \
10949                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10950                awk '/ldlm_cancel/ {print $2}')
10951         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10952                awk '/ldlm_bl_callback/ {print $2}')
10953         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10954                 $LCTL dk $TMP/cancel.debug.txt
10955         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10956                 $LCTL dk $TMP/blocking.debug.txt
10957         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10958         lru_resize_enable mdc
10959         lru_resize_enable osc
10960 }
10961 run_test 120e "Early Lock Cancel: unlink test"
10962
10963 test_120f() {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10966                 skip_env "no early lock cancel on server"
10967         remote_mds_nodsh && skip "remote MDS with nodsh"
10968
10969         test_mkdir -i0 -c1 $DIR/$tdir
10970         lru_resize_disable mdc
10971         lru_resize_disable osc
10972         test_mkdir -i0 -c1 $DIR/$tdir/d1
10973         test_mkdir -i0 -c1 $DIR/$tdir/d2
10974         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10975         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10976         cancel_lru_locks mdc
10977         cancel_lru_locks osc
10978         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10979         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10980         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10981         # XXX client can not do early lock cancel of OST lock
10982         # during rename (LU-4206), so cancel osc lock now.
10983         sleep 2
10984         cancel_lru_locks osc
10985         can1=$(do_facet mds1 \
10986                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10987                awk '/ldlm_cancel/ {print $2}')
10988         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10989                awk '/ldlm_bl_callback/ {print $2}')
10990         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10991         sleep 5
10992         can2=$(do_facet mds1 \
10993                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10994                awk '/ldlm_cancel/ {print $2}')
10995         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10996                awk '/ldlm_bl_callback/ {print $2}')
10997         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10998         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10999         lru_resize_enable mdc
11000         lru_resize_enable osc
11001 }
11002 run_test 120f "Early Lock Cancel: rename test"
11003
11004 test_120g() {
11005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11006         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11007                 skip_env "no early lock cancel on server"
11008         remote_mds_nodsh && skip "remote MDS with nodsh"
11009
11010         lru_resize_disable mdc
11011         lru_resize_disable osc
11012         count=10000
11013         echo create $count files
11014         test_mkdir $DIR/$tdir
11015         cancel_lru_locks mdc
11016         cancel_lru_locks osc
11017         t0=$(date +%s)
11018
11019         can0=$(do_facet $SINGLEMDS \
11020                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11021                awk '/ldlm_cancel/ {print $2}')
11022         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11023                awk '/ldlm_bl_callback/ {print $2}')
11024         createmany -o $DIR/$tdir/f $count
11025         sync
11026         can1=$(do_facet $SINGLEMDS \
11027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11028                awk '/ldlm_cancel/ {print $2}')
11029         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11030                awk '/ldlm_bl_callback/ {print $2}')
11031         t1=$(date +%s)
11032         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11033         echo rm $count files
11034         rm -r $DIR/$tdir
11035         sync
11036         can2=$(do_facet $SINGLEMDS \
11037                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11038                awk '/ldlm_cancel/ {print $2}')
11039         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11040                awk '/ldlm_bl_callback/ {print $2}')
11041         t2=$(date +%s)
11042         echo total: $count removes in $((t2-t1))
11043         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11044         sleep 2
11045         # wait for commitment of removal
11046         lru_resize_enable mdc
11047         lru_resize_enable osc
11048 }
11049 run_test 120g "Early Lock Cancel: performance test"
11050
11051 test_121() { #bug #10589
11052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11053
11054         rm -rf $DIR/$tfile
11055         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11056 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11057         lctl set_param fail_loc=0x310
11058         cancel_lru_locks osc > /dev/null
11059         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11060         lctl set_param fail_loc=0
11061         [[ $reads -eq $writes ]] ||
11062                 error "read $reads blocks, must be $writes blocks"
11063 }
11064 run_test 121 "read cancel race ========="
11065
11066 test_123a() { # was test 123, statahead(bug 11401)
11067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11068
11069         SLOWOK=0
11070         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11071                 log "testing UP system. Performance may be lower than expected."
11072                 SLOWOK=1
11073         fi
11074
11075         rm -rf $DIR/$tdir
11076         test_mkdir $DIR/$tdir
11077         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11078         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11079         MULT=10
11080         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11081                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11082
11083                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11084                 lctl set_param -n llite.*.statahead_max 0
11085                 lctl get_param llite.*.statahead_max
11086                 cancel_lru_locks mdc
11087                 cancel_lru_locks osc
11088                 stime=`date +%s`
11089                 time ls -l $DIR/$tdir | wc -l
11090                 etime=`date +%s`
11091                 delta=$((etime - stime))
11092                 log "ls $i files without statahead: $delta sec"
11093                 lctl set_param llite.*.statahead_max=$max
11094
11095                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11096                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11097                 cancel_lru_locks mdc
11098                 cancel_lru_locks osc
11099                 stime=`date +%s`
11100                 time ls -l $DIR/$tdir | wc -l
11101                 etime=`date +%s`
11102                 delta_sa=$((etime - stime))
11103                 log "ls $i files with statahead: $delta_sa sec"
11104                 lctl get_param -n llite.*.statahead_stats
11105                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11106
11107                 [[ $swrong -lt $ewrong ]] &&
11108                         log "statahead was stopped, maybe too many locks held!"
11109                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11110
11111                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11112                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11113                     lctl set_param -n llite.*.statahead_max 0
11114                     lctl get_param llite.*.statahead_max
11115                     cancel_lru_locks mdc
11116                     cancel_lru_locks osc
11117                     stime=`date +%s`
11118                     time ls -l $DIR/$tdir | wc -l
11119                     etime=`date +%s`
11120                     delta=$((etime - stime))
11121                     log "ls $i files again without statahead: $delta sec"
11122                     lctl set_param llite.*.statahead_max=$max
11123                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11124                         if [  $SLOWOK -eq 0 ]; then
11125                                 error "ls $i files is slower with statahead!"
11126                         else
11127                                 log "ls $i files is slower with statahead!"
11128                         fi
11129                         break
11130                     fi
11131                 fi
11132
11133                 [ $delta -gt 20 ] && break
11134                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11135                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11136         done
11137         log "ls done"
11138
11139         stime=`date +%s`
11140         rm -r $DIR/$tdir
11141         sync
11142         etime=`date +%s`
11143         delta=$((etime - stime))
11144         log "rm -r $DIR/$tdir/: $delta seconds"
11145         log "rm done"
11146         lctl get_param -n llite.*.statahead_stats
11147 }
11148 run_test 123a "verify statahead work"
11149
11150 test_123b () { # statahead(bug 15027)
11151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11152
11153         test_mkdir $DIR/$tdir
11154         createmany -o $DIR/$tdir/$tfile-%d 1000
11155
11156         cancel_lru_locks mdc
11157         cancel_lru_locks osc
11158
11159 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11160         lctl set_param fail_loc=0x80000803
11161         ls -lR $DIR/$tdir > /dev/null
11162         log "ls done"
11163         lctl set_param fail_loc=0x0
11164         lctl get_param -n llite.*.statahead_stats
11165         rm -r $DIR/$tdir
11166         sync
11167
11168 }
11169 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11170
11171 test_123c() {
11172         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11173
11174         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11175         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11176         touch $DIR/$tdir.1/{1..3}
11177         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11178
11179         remount_client $MOUNT
11180
11181         $MULTIOP $DIR/$tdir.0 Q
11182
11183         # let statahead to complete
11184         ls -l $DIR/$tdir.0 > /dev/null
11185
11186         testid=$(echo $TESTNAME | tr '_' ' ')
11187         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11188                 error "statahead warning" || true
11189 }
11190 run_test 123c "Can not initialize inode warning on DNE statahead"
11191
11192 test_124a() {
11193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11194         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11195                 skip_env "no lru resize on server"
11196
11197         local NR=2000
11198
11199         test_mkdir $DIR/$tdir
11200
11201         log "create $NR files at $DIR/$tdir"
11202         createmany -o $DIR/$tdir/f $NR ||
11203                 error "failed to create $NR files in $DIR/$tdir"
11204
11205         cancel_lru_locks mdc
11206         ls -l $DIR/$tdir > /dev/null
11207
11208         local NSDIR=""
11209         local LRU_SIZE=0
11210         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11211                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11212                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11213                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11214                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11215                         log "NSDIR=$NSDIR"
11216                         log "NS=$(basename $NSDIR)"
11217                         break
11218                 fi
11219         done
11220
11221         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11222                 skip "Not enough cached locks created!"
11223         fi
11224         log "LRU=$LRU_SIZE"
11225
11226         local SLEEP=30
11227
11228         # We know that lru resize allows one client to hold $LIMIT locks
11229         # for 10h. After that locks begin to be killed by client.
11230         local MAX_HRS=10
11231         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11232         log "LIMIT=$LIMIT"
11233         if [ $LIMIT -lt $LRU_SIZE ]; then
11234                 skip "Limit is too small $LIMIT"
11235         fi
11236
11237         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11238         # killing locks. Some time was spent for creating locks. This means
11239         # that up to the moment of sleep finish we must have killed some of
11240         # them (10-100 locks). This depends on how fast ther were created.
11241         # Many of them were touched in almost the same moment and thus will
11242         # be killed in groups.
11243         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11244
11245         # Use $LRU_SIZE_B here to take into account real number of locks
11246         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11247         local LRU_SIZE_B=$LRU_SIZE
11248         log "LVF=$LVF"
11249         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11250         log "OLD_LVF=$OLD_LVF"
11251         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11252
11253         # Let's make sure that we really have some margin. Client checks
11254         # cached locks every 10 sec.
11255         SLEEP=$((SLEEP+20))
11256         log "Sleep ${SLEEP} sec"
11257         local SEC=0
11258         while ((SEC<$SLEEP)); do
11259                 echo -n "..."
11260                 sleep 5
11261                 SEC=$((SEC+5))
11262                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11263                 echo -n "$LRU_SIZE"
11264         done
11265         echo ""
11266         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11267         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11268
11269         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11270                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11271                 unlinkmany $DIR/$tdir/f $NR
11272                 return
11273         }
11274
11275         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11276         log "unlink $NR files at $DIR/$tdir"
11277         unlinkmany $DIR/$tdir/f $NR
11278 }
11279 run_test 124a "lru resize ======================================="
11280
11281 get_max_pool_limit()
11282 {
11283         local limit=$($LCTL get_param \
11284                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11285         local max=0
11286         for l in $limit; do
11287                 if [[ $l -gt $max ]]; then
11288                         max=$l
11289                 fi
11290         done
11291         echo $max
11292 }
11293
11294 test_124b() {
11295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11296         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11297                 skip_env "no lru resize on server"
11298
11299         LIMIT=$(get_max_pool_limit)
11300
11301         NR=$(($(default_lru_size)*20))
11302         if [[ $NR -gt $LIMIT ]]; then
11303                 log "Limit lock number by $LIMIT locks"
11304                 NR=$LIMIT
11305         fi
11306
11307         IFree=$(mdsrate_inodes_available)
11308         if [ $IFree -lt $NR ]; then
11309                 log "Limit lock number by $IFree inodes"
11310                 NR=$IFree
11311         fi
11312
11313         lru_resize_disable mdc
11314         test_mkdir -p $DIR/$tdir/disable_lru_resize
11315
11316         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11317         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11318         cancel_lru_locks mdc
11319         stime=`date +%s`
11320         PID=""
11321         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11322         PID="$PID $!"
11323         sleep 2
11324         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11325         PID="$PID $!"
11326         sleep 2
11327         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11328         PID="$PID $!"
11329         wait $PID
11330         etime=`date +%s`
11331         nolruresize_delta=$((etime-stime))
11332         log "ls -la time: $nolruresize_delta seconds"
11333         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11334         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11335
11336         lru_resize_enable mdc
11337         test_mkdir -p $DIR/$tdir/enable_lru_resize
11338
11339         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11340         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11341         cancel_lru_locks mdc
11342         stime=`date +%s`
11343         PID=""
11344         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11345         PID="$PID $!"
11346         sleep 2
11347         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11348         PID="$PID $!"
11349         sleep 2
11350         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11351         PID="$PID $!"
11352         wait $PID
11353         etime=`date +%s`
11354         lruresize_delta=$((etime-stime))
11355         log "ls -la time: $lruresize_delta seconds"
11356         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11357
11358         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11359                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11360         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11361                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11362         else
11363                 log "lru resize performs the same with no lru resize"
11364         fi
11365         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11366 }
11367 run_test 124b "lru resize (performance test) ======================="
11368
11369 test_124c() {
11370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11371         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11372                 skip_env "no lru resize on server"
11373
11374         # cache ununsed locks on client
11375         local nr=100
11376         cancel_lru_locks mdc
11377         test_mkdir $DIR/$tdir
11378         createmany -o $DIR/$tdir/f $nr ||
11379                 error "failed to create $nr files in $DIR/$tdir"
11380         ls -l $DIR/$tdir > /dev/null
11381
11382         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11383         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11384         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11385         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11386         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11387
11388         # set lru_max_age to 1 sec
11389         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11390         echo "sleep $((recalc_p * 2)) seconds..."
11391         sleep $((recalc_p * 2))
11392
11393         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11394         # restore lru_max_age
11395         $LCTL set_param -n $nsdir.lru_max_age $max_age
11396         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11397         unlinkmany $DIR/$tdir/f $nr
11398 }
11399 run_test 124c "LRUR cancel very aged locks"
11400
11401 test_124d() {
11402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11403         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11404                 skip_env "no lru resize on server"
11405
11406         # cache ununsed locks on client
11407         local nr=100
11408
11409         lru_resize_disable mdc
11410         stack_trap "lru_resize_enable mdc" EXIT
11411
11412         cancel_lru_locks mdc
11413
11414         # asynchronous object destroy at MDT could cause bl ast to client
11415         test_mkdir $DIR/$tdir
11416         createmany -o $DIR/$tdir/f $nr ||
11417                 error "failed to create $nr files in $DIR/$tdir"
11418         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11419
11420         ls -l $DIR/$tdir > /dev/null
11421
11422         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11423         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11424         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11425         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11426
11427         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11428
11429         # set lru_max_age to 1 sec
11430         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11431         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11432
11433         echo "sleep $((recalc_p * 2)) seconds..."
11434         sleep $((recalc_p * 2))
11435
11436         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11437
11438         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11439 }
11440 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11441
11442 test_125() { # 13358
11443         $LCTL get_param -n llite.*.client_type | grep -q local ||
11444                 skip "must run as local client"
11445         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11446                 skip_env "must have acl enabled"
11447         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11448
11449         test_mkdir $DIR/$tdir
11450         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11451         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11452         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11453 }
11454 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11455
11456 test_126() { # bug 12829/13455
11457         $GSS && skip_env "must run as gss disabled"
11458         $LCTL get_param -n llite.*.client_type | grep -q local ||
11459                 skip "must run as local client"
11460         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11461
11462         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11463         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11464         rm -f $DIR/$tfile
11465         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11466 }
11467 run_test 126 "check that the fsgid provided by the client is taken into account"
11468
11469 test_127a() { # bug 15521
11470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11471         local name count samp unit min max sum sumsq
11472
11473         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11474         echo "stats before reset"
11475         $LCTL get_param osc.*.stats
11476         $LCTL set_param osc.*.stats=0
11477         local fsize=$((2048 * 1024))
11478
11479         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11480         cancel_lru_locks osc
11481         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11482
11483         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11484         stack_trap "rm -f $TMP/$tfile.tmp"
11485         while read name count samp unit min max sum sumsq; do
11486                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11487                 [ ! $min ] && error "Missing min value for $name proc entry"
11488                 eval $name=$count || error "Wrong proc format"
11489
11490                 case $name in
11491                 read_bytes|write_bytes)
11492                         [[ "$unit" =~ "bytes" ]] ||
11493                                 error "unit is not 'bytes': $unit"
11494                         (( $min >= 4096 )) || error "min is too small: $min"
11495                         (( $min <= $fsize )) || error "min is too big: $min"
11496                         (( $max >= 4096 )) || error "max is too small: $max"
11497                         (( $max <= $fsize )) || error "max is too big: $max"
11498                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11499                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11500                                 error "sumsquare is too small: $sumsq"
11501                         (( $sumsq <= $fsize * $fsize )) ||
11502                                 error "sumsquare is too big: $sumsq"
11503                         ;;
11504                 ost_read|ost_write)
11505                         [[ "$unit" =~ "usec" ]] ||
11506                                 error "unit is not 'usec': $unit"
11507                         ;;
11508                 *)      ;;
11509                 esac
11510         done < $DIR/$tfile.tmp
11511
11512         #check that we actually got some stats
11513         [ "$read_bytes" ] || error "Missing read_bytes stats"
11514         [ "$write_bytes" ] || error "Missing write_bytes stats"
11515         [ "$read_bytes" != 0 ] || error "no read done"
11516         [ "$write_bytes" != 0 ] || error "no write done"
11517 }
11518 run_test 127a "verify the client stats are sane"
11519
11520 test_127b() { # bug LU-333
11521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11522         local name count samp unit min max sum sumsq
11523
11524         echo "stats before reset"
11525         $LCTL get_param llite.*.stats
11526         $LCTL set_param llite.*.stats=0
11527
11528         # perform 2 reads and writes so MAX is different from SUM.
11529         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11530         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11531         cancel_lru_locks osc
11532         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11533         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11534
11535         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11536         stack_trap "rm -f $TMP/$tfile.tmp"
11537         while read name count samp unit min max sum sumsq; do
11538                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11539                 eval $name=$count || error "Wrong proc format"
11540
11541                 case $name in
11542                 read_bytes|write_bytes)
11543                         [[ "$unit" =~ "bytes" ]] ||
11544                                 error "unit is not 'bytes': $unit"
11545                         (( $count == 2 )) || error "count is not 2: $count"
11546                         (( $min == $PAGE_SIZE )) ||
11547                                 error "min is not $PAGE_SIZE: $min"
11548                         (( $max == $PAGE_SIZE )) ||
11549                                 error "max is not $PAGE_SIZE: $max"
11550                         (( $sum == $PAGE_SIZE * 2 )) ||
11551                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11552                         ;;
11553                 read|write)
11554                         [[ "$unit" =~ "usec" ]] ||
11555                                 error "unit is not 'usec': $unit"
11556                         ;;
11557                 *)      ;;
11558                 esac
11559         done < $TMP/$tfile.tmp
11560
11561         #check that we actually got some stats
11562         [ "$read_bytes" ] || error "Missing read_bytes stats"
11563         [ "$write_bytes" ] || error "Missing write_bytes stats"
11564         [ "$read_bytes" != 0 ] || error "no read done"
11565         [ "$write_bytes" != 0 ] || error "no write done"
11566 }
11567 run_test 127b "verify the llite client stats are sane"
11568
11569 test_127c() { # LU-12394
11570         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11571         local size
11572         local bsize
11573         local reads
11574         local writes
11575         local count
11576
11577         $LCTL set_param llite.*.extents_stats=1
11578         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11579
11580         # Use two stripes so there is enough space in default config
11581         $LFS setstripe -c 2 $DIR/$tfile
11582
11583         # Extent stats start at 0-4K and go in power of two buckets
11584         # LL_HIST_START = 12 --> 2^12 = 4K
11585         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11586         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11587         # small configs
11588         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11589                 do
11590                 # Write and read, 2x each, second time at a non-zero offset
11591                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11592                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11593                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11594                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11595                 rm -f $DIR/$tfile
11596         done
11597
11598         $LCTL get_param llite.*.extents_stats
11599
11600         count=2
11601         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11602                 do
11603                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11604                                 grep -m 1 $bsize)
11605                 reads=$(echo $bucket | awk '{print $5}')
11606                 writes=$(echo $bucket | awk '{print $9}')
11607                 [ "$reads" -eq $count ] ||
11608                         error "$reads reads in < $bsize bucket, expect $count"
11609                 [ "$writes" -eq $count ] ||
11610                         error "$writes writes in < $bsize bucket, expect $count"
11611         done
11612
11613         # Test mmap write and read
11614         $LCTL set_param llite.*.extents_stats=c
11615         size=512
11616         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11617         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11618         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11619
11620         $LCTL get_param llite.*.extents_stats
11621
11622         count=$(((size*1024) / PAGE_SIZE))
11623
11624         bsize=$((2 * PAGE_SIZE / 1024))K
11625
11626         bucket=$($LCTL get_param -n llite.*.extents_stats |
11627                         grep -m 1 $bsize)
11628         reads=$(echo $bucket | awk '{print $5}')
11629         writes=$(echo $bucket | awk '{print $9}')
11630         # mmap writes fault in the page first, creating an additonal read
11631         [ "$reads" -eq $((2 * count)) ] ||
11632                 error "$reads reads in < $bsize bucket, expect $count"
11633         [ "$writes" -eq $count ] ||
11634                 error "$writes writes in < $bsize bucket, expect $count"
11635 }
11636 run_test 127c "test llite extent stats with regular & mmap i/o"
11637
11638 test_128() { # bug 15212
11639         touch $DIR/$tfile
11640         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11641                 find $DIR/$tfile
11642                 find $DIR/$tfile
11643         EOF
11644
11645         result=$(grep error $TMP/$tfile.log)
11646         rm -f $DIR/$tfile $TMP/$tfile.log
11647         [ -z "$result" ] ||
11648                 error "consecutive find's under interactive lfs failed"
11649 }
11650 run_test 128 "interactive lfs for 2 consecutive find's"
11651
11652 set_dir_limits () {
11653         local mntdev
11654         local canondev
11655         local node
11656
11657         local ldproc=/proc/fs/ldiskfs
11658         local facets=$(get_facets MDS)
11659
11660         for facet in ${facets//,/ }; do
11661                 canondev=$(ldiskfs_canon \
11662                            *.$(convert_facet2label $facet).mntdev $facet)
11663                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11664                         ldproc=/sys/fs/ldiskfs
11665                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11666                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11667         done
11668 }
11669
11670 check_mds_dmesg() {
11671         local facets=$(get_facets MDS)
11672         for facet in ${facets//,/ }; do
11673                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11674         done
11675         return 1
11676 }
11677
11678 test_129() {
11679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11680         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11681                 skip "Need MDS version with at least 2.5.56"
11682         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11683                 skip_env "ldiskfs only test"
11684         fi
11685         remote_mds_nodsh && skip "remote MDS with nodsh"
11686
11687         local ENOSPC=28
11688         local EFBIG=27
11689         local has_warning=false
11690
11691         rm -rf $DIR/$tdir
11692         mkdir -p $DIR/$tdir
11693
11694         # block size of mds1
11695         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11696         set_dir_limits $maxsize $maxsize
11697         local dirsize=$(stat -c%s "$DIR/$tdir")
11698         local nfiles=0
11699         while [[ $dirsize -le $maxsize ]]; do
11700                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11701                 rc=$?
11702                 if ! $has_warning; then
11703                         check_mds_dmesg '"is approaching"' && has_warning=true
11704                 fi
11705                 # check two errors:
11706                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11707                 # EFBIG for previous versions included in ldiskfs series
11708                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11709                         set_dir_limits 0 0
11710                         echo "return code $rc received as expected"
11711
11712                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11713                                 error_exit "create failed w/o dir size limit"
11714
11715                         check_mds_dmesg '"has reached"' ||
11716                                 error_exit "reached message should be output"
11717
11718                         [ $has_warning = "false" ] &&
11719                                 error_exit "warning message should be output"
11720
11721                         dirsize=$(stat -c%s "$DIR/$tdir")
11722
11723                         [[ $dirsize -ge $maxsize ]] && return 0
11724                         error_exit "current dir size $dirsize, " \
11725                                    "previous limit $maxsize"
11726                 elif [ $rc -ne 0 ]; then
11727                         set_dir_limits 0 0
11728                         error_exit "return $rc received instead of expected " \
11729                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11730                 fi
11731                 nfiles=$((nfiles + 1))
11732                 dirsize=$(stat -c%s "$DIR/$tdir")
11733         done
11734
11735         set_dir_limits 0 0
11736         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11737 }
11738 run_test 129 "test directory size limit ========================"
11739
11740 OLDIFS="$IFS"
11741 cleanup_130() {
11742         trap 0
11743         IFS="$OLDIFS"
11744 }
11745
11746 test_130a() {
11747         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11748         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11749
11750         trap cleanup_130 EXIT RETURN
11751
11752         local fm_file=$DIR/$tfile
11753         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11754         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11755                 error "dd failed for $fm_file"
11756
11757         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11758         filefrag -ves $fm_file
11759         RC=$?
11760         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11761                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11762         [ $RC != 0 ] && error "filefrag $fm_file failed"
11763
11764         filefrag_op=$(filefrag -ve -k $fm_file |
11765                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11766         lun=$($LFS getstripe -i $fm_file)
11767
11768         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11769         IFS=$'\n'
11770         tot_len=0
11771         for line in $filefrag_op
11772         do
11773                 frag_lun=`echo $line | cut -d: -f5`
11774                 ext_len=`echo $line | cut -d: -f4`
11775                 if (( $frag_lun != $lun )); then
11776                         cleanup_130
11777                         error "FIEMAP on 1-stripe file($fm_file) failed"
11778                         return
11779                 fi
11780                 (( tot_len += ext_len ))
11781         done
11782
11783         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11784                 cleanup_130
11785                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11786                 return
11787         fi
11788
11789         cleanup_130
11790
11791         echo "FIEMAP on single striped file succeeded"
11792 }
11793 run_test 130a "FIEMAP (1-stripe file)"
11794
11795 test_130b() {
11796         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11797
11798         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11799         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11800
11801         trap cleanup_130 EXIT RETURN
11802
11803         local fm_file=$DIR/$tfile
11804         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11805                         error "setstripe on $fm_file"
11806         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11807                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11808
11809         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11810                 error "dd failed on $fm_file"
11811
11812         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11813         filefrag_op=$(filefrag -ve -k $fm_file |
11814                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11815
11816         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11817                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11818
11819         IFS=$'\n'
11820         tot_len=0
11821         num_luns=1
11822         for line in $filefrag_op
11823         do
11824                 frag_lun=$(echo $line | cut -d: -f5 |
11825                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11826                 ext_len=$(echo $line | cut -d: -f4)
11827                 if (( $frag_lun != $last_lun )); then
11828                         if (( tot_len != 1024 )); then
11829                                 cleanup_130
11830                                 error "FIEMAP on $fm_file failed; returned " \
11831                                 "len $tot_len for OST $last_lun instead of 1024"
11832                                 return
11833                         else
11834                                 (( num_luns += 1 ))
11835                                 tot_len=0
11836                         fi
11837                 fi
11838                 (( tot_len += ext_len ))
11839                 last_lun=$frag_lun
11840         done
11841         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11842                 cleanup_130
11843                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11844                         "luns or wrong len for OST $last_lun"
11845                 return
11846         fi
11847
11848         cleanup_130
11849
11850         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11851 }
11852 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11853
11854 test_130c() {
11855         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11856
11857         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11858         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11859
11860         trap cleanup_130 EXIT RETURN
11861
11862         local fm_file=$DIR/$tfile
11863         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11864         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11865                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11866
11867         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11868                         error "dd failed on $fm_file"
11869
11870         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11871         filefrag_op=$(filefrag -ve -k $fm_file |
11872                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11873
11874         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11875                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11876
11877         IFS=$'\n'
11878         tot_len=0
11879         num_luns=1
11880         for line in $filefrag_op
11881         do
11882                 frag_lun=$(echo $line | cut -d: -f5 |
11883                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11884                 ext_len=$(echo $line | cut -d: -f4)
11885                 if (( $frag_lun != $last_lun )); then
11886                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11887                         if (( logical != 512 )); then
11888                                 cleanup_130
11889                                 error "FIEMAP on $fm_file failed; returned " \
11890                                 "logical start for lun $logical instead of 512"
11891                                 return
11892                         fi
11893                         if (( tot_len != 512 )); then
11894                                 cleanup_130
11895                                 error "FIEMAP on $fm_file failed; returned " \
11896                                 "len $tot_len for OST $last_lun instead of 1024"
11897                                 return
11898                         else
11899                                 (( num_luns += 1 ))
11900                                 tot_len=0
11901                         fi
11902                 fi
11903                 (( tot_len += ext_len ))
11904                 last_lun=$frag_lun
11905         done
11906         if (( num_luns != 2 || tot_len != 512 )); then
11907                 cleanup_130
11908                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11909                         "luns or wrong len for OST $last_lun"
11910                 return
11911         fi
11912
11913         cleanup_130
11914
11915         echo "FIEMAP on 2-stripe file with hole succeeded"
11916 }
11917 run_test 130c "FIEMAP (2-stripe file with hole)"
11918
11919 test_130d() {
11920         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11921
11922         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11923         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11924
11925         trap cleanup_130 EXIT RETURN
11926
11927         local fm_file=$DIR/$tfile
11928         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11929                         error "setstripe on $fm_file"
11930         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11931                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11932
11933         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11934         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11935                 error "dd failed on $fm_file"
11936
11937         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11938         filefrag_op=$(filefrag -ve -k $fm_file |
11939                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11940
11941         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11942                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11943
11944         IFS=$'\n'
11945         tot_len=0
11946         num_luns=1
11947         for line in $filefrag_op
11948         do
11949                 frag_lun=$(echo $line | cut -d: -f5 |
11950                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11951                 ext_len=$(echo $line | cut -d: -f4)
11952                 if (( $frag_lun != $last_lun )); then
11953                         if (( tot_len != 1024 )); then
11954                                 cleanup_130
11955                                 error "FIEMAP on $fm_file failed; returned " \
11956                                 "len $tot_len for OST $last_lun instead of 1024"
11957                                 return
11958                         else
11959                                 (( num_luns += 1 ))
11960                                 tot_len=0
11961                         fi
11962                 fi
11963                 (( tot_len += ext_len ))
11964                 last_lun=$frag_lun
11965         done
11966         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11967                 cleanup_130
11968                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11969                         "luns or wrong len for OST $last_lun"
11970                 return
11971         fi
11972
11973         cleanup_130
11974
11975         echo "FIEMAP on N-stripe file succeeded"
11976 }
11977 run_test 130d "FIEMAP (N-stripe file)"
11978
11979 test_130e() {
11980         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11981
11982         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11983         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11984
11985         trap cleanup_130 EXIT RETURN
11986
11987         local fm_file=$DIR/$tfile
11988         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11989         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11990                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11991
11992         NUM_BLKS=512
11993         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11994         for ((i = 0; i < $NUM_BLKS; i++))
11995         do
11996                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11997         done
11998
11999         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12000         filefrag_op=$(filefrag -ve -k $fm_file |
12001                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12002
12003         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12004                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12005
12006         IFS=$'\n'
12007         tot_len=0
12008         num_luns=1
12009         for line in $filefrag_op
12010         do
12011                 frag_lun=$(echo $line | cut -d: -f5 |
12012                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12013                 ext_len=$(echo $line | cut -d: -f4)
12014                 if (( $frag_lun != $last_lun )); then
12015                         if (( tot_len != $EXPECTED_LEN )); then
12016                                 cleanup_130
12017                                 error "FIEMAP on $fm_file failed; returned " \
12018                                 "len $tot_len for OST $last_lun instead " \
12019                                 "of $EXPECTED_LEN"
12020                                 return
12021                         else
12022                                 (( num_luns += 1 ))
12023                                 tot_len=0
12024                         fi
12025                 fi
12026                 (( tot_len += ext_len ))
12027                 last_lun=$frag_lun
12028         done
12029         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12030                 cleanup_130
12031                 error "FIEMAP on $fm_file failed; returned wrong number " \
12032                         "of luns or wrong len for OST $last_lun"
12033                 return
12034         fi
12035
12036         cleanup_130
12037
12038         echo "FIEMAP with continuation calls succeeded"
12039 }
12040 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12041
12042 test_130f() {
12043         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12044         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12045
12046         local fm_file=$DIR/$tfile
12047         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12048                 error "multiop create with lov_delay_create on $fm_file"
12049
12050         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12051         filefrag_extents=$(filefrag -vek $fm_file |
12052                            awk '/extents? found/ { print $2 }')
12053         if [[ "$filefrag_extents" != "0" ]]; then
12054                 error "FIEMAP on $fm_file failed; " \
12055                       "returned $filefrag_extents expected 0"
12056         fi
12057
12058         rm -f $fm_file
12059 }
12060 run_test 130f "FIEMAP (unstriped file)"
12061
12062 # Test for writev/readv
12063 test_131a() {
12064         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12065                 error "writev test failed"
12066         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12067                 error "readv failed"
12068         rm -f $DIR/$tfile
12069 }
12070 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12071
12072 test_131b() {
12073         local fsize=$((524288 + 1048576 + 1572864))
12074         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12075                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12076                         error "append writev test failed"
12077
12078         ((fsize += 1572864 + 1048576))
12079         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12080                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12081                         error "append writev test failed"
12082         rm -f $DIR/$tfile
12083 }
12084 run_test 131b "test append writev"
12085
12086 test_131c() {
12087         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12088         error "NOT PASS"
12089 }
12090 run_test 131c "test read/write on file w/o objects"
12091
12092 test_131d() {
12093         rwv -f $DIR/$tfile -w -n 1 1572864
12094         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12095         if [ "$NOB" != 1572864 ]; then
12096                 error "Short read filed: read $NOB bytes instead of 1572864"
12097         fi
12098         rm -f $DIR/$tfile
12099 }
12100 run_test 131d "test short read"
12101
12102 test_131e() {
12103         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12104         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12105         error "read hitting hole failed"
12106         rm -f $DIR/$tfile
12107 }
12108 run_test 131e "test read hitting hole"
12109
12110 check_stats() {
12111         local facet=$1
12112         local op=$2
12113         local want=${3:-0}
12114         local res
12115
12116         case $facet in
12117         mds*) res=$(do_facet $facet \
12118                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12119                  ;;
12120         ost*) res=$(do_facet $facet \
12121                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12122                  ;;
12123         *) error "Wrong facet '$facet'" ;;
12124         esac
12125         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12126         # if the argument $3 is zero, it means any stat increment is ok.
12127         if [[ $want -gt 0 ]]; then
12128                 local count=$(echo $res | awk '{ print $2 }')
12129                 [[ $count -ne $want ]] &&
12130                         error "The $op counter on $facet is $count, not $want"
12131         fi
12132 }
12133
12134 test_133a() {
12135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12136         remote_ost_nodsh && skip "remote OST with nodsh"
12137         remote_mds_nodsh && skip "remote MDS with nodsh"
12138         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12139                 skip_env "MDS doesn't support rename stats"
12140
12141         local testdir=$DIR/${tdir}/stats_testdir
12142
12143         mkdir -p $DIR/${tdir}
12144
12145         # clear stats.
12146         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12147         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12148
12149         # verify mdt stats first.
12150         mkdir ${testdir} || error "mkdir failed"
12151         check_stats $SINGLEMDS "mkdir" 1
12152         touch ${testdir}/${tfile} || error "touch failed"
12153         check_stats $SINGLEMDS "open" 1
12154         check_stats $SINGLEMDS "close" 1
12155         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12156                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12157                 check_stats $SINGLEMDS "mknod" 2
12158         }
12159         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12160         check_stats $SINGLEMDS "unlink" 1
12161         rm -f ${testdir}/${tfile} || error "file remove failed"
12162         check_stats $SINGLEMDS "unlink" 2
12163
12164         # remove working dir and check mdt stats again.
12165         rmdir ${testdir} || error "rmdir failed"
12166         check_stats $SINGLEMDS "rmdir" 1
12167
12168         local testdir1=$DIR/${tdir}/stats_testdir1
12169         mkdir -p ${testdir}
12170         mkdir -p ${testdir1}
12171         touch ${testdir1}/test1
12172         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12173         check_stats $SINGLEMDS "crossdir_rename" 1
12174
12175         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12176         check_stats $SINGLEMDS "samedir_rename" 1
12177
12178         rm -rf $DIR/${tdir}
12179 }
12180 run_test 133a "Verifying MDT stats ========================================"
12181
12182 test_133b() {
12183         local res
12184
12185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12186         remote_ost_nodsh && skip "remote OST with nodsh"
12187         remote_mds_nodsh && skip "remote MDS with nodsh"
12188
12189         local testdir=$DIR/${tdir}/stats_testdir
12190
12191         mkdir -p ${testdir} || error "mkdir failed"
12192         touch ${testdir}/${tfile} || error "touch failed"
12193         cancel_lru_locks mdc
12194
12195         # clear stats.
12196         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12197         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12198
12199         # extra mdt stats verification.
12200         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12201         check_stats $SINGLEMDS "setattr" 1
12202         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12203         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12204         then            # LU-1740
12205                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12206                 check_stats $SINGLEMDS "getattr" 1
12207         fi
12208         rm -rf $DIR/${tdir}
12209
12210         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12211         # so the check below is not reliable
12212         [ $MDSCOUNT -eq 1 ] || return 0
12213
12214         # Sleep to avoid a cached response.
12215         #define OBD_STATFS_CACHE_SECONDS 1
12216         sleep 2
12217         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12218         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12219         $LFS df || error "lfs failed"
12220         check_stats $SINGLEMDS "statfs" 1
12221
12222         # check aggregated statfs (LU-10018)
12223         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12224                 return 0
12225         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12226                 return 0
12227         sleep 2
12228         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12229         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12230         df $DIR
12231         check_stats $SINGLEMDS "statfs" 1
12232
12233         # We want to check that the client didn't send OST_STATFS to
12234         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12235         # extra care is needed here.
12236         if remote_mds; then
12237                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12238                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12239
12240                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12241                 [ "$res" ] && error "OST got STATFS"
12242         fi
12243
12244         return 0
12245 }
12246 run_test 133b "Verifying extra MDT stats =================================="
12247
12248 test_133c() {
12249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12250         remote_ost_nodsh && skip "remote OST with nodsh"
12251         remote_mds_nodsh && skip "remote MDS with nodsh"
12252
12253         local testdir=$DIR/$tdir/stats_testdir
12254
12255         test_mkdir -p $testdir
12256
12257         # verify obdfilter stats.
12258         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12259         sync
12260         cancel_lru_locks osc
12261         wait_delete_completed
12262
12263         # clear stats.
12264         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12265         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12266
12267         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12268                 error "dd failed"
12269         sync
12270         cancel_lru_locks osc
12271         check_stats ost1 "write" 1
12272
12273         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12274         check_stats ost1 "read" 1
12275
12276         > $testdir/$tfile || error "truncate failed"
12277         check_stats ost1 "punch" 1
12278
12279         rm -f $testdir/$tfile || error "file remove failed"
12280         wait_delete_completed
12281         check_stats ost1 "destroy" 1
12282
12283         rm -rf $DIR/$tdir
12284 }
12285 run_test 133c "Verifying OST stats ========================================"
12286
12287 order_2() {
12288         local value=$1
12289         local orig=$value
12290         local order=1
12291
12292         while [ $value -ge 2 ]; do
12293                 order=$((order*2))
12294                 value=$((value/2))
12295         done
12296
12297         if [ $orig -gt $order ]; then
12298                 order=$((order*2))
12299         fi
12300         echo $order
12301 }
12302
12303 size_in_KMGT() {
12304     local value=$1
12305     local size=('K' 'M' 'G' 'T');
12306     local i=0
12307     local size_string=$value
12308
12309     while [ $value -ge 1024 ]; do
12310         if [ $i -gt 3 ]; then
12311             #T is the biggest unit we get here, if that is bigger,
12312             #just return XXXT
12313             size_string=${value}T
12314             break
12315         fi
12316         value=$((value >> 10))
12317         if [ $value -lt 1024 ]; then
12318             size_string=${value}${size[$i]}
12319             break
12320         fi
12321         i=$((i + 1))
12322     done
12323
12324     echo $size_string
12325 }
12326
12327 get_rename_size() {
12328         local size=$1
12329         local context=${2:-.}
12330         local sample=$(do_facet $SINGLEMDS $LCTL \
12331                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12332                 grep -A1 $context |
12333                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12334         echo $sample
12335 }
12336
12337 test_133d() {
12338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12339         remote_ost_nodsh && skip "remote OST with nodsh"
12340         remote_mds_nodsh && skip "remote MDS with nodsh"
12341         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12342                 skip_env "MDS doesn't support rename stats"
12343
12344         local testdir1=$DIR/${tdir}/stats_testdir1
12345         local testdir2=$DIR/${tdir}/stats_testdir2
12346         mkdir -p $DIR/${tdir}
12347
12348         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12349
12350         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12351         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12352
12353         createmany -o $testdir1/test 512 || error "createmany failed"
12354
12355         # check samedir rename size
12356         mv ${testdir1}/test0 ${testdir1}/test_0
12357
12358         local testdir1_size=$(ls -l $DIR/${tdir} |
12359                 awk '/stats_testdir1/ {print $5}')
12360         local testdir2_size=$(ls -l $DIR/${tdir} |
12361                 awk '/stats_testdir2/ {print $5}')
12362
12363         testdir1_size=$(order_2 $testdir1_size)
12364         testdir2_size=$(order_2 $testdir2_size)
12365
12366         testdir1_size=$(size_in_KMGT $testdir1_size)
12367         testdir2_size=$(size_in_KMGT $testdir2_size)
12368
12369         echo "source rename dir size: ${testdir1_size}"
12370         echo "target rename dir size: ${testdir2_size}"
12371
12372         local cmd="do_facet $SINGLEMDS $LCTL "
12373         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12374
12375         eval $cmd || error "$cmd failed"
12376         local samedir=$($cmd | grep 'same_dir')
12377         local same_sample=$(get_rename_size $testdir1_size)
12378         [ -z "$samedir" ] && error "samedir_rename_size count error"
12379         [[ $same_sample -eq 1 ]] ||
12380                 error "samedir_rename_size error $same_sample"
12381         echo "Check same dir rename stats success"
12382
12383         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12384
12385         # check crossdir rename size
12386         mv ${testdir1}/test_0 ${testdir2}/test_0
12387
12388         testdir1_size=$(ls -l $DIR/${tdir} |
12389                 awk '/stats_testdir1/ {print $5}')
12390         testdir2_size=$(ls -l $DIR/${tdir} |
12391                 awk '/stats_testdir2/ {print $5}')
12392
12393         testdir1_size=$(order_2 $testdir1_size)
12394         testdir2_size=$(order_2 $testdir2_size)
12395
12396         testdir1_size=$(size_in_KMGT $testdir1_size)
12397         testdir2_size=$(size_in_KMGT $testdir2_size)
12398
12399         echo "source rename dir size: ${testdir1_size}"
12400         echo "target rename dir size: ${testdir2_size}"
12401
12402         eval $cmd || error "$cmd failed"
12403         local crossdir=$($cmd | grep 'crossdir')
12404         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12405         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12406         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12407         [[ $src_sample -eq 1 ]] ||
12408                 error "crossdir_rename_size error $src_sample"
12409         [[ $tgt_sample -eq 1 ]] ||
12410                 error "crossdir_rename_size error $tgt_sample"
12411         echo "Check cross dir rename stats success"
12412         rm -rf $DIR/${tdir}
12413 }
12414 run_test 133d "Verifying rename_stats ========================================"
12415
12416 test_133e() {
12417         remote_mds_nodsh && skip "remote MDS with nodsh"
12418         remote_ost_nodsh && skip "remote OST with nodsh"
12419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12420
12421         local testdir=$DIR/${tdir}/stats_testdir
12422         local ctr f0 f1 bs=32768 count=42 sum
12423
12424         mkdir -p ${testdir} || error "mkdir failed"
12425
12426         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12427
12428         for ctr in {write,read}_bytes; do
12429                 sync
12430                 cancel_lru_locks osc
12431
12432                 do_facet ost1 $LCTL set_param -n \
12433                         "obdfilter.*.exports.clear=clear"
12434
12435                 if [ $ctr = write_bytes ]; then
12436                         f0=/dev/zero
12437                         f1=${testdir}/${tfile}
12438                 else
12439                         f0=${testdir}/${tfile}
12440                         f1=/dev/null
12441                 fi
12442
12443                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12444                         error "dd failed"
12445                 sync
12446                 cancel_lru_locks osc
12447
12448                 sum=$(do_facet ost1 $LCTL get_param \
12449                         "obdfilter.*.exports.*.stats" |
12450                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12451                                 $1 == ctr { sum += $7 }
12452                                 END { printf("%0.0f", sum) }')
12453
12454                 if ((sum != bs * count)); then
12455                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12456                 fi
12457         done
12458
12459         rm -rf $DIR/${tdir}
12460 }
12461 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12462
12463 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12464
12465 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12466 # not honor the -ignore_readdir_race option correctly. So we call
12467 # error_ignore() rather than error() in these cases. See LU-11152.
12468 error_133() {
12469         if (find --version; do_facet mds1 find --version) |
12470                 grep -q '\b4\.5\.1[1-4]\b'; then
12471                 error_ignore LU-11152 "$@"
12472         else
12473                 error "$@"
12474         fi
12475 }
12476
12477 test_133f() {
12478         # First without trusting modes.
12479         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12480         echo "proc_dirs='$proc_dirs'"
12481         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12482         find $proc_dirs -exec cat '{}' \; &> /dev/null
12483
12484         # Second verifying readability.
12485         $LCTL get_param -R '*' &> /dev/null
12486
12487         # Verifing writability with badarea_io.
12488         find $proc_dirs \
12489                 -ignore_readdir_race \
12490                 -type f \
12491                 -not -name force_lbug \
12492                 -not -name changelog_mask \
12493                 -exec badarea_io '{}' \; ||
12494                         error_133 "find $proc_dirs failed"
12495 }
12496 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12497
12498 test_133g() {
12499         remote_mds_nodsh && skip "remote MDS with nodsh"
12500         remote_ost_nodsh && skip "remote OST with nodsh"
12501
12502         local facet
12503         for facet in mds1 ost1; do
12504                 local facet_ver=$(lustre_version_code $facet)
12505                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
12506                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
12507                 else
12508                         log "$facet: too old lustre for get_param -R"
12509                 fi
12510                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
12511                         do_facet $facet "$LCTL list_param -R '*' | grep '=' |
12512                                 tr -d= | egrep -v 'force_lbug|changelog_mask' |
12513                                 xargs badarea_io" ||
12514                                         error_133 "$facet badarea_io failed"
12515                 else
12516                         skip_noexit "$facet: too old lustre for get_param -R"
12517                 fi
12518         done
12519
12520         # remount the FS in case writes/reads /proc break the FS
12521         cleanup || error "failed to unmount"
12522         setup || error "failed to setup"
12523         true
12524 }
12525 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12526
12527 test_133h() {
12528         remote_mds_nodsh && skip "remote MDS with nodsh"
12529         remote_ost_nodsh && skip "remote OST with nodsh"
12530         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12531                 skip "Need MDS version at least 2.9.54"
12532
12533         local facet
12534
12535         for facet in client mds1 ost1; do
12536                 local facet_proc_dirs=$(do_facet $facet \
12537                                         \\\ls -d $proc_regexp 2> /dev/null)
12538                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12539                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12540                 # Get the list of files that are missing the terminating newline
12541                 local missing=($(do_facet $facet \
12542                         find ${facet_proc_dirs} -type f \|              \
12543                                 while read F\; do                       \
12544                                         awk -v FS='\v' -v RS='\v\v'     \
12545                                         "'END { if(NR>0 &&              \
12546                                         \\\$NF !~ /.*\\\n\$/)           \
12547                                                 print FILENAME}'"       \
12548                                         '\$F'\;                         \
12549                                 done 2>/dev/null))
12550                 [ ${#missing[*]} -eq 0 ] ||
12551                         error "files do not end with newline: ${missing[*]}"
12552         done
12553 }
12554 run_test 133h "Proc files should end with newlines"
12555
12556 test_134a() {
12557         remote_mds_nodsh && skip "remote MDS with nodsh"
12558         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12559                 skip "Need MDS version at least 2.7.54"
12560
12561         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12562         cancel_lru_locks mdc
12563
12564         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12565         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12566         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12567
12568         local nr=1000
12569         createmany -o $DIR/$tdir/f $nr ||
12570                 error "failed to create $nr files in $DIR/$tdir"
12571         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12572
12573         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12574         do_facet mds1 $LCTL set_param fail_loc=0x327
12575         do_facet mds1 $LCTL set_param fail_val=500
12576         touch $DIR/$tdir/m
12577
12578         echo "sleep 10 seconds ..."
12579         sleep 10
12580         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12581
12582         do_facet mds1 $LCTL set_param fail_loc=0
12583         do_facet mds1 $LCTL set_param fail_val=0
12584         [ $lck_cnt -lt $unused ] ||
12585                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12586
12587         rm $DIR/$tdir/m
12588         unlinkmany $DIR/$tdir/f $nr
12589 }
12590 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12591
12592 test_134b() {
12593         remote_mds_nodsh && skip "remote MDS with nodsh"
12594         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12595                 skip "Need MDS version at least 2.7.54"
12596
12597         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12598         cancel_lru_locks mdc
12599
12600         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12601                         ldlm.lock_reclaim_threshold_mb)
12602         # disable reclaim temporarily
12603         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12604
12605         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12606         do_facet mds1 $LCTL set_param fail_loc=0x328
12607         do_facet mds1 $LCTL set_param fail_val=500
12608
12609         $LCTL set_param debug=+trace
12610
12611         local nr=600
12612         createmany -o $DIR/$tdir/f $nr &
12613         local create_pid=$!
12614
12615         echo "Sleep $TIMEOUT seconds ..."
12616         sleep $TIMEOUT
12617         if ! ps -p $create_pid  > /dev/null 2>&1; then
12618                 do_facet mds1 $LCTL set_param fail_loc=0
12619                 do_facet mds1 $LCTL set_param fail_val=0
12620                 do_facet mds1 $LCTL set_param \
12621                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12622                 error "createmany finished incorrectly!"
12623         fi
12624         do_facet mds1 $LCTL set_param fail_loc=0
12625         do_facet mds1 $LCTL set_param fail_val=0
12626         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12627         wait $create_pid || return 1
12628
12629         unlinkmany $DIR/$tdir/f $nr
12630 }
12631 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12632
12633 test_135() {
12634         remote_mds_nodsh && skip "remote MDS with nodsh"
12635         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12636                 skip "Need MDS version at least 2.13.50"
12637         local fname
12638
12639         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12640
12641 #define OBD_FAIL_PLAIN_RECORDS 0x1319
12642         #set only one record at plain llog
12643         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
12644
12645         #fill already existed plain llog each 64767
12646         #wrapping whole catalog
12647         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12648
12649         createmany -o $DIR/$tdir/$tfile_ 64700
12650         for (( i = 0; i < 64700; i = i + 2 ))
12651         do
12652                 rm $DIR/$tdir/$tfile_$i &
12653                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12654                 local pid=$!
12655                 wait $pid
12656         done
12657
12658         #waiting osp synchronization
12659         wait_delete_completed
12660 }
12661 run_test 135 "Race catalog processing"
12662
12663 test_136() {
12664         remote_mds_nodsh && skip "remote MDS with nodsh"
12665         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12666                 skip "Need MDS version at least 2.13.50"
12667         local fname
12668
12669         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12670         $SETSTRIPE -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
12671         #set only one record at plain llog
12672 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
12673         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
12674
12675         #fill already existed 2 plain llogs each 64767
12676         #wrapping whole catalog
12677         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12678         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
12679         wait_delete_completed
12680
12681         createmany -o $DIR/$tdir/$tfile_ 10
12682         sleep 25
12683
12684         do_facet $SINGLEMDS $LCTL set_param fail_val=3
12685         for (( i = 0; i < 10; i = i + 3 ))
12686         do
12687                 rm $DIR/$tdir/$tfile_$i &
12688                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12689                 local pid=$!
12690                 wait $pid
12691                 sleep 7
12692                 rm $DIR/$tdir/$tfile_$((i + 2)) &
12693         done
12694
12695         #waiting osp synchronization
12696         wait_delete_completed
12697 }
12698 run_test 136 "Race catalog processing 2"
12699
12700 test_140() { #bug-17379
12701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12702
12703         test_mkdir $DIR/$tdir
12704         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12705         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12706
12707         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12708         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12709         local i=0
12710         while i=$((i + 1)); do
12711                 test_mkdir $i
12712                 cd $i || error "Changing to $i"
12713                 ln -s ../stat stat || error "Creating stat symlink"
12714                 # Read the symlink until ELOOP present,
12715                 # not LBUGing the system is considered success,
12716                 # we didn't overrun the stack.
12717                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12718                 if [ $ret -ne 0 ]; then
12719                         if [ $ret -eq 40 ]; then
12720                                 break  # -ELOOP
12721                         else
12722                                 error "Open stat symlink"
12723                                         return
12724                         fi
12725                 fi
12726         done
12727         i=$((i - 1))
12728         echo "The symlink depth = $i"
12729         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12730                 error "Invalid symlink depth"
12731
12732         # Test recursive symlink
12733         ln -s symlink_self symlink_self
12734         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12735         echo "open symlink_self returns $ret"
12736         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12737 }
12738 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12739
12740 test_150() {
12741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12742
12743         local TF="$TMP/$tfile"
12744
12745         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12746         cp $TF $DIR/$tfile
12747         cancel_lru_locks $OSC
12748         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12749         remount_client $MOUNT
12750         df -P $MOUNT
12751         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12752
12753         $TRUNCATE $TF 6000
12754         $TRUNCATE $DIR/$tfile 6000
12755         cancel_lru_locks $OSC
12756         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12757
12758         echo "12345" >>$TF
12759         echo "12345" >>$DIR/$tfile
12760         cancel_lru_locks $OSC
12761         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12762
12763         echo "12345" >>$TF
12764         echo "12345" >>$DIR/$tfile
12765         cancel_lru_locks $OSC
12766         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12767
12768         rm -f $TF
12769         true
12770 }
12771 run_test 150 "truncate/append tests"
12772
12773 #LU-2902 roc_hit was not able to read all values from lproc
12774 function roc_hit_init() {
12775         local list=$(comma_list $(osts_nodes))
12776         local dir=$DIR/$tdir-check
12777         local file=$dir/$tfile
12778         local BEFORE
12779         local AFTER
12780         local idx
12781
12782         test_mkdir $dir
12783         #use setstripe to do a write to every ost
12784         for i in $(seq 0 $((OSTCOUNT-1))); do
12785                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12786                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12787                 idx=$(printf %04x $i)
12788                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12789                         awk '$1 == "cache_access" {sum += $7}
12790                                 END { printf("%0.0f", sum) }')
12791
12792                 cancel_lru_locks osc
12793                 cat $file >/dev/null
12794
12795                 AFTER=$(get_osd_param $list *OST*$idx stats |
12796                         awk '$1 == "cache_access" {sum += $7}
12797                                 END { printf("%0.0f", sum) }')
12798
12799                 echo BEFORE:$BEFORE AFTER:$AFTER
12800                 if ! let "AFTER - BEFORE == 4"; then
12801                         rm -rf $dir
12802                         error "roc_hit is not safe to use"
12803                 fi
12804                 rm $file
12805         done
12806
12807         rm -rf $dir
12808 }
12809
12810 function roc_hit() {
12811         local list=$(comma_list $(osts_nodes))
12812         echo $(get_osd_param $list '' stats |
12813                 awk '$1 == "cache_hit" {sum += $7}
12814                         END { printf("%0.0f", sum) }')
12815 }
12816
12817 function set_cache() {
12818         local on=1
12819
12820         if [ "$2" == "off" ]; then
12821                 on=0;
12822         fi
12823         local list=$(comma_list $(osts_nodes))
12824         set_osd_param $list '' $1_cache_enable $on
12825
12826         cancel_lru_locks osc
12827 }
12828
12829 test_151() {
12830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12831         remote_ost_nodsh && skip "remote OST with nodsh"
12832
12833         local CPAGES=3
12834         local list=$(comma_list $(osts_nodes))
12835
12836         # check whether obdfilter is cache capable at all
12837         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12838                 skip "not cache-capable obdfilter"
12839         fi
12840
12841         # check cache is enabled on all obdfilters
12842         if get_osd_param $list '' read_cache_enable | grep 0; then
12843                 skip "oss cache is disabled"
12844         fi
12845
12846         set_osd_param $list '' writethrough_cache_enable 1
12847
12848         # check write cache is enabled on all obdfilters
12849         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12850                 skip "oss write cache is NOT enabled"
12851         fi
12852
12853         roc_hit_init
12854
12855         #define OBD_FAIL_OBD_NO_LRU  0x609
12856         do_nodes $list $LCTL set_param fail_loc=0x609
12857
12858         # pages should be in the case right after write
12859         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12860                 error "dd failed"
12861
12862         local BEFORE=$(roc_hit)
12863         cancel_lru_locks osc
12864         cat $DIR/$tfile >/dev/null
12865         local AFTER=$(roc_hit)
12866
12867         do_nodes $list $LCTL set_param fail_loc=0
12868
12869         if ! let "AFTER - BEFORE == CPAGES"; then
12870                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12871         fi
12872
12873         cancel_lru_locks osc
12874         # invalidates OST cache
12875         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
12876         set_osd_param $list '' read_cache_enable 0
12877         cat $DIR/$tfile >/dev/null
12878
12879         # now data shouldn't be found in the cache
12880         BEFORE=$(roc_hit)
12881         cancel_lru_locks osc
12882         cat $DIR/$tfile >/dev/null
12883         AFTER=$(roc_hit)
12884         if let "AFTER - BEFORE != 0"; then
12885                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12886         fi
12887
12888         set_osd_param $list '' read_cache_enable 1
12889         rm -f $DIR/$tfile
12890 }
12891 run_test 151 "test cache on oss and controls ==============================="
12892
12893 test_152() {
12894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12895
12896         local TF="$TMP/$tfile"
12897
12898         # simulate ENOMEM during write
12899 #define OBD_FAIL_OST_NOMEM      0x226
12900         lctl set_param fail_loc=0x80000226
12901         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12902         cp $TF $DIR/$tfile
12903         sync || error "sync failed"
12904         lctl set_param fail_loc=0
12905
12906         # discard client's cache
12907         cancel_lru_locks osc
12908
12909         # simulate ENOMEM during read
12910         lctl set_param fail_loc=0x80000226
12911         cmp $TF $DIR/$tfile || error "cmp failed"
12912         lctl set_param fail_loc=0
12913
12914         rm -f $TF
12915 }
12916 run_test 152 "test read/write with enomem ============================"
12917
12918 test_153() {
12919         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12920 }
12921 run_test 153 "test if fdatasync does not crash ======================="
12922
12923 dot_lustre_fid_permission_check() {
12924         local fid=$1
12925         local ffid=$MOUNT/.lustre/fid/$fid
12926         local test_dir=$2
12927
12928         echo "stat fid $fid"
12929         stat $ffid > /dev/null || error "stat $ffid failed."
12930         echo "touch fid $fid"
12931         touch $ffid || error "touch $ffid failed."
12932         echo "write to fid $fid"
12933         cat /etc/hosts > $ffid || error "write $ffid failed."
12934         echo "read fid $fid"
12935         diff /etc/hosts $ffid || error "read $ffid failed."
12936         echo "append write to fid $fid"
12937         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12938         echo "rename fid $fid"
12939         mv $ffid $test_dir/$tfile.1 &&
12940                 error "rename $ffid to $tfile.1 should fail."
12941         touch $test_dir/$tfile.1
12942         mv $test_dir/$tfile.1 $ffid &&
12943                 error "rename $tfile.1 to $ffid should fail."
12944         rm -f $test_dir/$tfile.1
12945         echo "truncate fid $fid"
12946         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12947         echo "link fid $fid"
12948         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12949         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12950                 echo "setfacl fid $fid"
12951                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12952                 echo "getfacl fid $fid"
12953                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12954         fi
12955         echo "unlink fid $fid"
12956         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12957         echo "mknod fid $fid"
12958         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12959
12960         fid=[0xf00000400:0x1:0x0]
12961         ffid=$MOUNT/.lustre/fid/$fid
12962
12963         echo "stat non-exist fid $fid"
12964         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12965         echo "write to non-exist fid $fid"
12966         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12967         echo "link new fid $fid"
12968         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12969
12970         mkdir -p $test_dir/$tdir
12971         touch $test_dir/$tdir/$tfile
12972         fid=$($LFS path2fid $test_dir/$tdir)
12973         rc=$?
12974         [ $rc -ne 0 ] &&
12975                 error "error: could not get fid for $test_dir/$dir/$tfile."
12976
12977         ffid=$MOUNT/.lustre/fid/$fid
12978
12979         echo "ls $fid"
12980         ls $ffid > /dev/null || error "ls $ffid failed."
12981         echo "touch $fid/$tfile.1"
12982         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12983
12984         echo "touch $MOUNT/.lustre/fid/$tfile"
12985         touch $MOUNT/.lustre/fid/$tfile && \
12986                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12987
12988         echo "setxattr to $MOUNT/.lustre/fid"
12989         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12990
12991         echo "listxattr for $MOUNT/.lustre/fid"
12992         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12993
12994         echo "delxattr from $MOUNT/.lustre/fid"
12995         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12996
12997         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12998         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12999                 error "touch invalid fid should fail."
13000
13001         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13002         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13003                 error "touch non-normal fid should fail."
13004
13005         echo "rename $tdir to $MOUNT/.lustre/fid"
13006         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13007                 error "rename to $MOUNT/.lustre/fid should fail."
13008
13009         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13010         then            # LU-3547
13011                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13012                 local new_obf_mode=777
13013
13014                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13015                 chmod $new_obf_mode $DIR/.lustre/fid ||
13016                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13017
13018                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13019                 [ $obf_mode -eq $new_obf_mode ] ||
13020                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13021
13022                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13023                 chmod $old_obf_mode $DIR/.lustre/fid ||
13024                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13025         fi
13026
13027         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13028         fid=$($LFS path2fid $test_dir/$tfile-2)
13029
13030         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13031         then # LU-5424
13032                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13033                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13034                         error "create lov data thru .lustre failed"
13035         fi
13036         echo "cp /etc/passwd $test_dir/$tfile-2"
13037         cp /etc/passwd $test_dir/$tfile-2 ||
13038                 error "copy to $test_dir/$tfile-2 failed."
13039         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13040         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13041                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13042
13043         rm -rf $test_dir/tfile.lnk
13044         rm -rf $test_dir/$tfile-2
13045 }
13046
13047 test_154A() {
13048         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13049                 skip "Need MDS version at least 2.4.1"
13050
13051         local tf=$DIR/$tfile
13052         touch $tf
13053
13054         local fid=$($LFS path2fid $tf)
13055         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13056
13057         # check that we get the same pathname back
13058         local found=$($LFS fid2path $MOUNT "$fid")
13059         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13060         [ "$found" == "$tf" ] ||
13061                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13062 }
13063 run_test 154A "lfs path2fid and fid2path basic checks"
13064
13065 test_154B() {
13066         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13067                 skip "Need MDS version at least 2.4.1"
13068
13069         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13070         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13071         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13072         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13073
13074         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13075         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13076
13077         # check that we get the same pathname
13078         echo "PFID: $PFID, name: $name"
13079         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13080         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13081         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13082                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13083
13084         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13085 }
13086 run_test 154B "verify the ll_decode_linkea tool"
13087
13088 test_154a() {
13089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13090         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13091         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13092                 skip "Need MDS version at least 2.2.51"
13093         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13094
13095         cp /etc/hosts $DIR/$tfile
13096
13097         fid=$($LFS path2fid $DIR/$tfile)
13098         rc=$?
13099         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13100
13101         dot_lustre_fid_permission_check "$fid" $DIR ||
13102                 error "dot lustre permission check $fid failed"
13103
13104         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13105
13106         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13107
13108         touch $MOUNT/.lustre/file &&
13109                 error "creation is not allowed under .lustre"
13110
13111         mkdir $MOUNT/.lustre/dir &&
13112                 error "mkdir is not allowed under .lustre"
13113
13114         rm -rf $DIR/$tfile
13115 }
13116 run_test 154a "Open-by-FID"
13117
13118 test_154b() {
13119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13120         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13122         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13123                 skip "Need MDS version at least 2.2.51"
13124
13125         local remote_dir=$DIR/$tdir/remote_dir
13126         local MDTIDX=1
13127         local rc=0
13128
13129         mkdir -p $DIR/$tdir
13130         $LFS mkdir -i $MDTIDX $remote_dir ||
13131                 error "create remote directory failed"
13132
13133         cp /etc/hosts $remote_dir/$tfile
13134
13135         fid=$($LFS path2fid $remote_dir/$tfile)
13136         rc=$?
13137         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13138
13139         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13140                 error "dot lustre permission check $fid failed"
13141         rm -rf $DIR/$tdir
13142 }
13143 run_test 154b "Open-by-FID for remote directory"
13144
13145 test_154c() {
13146         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13147                 skip "Need MDS version at least 2.4.1"
13148
13149         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13150         local FID1=$($LFS path2fid $DIR/$tfile.1)
13151         local FID2=$($LFS path2fid $DIR/$tfile.2)
13152         local FID3=$($LFS path2fid $DIR/$tfile.3)
13153
13154         local N=1
13155         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13156                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13157                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13158                 local want=FID$N
13159                 [ "$FID" = "${!want}" ] ||
13160                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13161                 N=$((N + 1))
13162         done
13163
13164         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13165         do
13166                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13167                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13168                 N=$((N + 1))
13169         done
13170 }
13171 run_test 154c "lfs path2fid and fid2path multiple arguments"
13172
13173 test_154d() {
13174         remote_mds_nodsh && skip "remote MDS with nodsh"
13175         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13176                 skip "Need MDS version at least 2.5.53"
13177
13178         if remote_mds; then
13179                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13180         else
13181                 nid="0@lo"
13182         fi
13183         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13184         local fd
13185         local cmd
13186
13187         rm -f $DIR/$tfile
13188         touch $DIR/$tfile
13189
13190         local fid=$($LFS path2fid $DIR/$tfile)
13191         # Open the file
13192         fd=$(free_fd)
13193         cmd="exec $fd<$DIR/$tfile"
13194         eval $cmd
13195         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13196         echo "$fid_list" | grep "$fid"
13197         rc=$?
13198
13199         cmd="exec $fd>/dev/null"
13200         eval $cmd
13201         if [ $rc -ne 0 ]; then
13202                 error "FID $fid not found in open files list $fid_list"
13203         fi
13204 }
13205 run_test 154d "Verify open file fid"
13206
13207 test_154e()
13208 {
13209         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13210                 skip "Need MDS version at least 2.6.50"
13211
13212         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13213                 error ".lustre returned by readdir"
13214         fi
13215 }
13216 run_test 154e ".lustre is not returned by readdir"
13217
13218 test_154f() {
13219         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13220
13221         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13222         test_mkdir -p -c1 $DIR/$tdir/d
13223         # test dirs inherit from its stripe
13224         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13225         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13226         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13227         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13228         touch $DIR/f
13229
13230         # get fid of parents
13231         local FID0=$($LFS path2fid $DIR/$tdir/d)
13232         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13233         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13234         local FID3=$($LFS path2fid $DIR)
13235
13236         # check that path2fid --parents returns expected <parent_fid>/name
13237         # 1) test for a directory (single parent)
13238         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13239         [ "$parent" == "$FID0/foo1" ] ||
13240                 error "expected parent: $FID0/foo1, got: $parent"
13241
13242         # 2) test for a file with nlink > 1 (multiple parents)
13243         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13244         echo "$parent" | grep -F "$FID1/$tfile" ||
13245                 error "$FID1/$tfile not returned in parent list"
13246         echo "$parent" | grep -F "$FID2/link" ||
13247                 error "$FID2/link not returned in parent list"
13248
13249         # 3) get parent by fid
13250         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13251         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13252         echo "$parent" | grep -F "$FID1/$tfile" ||
13253                 error "$FID1/$tfile not returned in parent list (by fid)"
13254         echo "$parent" | grep -F "$FID2/link" ||
13255                 error "$FID2/link not returned in parent list (by fid)"
13256
13257         # 4) test for entry in root directory
13258         parent=$($LFS path2fid --parents $DIR/f)
13259         echo "$parent" | grep -F "$FID3/f" ||
13260                 error "$FID3/f not returned in parent list"
13261
13262         # 5) test it on root directory
13263         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13264                 error "$MOUNT should not have parents"
13265
13266         # enable xattr caching and check that linkea is correctly updated
13267         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13268         save_lustre_params client "llite.*.xattr_cache" > $save
13269         lctl set_param llite.*.xattr_cache 1
13270
13271         # 6.1) linkea update on rename
13272         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13273
13274         # get parents by fid
13275         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13276         # foo1 should no longer be returned in parent list
13277         echo "$parent" | grep -F "$FID1" &&
13278                 error "$FID1 should no longer be in parent list"
13279         # the new path should appear
13280         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13281                 error "$FID2/$tfile.moved is not in parent list"
13282
13283         # 6.2) linkea update on unlink
13284         rm -f $DIR/$tdir/d/foo2/link
13285         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13286         # foo2/link should no longer be returned in parent list
13287         echo "$parent" | grep -F "$FID2/link" &&
13288                 error "$FID2/link should no longer be in parent list"
13289         true
13290
13291         rm -f $DIR/f
13292         restore_lustre_params < $save
13293         rm -f $save
13294 }
13295 run_test 154f "get parent fids by reading link ea"
13296
13297 test_154g()
13298 {
13299         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13300         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13301            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13302                 skip "Need MDS version at least 2.6.92"
13303
13304         mkdir -p $DIR/$tdir
13305         llapi_fid_test -d $DIR/$tdir
13306 }
13307 run_test 154g "various llapi FID tests"
13308
13309 test_155_small_load() {
13310     local temp=$TMP/$tfile
13311     local file=$DIR/$tfile
13312
13313     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13314         error "dd of=$temp bs=6096 count=1 failed"
13315     cp $temp $file
13316     cancel_lru_locks $OSC
13317     cmp $temp $file || error "$temp $file differ"
13318
13319     $TRUNCATE $temp 6000
13320     $TRUNCATE $file 6000
13321     cmp $temp $file || error "$temp $file differ (truncate1)"
13322
13323     echo "12345" >>$temp
13324     echo "12345" >>$file
13325     cmp $temp $file || error "$temp $file differ (append1)"
13326
13327     echo "12345" >>$temp
13328     echo "12345" >>$file
13329     cmp $temp $file || error "$temp $file differ (append2)"
13330
13331     rm -f $temp $file
13332     true
13333 }
13334
13335 test_155_big_load() {
13336         remote_ost_nodsh && skip "remote OST with nodsh"
13337
13338         local temp=$TMP/$tfile
13339         local file=$DIR/$tfile
13340
13341         free_min_max
13342         local cache_size=$(do_facet ost$((MAXI+1)) \
13343                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13344         local large_file_size=$((cache_size * 2))
13345
13346         echo "OSS cache size: $cache_size KB"
13347         echo "Large file size: $large_file_size KB"
13348
13349         [ $MAXV -le $large_file_size ] &&
13350                 skip_env "max available OST size needs > $large_file_size KB"
13351
13352         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13353
13354         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13355                 error "dd of=$temp bs=$large_file_size count=1k failed"
13356         cp $temp $file
13357         ls -lh $temp $file
13358         cancel_lru_locks osc
13359         cmp $temp $file || error "$temp $file differ"
13360
13361         rm -f $temp $file
13362         true
13363 }
13364
13365 save_writethrough() {
13366         local facets=$(get_facets OST)
13367
13368         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13369 }
13370
13371 test_155a() {
13372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13373
13374         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13375
13376         save_writethrough $p
13377
13378         set_cache read on
13379         set_cache writethrough on
13380         test_155_small_load
13381         restore_lustre_params < $p
13382         rm -f $p
13383 }
13384 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13385
13386 test_155b() {
13387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13388
13389         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13390
13391         save_writethrough $p
13392
13393         set_cache read on
13394         set_cache writethrough off
13395         test_155_small_load
13396         restore_lustre_params < $p
13397         rm -f $p
13398 }
13399 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13400
13401 test_155c() {
13402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13403
13404         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13405
13406         save_writethrough $p
13407
13408         set_cache read off
13409         set_cache writethrough on
13410         test_155_small_load
13411         restore_lustre_params < $p
13412         rm -f $p
13413 }
13414 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13415
13416 test_155d() {
13417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13418
13419         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13420
13421         save_writethrough $p
13422
13423         set_cache read off
13424         set_cache writethrough off
13425         test_155_small_load
13426         restore_lustre_params < $p
13427         rm -f $p
13428 }
13429 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13430
13431 test_155e() {
13432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13433
13434         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13435
13436         save_writethrough $p
13437
13438         set_cache read on
13439         set_cache writethrough on
13440         test_155_big_load
13441         restore_lustre_params < $p
13442         rm -f $p
13443 }
13444 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13445
13446 test_155f() {
13447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13448
13449         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13450
13451         save_writethrough $p
13452
13453         set_cache read on
13454         set_cache writethrough off
13455         test_155_big_load
13456         restore_lustre_params < $p
13457         rm -f $p
13458 }
13459 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13460
13461 test_155g() {
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463
13464         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13465
13466         save_writethrough $p
13467
13468         set_cache read off
13469         set_cache writethrough on
13470         test_155_big_load
13471         restore_lustre_params < $p
13472         rm -f $p
13473 }
13474 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13475
13476 test_155h() {
13477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13478
13479         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13480
13481         save_writethrough $p
13482
13483         set_cache read off
13484         set_cache writethrough off
13485         test_155_big_load
13486         restore_lustre_params < $p
13487         rm -f $p
13488 }
13489 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13490
13491 test_156() {
13492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13493         remote_ost_nodsh && skip "remote OST with nodsh"
13494         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13495                 skip "stats not implemented on old servers"
13496         [ "$ost1_FSTYPE" = "zfs" ] &&
13497                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13498
13499         local CPAGES=3
13500         local BEFORE
13501         local AFTER
13502         local file="$DIR/$tfile"
13503         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13504
13505         save_writethrough $p
13506         roc_hit_init
13507
13508         log "Turn on read and write cache"
13509         set_cache read on
13510         set_cache writethrough on
13511
13512         log "Write data and read it back."
13513         log "Read should be satisfied from the cache."
13514         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13515         BEFORE=$(roc_hit)
13516         cancel_lru_locks osc
13517         cat $file >/dev/null
13518         AFTER=$(roc_hit)
13519         if ! let "AFTER - BEFORE == CPAGES"; then
13520                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13521         else
13522                 log "cache hits: before: $BEFORE, after: $AFTER"
13523         fi
13524
13525         log "Read again; it should be satisfied from the cache."
13526         BEFORE=$AFTER
13527         cancel_lru_locks osc
13528         cat $file >/dev/null
13529         AFTER=$(roc_hit)
13530         if ! let "AFTER - BEFORE == CPAGES"; then
13531                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13532         else
13533                 log "cache hits:: before: $BEFORE, after: $AFTER"
13534         fi
13535
13536         log "Turn off the read cache and turn on the write cache"
13537         set_cache read off
13538         set_cache writethrough on
13539
13540         log "Read again; it should be satisfied from the cache."
13541         BEFORE=$(roc_hit)
13542         cancel_lru_locks osc
13543         cat $file >/dev/null
13544         AFTER=$(roc_hit)
13545         if ! let "AFTER - BEFORE == CPAGES"; then
13546                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13547         else
13548                 log "cache hits:: before: $BEFORE, after: $AFTER"
13549         fi
13550
13551         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13552                 # > 2.12.56 uses pagecache if cached
13553                 log "Read again; it should not be satisfied from the cache."
13554                 BEFORE=$AFTER
13555                 cancel_lru_locks osc
13556                 cat $file >/dev/null
13557                 AFTER=$(roc_hit)
13558                 if ! let "AFTER - BEFORE == 0"; then
13559                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13560                 else
13561                         log "cache hits:: before: $BEFORE, after: $AFTER"
13562                 fi
13563         fi
13564
13565         log "Write data and read it back."
13566         log "Read should be satisfied from the cache."
13567         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13568         BEFORE=$(roc_hit)
13569         cancel_lru_locks osc
13570         cat $file >/dev/null
13571         AFTER=$(roc_hit)
13572         if ! let "AFTER - BEFORE == CPAGES"; then
13573                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13574         else
13575                 log "cache hits:: before: $BEFORE, after: $AFTER"
13576         fi
13577
13578         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13579                 # > 2.12.56 uses pagecache if cached
13580                 log "Read again; it should not be satisfied from the cache."
13581                 BEFORE=$AFTER
13582                 cancel_lru_locks osc
13583                 cat $file >/dev/null
13584                 AFTER=$(roc_hit)
13585                 if ! let "AFTER - BEFORE == 0"; then
13586                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13587                 else
13588                         log "cache hits:: before: $BEFORE, after: $AFTER"
13589                 fi
13590         fi
13591
13592         log "Turn off read and write cache"
13593         set_cache read off
13594         set_cache writethrough off
13595
13596         log "Write data and read it back"
13597         log "It should not be satisfied from the cache."
13598         rm -f $file
13599         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13600         cancel_lru_locks osc
13601         BEFORE=$(roc_hit)
13602         cat $file >/dev/null
13603         AFTER=$(roc_hit)
13604         if ! let "AFTER - BEFORE == 0"; then
13605                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13606         else
13607                 log "cache hits:: before: $BEFORE, after: $AFTER"
13608         fi
13609
13610         log "Turn on the read cache and turn off the write cache"
13611         set_cache read on
13612         set_cache writethrough off
13613
13614         log "Write data and read it back"
13615         log "It should not be satisfied from the cache."
13616         rm -f $file
13617         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13618         BEFORE=$(roc_hit)
13619         cancel_lru_locks osc
13620         cat $file >/dev/null
13621         AFTER=$(roc_hit)
13622         if ! let "AFTER - BEFORE == 0"; then
13623                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13624         else
13625                 log "cache hits:: before: $BEFORE, after: $AFTER"
13626         fi
13627
13628         log "Read again; it should be satisfied from the cache."
13629         BEFORE=$(roc_hit)
13630         cancel_lru_locks osc
13631         cat $file >/dev/null
13632         AFTER=$(roc_hit)
13633         if ! let "AFTER - BEFORE == CPAGES"; then
13634                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13635         else
13636                 log "cache hits:: before: $BEFORE, after: $AFTER"
13637         fi
13638
13639         restore_lustre_params < $p
13640         rm -f $p $file
13641 }
13642 run_test 156 "Verification of tunables"
13643
13644 test_160a() {
13645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13646         remote_mds_nodsh && skip "remote MDS with nodsh"
13647         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13648                 skip "Need MDS version at least 2.2.0"
13649
13650         changelog_register || error "changelog_register failed"
13651         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13652         changelog_users $SINGLEMDS | grep -q $cl_user ||
13653                 error "User $cl_user not found in changelog_users"
13654
13655         # change something
13656         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13657         changelog_clear 0 || error "changelog_clear failed"
13658         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13659         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13660         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13661         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13662         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13663         rm $DIR/$tdir/pics/desktop.jpg
13664
13665         changelog_dump | tail -10
13666
13667         echo "verifying changelog mask"
13668         changelog_chmask "-MKDIR"
13669         changelog_chmask "-CLOSE"
13670
13671         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13672         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13673
13674         changelog_chmask "+MKDIR"
13675         changelog_chmask "+CLOSE"
13676
13677         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13678         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13679
13680         changelog_dump | tail -10
13681         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13682         CLOSES=$(changelog_dump | grep -c "CLOSE")
13683         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13684         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13685
13686         # verify contents
13687         echo "verifying target fid"
13688         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13689         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13690         [ "$fidc" == "$fidf" ] ||
13691                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13692         echo "verifying parent fid"
13693         # The FID returned from the Changelog may be the directory shard on
13694         # a different MDT, and not the FID returned by path2fid on the parent.
13695         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13696         # since this is what will matter when recreating this file in the tree.
13697         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13698         local pathp=$($LFS fid2path $MOUNT "$fidp")
13699         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13700                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13701
13702         echo "getting records for $cl_user"
13703         changelog_users $SINGLEMDS
13704         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13705         local nclr=3
13706         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13707                 error "changelog_clear failed"
13708         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13709         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13710         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13711                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13712
13713         local min0_rec=$(changelog_users $SINGLEMDS |
13714                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13715         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13716                           awk '{ print $1; exit; }')
13717
13718         changelog_dump | tail -n 5
13719         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13720         [ $first_rec == $((min0_rec + 1)) ] ||
13721                 error "first index should be $min0_rec + 1 not $first_rec"
13722
13723         # LU-3446 changelog index reset on MDT restart
13724         local cur_rec1=$(changelog_users $SINGLEMDS |
13725                          awk '/^current.index:/ { print $NF }')
13726         changelog_clear 0 ||
13727                 error "clear all changelog records for $cl_user failed"
13728         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13729         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13730                 error "Fail to start $SINGLEMDS"
13731         local cur_rec2=$(changelog_users $SINGLEMDS |
13732                          awk '/^current.index:/ { print $NF }')
13733         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13734         [ $cur_rec1 == $cur_rec2 ] ||
13735                 error "current index should be $cur_rec1 not $cur_rec2"
13736
13737         echo "verifying users from this test are deregistered"
13738         changelog_deregister || error "changelog_deregister failed"
13739         changelog_users $SINGLEMDS | grep -q $cl_user &&
13740                 error "User '$cl_user' still in changelog_users"
13741
13742         # lctl get_param -n mdd.*.changelog_users
13743         # current index: 144
13744         # ID    index (idle seconds)
13745         # cl3   144 (2)
13746         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13747                 # this is the normal case where all users were deregistered
13748                 # make sure no new records are added when no users are present
13749                 local last_rec1=$(changelog_users $SINGLEMDS |
13750                                   awk '/^current.index:/ { print $NF }')
13751                 touch $DIR/$tdir/chloe
13752                 local last_rec2=$(changelog_users $SINGLEMDS |
13753                                   awk '/^current.index:/ { print $NF }')
13754                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13755                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13756         else
13757                 # any changelog users must be leftovers from a previous test
13758                 changelog_users $SINGLEMDS
13759                 echo "other changelog users; can't verify off"
13760         fi
13761 }
13762 run_test 160a "changelog sanity"
13763
13764 test_160b() { # LU-3587
13765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13766         remote_mds_nodsh && skip "remote MDS with nodsh"
13767         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13768                 skip "Need MDS version at least 2.2.0"
13769
13770         changelog_register || error "changelog_register failed"
13771         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13772         changelog_users $SINGLEMDS | grep -q $cl_user ||
13773                 error "User '$cl_user' not found in changelog_users"
13774
13775         local longname1=$(str_repeat a 255)
13776         local longname2=$(str_repeat b 255)
13777
13778         cd $DIR
13779         echo "creating very long named file"
13780         touch $longname1 || error "create of '$longname1' failed"
13781         echo "renaming very long named file"
13782         mv $longname1 $longname2
13783
13784         changelog_dump | grep RENME | tail -n 5
13785         rm -f $longname2
13786 }
13787 run_test 160b "Verify that very long rename doesn't crash in changelog"
13788
13789 test_160c() {
13790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13791         remote_mds_nodsh && skip "remote MDS with nodsh"
13792
13793         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13794                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13795                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13796                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13797
13798         local rc=0
13799
13800         # Registration step
13801         changelog_register || error "changelog_register failed"
13802
13803         rm -rf $DIR/$tdir
13804         mkdir -p $DIR/$tdir
13805         $MCREATE $DIR/$tdir/foo_160c
13806         changelog_chmask "-TRUNC"
13807         $TRUNCATE $DIR/$tdir/foo_160c 200
13808         changelog_chmask "+TRUNC"
13809         $TRUNCATE $DIR/$tdir/foo_160c 199
13810         changelog_dump | tail -n 5
13811         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13812         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13813 }
13814 run_test 160c "verify that changelog log catch the truncate event"
13815
13816 test_160d() {
13817         remote_mds_nodsh && skip "remote MDS with nodsh"
13818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13820         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13821                 skip "Need MDS version at least 2.7.60"
13822
13823         # Registration step
13824         changelog_register || error "changelog_register failed"
13825
13826         mkdir -p $DIR/$tdir/migrate_dir
13827         changelog_clear 0 || error "changelog_clear failed"
13828
13829         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13830         changelog_dump | tail -n 5
13831         local migrates=$(changelog_dump | grep -c "MIGRT")
13832         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13833 }
13834 run_test 160d "verify that changelog log catch the migrate event"
13835
13836 test_160e() {
13837         remote_mds_nodsh && skip "remote MDS with nodsh"
13838
13839         # Create a user
13840         changelog_register || error "changelog_register failed"
13841
13842         # Delete a future user (expect fail)
13843         local MDT0=$(facet_svc $SINGLEMDS)
13844         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13845         local rc=$?
13846
13847         if [ $rc -eq 0 ]; then
13848                 error "Deleted non-existant user cl77"
13849         elif [ $rc -ne 2 ]; then
13850                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13851         fi
13852
13853         # Clear to a bad index (1 billion should be safe)
13854         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13855         rc=$?
13856
13857         if [ $rc -eq 0 ]; then
13858                 error "Successfully cleared to invalid CL index"
13859         elif [ $rc -ne 22 ]; then
13860                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13861         fi
13862 }
13863 run_test 160e "changelog negative testing (should return errors)"
13864
13865 test_160f() {
13866         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13867         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13868                 skip "Need MDS version at least 2.10.56"
13869
13870         local mdts=$(comma_list $(mdts_nodes))
13871
13872         # Create a user
13873         changelog_register || error "first changelog_register failed"
13874         changelog_register || error "second changelog_register failed"
13875         local cl_users
13876         declare -A cl_user1
13877         declare -A cl_user2
13878         local user_rec1
13879         local user_rec2
13880         local i
13881
13882         # generate some changelog records to accumulate on each MDT
13883         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13884         log "$(date +%s): creating first files"
13885         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13886                 error "create $DIR/$tdir/$tfile failed"
13887
13888         # check changelogs have been generated
13889         local start=$SECONDS
13890         local idle_time=$((MDSCOUNT * 5 + 5))
13891         local nbcl=$(changelog_dump | wc -l)
13892         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13893
13894         for param in "changelog_max_idle_time=$idle_time" \
13895                      "changelog_gc=1" \
13896                      "changelog_min_gc_interval=2" \
13897                      "changelog_min_free_cat_entries=3"; do
13898                 local MDT0=$(facet_svc $SINGLEMDS)
13899                 local var="${param%=*}"
13900                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13901
13902                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13903                 do_nodes $mdts $LCTL set_param mdd.*.$param
13904         done
13905
13906         # force cl_user2 to be idle (1st part), but also cancel the
13907         # cl_user1 records so that it is not evicted later in the test.
13908         local sleep1=$((idle_time / 2))
13909         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
13910         sleep $sleep1
13911
13912         # simulate changelog catalog almost full
13913         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13914         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13915
13916         for i in $(seq $MDSCOUNT); do
13917                 cl_users=(${CL_USERS[mds$i]})
13918                 cl_user1[mds$i]="${cl_users[0]}"
13919                 cl_user2[mds$i]="${cl_users[1]}"
13920
13921                 [ -n "${cl_user1[mds$i]}" ] ||
13922                         error "mds$i: no user registered"
13923                 [ -n "${cl_user2[mds$i]}" ] ||
13924                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13925
13926                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13927                 [ -n "$user_rec1" ] ||
13928                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13929                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13930                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13931                 [ -n "$user_rec2" ] ||
13932                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13933                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13934                      "$user_rec1 + 2 == $user_rec2"
13935                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13936                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13937                               "$user_rec1 + 2, but is $user_rec2"
13938                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13939                 [ -n "$user_rec2" ] ||
13940                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13941                 [ $user_rec1 == $user_rec2 ] ||
13942                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13943                               "$user_rec1, but is $user_rec2"
13944         done
13945
13946         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
13947         local sleep2=$((idle_time - (SECONDS - start) + 1))
13948         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
13949         sleep $sleep2
13950
13951         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
13952         # cl_user1 should be OK because it recently processed records.
13953         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
13954         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
13955                 error "create $DIR/$tdir/${tfile}b failed"
13956
13957         # ensure gc thread is done
13958         for i in $(mdts_nodes); do
13959                 wait_update $i \
13960                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13961                         error "$i: GC-thread not done"
13962         done
13963
13964         local first_rec
13965         for i in $(seq $MDSCOUNT); do
13966                 # check cl_user1 still registered
13967                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13968                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13969                 # check cl_user2 unregistered
13970                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13971                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13972
13973                 # check changelogs are present and starting at $user_rec1 + 1
13974                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13975                 [ -n "$user_rec1" ] ||
13976                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13977                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13978                             awk '{ print $1; exit; }')
13979
13980                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13981                 [ $((user_rec1 + 1)) == $first_rec ] ||
13982                         error "mds$i: first index should be $user_rec1 + 1, " \
13983                               "but is $first_rec"
13984         done
13985 }
13986 run_test 160f "changelog garbage collect (timestamped users)"
13987
13988 test_160g() {
13989         remote_mds_nodsh && skip "remote MDS with nodsh"
13990         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13991                 skip "Need MDS version at least 2.10.56"
13992
13993         local mdts=$(comma_list $(mdts_nodes))
13994
13995         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13996         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13997
13998         # Create a user
13999         changelog_register || error "first changelog_register failed"
14000         changelog_register || error "second changelog_register failed"
14001         local cl_users
14002         declare -A cl_user1
14003         declare -A cl_user2
14004         local user_rec1
14005         local user_rec2
14006         local i
14007
14008         # generate some changelog records to accumulate on each MDT
14009         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14010         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14011                 error "create $DIR/$tdir/$tfile failed"
14012
14013         # check changelogs have been generated
14014         local nbcl=$(changelog_dump | wc -l)
14015         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14016
14017         # reduce the max_idle_indexes value to make sure we exceed it
14018         max_ndx=$((nbcl / 2 - 1))
14019
14020         for param in "changelog_max_idle_indexes=$max_ndx" \
14021                      "changelog_gc=1" \
14022                      "changelog_min_gc_interval=2" \
14023                      "changelog_min_free_cat_entries=3"; do
14024                 local MDT0=$(facet_svc $SINGLEMDS)
14025                 local var="${param%=*}"
14026                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14027
14028                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14029                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14030                         error "unable to set mdd.*.$param"
14031         done
14032
14033         # simulate changelog catalog almost full
14034         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14035         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14036
14037         for i in $(seq $MDSCOUNT); do
14038                 cl_users=(${CL_USERS[mds$i]})
14039                 cl_user1[mds$i]="${cl_users[0]}"
14040                 cl_user2[mds$i]="${cl_users[1]}"
14041
14042                 [ -n "${cl_user1[mds$i]}" ] ||
14043                         error "mds$i: no user registered"
14044                 [ -n "${cl_user2[mds$i]}" ] ||
14045                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14046
14047                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14048                 [ -n "$user_rec1" ] ||
14049                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14050                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14051                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14052                 [ -n "$user_rec2" ] ||
14053                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14054                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14055                      "$user_rec1 + 2 == $user_rec2"
14056                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14057                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14058                               "$user_rec1 + 2, but is $user_rec2"
14059                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14060                 [ -n "$user_rec2" ] ||
14061                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14062                 [ $user_rec1 == $user_rec2 ] ||
14063                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14064                               "$user_rec1, but is $user_rec2"
14065         done
14066
14067         # ensure we are past the previous changelog_min_gc_interval set above
14068         sleep 2
14069
14070         # generate one more changelog to trigger fail_loc
14071         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14072                 error "create $DIR/$tdir/${tfile}bis failed"
14073
14074         # ensure gc thread is done
14075         for i in $(mdts_nodes); do
14076                 wait_update $i \
14077                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14078                         error "$i: GC-thread not done"
14079         done
14080
14081         local first_rec
14082         for i in $(seq $MDSCOUNT); do
14083                 # check cl_user1 still registered
14084                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14085                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14086                 # check cl_user2 unregistered
14087                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14088                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14089
14090                 # check changelogs are present and starting at $user_rec1 + 1
14091                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14092                 [ -n "$user_rec1" ] ||
14093                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14094                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14095                             awk '{ print $1; exit; }')
14096
14097                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14098                 [ $((user_rec1 + 1)) == $first_rec ] ||
14099                         error "mds$i: first index should be $user_rec1 + 1, " \
14100                               "but is $first_rec"
14101         done
14102 }
14103 run_test 160g "changelog garbage collect (old users)"
14104
14105 test_160h() {
14106         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14107         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14108                 skip "Need MDS version at least 2.10.56"
14109
14110         local mdts=$(comma_list $(mdts_nodes))
14111
14112         # Create a user
14113         changelog_register || error "first changelog_register failed"
14114         changelog_register || error "second changelog_register failed"
14115         local cl_users
14116         declare -A cl_user1
14117         declare -A cl_user2
14118         local user_rec1
14119         local user_rec2
14120         local i
14121
14122         # generate some changelog records to accumulate on each MDT
14123         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
14124         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14125                 error "create $DIR/$tdir/$tfile failed"
14126
14127         # check changelogs have been generated
14128         local nbcl=$(changelog_dump | wc -l)
14129         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14130
14131         for param in "changelog_max_idle_time=10" \
14132                      "changelog_gc=1" \
14133                      "changelog_min_gc_interval=2"; do
14134                 local MDT0=$(facet_svc $SINGLEMDS)
14135                 local var="${param%=*}"
14136                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14137
14138                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14139                 do_nodes $mdts $LCTL set_param mdd.*.$param
14140         done
14141
14142         # force cl_user2 to be idle (1st part)
14143         sleep 9
14144
14145         for i in $(seq $MDSCOUNT); do
14146                 cl_users=(${CL_USERS[mds$i]})
14147                 cl_user1[mds$i]="${cl_users[0]}"
14148                 cl_user2[mds$i]="${cl_users[1]}"
14149
14150                 [ -n "${cl_user1[mds$i]}" ] ||
14151                         error "mds$i: no user registered"
14152                 [ -n "${cl_user2[mds$i]}" ] ||
14153                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14154
14155                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14156                 [ -n "$user_rec1" ] ||
14157                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14158                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14159                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14160                 [ -n "$user_rec2" ] ||
14161                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14162                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14163                      "$user_rec1 + 2 == $user_rec2"
14164                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14165                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14166                               "$user_rec1 + 2, but is $user_rec2"
14167                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14168                 [ -n "$user_rec2" ] ||
14169                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14170                 [ $user_rec1 == $user_rec2 ] ||
14171                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14172                               "$user_rec1, but is $user_rec2"
14173         done
14174
14175         # force cl_user2 to be idle (2nd part) and to reach
14176         # changelog_max_idle_time
14177         sleep 2
14178
14179         # force each GC-thread start and block then
14180         # one per MDT/MDD, set fail_val accordingly
14181         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14182         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14183
14184         # generate more changelogs to trigger fail_loc
14185         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14186                 error "create $DIR/$tdir/${tfile}bis failed"
14187
14188         # stop MDT to stop GC-thread, should be done in back-ground as it will
14189         # block waiting for the thread to be released and exit
14190         declare -A stop_pids
14191         for i in $(seq $MDSCOUNT); do
14192                 stop mds$i &
14193                 stop_pids[mds$i]=$!
14194         done
14195
14196         for i in $(mdts_nodes); do
14197                 local facet
14198                 local nb=0
14199                 local facets=$(facets_up_on_host $i)
14200
14201                 for facet in ${facets//,/ }; do
14202                         if [[ $facet == mds* ]]; then
14203                                 nb=$((nb + 1))
14204                         fi
14205                 done
14206                 # ensure each MDS's gc threads are still present and all in "R"
14207                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14208                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14209                         error "$i: expected $nb GC-thread"
14210                 wait_update $i \
14211                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14212                         "R" 20 ||
14213                         error "$i: GC-thread not found in R-state"
14214                 # check umounts of each MDT on MDS have reached kthread_stop()
14215                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14216                         error "$i: expected $nb umount"
14217                 wait_update $i \
14218                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14219                         error "$i: umount not found in D-state"
14220         done
14221
14222         # release all GC-threads
14223         do_nodes $mdts $LCTL set_param fail_loc=0
14224
14225         # wait for MDT stop to complete
14226         for i in $(seq $MDSCOUNT); do
14227                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14228         done
14229
14230         # XXX
14231         # may try to check if any orphan changelog records are present
14232         # via ldiskfs/zfs and llog_reader...
14233
14234         # re-start/mount MDTs
14235         for i in $(seq $MDSCOUNT); do
14236                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14237                         error "Fail to start mds$i"
14238         done
14239
14240         local first_rec
14241         for i in $(seq $MDSCOUNT); do
14242                 # check cl_user1 still registered
14243                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14244                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14245                 # check cl_user2 unregistered
14246                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14247                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14248
14249                 # check changelogs are present and starting at $user_rec1 + 1
14250                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14251                 [ -n "$user_rec1" ] ||
14252                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14253                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14254                             awk '{ print $1; exit; }')
14255
14256                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14257                 [ $((user_rec1 + 1)) == $first_rec ] ||
14258                         error "mds$i: first index should be $user_rec1 + 1, " \
14259                               "but is $first_rec"
14260         done
14261 }
14262 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14263               "during mount"
14264
14265 test_160i() {
14266
14267         local mdts=$(comma_list $(mdts_nodes))
14268
14269         changelog_register || error "first changelog_register failed"
14270
14271         # generate some changelog records to accumulate on each MDT
14272         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14273         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14274                 error "create $DIR/$tdir/$tfile failed"
14275
14276         # check changelogs have been generated
14277         local nbcl=$(changelog_dump | wc -l)
14278         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14279
14280         # simulate race between register and unregister
14281         # XXX as fail_loc is set per-MDS, with DNE configs the race
14282         # simulation will only occur for one MDT per MDS and for the
14283         # others the normal race scenario will take place
14284         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14285         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14286         do_nodes $mdts $LCTL set_param fail_val=1
14287
14288         # unregister 1st user
14289         changelog_deregister &
14290         local pid1=$!
14291         # wait some time for deregister work to reach race rdv
14292         sleep 2
14293         # register 2nd user
14294         changelog_register || error "2nd user register failed"
14295
14296         wait $pid1 || error "1st user deregister failed"
14297
14298         local i
14299         local last_rec
14300         declare -A LAST_REC
14301         for i in $(seq $MDSCOUNT); do
14302                 if changelog_users mds$i | grep "^cl"; then
14303                         # make sure new records are added with one user present
14304                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14305                                           awk '/^current.index:/ { print $NF }')
14306                 else
14307                         error "mds$i has no user registered"
14308                 fi
14309         done
14310
14311         # generate more changelog records to accumulate on each MDT
14312         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14313                 error "create $DIR/$tdir/${tfile}bis failed"
14314
14315         for i in $(seq $MDSCOUNT); do
14316                 last_rec=$(changelog_users $SINGLEMDS |
14317                            awk '/^current.index:/ { print $NF }')
14318                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14319                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14320                         error "changelogs are off on mds$i"
14321         done
14322 }
14323 run_test 160i "changelog user register/unregister race"
14324
14325 test_160j() {
14326         remote_mds_nodsh && skip "remote MDS with nodsh"
14327         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14328                 skip "Need MDS version at least 2.12.56"
14329
14330         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14331
14332         changelog_register || error "first changelog_register failed"
14333
14334         # generate some changelog
14335         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14336         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14337                 error "create $DIR/$tdir/${tfile}bis failed"
14338
14339         # open the changelog device
14340         exec 3>/dev/changelog-$FSNAME-MDT0000
14341         exec 4</dev/changelog-$FSNAME-MDT0000
14342
14343         # umount the first lustre mount
14344         umount $MOUNT
14345
14346         # read changelog
14347         cat <&4 >/dev/null || error "read changelog failed"
14348
14349         # clear changelog
14350         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14351         changelog_users $SINGLEMDS | grep -q $cl_user ||
14352                 error "User $cl_user not found in changelog_users"
14353
14354         printf 'clear:'$cl_user':0' >&3
14355
14356         # close
14357         exec 3>&-
14358         exec 4<&-
14359
14360         # cleanup
14361         changelog_deregister || error "changelog_deregister failed"
14362
14363         umount $MOUNT2
14364         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14365 }
14366 run_test 160j "client can be umounted  while its chanangelog is being used"
14367
14368 test_160k() {
14369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14370         remote_mds_nodsh && skip "remote MDS with nodsh"
14371
14372         mkdir -p $DIR/$tdir/1/1
14373
14374         changelog_register || error "changelog_register failed"
14375         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14376
14377         changelog_users $SINGLEMDS | grep -q $cl_user ||
14378                 error "User '$cl_user' not found in changelog_users"
14379 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14380         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14381         rmdir $DIR/$tdir/1/1 & sleep 1
14382         mkdir $DIR/$tdir/2
14383         touch $DIR/$tdir/2/2
14384         rm -rf $DIR/$tdir/2
14385
14386         wait
14387         sleep 4
14388
14389         changelog_dump | grep rmdir || error "rmdir not recorded"
14390
14391         rm -rf $DIR/$tdir
14392         changelog_deregister
14393 }
14394 run_test 160k "Verify that changelog records are not lost"
14395
14396 test_161a() {
14397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14398
14399         test_mkdir -c1 $DIR/$tdir
14400         cp /etc/hosts $DIR/$tdir/$tfile
14401         test_mkdir -c1 $DIR/$tdir/foo1
14402         test_mkdir -c1 $DIR/$tdir/foo2
14403         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14404         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14405         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14406         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14407         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14408         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14409                 $LFS fid2path $DIR $FID
14410                 error "bad link ea"
14411         fi
14412         # middle
14413         rm $DIR/$tdir/foo2/zachary
14414         # last
14415         rm $DIR/$tdir/foo2/thor
14416         # first
14417         rm $DIR/$tdir/$tfile
14418         # rename
14419         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14420         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14421                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14422         rm $DIR/$tdir/foo2/maggie
14423
14424         # overflow the EA
14425         local longname=$tfile.avg_len_is_thirty_two_
14426         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14427                 error_noexit 'failed to unlink many hardlinks'" EXIT
14428         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14429                 error "failed to hardlink many files"
14430         links=$($LFS fid2path $DIR $FID | wc -l)
14431         echo -n "${links}/1000 links in link EA"
14432         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14433 }
14434 run_test 161a "link ea sanity"
14435
14436 test_161b() {
14437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14438         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14439
14440         local MDTIDX=1
14441         local remote_dir=$DIR/$tdir/remote_dir
14442
14443         mkdir -p $DIR/$tdir
14444         $LFS mkdir -i $MDTIDX $remote_dir ||
14445                 error "create remote directory failed"
14446
14447         cp /etc/hosts $remote_dir/$tfile
14448         mkdir -p $remote_dir/foo1
14449         mkdir -p $remote_dir/foo2
14450         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14451         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14452         ln $remote_dir/$tfile $remote_dir/foo1/luna
14453         ln $remote_dir/$tfile $remote_dir/foo2/thor
14454
14455         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14456                      tr -d ']')
14457         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14458                 $LFS fid2path $DIR $FID
14459                 error "bad link ea"
14460         fi
14461         # middle
14462         rm $remote_dir/foo2/zachary
14463         # last
14464         rm $remote_dir/foo2/thor
14465         # first
14466         rm $remote_dir/$tfile
14467         # rename
14468         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14469         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14470         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14471                 $LFS fid2path $DIR $FID
14472                 error "bad link rename"
14473         fi
14474         rm $remote_dir/foo2/maggie
14475
14476         # overflow the EA
14477         local longname=filename_avg_len_is_thirty_two_
14478         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14479                 error "failed to hardlink many files"
14480         links=$($LFS fid2path $DIR $FID | wc -l)
14481         echo -n "${links}/1000 links in link EA"
14482         [[ ${links} -gt 60 ]] ||
14483                 error "expected at least 60 links in link EA"
14484         unlinkmany $remote_dir/foo2/$longname 1000 ||
14485         error "failed to unlink many hardlinks"
14486 }
14487 run_test 161b "link ea sanity under remote directory"
14488
14489 test_161c() {
14490         remote_mds_nodsh && skip "remote MDS with nodsh"
14491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14492         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14493                 skip "Need MDS version at least 2.1.5"
14494
14495         # define CLF_RENAME_LAST 0x0001
14496         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14497         changelog_register || error "changelog_register failed"
14498
14499         rm -rf $DIR/$tdir
14500         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14501         touch $DIR/$tdir/foo_161c
14502         touch $DIR/$tdir/bar_161c
14503         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14504         changelog_dump | grep RENME | tail -n 5
14505         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14506         changelog_clear 0 || error "changelog_clear failed"
14507         if [ x$flags != "x0x1" ]; then
14508                 error "flag $flags is not 0x1"
14509         fi
14510
14511         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14512         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14513         touch $DIR/$tdir/foo_161c
14514         touch $DIR/$tdir/bar_161c
14515         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14516         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14517         changelog_dump | grep RENME | tail -n 5
14518         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14519         changelog_clear 0 || error "changelog_clear failed"
14520         if [ x$flags != "x0x0" ]; then
14521                 error "flag $flags is not 0x0"
14522         fi
14523         echo "rename overwrite a target having nlink > 1," \
14524                 "changelog record has flags of $flags"
14525
14526         # rename doesn't overwrite a target (changelog flag 0x0)
14527         touch $DIR/$tdir/foo_161c
14528         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14529         changelog_dump | grep RENME | tail -n 5
14530         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14531         changelog_clear 0 || error "changelog_clear failed"
14532         if [ x$flags != "x0x0" ]; then
14533                 error "flag $flags is not 0x0"
14534         fi
14535         echo "rename doesn't overwrite a target," \
14536                 "changelog record has flags of $flags"
14537
14538         # define CLF_UNLINK_LAST 0x0001
14539         # unlink a file having nlink = 1 (changelog flag 0x1)
14540         rm -f $DIR/$tdir/foo2_161c
14541         changelog_dump | grep UNLNK | tail -n 5
14542         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14543         changelog_clear 0 || error "changelog_clear failed"
14544         if [ x$flags != "x0x1" ]; then
14545                 error "flag $flags is not 0x1"
14546         fi
14547         echo "unlink a file having nlink = 1," \
14548                 "changelog record has flags of $flags"
14549
14550         # unlink a file having nlink > 1 (changelog flag 0x0)
14551         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14552         rm -f $DIR/$tdir/foobar_161c
14553         changelog_dump | grep UNLNK | tail -n 5
14554         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14555         changelog_clear 0 || error "changelog_clear failed"
14556         if [ x$flags != "x0x0" ]; then
14557                 error "flag $flags is not 0x0"
14558         fi
14559         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14560 }
14561 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14562
14563 test_161d() {
14564         remote_mds_nodsh && skip "remote MDS with nodsh"
14565         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14566
14567         local pid
14568         local fid
14569
14570         changelog_register || error "changelog_register failed"
14571
14572         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14573         # interfer with $MOUNT/.lustre/fid/ access
14574         mkdir $DIR/$tdir
14575         [[ $? -eq 0 ]] || error "mkdir failed"
14576
14577         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14578         $LCTL set_param fail_loc=0x8000140c
14579         # 5s pause
14580         $LCTL set_param fail_val=5
14581
14582         # create file
14583         echo foofoo > $DIR/$tdir/$tfile &
14584         pid=$!
14585
14586         # wait for create to be delayed
14587         sleep 2
14588
14589         ps -p $pid
14590         [[ $? -eq 0 ]] || error "create should be blocked"
14591
14592         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14593         stack_trap "rm -f $tempfile"
14594         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14595         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14596         # some delay may occur during ChangeLog publishing and file read just
14597         # above, that could allow file write to happen finally
14598         [[ -s $tempfile ]] && echo "file should be empty"
14599
14600         $LCTL set_param fail_loc=0
14601
14602         wait $pid
14603         [[ $? -eq 0 ]] || error "create failed"
14604 }
14605 run_test 161d "create with concurrent .lustre/fid access"
14606
14607 check_path() {
14608         local expected="$1"
14609         shift
14610         local fid="$2"
14611
14612         local path
14613         path=$($LFS fid2path "$@")
14614         local rc=$?
14615
14616         if [ $rc -ne 0 ]; then
14617                 error "path looked up of '$expected' failed: rc=$rc"
14618         elif [ "$path" != "$expected" ]; then
14619                 error "path looked up '$path' instead of '$expected'"
14620         else
14621                 echo "FID '$fid' resolves to path '$path' as expected"
14622         fi
14623 }
14624
14625 test_162a() { # was test_162
14626         test_mkdir -p -c1 $DIR/$tdir/d2
14627         touch $DIR/$tdir/d2/$tfile
14628         touch $DIR/$tdir/d2/x1
14629         touch $DIR/$tdir/d2/x2
14630         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14631         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14632         # regular file
14633         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14634         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14635
14636         # softlink
14637         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14638         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14639         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14640
14641         # softlink to wrong file
14642         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14643         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14644         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14645
14646         # hardlink
14647         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14648         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14649         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14650         # fid2path dir/fsname should both work
14651         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14652         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14653
14654         # hardlink count: check that there are 2 links
14655         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14656         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14657
14658         # hardlink indexing: remove the first link
14659         rm $DIR/$tdir/d2/p/q/r/hlink
14660         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14661 }
14662 run_test 162a "path lookup sanity"
14663
14664 test_162b() {
14665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14667
14668         mkdir $DIR/$tdir
14669         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14670                                 error "create striped dir failed"
14671
14672         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14673                                         tail -n 1 | awk '{print $2}')
14674         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14675
14676         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14677         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14678
14679         # regular file
14680         for ((i=0;i<5;i++)); do
14681                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14682                         error "get fid for f$i failed"
14683                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14684
14685                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14686                         error "get fid for d$i failed"
14687                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14688         done
14689
14690         return 0
14691 }
14692 run_test 162b "striped directory path lookup sanity"
14693
14694 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14695 test_162c() {
14696         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14697                 skip "Need MDS version at least 2.7.51"
14698
14699         local lpath=$tdir.local
14700         local rpath=$tdir.remote
14701
14702         test_mkdir $DIR/$lpath
14703         test_mkdir $DIR/$rpath
14704
14705         for ((i = 0; i <= 101; i++)); do
14706                 lpath="$lpath/$i"
14707                 mkdir $DIR/$lpath
14708                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14709                         error "get fid for local directory $DIR/$lpath failed"
14710                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14711
14712                 rpath="$rpath/$i"
14713                 test_mkdir $DIR/$rpath
14714                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14715                         error "get fid for remote directory $DIR/$rpath failed"
14716                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14717         done
14718
14719         return 0
14720 }
14721 run_test 162c "fid2path works with paths 100 or more directories deep"
14722
14723 test_169() {
14724         # do directio so as not to populate the page cache
14725         log "creating a 10 Mb file"
14726         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14727         log "starting reads"
14728         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14729         log "truncating the file"
14730         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14731         log "killing dd"
14732         kill %+ || true # reads might have finished
14733         echo "wait until dd is finished"
14734         wait
14735         log "removing the temporary file"
14736         rm -rf $DIR/$tfile || error "tmp file removal failed"
14737 }
14738 run_test 169 "parallel read and truncate should not deadlock"
14739
14740 test_170() {
14741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14742
14743         $LCTL clear     # bug 18514
14744         $LCTL debug_daemon start $TMP/${tfile}_log_good
14745         touch $DIR/$tfile
14746         $LCTL debug_daemon stop
14747         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14748                 error "sed failed to read log_good"
14749
14750         $LCTL debug_daemon start $TMP/${tfile}_log_good
14751         rm -rf $DIR/$tfile
14752         $LCTL debug_daemon stop
14753
14754         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14755                error "lctl df log_bad failed"
14756
14757         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14758         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14759
14760         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14761         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14762
14763         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14764                 error "bad_line good_line1 good_line2 are empty"
14765
14766         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14767         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14768         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14769
14770         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14771         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14772         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14773
14774         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14775                 error "bad_line_new good_line_new are empty"
14776
14777         local expected_good=$((good_line1 + good_line2*2))
14778
14779         rm -f $TMP/${tfile}*
14780         # LU-231, short malformed line may not be counted into bad lines
14781         if [ $bad_line -ne $bad_line_new ] &&
14782                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14783                 error "expected $bad_line bad lines, but got $bad_line_new"
14784                 return 1
14785         fi
14786
14787         if [ $expected_good -ne $good_line_new ]; then
14788                 error "expected $expected_good good lines, but got $good_line_new"
14789                 return 2
14790         fi
14791         true
14792 }
14793 run_test 170 "test lctl df to handle corrupted log ====================="
14794
14795 test_171() { # bug20592
14796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14797
14798         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14799         $LCTL set_param fail_loc=0x50e
14800         $LCTL set_param fail_val=3000
14801         multiop_bg_pause $DIR/$tfile O_s || true
14802         local MULTIPID=$!
14803         kill -USR1 $MULTIPID
14804         # cause log dump
14805         sleep 3
14806         wait $MULTIPID
14807         if dmesg | grep "recursive fault"; then
14808                 error "caught a recursive fault"
14809         fi
14810         $LCTL set_param fail_loc=0
14811         true
14812 }
14813 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14814
14815 # it would be good to share it with obdfilter-survey/iokit-libecho code
14816 setup_obdecho_osc () {
14817         local rc=0
14818         local ost_nid=$1
14819         local obdfilter_name=$2
14820         echo "Creating new osc for $obdfilter_name on $ost_nid"
14821         # make sure we can find loopback nid
14822         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14823
14824         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14825                            ${obdfilter_name}_osc_UUID || rc=2; }
14826         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14827                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14828         return $rc
14829 }
14830
14831 cleanup_obdecho_osc () {
14832         local obdfilter_name=$1
14833         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14834         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14835         return 0
14836 }
14837
14838 obdecho_test() {
14839         local OBD=$1
14840         local node=$2
14841         local pages=${3:-64}
14842         local rc=0
14843         local id
14844
14845         local count=10
14846         local obd_size=$(get_obd_size $node $OBD)
14847         local page_size=$(get_page_size $node)
14848         if [[ -n "$obd_size" ]]; then
14849                 local new_count=$((obd_size / (pages * page_size / 1024)))
14850                 [[ $new_count -ge $count ]] || count=$new_count
14851         fi
14852
14853         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14854         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14855                            rc=2; }
14856         if [ $rc -eq 0 ]; then
14857             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14858             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14859         fi
14860         echo "New object id is $id"
14861         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14862                            rc=4; }
14863         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14864                            "test_brw $count w v $pages $id" || rc=4; }
14865         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14866                            rc=4; }
14867         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14868                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14869         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14870                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14871         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14872         return $rc
14873 }
14874
14875 test_180a() {
14876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14877
14878         if ! module_loaded obdecho; then
14879                 load_module obdecho/obdecho &&
14880                         stack_trap "rmmod obdecho" EXIT ||
14881                         error "unable to load obdecho on client"
14882         fi
14883
14884         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14885         local host=$($LCTL get_param -n osc.$osc.import |
14886                      awk '/current_connection:/ { print $2 }' )
14887         local target=$($LCTL get_param -n osc.$osc.import |
14888                        awk '/target:/ { print $2 }' )
14889         target=${target%_UUID}
14890
14891         if [ -n "$target" ]; then
14892                 setup_obdecho_osc $host $target &&
14893                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14894                         { error "obdecho setup failed with $?"; return; }
14895
14896                 obdecho_test ${target}_osc client ||
14897                         error "obdecho_test failed on ${target}_osc"
14898         else
14899                 $LCTL get_param osc.$osc.import
14900                 error "there is no osc.$osc.import target"
14901         fi
14902 }
14903 run_test 180a "test obdecho on osc"
14904
14905 test_180b() {
14906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14907         remote_ost_nodsh && skip "remote OST with nodsh"
14908
14909         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14910                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14911                 error "failed to load module obdecho"
14912
14913         local target=$(do_facet ost1 $LCTL dl |
14914                        awk '/obdfilter/ { print $4; exit; }')
14915
14916         if [ -n "$target" ]; then
14917                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14918         else
14919                 do_facet ost1 $LCTL dl
14920                 error "there is no obdfilter target on ost1"
14921         fi
14922 }
14923 run_test 180b "test obdecho directly on obdfilter"
14924
14925 test_180c() { # LU-2598
14926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14927         remote_ost_nodsh && skip "remote OST with nodsh"
14928         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14929                 skip "Need MDS version at least 2.4.0"
14930
14931         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14932                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14933                 error "failed to load module obdecho"
14934
14935         local target=$(do_facet ost1 $LCTL dl |
14936                        awk '/obdfilter/ { print $4; exit; }')
14937
14938         if [ -n "$target" ]; then
14939                 local pages=16384 # 64MB bulk I/O RPC size
14940
14941                 obdecho_test "$target" ost1 "$pages" ||
14942                         error "obdecho_test with pages=$pages failed with $?"
14943         else
14944                 do_facet ost1 $LCTL dl
14945                 error "there is no obdfilter target on ost1"
14946         fi
14947 }
14948 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14949
14950 test_181() { # bug 22177
14951         test_mkdir $DIR/$tdir
14952         # create enough files to index the directory
14953         createmany -o $DIR/$tdir/foobar 4000
14954         # print attributes for debug purpose
14955         lsattr -d .
14956         # open dir
14957         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14958         MULTIPID=$!
14959         # remove the files & current working dir
14960         unlinkmany $DIR/$tdir/foobar 4000
14961         rmdir $DIR/$tdir
14962         kill -USR1 $MULTIPID
14963         wait $MULTIPID
14964         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14965         return 0
14966 }
14967 run_test 181 "Test open-unlinked dir ========================"
14968
14969 test_182() {
14970         local fcount=1000
14971         local tcount=10
14972
14973         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14974
14975         $LCTL set_param mdc.*.rpc_stats=clear
14976
14977         for (( i = 0; i < $tcount; i++ )) ; do
14978                 mkdir $DIR/$tdir/$i
14979         done
14980
14981         for (( i = 0; i < $tcount; i++ )) ; do
14982                 createmany -o $DIR/$tdir/$i/f- $fcount &
14983         done
14984         wait
14985
14986         for (( i = 0; i < $tcount; i++ )) ; do
14987                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14988         done
14989         wait
14990
14991         $LCTL get_param mdc.*.rpc_stats
14992
14993         rm -rf $DIR/$tdir
14994 }
14995 run_test 182 "Test parallel modify metadata operations ================"
14996
14997 test_183() { # LU-2275
14998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14999         remote_mds_nodsh && skip "remote MDS with nodsh"
15000         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15001                 skip "Need MDS version at least 2.3.56"
15002
15003         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15004         echo aaa > $DIR/$tdir/$tfile
15005
15006 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15007         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15008
15009         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15010         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15011
15012         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15013
15014         # Flush negative dentry cache
15015         touch $DIR/$tdir/$tfile
15016
15017         # We are not checking for any leaked references here, they'll
15018         # become evident next time we do cleanup with module unload.
15019         rm -rf $DIR/$tdir
15020 }
15021 run_test 183 "No crash or request leak in case of strange dispositions ========"
15022
15023 # test suite 184 is for LU-2016, LU-2017
15024 test_184a() {
15025         check_swap_layouts_support
15026
15027         dir0=$DIR/$tdir/$testnum
15028         test_mkdir -p -c1 $dir0
15029         ref1=/etc/passwd
15030         ref2=/etc/group
15031         file1=$dir0/f1
15032         file2=$dir0/f2
15033         $LFS setstripe -c1 $file1
15034         cp $ref1 $file1
15035         $LFS setstripe -c2 $file2
15036         cp $ref2 $file2
15037         gen1=$($LFS getstripe -g $file1)
15038         gen2=$($LFS getstripe -g $file2)
15039
15040         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15041         gen=$($LFS getstripe -g $file1)
15042         [[ $gen1 != $gen ]] ||
15043                 "Layout generation on $file1 does not change"
15044         gen=$($LFS getstripe -g $file2)
15045         [[ $gen2 != $gen ]] ||
15046                 "Layout generation on $file2 does not change"
15047
15048         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15049         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15050
15051         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15052 }
15053 run_test 184a "Basic layout swap"
15054
15055 test_184b() {
15056         check_swap_layouts_support
15057
15058         dir0=$DIR/$tdir/$testnum
15059         mkdir -p $dir0 || error "creating dir $dir0"
15060         file1=$dir0/f1
15061         file2=$dir0/f2
15062         file3=$dir0/f3
15063         dir1=$dir0/d1
15064         dir2=$dir0/d2
15065         mkdir $dir1 $dir2
15066         $LFS setstripe -c1 $file1
15067         $LFS setstripe -c2 $file2
15068         $LFS setstripe -c1 $file3
15069         chown $RUNAS_ID $file3
15070         gen1=$($LFS getstripe -g $file1)
15071         gen2=$($LFS getstripe -g $file2)
15072
15073         $LFS swap_layouts $dir1 $dir2 &&
15074                 error "swap of directories layouts should fail"
15075         $LFS swap_layouts $dir1 $file1 &&
15076                 error "swap of directory and file layouts should fail"
15077         $RUNAS $LFS swap_layouts $file1 $file2 &&
15078                 error "swap of file we cannot write should fail"
15079         $LFS swap_layouts $file1 $file3 &&
15080                 error "swap of file with different owner should fail"
15081         /bin/true # to clear error code
15082 }
15083 run_test 184b "Forbidden layout swap (will generate errors)"
15084
15085 test_184c() {
15086         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15087         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15088         check_swap_layouts_support
15089
15090         local dir0=$DIR/$tdir/$testnum
15091         mkdir -p $dir0 || error "creating dir $dir0"
15092
15093         local ref1=$dir0/ref1
15094         local ref2=$dir0/ref2
15095         local file1=$dir0/file1
15096         local file2=$dir0/file2
15097         # create a file large enough for the concurrent test
15098         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15099         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15100         echo "ref file size: ref1($(stat -c %s $ref1))," \
15101              "ref2($(stat -c %s $ref2))"
15102
15103         cp $ref2 $file2
15104         dd if=$ref1 of=$file1 bs=16k &
15105         local DD_PID=$!
15106
15107         # Make sure dd starts to copy file
15108         while [ ! -f $file1 ]; do sleep 0.1; done
15109
15110         $LFS swap_layouts $file1 $file2
15111         local rc=$?
15112         wait $DD_PID
15113         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15114         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15115
15116         # how many bytes copied before swapping layout
15117         local copied=$(stat -c %s $file2)
15118         local remaining=$(stat -c %s $ref1)
15119         remaining=$((remaining - copied))
15120         echo "Copied $copied bytes before swapping layout..."
15121
15122         cmp -n $copied $file1 $ref2 | grep differ &&
15123                 error "Content mismatch [0, $copied) of ref2 and file1"
15124         cmp -n $copied $file2 $ref1 ||
15125                 error "Content mismatch [0, $copied) of ref1 and file2"
15126         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15127                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15128
15129         # clean up
15130         rm -f $ref1 $ref2 $file1 $file2
15131 }
15132 run_test 184c "Concurrent write and layout swap"
15133
15134 test_184d() {
15135         check_swap_layouts_support
15136         [ -z "$(which getfattr 2>/dev/null)" ] &&
15137                 skip_env "no getfattr command"
15138
15139         local file1=$DIR/$tdir/$tfile-1
15140         local file2=$DIR/$tdir/$tfile-2
15141         local file3=$DIR/$tdir/$tfile-3
15142         local lovea1
15143         local lovea2
15144
15145         mkdir -p $DIR/$tdir
15146         touch $file1 || error "create $file1 failed"
15147         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15148                 error "create $file2 failed"
15149         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15150                 error "create $file3 failed"
15151         lovea1=$(get_layout_param $file1)
15152
15153         $LFS swap_layouts $file2 $file3 ||
15154                 error "swap $file2 $file3 layouts failed"
15155         $LFS swap_layouts $file1 $file2 ||
15156                 error "swap $file1 $file2 layouts failed"
15157
15158         lovea2=$(get_layout_param $file2)
15159         echo "$lovea1"
15160         echo "$lovea2"
15161         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15162
15163         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15164         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15165 }
15166 run_test 184d "allow stripeless layouts swap"
15167
15168 test_184e() {
15169         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15170                 skip "Need MDS version at least 2.6.94"
15171         check_swap_layouts_support
15172         [ -z "$(which getfattr 2>/dev/null)" ] &&
15173                 skip_env "no getfattr command"
15174
15175         local file1=$DIR/$tdir/$tfile-1
15176         local file2=$DIR/$tdir/$tfile-2
15177         local file3=$DIR/$tdir/$tfile-3
15178         local lovea
15179
15180         mkdir -p $DIR/$tdir
15181         touch $file1 || error "create $file1 failed"
15182         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15183                 error "create $file2 failed"
15184         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15185                 error "create $file3 failed"
15186
15187         $LFS swap_layouts $file1 $file2 ||
15188                 error "swap $file1 $file2 layouts failed"
15189
15190         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15191         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15192
15193         echo 123 > $file1 || error "Should be able to write into $file1"
15194
15195         $LFS swap_layouts $file1 $file3 ||
15196                 error "swap $file1 $file3 layouts failed"
15197
15198         echo 123 > $file1 || error "Should be able to write into $file1"
15199
15200         rm -rf $file1 $file2 $file3
15201 }
15202 run_test 184e "Recreate layout after stripeless layout swaps"
15203
15204 test_184f() {
15205         # Create a file with name longer than sizeof(struct stat) ==
15206         # 144 to see if we can get chars from the file name to appear
15207         # in the returned striping. Note that 'f' == 0x66.
15208         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15209
15210         mkdir -p $DIR/$tdir
15211         mcreate $DIR/$tdir/$file
15212         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15213                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15214         fi
15215 }
15216 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15217
15218 test_185() { # LU-2441
15219         # LU-3553 - no volatile file support in old servers
15220         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15221                 skip "Need MDS version at least 2.3.60"
15222
15223         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15224         touch $DIR/$tdir/spoo
15225         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15226         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15227                 error "cannot create/write a volatile file"
15228         [ "$FILESET" == "" ] &&
15229         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15230                 error "FID is still valid after close"
15231
15232         multiop_bg_pause $DIR/$tdir vVw4096_c
15233         local multi_pid=$!
15234
15235         local OLD_IFS=$IFS
15236         IFS=":"
15237         local fidv=($fid)
15238         IFS=$OLD_IFS
15239         # assume that the next FID for this client is sequential, since stdout
15240         # is unfortunately eaten by multiop_bg_pause
15241         local n=$((${fidv[1]} + 1))
15242         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15243         if [ "$FILESET" == "" ]; then
15244                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15245                         error "FID is missing before close"
15246         fi
15247         kill -USR1 $multi_pid
15248         # 1 second delay, so if mtime change we will see it
15249         sleep 1
15250         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15251         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15252 }
15253 run_test 185 "Volatile file support"
15254
15255 function create_check_volatile() {
15256         local idx=$1
15257         local tgt
15258
15259         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15260         local PID=$!
15261         sleep 1
15262         local FID=$(cat /tmp/${tfile}.fid)
15263         [ "$FID" == "" ] && error "can't get FID for volatile"
15264         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15265         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15266         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15267         kill -USR1 $PID
15268         wait
15269         sleep 1
15270         cancel_lru_locks mdc # flush opencache
15271         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15272         return 0
15273 }
15274
15275 test_185a(){
15276         # LU-12516 - volatile creation via .lustre
15277         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15278                 skip "Need MDS version at least 2.3.55"
15279
15280         create_check_volatile 0
15281         [ $MDSCOUNT -lt 2 ] && return 0
15282
15283         # DNE case
15284         create_check_volatile 1
15285
15286         return 0
15287 }
15288 run_test 185a "Volatile file creation in .lustre/fid/"
15289
15290 test_187a() {
15291         remote_mds_nodsh && skip "remote MDS with nodsh"
15292         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15293                 skip "Need MDS version at least 2.3.0"
15294
15295         local dir0=$DIR/$tdir/$testnum
15296         mkdir -p $dir0 || error "creating dir $dir0"
15297
15298         local file=$dir0/file1
15299         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15300         local dv1=$($LFS data_version $file)
15301         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15302         local dv2=$($LFS data_version $file)
15303         [[ $dv1 != $dv2 ]] ||
15304                 error "data version did not change on write $dv1 == $dv2"
15305
15306         # clean up
15307         rm -f $file1
15308 }
15309 run_test 187a "Test data version change"
15310
15311 test_187b() {
15312         remote_mds_nodsh && skip "remote MDS with nodsh"
15313         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15314                 skip "Need MDS version at least 2.3.0"
15315
15316         local dir0=$DIR/$tdir/$testnum
15317         mkdir -p $dir0 || error "creating dir $dir0"
15318
15319         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15320         [[ ${DV[0]} != ${DV[1]} ]] ||
15321                 error "data version did not change on write"\
15322                       " ${DV[0]} == ${DV[1]}"
15323
15324         # clean up
15325         rm -f $file1
15326 }
15327 run_test 187b "Test data version change on volatile file"
15328
15329 test_200() {
15330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15331         remote_mgs_nodsh && skip "remote MGS with nodsh"
15332         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15333
15334         local POOL=${POOL:-cea1}
15335         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15336         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15337         # Pool OST targets
15338         local first_ost=0
15339         local last_ost=$(($OSTCOUNT - 1))
15340         local ost_step=2
15341         local ost_list=$(seq $first_ost $ost_step $last_ost)
15342         local ost_range="$first_ost $last_ost $ost_step"
15343         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15344         local file_dir=$POOL_ROOT/file_tst
15345         local subdir=$test_path/subdir
15346         local rc=0
15347
15348         while : ; do
15349                 # former test_200a test_200b
15350                 pool_add $POOL                          || { rc=$? ; break; }
15351                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15352                 # former test_200c test_200d
15353                 mkdir -p $test_path
15354                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15355                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15356                 mkdir -p $subdir
15357                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15358                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15359                                                         || { rc=$? ; break; }
15360                 # former test_200e test_200f
15361                 local files=$((OSTCOUNT*3))
15362                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15363                                                         || { rc=$? ; break; }
15364                 pool_create_files $POOL $file_dir $files "$ost_list" \
15365                                                         || { rc=$? ; break; }
15366                 # former test_200g test_200h
15367                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15368                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15369
15370                 # former test_201a test_201b test_201c
15371                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15372
15373                 local f=$test_path/$tfile
15374                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15375                 pool_remove $POOL $f                    || { rc=$? ; break; }
15376                 break
15377         done
15378
15379         destroy_test_pools
15380
15381         return $rc
15382 }
15383 run_test 200 "OST pools"
15384
15385 # usage: default_attr <count | size | offset>
15386 default_attr() {
15387         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15388 }
15389
15390 # usage: check_default_stripe_attr
15391 check_default_stripe_attr() {
15392         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15393         case $1 in
15394         --stripe-count|-c)
15395                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15396         --stripe-size|-S)
15397                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15398         --stripe-index|-i)
15399                 EXPECTED=-1;;
15400         *)
15401                 error "unknown getstripe attr '$1'"
15402         esac
15403
15404         [ $ACTUAL == $EXPECTED ] ||
15405                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15406 }
15407
15408 test_204a() {
15409         test_mkdir $DIR/$tdir
15410         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15411
15412         check_default_stripe_attr --stripe-count
15413         check_default_stripe_attr --stripe-size
15414         check_default_stripe_attr --stripe-index
15415 }
15416 run_test 204a "Print default stripe attributes"
15417
15418 test_204b() {
15419         test_mkdir $DIR/$tdir
15420         $LFS setstripe --stripe-count 1 $DIR/$tdir
15421
15422         check_default_stripe_attr --stripe-size
15423         check_default_stripe_attr --stripe-index
15424 }
15425 run_test 204b "Print default stripe size and offset"
15426
15427 test_204c() {
15428         test_mkdir $DIR/$tdir
15429         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15430
15431         check_default_stripe_attr --stripe-count
15432         check_default_stripe_attr --stripe-index
15433 }
15434 run_test 204c "Print default stripe count and offset"
15435
15436 test_204d() {
15437         test_mkdir $DIR/$tdir
15438         $LFS setstripe --stripe-index 0 $DIR/$tdir
15439
15440         check_default_stripe_attr --stripe-count
15441         check_default_stripe_attr --stripe-size
15442 }
15443 run_test 204d "Print default stripe count and size"
15444
15445 test_204e() {
15446         test_mkdir $DIR/$tdir
15447         $LFS setstripe -d $DIR/$tdir
15448
15449         check_default_stripe_attr --stripe-count --raw
15450         check_default_stripe_attr --stripe-size --raw
15451         check_default_stripe_attr --stripe-index --raw
15452 }
15453 run_test 204e "Print raw stripe attributes"
15454
15455 test_204f() {
15456         test_mkdir $DIR/$tdir
15457         $LFS setstripe --stripe-count 1 $DIR/$tdir
15458
15459         check_default_stripe_attr --stripe-size --raw
15460         check_default_stripe_attr --stripe-index --raw
15461 }
15462 run_test 204f "Print raw stripe size and offset"
15463
15464 test_204g() {
15465         test_mkdir $DIR/$tdir
15466         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15467
15468         check_default_stripe_attr --stripe-count --raw
15469         check_default_stripe_attr --stripe-index --raw
15470 }
15471 run_test 204g "Print raw stripe count and offset"
15472
15473 test_204h() {
15474         test_mkdir $DIR/$tdir
15475         $LFS setstripe --stripe-index 0 $DIR/$tdir
15476
15477         check_default_stripe_attr --stripe-count --raw
15478         check_default_stripe_attr --stripe-size --raw
15479 }
15480 run_test 204h "Print raw stripe count and size"
15481
15482 # Figure out which job scheduler is being used, if any,
15483 # or use a fake one
15484 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15485         JOBENV=SLURM_JOB_ID
15486 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15487         JOBENV=LSB_JOBID
15488 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15489         JOBENV=PBS_JOBID
15490 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15491         JOBENV=LOADL_STEP_ID
15492 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15493         JOBENV=JOB_ID
15494 else
15495         $LCTL list_param jobid_name > /dev/null 2>&1
15496         if [ $? -eq 0 ]; then
15497                 JOBENV=nodelocal
15498         else
15499                 JOBENV=FAKE_JOBID
15500         fi
15501 fi
15502 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15503
15504 verify_jobstats() {
15505         local cmd=($1)
15506         shift
15507         local facets="$@"
15508
15509 # we don't really need to clear the stats for this test to work, since each
15510 # command has a unique jobid, but it makes debugging easier if needed.
15511 #       for facet in $facets; do
15512 #               local dev=$(convert_facet2label $facet)
15513 #               # clear old jobstats
15514 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15515 #       done
15516
15517         # use a new JobID for each test, or we might see an old one
15518         [ "$JOBENV" = "FAKE_JOBID" ] &&
15519                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15520
15521         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15522
15523         [ "$JOBENV" = "nodelocal" ] && {
15524                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15525                 $LCTL set_param jobid_name=$FAKE_JOBID
15526                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15527         }
15528
15529         log "Test: ${cmd[*]}"
15530         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15531
15532         if [ $JOBENV = "FAKE_JOBID" ]; then
15533                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15534         else
15535                 ${cmd[*]}
15536         fi
15537
15538         # all files are created on OST0000
15539         for facet in $facets; do
15540                 local stats="*.$(convert_facet2label $facet).job_stats"
15541
15542                 # strip out libtool wrappers for in-tree executables
15543                 if [ $(do_facet $facet lctl get_param $stats |
15544                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15545                         do_facet $facet lctl get_param $stats
15546                         error "No jobstats for $JOBVAL found on $facet::$stats"
15547                 fi
15548         done
15549 }
15550
15551 jobstats_set() {
15552         local new_jobenv=$1
15553
15554         set_persistent_param_and_check client "jobid_var" \
15555                 "$FSNAME.sys.jobid_var" $new_jobenv
15556 }
15557
15558 test_205a() { # Job stats
15559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15560         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15561                 skip "Need MDS version with at least 2.7.1"
15562         remote_mgs_nodsh && skip "remote MGS with nodsh"
15563         remote_mds_nodsh && skip "remote MDS with nodsh"
15564         remote_ost_nodsh && skip "remote OST with nodsh"
15565         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15566                 skip "Server doesn't support jobstats"
15567         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15568
15569         local old_jobenv=$($LCTL get_param -n jobid_var)
15570         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15571
15572         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15573                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15574         else
15575                 stack_trap "do_facet mgs $PERM_CMD \
15576                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15577         fi
15578         changelog_register
15579
15580         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15581                                 mdt.*.job_cleanup_interval | head -n 1)
15582         local new_interval=5
15583         do_facet $SINGLEMDS \
15584                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15585         stack_trap "do_facet $SINGLEMDS \
15586                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15587         local start=$SECONDS
15588
15589         local cmd
15590         # mkdir
15591         cmd="mkdir $DIR/$tdir"
15592         verify_jobstats "$cmd" "$SINGLEMDS"
15593         # rmdir
15594         cmd="rmdir $DIR/$tdir"
15595         verify_jobstats "$cmd" "$SINGLEMDS"
15596         # mkdir on secondary MDT
15597         if [ $MDSCOUNT -gt 1 ]; then
15598                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15599                 verify_jobstats "$cmd" "mds2"
15600         fi
15601         # mknod
15602         cmd="mknod $DIR/$tfile c 1 3"
15603         verify_jobstats "$cmd" "$SINGLEMDS"
15604         # unlink
15605         cmd="rm -f $DIR/$tfile"
15606         verify_jobstats "$cmd" "$SINGLEMDS"
15607         # create all files on OST0000 so verify_jobstats can find OST stats
15608         # open & close
15609         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15610         verify_jobstats "$cmd" "$SINGLEMDS"
15611         # setattr
15612         cmd="touch $DIR/$tfile"
15613         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15614         # write
15615         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15616         verify_jobstats "$cmd" "ost1"
15617         # read
15618         cancel_lru_locks osc
15619         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15620         verify_jobstats "$cmd" "ost1"
15621         # truncate
15622         cmd="$TRUNCATE $DIR/$tfile 0"
15623         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15624         # rename
15625         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15626         verify_jobstats "$cmd" "$SINGLEMDS"
15627         # jobstats expiry - sleep until old stats should be expired
15628         local left=$((new_interval + 5 - (SECONDS - start)))
15629         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15630                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15631                         "0" $left
15632         cmd="mkdir $DIR/$tdir.expire"
15633         verify_jobstats "$cmd" "$SINGLEMDS"
15634         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15635             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15636
15637         # Ensure that jobid are present in changelog (if supported by MDS)
15638         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15639                 changelog_dump | tail -10
15640                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15641                 [ $jobids -eq 9 ] ||
15642                         error "Wrong changelog jobid count $jobids != 9"
15643
15644                 # LU-5862
15645                 JOBENV="disable"
15646                 jobstats_set $JOBENV
15647                 touch $DIR/$tfile
15648                 changelog_dump | grep $tfile
15649                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15650                 [ $jobids -eq 0 ] ||
15651                         error "Unexpected jobids when jobid_var=$JOBENV"
15652         fi
15653
15654         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15655         JOBENV="JOBCOMPLEX"
15656         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15657
15658         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15659 }
15660 run_test 205a "Verify job stats"
15661
15662 # LU-13117
15663 test_205b() {
15664         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
15665         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
15666         do_facet $SINGLEMDS $LCTL get_param mdt.*.job_stats |
15667                 grep job_id: | grep foolish &&
15668                         error "Unexpected jobid found"
15669         true
15670 }
15671 run_test 205b "Verify job stats jobid parsing"
15672
15673 # LU-1480, LU-1773 and LU-1657
15674 test_206() {
15675         mkdir -p $DIR/$tdir
15676         $LFS setstripe -c -1 $DIR/$tdir
15677 #define OBD_FAIL_LOV_INIT 0x1403
15678         $LCTL set_param fail_loc=0xa0001403
15679         $LCTL set_param fail_val=1
15680         touch $DIR/$tdir/$tfile || true
15681 }
15682 run_test 206 "fail lov_init_raid0() doesn't lbug"
15683
15684 test_207a() {
15685         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15686         local fsz=`stat -c %s $DIR/$tfile`
15687         cancel_lru_locks mdc
15688
15689         # do not return layout in getattr intent
15690 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15691         $LCTL set_param fail_loc=0x170
15692         local sz=`stat -c %s $DIR/$tfile`
15693
15694         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15695
15696         rm -rf $DIR/$tfile
15697 }
15698 run_test 207a "can refresh layout at glimpse"
15699
15700 test_207b() {
15701         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15702         local cksum=`md5sum $DIR/$tfile`
15703         local fsz=`stat -c %s $DIR/$tfile`
15704         cancel_lru_locks mdc
15705         cancel_lru_locks osc
15706
15707         # do not return layout in getattr intent
15708 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15709         $LCTL set_param fail_loc=0x171
15710
15711         # it will refresh layout after the file is opened but before read issues
15712         echo checksum is "$cksum"
15713         echo "$cksum" |md5sum -c --quiet || error "file differs"
15714
15715         rm -rf $DIR/$tfile
15716 }
15717 run_test 207b "can refresh layout at open"
15718
15719 test_208() {
15720         # FIXME: in this test suite, only RD lease is used. This is okay
15721         # for now as only exclusive open is supported. After generic lease
15722         # is done, this test suite should be revised. - Jinshan
15723
15724         remote_mds_nodsh && skip "remote MDS with nodsh"
15725         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15726                 skip "Need MDS version at least 2.4.52"
15727
15728         echo "==== test 1: verify get lease work"
15729         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15730
15731         echo "==== test 2: verify lease can be broken by upcoming open"
15732         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15733         local PID=$!
15734         sleep 1
15735
15736         $MULTIOP $DIR/$tfile oO_RDONLY:c
15737         kill -USR1 $PID && wait $PID || error "break lease error"
15738
15739         echo "==== test 3: verify lease can't be granted if an open already exists"
15740         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15741         local PID=$!
15742         sleep 1
15743
15744         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15745         kill -USR1 $PID && wait $PID || error "open file error"
15746
15747         echo "==== test 4: lease can sustain over recovery"
15748         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15749         PID=$!
15750         sleep 1
15751
15752         fail mds1
15753
15754         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15755
15756         echo "==== test 5: lease broken can't be regained by replay"
15757         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15758         PID=$!
15759         sleep 1
15760
15761         # open file to break lease and then recovery
15762         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15763         fail mds1
15764
15765         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15766
15767         rm -f $DIR/$tfile
15768 }
15769 run_test 208 "Exclusive open"
15770
15771 test_209() {
15772         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15773                 skip_env "must have disp_stripe"
15774
15775         touch $DIR/$tfile
15776         sync; sleep 5; sync;
15777
15778         echo 3 > /proc/sys/vm/drop_caches
15779         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15780
15781         # open/close 500 times
15782         for i in $(seq 500); do
15783                 cat $DIR/$tfile
15784         done
15785
15786         echo 3 > /proc/sys/vm/drop_caches
15787         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15788
15789         echo "before: $req_before, after: $req_after"
15790         [ $((req_after - req_before)) -ge 300 ] &&
15791                 error "open/close requests are not freed"
15792         return 0
15793 }
15794 run_test 209 "read-only open/close requests should be freed promptly"
15795
15796 test_212() {
15797         size=`date +%s`
15798         size=$((size % 8192 + 1))
15799         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15800         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15801         rm -f $DIR/f212 $DIR/f212.xyz
15802 }
15803 run_test 212 "Sendfile test ============================================"
15804
15805 test_213() {
15806         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15807         cancel_lru_locks osc
15808         lctl set_param fail_loc=0x8000040f
15809         # generate a read lock
15810         cat $DIR/$tfile > /dev/null
15811         # write to the file, it will try to cancel the above read lock.
15812         cat /etc/hosts >> $DIR/$tfile
15813 }
15814 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15815
15816 test_214() { # for bug 20133
15817         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15818         for (( i=0; i < 340; i++ )) ; do
15819                 touch $DIR/$tdir/d214c/a$i
15820         done
15821
15822         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15823         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15824         ls $DIR/d214c || error "ls $DIR/d214c failed"
15825         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15826         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15827 }
15828 run_test 214 "hash-indexed directory test - bug 20133"
15829
15830 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15831 create_lnet_proc_files() {
15832         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15833 }
15834
15835 # counterpart of create_lnet_proc_files
15836 remove_lnet_proc_files() {
15837         rm -f $TMP/lnet_$1.sys
15838 }
15839
15840 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15841 # 3rd arg as regexp for body
15842 check_lnet_proc_stats() {
15843         local l=$(cat "$TMP/lnet_$1" |wc -l)
15844         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15845
15846         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15847 }
15848
15849 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15850 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15851 # optional and can be regexp for 2nd line (lnet.routes case)
15852 check_lnet_proc_entry() {
15853         local blp=2          # blp stands for 'position of 1st line of body'
15854         [ -z "$5" ] || blp=3 # lnet.routes case
15855
15856         local l=$(cat "$TMP/lnet_$1" |wc -l)
15857         # subtracting one from $blp because the body can be empty
15858         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15859
15860         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15861                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15862
15863         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15864                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15865
15866         # bail out if any unexpected line happened
15867         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15868         [ "$?" != 0 ] || error "$2 misformatted"
15869 }
15870
15871 test_215() { # for bugs 18102, 21079, 21517
15872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15873
15874         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15875         local P='[1-9][0-9]*'           # positive numeric
15876         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15877         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15878         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15879         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15880
15881         local L1 # regexp for 1st line
15882         local L2 # regexp for 2nd line (optional)
15883         local BR # regexp for the rest (body)
15884
15885         # lnet.stats should look as 11 space-separated non-negative numerics
15886         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15887         create_lnet_proc_files "stats"
15888         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15889         remove_lnet_proc_files "stats"
15890
15891         # lnet.routes should look like this:
15892         # Routing disabled/enabled
15893         # net hops priority state router
15894         # where net is a string like tcp0, hops > 0, priority >= 0,
15895         # state is up/down,
15896         # router is a string like 192.168.1.1@tcp2
15897         L1="^Routing (disabled|enabled)$"
15898         L2="^net +hops +priority +state +router$"
15899         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15900         create_lnet_proc_files "routes"
15901         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15902         remove_lnet_proc_files "routes"
15903
15904         # lnet.routers should look like this:
15905         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15906         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15907         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15908         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15909         L1="^ref +rtr_ref +alive +router$"
15910         BR="^$P +$P +(up|down) +$NID$"
15911         create_lnet_proc_files "routers"
15912         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15913         remove_lnet_proc_files "routers"
15914
15915         # lnet.peers should look like this:
15916         # nid refs state last max rtr min tx min queue
15917         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15918         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15919         # numeric (0 or >0 or <0), queue >= 0.
15920         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15921         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15922         create_lnet_proc_files "peers"
15923         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15924         remove_lnet_proc_files "peers"
15925
15926         # lnet.buffers  should look like this:
15927         # pages count credits min
15928         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15929         L1="^pages +count +credits +min$"
15930         BR="^ +$N +$N +$I +$I$"
15931         create_lnet_proc_files "buffers"
15932         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15933         remove_lnet_proc_files "buffers"
15934
15935         # lnet.nis should look like this:
15936         # nid status alive refs peer rtr max tx min
15937         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15938         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15939         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15940         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15941         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15942         create_lnet_proc_files "nis"
15943         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15944         remove_lnet_proc_files "nis"
15945
15946         # can we successfully write to lnet.stats?
15947         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15948 }
15949 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15950
15951 test_216() { # bug 20317
15952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15953         remote_ost_nodsh && skip "remote OST with nodsh"
15954
15955         local node
15956         local facets=$(get_facets OST)
15957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15958
15959         save_lustre_params client "osc.*.contention_seconds" > $p
15960         save_lustre_params $facets \
15961                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15962         save_lustre_params $facets \
15963                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15964         save_lustre_params $facets \
15965                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15966         clear_stats osc.*.osc_stats
15967
15968         # agressive lockless i/o settings
15969         do_nodes $(comma_list $(osts_nodes)) \
15970                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15971                         ldlm.namespaces.filter-*.contended_locks=0 \
15972                         ldlm.namespaces.filter-*.contention_seconds=60"
15973         lctl set_param -n osc.*.contention_seconds=60
15974
15975         $DIRECTIO write $DIR/$tfile 0 10 4096
15976         $CHECKSTAT -s 40960 $DIR/$tfile
15977
15978         # disable lockless i/o
15979         do_nodes $(comma_list $(osts_nodes)) \
15980                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15981                         ldlm.namespaces.filter-*.contended_locks=32 \
15982                         ldlm.namespaces.filter-*.contention_seconds=0"
15983         lctl set_param -n osc.*.contention_seconds=0
15984         clear_stats osc.*.osc_stats
15985
15986         dd if=/dev/zero of=$DIR/$tfile count=0
15987         $CHECKSTAT -s 0 $DIR/$tfile
15988
15989         restore_lustre_params <$p
15990         rm -f $p
15991         rm $DIR/$tfile
15992 }
15993 run_test 216 "check lockless direct write updates file size and kms correctly"
15994
15995 test_217() { # bug 22430
15996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15997
15998         local node
15999         local nid
16000
16001         for node in $(nodes_list); do
16002                 nid=$(host_nids_address $node $NETTYPE)
16003                 if [[ $nid = *-* ]] ; then
16004                         echo "lctl ping $(h2nettype $nid)"
16005                         lctl ping $(h2nettype $nid)
16006                 else
16007                         echo "skipping $node (no hyphen detected)"
16008                 fi
16009         done
16010 }
16011 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16012
16013 test_218() {
16014        # do directio so as not to populate the page cache
16015        log "creating a 10 Mb file"
16016        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16017        log "starting reads"
16018        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16019        log "truncating the file"
16020        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16021        log "killing dd"
16022        kill %+ || true # reads might have finished
16023        echo "wait until dd is finished"
16024        wait
16025        log "removing the temporary file"
16026        rm -rf $DIR/$tfile || error "tmp file removal failed"
16027 }
16028 run_test 218 "parallel read and truncate should not deadlock"
16029
16030 test_219() {
16031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16032
16033         # write one partial page
16034         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16035         # set no grant so vvp_io_commit_write will do sync write
16036         $LCTL set_param fail_loc=0x411
16037         # write a full page at the end of file
16038         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16039
16040         $LCTL set_param fail_loc=0
16041         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16042         $LCTL set_param fail_loc=0x411
16043         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16044
16045         # LU-4201
16046         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16047         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16048 }
16049 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16050
16051 test_220() { #LU-325
16052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16053         remote_ost_nodsh && skip "remote OST with nodsh"
16054         remote_mds_nodsh && skip "remote MDS with nodsh"
16055         remote_mgs_nodsh && skip "remote MGS with nodsh"
16056
16057         local OSTIDX=0
16058
16059         # create on MDT0000 so the last_id and next_id are correct
16060         mkdir $DIR/$tdir
16061         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16062         OST=${OST%_UUID}
16063
16064         # on the mdt's osc
16065         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16066         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16067                         osp.$mdtosc_proc1.prealloc_last_id)
16068         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16069                         osp.$mdtosc_proc1.prealloc_next_id)
16070
16071         $LFS df -i
16072
16073         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16074         #define OBD_FAIL_OST_ENOINO              0x229
16075         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16076         create_pool $FSNAME.$TESTNAME || return 1
16077         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16078
16079         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16080
16081         MDSOBJS=$((last_id - next_id))
16082         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16083
16084         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16085         echo "OST still has $count kbytes free"
16086
16087         echo "create $MDSOBJS files @next_id..."
16088         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16089
16090         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16091                         osp.$mdtosc_proc1.prealloc_last_id)
16092         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16093                         osp.$mdtosc_proc1.prealloc_next_id)
16094
16095         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16096         $LFS df -i
16097
16098         echo "cleanup..."
16099
16100         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16101         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16102
16103         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16104                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16105         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16106                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16107         echo "unlink $MDSOBJS files @$next_id..."
16108         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16109 }
16110 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16111
16112 test_221() {
16113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16114
16115         dd if=`which date` of=$MOUNT/date oflag=sync
16116         chmod +x $MOUNT/date
16117
16118         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16119         $LCTL set_param fail_loc=0x80001401
16120
16121         $MOUNT/date > /dev/null
16122         rm -f $MOUNT/date
16123 }
16124 run_test 221 "make sure fault and truncate race to not cause OOM"
16125
16126 test_222a () {
16127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16128
16129         rm -rf $DIR/$tdir
16130         test_mkdir $DIR/$tdir
16131         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16132         createmany -o $DIR/$tdir/$tfile 10
16133         cancel_lru_locks mdc
16134         cancel_lru_locks osc
16135         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16136         $LCTL set_param fail_loc=0x31a
16137         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16138         $LCTL set_param fail_loc=0
16139         rm -r $DIR/$tdir
16140 }
16141 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16142
16143 test_222b () {
16144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16145
16146         rm -rf $DIR/$tdir
16147         test_mkdir $DIR/$tdir
16148         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16149         createmany -o $DIR/$tdir/$tfile 10
16150         cancel_lru_locks mdc
16151         cancel_lru_locks osc
16152         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16153         $LCTL set_param fail_loc=0x31a
16154         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16155         $LCTL set_param fail_loc=0
16156 }
16157 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16158
16159 test_223 () {
16160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16161
16162         rm -rf $DIR/$tdir
16163         test_mkdir $DIR/$tdir
16164         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16165         createmany -o $DIR/$tdir/$tfile 10
16166         cancel_lru_locks mdc
16167         cancel_lru_locks osc
16168         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16169         $LCTL set_param fail_loc=0x31b
16170         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16171         $LCTL set_param fail_loc=0
16172         rm -r $DIR/$tdir
16173 }
16174 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16175
16176 test_224a() { # LU-1039, MRP-303
16177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16178
16179         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16180         $LCTL set_param fail_loc=0x508
16181         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16182         $LCTL set_param fail_loc=0
16183         df $DIR
16184 }
16185 run_test 224a "Don't panic on bulk IO failure"
16186
16187 test_224b() { # LU-1039, MRP-303
16188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16189
16190         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16191         cancel_lru_locks osc
16192         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16193         $LCTL set_param fail_loc=0x515
16194         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16195         $LCTL set_param fail_loc=0
16196         df $DIR
16197 }
16198 run_test 224b "Don't panic on bulk IO failure"
16199
16200 test_224c() { # LU-6441
16201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16202         remote_mds_nodsh && skip "remote MDS with nodsh"
16203
16204         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16205         save_writethrough $p
16206         set_cache writethrough on
16207
16208         local pages_per_rpc=$($LCTL get_param \
16209                                 osc.*.max_pages_per_rpc)
16210         local at_max=$($LCTL get_param -n at_max)
16211         local timeout=$($LCTL get_param -n timeout)
16212         local test_at="at_max"
16213         local param_at="$FSNAME.sys.at_max"
16214         local test_timeout="timeout"
16215         local param_timeout="$FSNAME.sys.timeout"
16216
16217         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16218
16219         set_persistent_param_and_check client "$test_at" "$param_at" 0
16220         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16221
16222         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16223         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16224         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16225         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16226         sync
16227         do_facet ost1 "$LCTL set_param fail_loc=0"
16228
16229         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16230         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16231                 $timeout
16232
16233         $LCTL set_param -n $pages_per_rpc
16234         restore_lustre_params < $p
16235         rm -f $p
16236 }
16237 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16238
16239 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16240 test_225a () {
16241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16242         if [ -z ${MDSSURVEY} ]; then
16243                 skip_env "mds-survey not found"
16244         fi
16245         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16246                 skip "Need MDS version at least 2.2.51"
16247
16248         local mds=$(facet_host $SINGLEMDS)
16249         local target=$(do_nodes $mds 'lctl dl' |
16250                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16251
16252         local cmd1="file_count=1000 thrhi=4"
16253         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16254         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16255         local cmd="$cmd1 $cmd2 $cmd3"
16256
16257         rm -f ${TMP}/mds_survey*
16258         echo + $cmd
16259         eval $cmd || error "mds-survey with zero-stripe failed"
16260         cat ${TMP}/mds_survey*
16261         rm -f ${TMP}/mds_survey*
16262 }
16263 run_test 225a "Metadata survey sanity with zero-stripe"
16264
16265 test_225b () {
16266         if [ -z ${MDSSURVEY} ]; then
16267                 skip_env "mds-survey not found"
16268         fi
16269         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16270                 skip "Need MDS version at least 2.2.51"
16271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16272         remote_mds_nodsh && skip "remote MDS with nodsh"
16273         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16274                 skip_env "Need to mount OST to test"
16275         fi
16276
16277         local mds=$(facet_host $SINGLEMDS)
16278         local target=$(do_nodes $mds 'lctl dl' |
16279                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16280
16281         local cmd1="file_count=1000 thrhi=4"
16282         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16283         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16284         local cmd="$cmd1 $cmd2 $cmd3"
16285
16286         rm -f ${TMP}/mds_survey*
16287         echo + $cmd
16288         eval $cmd || error "mds-survey with stripe_count failed"
16289         cat ${TMP}/mds_survey*
16290         rm -f ${TMP}/mds_survey*
16291 }
16292 run_test 225b "Metadata survey sanity with stripe_count = 1"
16293
16294 mcreate_path2fid () {
16295         local mode=$1
16296         local major=$2
16297         local minor=$3
16298         local name=$4
16299         local desc=$5
16300         local path=$DIR/$tdir/$name
16301         local fid
16302         local rc
16303         local fid_path
16304
16305         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16306                 error "cannot create $desc"
16307
16308         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16309         rc=$?
16310         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16311
16312         fid_path=$($LFS fid2path $MOUNT $fid)
16313         rc=$?
16314         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16315
16316         [ "$path" == "$fid_path" ] ||
16317                 error "fid2path returned $fid_path, expected $path"
16318
16319         echo "pass with $path and $fid"
16320 }
16321
16322 test_226a () {
16323         rm -rf $DIR/$tdir
16324         mkdir -p $DIR/$tdir
16325
16326         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16327         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16328         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16329         mcreate_path2fid 0040666 0 0 dir "directory"
16330         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16331         mcreate_path2fid 0100666 0 0 file "regular file"
16332         mcreate_path2fid 0120666 0 0 link "symbolic link"
16333         mcreate_path2fid 0140666 0 0 sock "socket"
16334 }
16335 run_test 226a "call path2fid and fid2path on files of all type"
16336
16337 test_226b () {
16338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16339
16340         local MDTIDX=1
16341
16342         rm -rf $DIR/$tdir
16343         mkdir -p $DIR/$tdir
16344         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16345                 error "create remote directory failed"
16346         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16347         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16348                                 "character special file (null)"
16349         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16350                                 "character special file (no device)"
16351         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16352         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16353                                 "block special file (loop)"
16354         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16355         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16356         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16357 }
16358 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16359
16360 # LU-1299 Executing or running ldd on a truncated executable does not
16361 # cause an out-of-memory condition.
16362 test_227() {
16363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16364         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16365
16366         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16367         chmod +x $MOUNT/date
16368
16369         $MOUNT/date > /dev/null
16370         ldd $MOUNT/date > /dev/null
16371         rm -f $MOUNT/date
16372 }
16373 run_test 227 "running truncated executable does not cause OOM"
16374
16375 # LU-1512 try to reuse idle OI blocks
16376 test_228a() {
16377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16378         remote_mds_nodsh && skip "remote MDS with nodsh"
16379         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16380
16381         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16382         local myDIR=$DIR/$tdir
16383
16384         mkdir -p $myDIR
16385         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16386         $LCTL set_param fail_loc=0x80001002
16387         createmany -o $myDIR/t- 10000
16388         $LCTL set_param fail_loc=0
16389         # The guard is current the largest FID holder
16390         touch $myDIR/guard
16391         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16392                     tr -d '[')
16393         local IDX=$(($SEQ % 64))
16394
16395         do_facet $SINGLEMDS sync
16396         # Make sure journal flushed.
16397         sleep 6
16398         local blk1=$(do_facet $SINGLEMDS \
16399                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16400                      grep Blockcount | awk '{print $4}')
16401
16402         # Remove old files, some OI blocks will become idle.
16403         unlinkmany $myDIR/t- 10000
16404         # Create new files, idle OI blocks should be reused.
16405         createmany -o $myDIR/t- 2000
16406         do_facet $SINGLEMDS sync
16407         # Make sure journal flushed.
16408         sleep 6
16409         local blk2=$(do_facet $SINGLEMDS \
16410                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16411                      grep Blockcount | awk '{print $4}')
16412
16413         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16414 }
16415 run_test 228a "try to reuse idle OI blocks"
16416
16417 test_228b() {
16418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16419         remote_mds_nodsh && skip "remote MDS with nodsh"
16420         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16421
16422         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16423         local myDIR=$DIR/$tdir
16424
16425         mkdir -p $myDIR
16426         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16427         $LCTL set_param fail_loc=0x80001002
16428         createmany -o $myDIR/t- 10000
16429         $LCTL set_param fail_loc=0
16430         # The guard is current the largest FID holder
16431         touch $myDIR/guard
16432         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16433                     tr -d '[')
16434         local IDX=$(($SEQ % 64))
16435
16436         do_facet $SINGLEMDS sync
16437         # Make sure journal flushed.
16438         sleep 6
16439         local blk1=$(do_facet $SINGLEMDS \
16440                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16441                      grep Blockcount | awk '{print $4}')
16442
16443         # Remove old files, some OI blocks will become idle.
16444         unlinkmany $myDIR/t- 10000
16445
16446         # stop the MDT
16447         stop $SINGLEMDS || error "Fail to stop MDT."
16448         # remount the MDT
16449         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16450
16451         df $MOUNT || error "Fail to df."
16452         # Create new files, idle OI blocks should be reused.
16453         createmany -o $myDIR/t- 2000
16454         do_facet $SINGLEMDS sync
16455         # Make sure journal flushed.
16456         sleep 6
16457         local blk2=$(do_facet $SINGLEMDS \
16458                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16459                      grep Blockcount | awk '{print $4}')
16460
16461         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16462 }
16463 run_test 228b "idle OI blocks can be reused after MDT restart"
16464
16465 #LU-1881
16466 test_228c() {
16467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16468         remote_mds_nodsh && skip "remote MDS with nodsh"
16469         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16470
16471         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16472         local myDIR=$DIR/$tdir
16473
16474         mkdir -p $myDIR
16475         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16476         $LCTL set_param fail_loc=0x80001002
16477         # 20000 files can guarantee there are index nodes in the OI file
16478         createmany -o $myDIR/t- 20000
16479         $LCTL set_param fail_loc=0
16480         # The guard is current the largest FID holder
16481         touch $myDIR/guard
16482         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16483                     tr -d '[')
16484         local IDX=$(($SEQ % 64))
16485
16486         do_facet $SINGLEMDS sync
16487         # Make sure journal flushed.
16488         sleep 6
16489         local blk1=$(do_facet $SINGLEMDS \
16490                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16491                      grep Blockcount | awk '{print $4}')
16492
16493         # Remove old files, some OI blocks will become idle.
16494         unlinkmany $myDIR/t- 20000
16495         rm -f $myDIR/guard
16496         # The OI file should become empty now
16497
16498         # Create new files, idle OI blocks should be reused.
16499         createmany -o $myDIR/t- 2000
16500         do_facet $SINGLEMDS sync
16501         # Make sure journal flushed.
16502         sleep 6
16503         local blk2=$(do_facet $SINGLEMDS \
16504                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16505                      grep Blockcount | awk '{print $4}')
16506
16507         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16508 }
16509 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16510
16511 test_229() { # LU-2482, LU-3448
16512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16513         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16514         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16515                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16516
16517         rm -f $DIR/$tfile
16518
16519         # Create a file with a released layout and stripe count 2.
16520         $MULTIOP $DIR/$tfile H2c ||
16521                 error "failed to create file with released layout"
16522
16523         $LFS getstripe -v $DIR/$tfile
16524
16525         local pattern=$($LFS getstripe -L $DIR/$tfile)
16526         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16527
16528         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16529                 error "getstripe"
16530         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16531         stat $DIR/$tfile || error "failed to stat released file"
16532
16533         chown $RUNAS_ID $DIR/$tfile ||
16534                 error "chown $RUNAS_ID $DIR/$tfile failed"
16535
16536         chgrp $RUNAS_ID $DIR/$tfile ||
16537                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16538
16539         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16540         rm $DIR/$tfile || error "failed to remove released file"
16541 }
16542 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16543
16544 test_230a() {
16545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16546         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16547         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16548                 skip "Need MDS version at least 2.11.52"
16549
16550         local MDTIDX=1
16551
16552         test_mkdir $DIR/$tdir
16553         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16554         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16555         [ $mdt_idx -ne 0 ] &&
16556                 error "create local directory on wrong MDT $mdt_idx"
16557
16558         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16559                         error "create remote directory failed"
16560         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16561         [ $mdt_idx -ne $MDTIDX ] &&
16562                 error "create remote directory on wrong MDT $mdt_idx"
16563
16564         createmany -o $DIR/$tdir/test_230/t- 10 ||
16565                 error "create files on remote directory failed"
16566         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16567         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16568         rm -r $DIR/$tdir || error "unlink remote directory failed"
16569 }
16570 run_test 230a "Create remote directory and files under the remote directory"
16571
16572 test_230b() {
16573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16575         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16576                 skip "Need MDS version at least 2.11.52"
16577
16578         local MDTIDX=1
16579         local mdt_index
16580         local i
16581         local file
16582         local pid
16583         local stripe_count
16584         local migrate_dir=$DIR/$tdir/migrate_dir
16585         local other_dir=$DIR/$tdir/other_dir
16586
16587         test_mkdir $DIR/$tdir
16588         test_mkdir -i0 -c1 $migrate_dir
16589         test_mkdir -i0 -c1 $other_dir
16590         for ((i=0; i<10; i++)); do
16591                 mkdir -p $migrate_dir/dir_${i}
16592                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16593                         error "create files under remote dir failed $i"
16594         done
16595
16596         cp /etc/passwd $migrate_dir/$tfile
16597         cp /etc/passwd $other_dir/$tfile
16598         chattr +SAD $migrate_dir
16599         chattr +SAD $migrate_dir/$tfile
16600
16601         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16602         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16603         local old_dir_mode=$(stat -c%f $migrate_dir)
16604         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16605
16606         mkdir -p $migrate_dir/dir_default_stripe2
16607         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16608         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16609
16610         mkdir -p $other_dir
16611         ln $migrate_dir/$tfile $other_dir/luna
16612         ln $migrate_dir/$tfile $migrate_dir/sofia
16613         ln $other_dir/$tfile $migrate_dir/david
16614         ln -s $migrate_dir/$tfile $other_dir/zachary
16615         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16616         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16617
16618         $LFS migrate -m $MDTIDX $migrate_dir ||
16619                 error "fails on migrating remote dir to MDT1"
16620
16621         echo "migratate to MDT1, then checking.."
16622         for ((i = 0; i < 10; i++)); do
16623                 for file in $(find $migrate_dir/dir_${i}); do
16624                         mdt_index=$($LFS getstripe -m $file)
16625                         [ $mdt_index == $MDTIDX ] ||
16626                                 error "$file is not on MDT${MDTIDX}"
16627                 done
16628         done
16629
16630         # the multiple link file should still in MDT0
16631         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16632         [ $mdt_index == 0 ] ||
16633                 error "$file is not on MDT${MDTIDX}"
16634
16635         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16636         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16637                 error " expect $old_dir_flag get $new_dir_flag"
16638
16639         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16640         [ "$old_file_flag" = "$new_file_flag" ] ||
16641                 error " expect $old_file_flag get $new_file_flag"
16642
16643         local new_dir_mode=$(stat -c%f $migrate_dir)
16644         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16645                 error "expect mode $old_dir_mode get $new_dir_mode"
16646
16647         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16648         [ "$old_file_mode" = "$new_file_mode" ] ||
16649                 error "expect mode $old_file_mode get $new_file_mode"
16650
16651         diff /etc/passwd $migrate_dir/$tfile ||
16652                 error "$tfile different after migration"
16653
16654         diff /etc/passwd $other_dir/luna ||
16655                 error "luna different after migration"
16656
16657         diff /etc/passwd $migrate_dir/sofia ||
16658                 error "sofia different after migration"
16659
16660         diff /etc/passwd $migrate_dir/david ||
16661                 error "david different after migration"
16662
16663         diff /etc/passwd $other_dir/zachary ||
16664                 error "zachary different after migration"
16665
16666         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16667                 error "${tfile}_ln different after migration"
16668
16669         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16670                 error "${tfile}_ln_other different after migration"
16671
16672         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16673         [ $stripe_count = 2 ] ||
16674                 error "dir strpe_count $d != 2 after migration."
16675
16676         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16677         [ $stripe_count = 2 ] ||
16678                 error "file strpe_count $d != 2 after migration."
16679
16680         #migrate back to MDT0
16681         MDTIDX=0
16682
16683         $LFS migrate -m $MDTIDX $migrate_dir ||
16684                 error "fails on migrating remote dir to MDT0"
16685
16686         echo "migrate back to MDT0, checking.."
16687         for file in $(find $migrate_dir); do
16688                 mdt_index=$($LFS getstripe -m $file)
16689                 [ $mdt_index == $MDTIDX ] ||
16690                         error "$file is not on MDT${MDTIDX}"
16691         done
16692
16693         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16694         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16695                 error " expect $old_dir_flag get $new_dir_flag"
16696
16697         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16698         [ "$old_file_flag" = "$new_file_flag" ] ||
16699                 error " expect $old_file_flag get $new_file_flag"
16700
16701         local new_dir_mode=$(stat -c%f $migrate_dir)
16702         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16703                 error "expect mode $old_dir_mode get $new_dir_mode"
16704
16705         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16706         [ "$old_file_mode" = "$new_file_mode" ] ||
16707                 error "expect mode $old_file_mode get $new_file_mode"
16708
16709         diff /etc/passwd ${migrate_dir}/$tfile ||
16710                 error "$tfile different after migration"
16711
16712         diff /etc/passwd ${other_dir}/luna ||
16713                 error "luna different after migration"
16714
16715         diff /etc/passwd ${migrate_dir}/sofia ||
16716                 error "sofia different after migration"
16717
16718         diff /etc/passwd ${other_dir}/zachary ||
16719                 error "zachary different after migration"
16720
16721         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16722                 error "${tfile}_ln different after migration"
16723
16724         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16725                 error "${tfile}_ln_other different after migration"
16726
16727         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16728         [ $stripe_count = 2 ] ||
16729                 error "dir strpe_count $d != 2 after migration."
16730
16731         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16732         [ $stripe_count = 2 ] ||
16733                 error "file strpe_count $d != 2 after migration."
16734
16735         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16736 }
16737 run_test 230b "migrate directory"
16738
16739 test_230c() {
16740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16742         remote_mds_nodsh && skip "remote MDS with nodsh"
16743         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16744                 skip "Need MDS version at least 2.11.52"
16745
16746         local MDTIDX=1
16747         local total=3
16748         local mdt_index
16749         local file
16750         local migrate_dir=$DIR/$tdir/migrate_dir
16751
16752         #If migrating directory fails in the middle, all entries of
16753         #the directory is still accessiable.
16754         test_mkdir $DIR/$tdir
16755         test_mkdir -i0 -c1 $migrate_dir
16756         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16757         stat $migrate_dir
16758         createmany -o $migrate_dir/f $total ||
16759                 error "create files under ${migrate_dir} failed"
16760
16761         # fail after migrating top dir, and this will fail only once, so the
16762         # first sub file migration will fail (currently f3), others succeed.
16763         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16764         do_facet mds1 lctl set_param fail_loc=0x1801
16765         local t=$(ls $migrate_dir | wc -l)
16766         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16767                 error "migrate should fail"
16768         local u=$(ls $migrate_dir | wc -l)
16769         [ "$u" == "$t" ] || error "$u != $t during migration"
16770
16771         # add new dir/file should succeed
16772         mkdir $migrate_dir/dir ||
16773                 error "mkdir failed under migrating directory"
16774         touch $migrate_dir/file ||
16775                 error "create file failed under migrating directory"
16776
16777         # add file with existing name should fail
16778         for file in $migrate_dir/f*; do
16779                 stat $file > /dev/null || error "stat $file failed"
16780                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16781                         error "open(O_CREAT|O_EXCL) $file should fail"
16782                 $MULTIOP $file m && error "create $file should fail"
16783                 touch $DIR/$tdir/remote_dir/$tfile ||
16784                         error "touch $tfile failed"
16785                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16786                         error "link $file should fail"
16787                 mdt_index=$($LFS getstripe -m $file)
16788                 if [ $mdt_index == 0 ]; then
16789                         # file failed to migrate is not allowed to rename to
16790                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16791                                 error "rename to $file should fail"
16792                 else
16793                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16794                                 error "rename to $file failed"
16795                 fi
16796                 echo hello >> $file || error "write $file failed"
16797         done
16798
16799         # resume migration with different options should fail
16800         $LFS migrate -m 0 $migrate_dir &&
16801                 error "migrate -m 0 $migrate_dir should fail"
16802
16803         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16804                 error "migrate -c 2 $migrate_dir should fail"
16805
16806         # resume migration should succeed
16807         $LFS migrate -m $MDTIDX $migrate_dir ||
16808                 error "migrate $migrate_dir failed"
16809
16810         echo "Finish migration, then checking.."
16811         for file in $(find $migrate_dir); do
16812                 mdt_index=$($LFS getstripe -m $file)
16813                 [ $mdt_index == $MDTIDX ] ||
16814                         error "$file is not on MDT${MDTIDX}"
16815         done
16816
16817         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16818 }
16819 run_test 230c "check directory accessiblity if migration failed"
16820
16821 test_230d() {
16822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16823         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16824         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16825                 skip "Need MDS version at least 2.11.52"
16826         # LU-11235
16827         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16828
16829         local migrate_dir=$DIR/$tdir/migrate_dir
16830         local old_index
16831         local new_index
16832         local old_count
16833         local new_count
16834         local new_hash
16835         local mdt_index
16836         local i
16837         local j
16838
16839         old_index=$((RANDOM % MDSCOUNT))
16840         old_count=$((MDSCOUNT - old_index))
16841         new_index=$((RANDOM % MDSCOUNT))
16842         new_count=$((MDSCOUNT - new_index))
16843         new_hash="all_char"
16844
16845         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16846         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16847
16848         test_mkdir $DIR/$tdir
16849         test_mkdir -i $old_index -c $old_count $migrate_dir
16850
16851         for ((i=0; i<100; i++)); do
16852                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16853                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16854                         error "create files under remote dir failed $i"
16855         done
16856
16857         echo -n "Migrate from MDT$old_index "
16858         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16859         echo -n "to MDT$new_index"
16860         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16861         echo
16862
16863         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16864         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16865                 error "migrate remote dir error"
16866
16867         echo "Finish migration, then checking.."
16868         for file in $(find $migrate_dir); do
16869                 mdt_index=$($LFS getstripe -m $file)
16870                 if [ $mdt_index -lt $new_index ] ||
16871                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16872                         error "$file is on MDT$mdt_index"
16873                 fi
16874         done
16875
16876         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16877 }
16878 run_test 230d "check migrate big directory"
16879
16880 test_230e() {
16881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16883         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16884                 skip "Need MDS version at least 2.11.52"
16885
16886         local i
16887         local j
16888         local a_fid
16889         local b_fid
16890
16891         mkdir -p $DIR/$tdir
16892         mkdir $DIR/$tdir/migrate_dir
16893         mkdir $DIR/$tdir/other_dir
16894         touch $DIR/$tdir/migrate_dir/a
16895         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16896         ls $DIR/$tdir/other_dir
16897
16898         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16899                 error "migrate dir fails"
16900
16901         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16902         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16903
16904         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16905         [ $mdt_index == 0 ] || error "a is not on MDT0"
16906
16907         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16908                 error "migrate dir fails"
16909
16910         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16911         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16912
16913         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16914         [ $mdt_index == 1 ] || error "a is not on MDT1"
16915
16916         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16917         [ $mdt_index == 1 ] || error "b is not on MDT1"
16918
16919         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16920         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16921
16922         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16923
16924         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16925 }
16926 run_test 230e "migrate mulitple local link files"
16927
16928 test_230f() {
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16931         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16932                 skip "Need MDS version at least 2.11.52"
16933
16934         local a_fid
16935         local ln_fid
16936
16937         mkdir -p $DIR/$tdir
16938         mkdir $DIR/$tdir/migrate_dir
16939         $LFS mkdir -i1 $DIR/$tdir/other_dir
16940         touch $DIR/$tdir/migrate_dir/a
16941         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16942         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16943         ls $DIR/$tdir/other_dir
16944
16945         # a should be migrated to MDT1, since no other links on MDT0
16946         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16947                 error "#1 migrate dir fails"
16948         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16949         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16950         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16951         [ $mdt_index == 1 ] || error "a is not on MDT1"
16952
16953         # a should stay on MDT1, because it is a mulitple link file
16954         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16955                 error "#2 migrate dir fails"
16956         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16957         [ $mdt_index == 1 ] || error "a is not on MDT1"
16958
16959         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16960                 error "#3 migrate dir fails"
16961
16962         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16963         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16964         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16965
16966         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16967         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16968
16969         # a should be migrated to MDT0, since no other links on MDT1
16970         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16971                 error "#4 migrate dir fails"
16972         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16973         [ $mdt_index == 0 ] || error "a is not on MDT0"
16974
16975         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16976 }
16977 run_test 230f "migrate mulitple remote link files"
16978
16979 test_230g() {
16980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16982         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16983                 skip "Need MDS version at least 2.11.52"
16984
16985         mkdir -p $DIR/$tdir/migrate_dir
16986
16987         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16988                 error "migrating dir to non-exist MDT succeeds"
16989         true
16990 }
16991 run_test 230g "migrate dir to non-exist MDT"
16992
16993 test_230h() {
16994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16995         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16996         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16997                 skip "Need MDS version at least 2.11.52"
16998
16999         local mdt_index
17000
17001         mkdir -p $DIR/$tdir/migrate_dir
17002
17003         $LFS migrate -m1 $DIR &&
17004                 error "migrating mountpoint1 should fail"
17005
17006         $LFS migrate -m1 $DIR/$tdir/.. &&
17007                 error "migrating mountpoint2 should fail"
17008
17009         # same as mv
17010         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17011                 error "migrating $tdir/migrate_dir/.. should fail"
17012
17013         true
17014 }
17015 run_test 230h "migrate .. and root"
17016
17017 test_230i() {
17018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17020         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17021                 skip "Need MDS version at least 2.11.52"
17022
17023         mkdir -p $DIR/$tdir/migrate_dir
17024
17025         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17026                 error "migration fails with a tailing slash"
17027
17028         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17029                 error "migration fails with two tailing slashes"
17030 }
17031 run_test 230i "lfs migrate -m tolerates trailing slashes"
17032
17033 test_230j() {
17034         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17035         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17036                 skip "Need MDS version at least 2.11.52"
17037
17038         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17039         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17040                 error "create $tfile failed"
17041         cat /etc/passwd > $DIR/$tdir/$tfile
17042
17043         $LFS migrate -m 1 $DIR/$tdir
17044
17045         cmp /etc/passwd $DIR/$tdir/$tfile ||
17046                 error "DoM file mismatch after migration"
17047 }
17048 run_test 230j "DoM file data not changed after dir migration"
17049
17050 test_230k() {
17051         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17052         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17053                 skip "Need MDS version at least 2.11.56"
17054
17055         local total=20
17056         local files_on_starting_mdt=0
17057
17058         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17059         $LFS getdirstripe $DIR/$tdir
17060         for i in $(seq $total); do
17061                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17062                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17063                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17064         done
17065
17066         echo "$files_on_starting_mdt files on MDT0"
17067
17068         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17069         $LFS getdirstripe $DIR/$tdir
17070
17071         files_on_starting_mdt=0
17072         for i in $(seq $total); do
17073                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17074                         error "file $tfile.$i mismatch after migration"
17075                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17076                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17077         done
17078
17079         echo "$files_on_starting_mdt files on MDT1 after migration"
17080         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17081
17082         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17083         $LFS getdirstripe $DIR/$tdir
17084
17085         files_on_starting_mdt=0
17086         for i in $(seq $total); do
17087                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17088                         error "file $tfile.$i mismatch after 2nd migration"
17089                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17090                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17091         done
17092
17093         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17094         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17095
17096         true
17097 }
17098 run_test 230k "file data not changed after dir migration"
17099
17100 test_230l() {
17101         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17102         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17103                 skip "Need MDS version at least 2.11.56"
17104
17105         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17106         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17107                 error "create files under remote dir failed $i"
17108         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17109 }
17110 run_test 230l "readdir between MDTs won't crash"
17111
17112 test_230m() {
17113         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17114         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17115                 skip "Need MDS version at least 2.11.56"
17116
17117         local MDTIDX=1
17118         local mig_dir=$DIR/$tdir/migrate_dir
17119         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17120         local shortstr="b"
17121         local val
17122
17123         echo "Creating files and dirs with xattrs"
17124         test_mkdir $DIR/$tdir
17125         test_mkdir -i0 -c1 $mig_dir
17126         mkdir $mig_dir/dir
17127         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17128                 error "cannot set xattr attr1 on dir"
17129         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17130                 error "cannot set xattr attr2 on dir"
17131         touch $mig_dir/dir/f0
17132         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17133                 error "cannot set xattr attr1 on file"
17134         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17135                 error "cannot set xattr attr2 on file"
17136         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17137         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17138         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17139         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17140         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17141         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17142         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17143         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17144         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17145
17146         echo "Migrating to MDT1"
17147         $LFS migrate -m $MDTIDX $mig_dir ||
17148                 error "fails on migrating dir to MDT1"
17149
17150         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17151         echo "Checking xattrs"
17152         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17153         [ "$val" = $longstr ] ||
17154                 error "expecting xattr1 $longstr on dir, found $val"
17155         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17156         [ "$val" = $shortstr ] ||
17157                 error "expecting xattr2 $shortstr on dir, found $val"
17158         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17159         [ "$val" = $longstr ] ||
17160                 error "expecting xattr1 $longstr on file, found $val"
17161         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17162         [ "$val" = $shortstr ] ||
17163                 error "expecting xattr2 $shortstr on file, found $val"
17164 }
17165 run_test 230m "xattrs not changed after dir migration"
17166
17167 test_231a()
17168 {
17169         # For simplicity this test assumes that max_pages_per_rpc
17170         # is the same across all OSCs
17171         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17172         local bulk_size=$((max_pages * PAGE_SIZE))
17173         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17174                                        head -n 1)
17175
17176         mkdir -p $DIR/$tdir
17177         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17178                 error "failed to set stripe with -S ${brw_size}M option"
17179
17180         # clear the OSC stats
17181         $LCTL set_param osc.*.stats=0 &>/dev/null
17182         stop_writeback
17183
17184         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17185         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17186                 oflag=direct &>/dev/null || error "dd failed"
17187
17188         sync; sleep 1; sync # just to be safe
17189         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17190         if [ x$nrpcs != "x1" ]; then
17191                 $LCTL get_param osc.*.stats
17192                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17193         fi
17194
17195         start_writeback
17196         # Drop the OSC cache, otherwise we will read from it
17197         cancel_lru_locks osc
17198
17199         # clear the OSC stats
17200         $LCTL set_param osc.*.stats=0 &>/dev/null
17201
17202         # Client reads $bulk_size.
17203         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17204                 iflag=direct &>/dev/null || error "dd failed"
17205
17206         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17207         if [ x$nrpcs != "x1" ]; then
17208                 $LCTL get_param osc.*.stats
17209                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17210         fi
17211 }
17212 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17213
17214 test_231b() {
17215         mkdir -p $DIR/$tdir
17216         local i
17217         for i in {0..1023}; do
17218                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17219                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17220                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17221         done
17222         sync
17223 }
17224 run_test 231b "must not assert on fully utilized OST request buffer"
17225
17226 test_232a() {
17227         mkdir -p $DIR/$tdir
17228         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17229
17230         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17231         do_facet ost1 $LCTL set_param fail_loc=0x31c
17232
17233         # ignore dd failure
17234         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17235
17236         do_facet ost1 $LCTL set_param fail_loc=0
17237         umount_client $MOUNT || error "umount failed"
17238         mount_client $MOUNT || error "mount failed"
17239         stop ost1 || error "cannot stop ost1"
17240         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17241 }
17242 run_test 232a "failed lock should not block umount"
17243
17244 test_232b() {
17245         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17246                 skip "Need MDS version at least 2.10.58"
17247
17248         mkdir -p $DIR/$tdir
17249         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17250         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17251         sync
17252         cancel_lru_locks osc
17253
17254         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17255         do_facet ost1 $LCTL set_param fail_loc=0x31c
17256
17257         # ignore failure
17258         $LFS data_version $DIR/$tdir/$tfile || true
17259
17260         do_facet ost1 $LCTL set_param fail_loc=0
17261         umount_client $MOUNT || error "umount failed"
17262         mount_client $MOUNT || error "mount failed"
17263         stop ost1 || error "cannot stop ost1"
17264         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17265 }
17266 run_test 232b "failed data version lock should not block umount"
17267
17268 test_233a() {
17269         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17270                 skip "Need MDS version at least 2.3.64"
17271         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17272
17273         local fid=$($LFS path2fid $MOUNT)
17274
17275         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17276                 error "cannot access $MOUNT using its FID '$fid'"
17277 }
17278 run_test 233a "checking that OBF of the FS root succeeds"
17279
17280 test_233b() {
17281         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17282                 skip "Need MDS version at least 2.5.90"
17283         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17284
17285         local fid=$($LFS path2fid $MOUNT/.lustre)
17286
17287         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17288                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17289
17290         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17291         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17292                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17293 }
17294 run_test 233b "checking that OBF of the FS .lustre succeeds"
17295
17296 test_234() {
17297         local p="$TMP/sanityN-$TESTNAME.parameters"
17298         save_lustre_params client "llite.*.xattr_cache" > $p
17299         lctl set_param llite.*.xattr_cache 1 ||
17300                 skip_env "xattr cache is not supported"
17301
17302         mkdir -p $DIR/$tdir || error "mkdir failed"
17303         touch $DIR/$tdir/$tfile || error "touch failed"
17304         # OBD_FAIL_LLITE_XATTR_ENOMEM
17305         $LCTL set_param fail_loc=0x1405
17306         getfattr -n user.attr $DIR/$tdir/$tfile &&
17307                 error "getfattr should have failed with ENOMEM"
17308         $LCTL set_param fail_loc=0x0
17309         rm -rf $DIR/$tdir
17310
17311         restore_lustre_params < $p
17312         rm -f $p
17313 }
17314 run_test 234 "xattr cache should not crash on ENOMEM"
17315
17316 test_235() {
17317         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17318                 skip "Need MDS version at least 2.4.52"
17319
17320         flock_deadlock $DIR/$tfile
17321         local RC=$?
17322         case $RC in
17323                 0)
17324                 ;;
17325                 124) error "process hangs on a deadlock"
17326                 ;;
17327                 *) error "error executing flock_deadlock $DIR/$tfile"
17328                 ;;
17329         esac
17330 }
17331 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17332
17333 #LU-2935
17334 test_236() {
17335         check_swap_layouts_support
17336
17337         local ref1=/etc/passwd
17338         local ref2=/etc/group
17339         local file1=$DIR/$tdir/f1
17340         local file2=$DIR/$tdir/f2
17341
17342         test_mkdir -c1 $DIR/$tdir
17343         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17344         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17345         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17346         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17347         local fd=$(free_fd)
17348         local cmd="exec $fd<>$file2"
17349         eval $cmd
17350         rm $file2
17351         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17352                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17353         cmd="exec $fd>&-"
17354         eval $cmd
17355         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17356
17357         #cleanup
17358         rm -rf $DIR/$tdir
17359 }
17360 run_test 236 "Layout swap on open unlinked file"
17361
17362 # LU-4659 linkea consistency
17363 test_238() {
17364         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17365                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17366                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17367                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17368
17369         touch $DIR/$tfile
17370         ln $DIR/$tfile $DIR/$tfile.lnk
17371         touch $DIR/$tfile.new
17372         mv $DIR/$tfile.new $DIR/$tfile
17373         local fid1=$($LFS path2fid $DIR/$tfile)
17374         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17375         local path1=$($LFS fid2path $FSNAME "$fid1")
17376         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17377         local path2=$($LFS fid2path $FSNAME "$fid2")
17378         [ $tfile.lnk == $path2 ] ||
17379                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17380         rm -f $DIR/$tfile*
17381 }
17382 run_test 238 "Verify linkea consistency"
17383
17384 test_239A() { # was test_239
17385         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17386                 skip "Need MDS version at least 2.5.60"
17387
17388         local list=$(comma_list $(mdts_nodes))
17389
17390         mkdir -p $DIR/$tdir
17391         createmany -o $DIR/$tdir/f- 5000
17392         unlinkmany $DIR/$tdir/f- 5000
17393         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17394                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17395         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17396                         osp.*MDT*.sync_in_flight" | calc_sum)
17397         [ "$changes" -eq 0 ] || error "$changes not synced"
17398 }
17399 run_test 239A "osp_sync test"
17400
17401 test_239a() { #LU-5297
17402         remote_mds_nodsh && skip "remote MDS with nodsh"
17403
17404         touch $DIR/$tfile
17405         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17406         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17407         chgrp $RUNAS_GID $DIR/$tfile
17408         wait_delete_completed
17409 }
17410 run_test 239a "process invalid osp sync record correctly"
17411
17412 test_239b() { #LU-5297
17413         remote_mds_nodsh && skip "remote MDS with nodsh"
17414
17415         touch $DIR/$tfile1
17416         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17417         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17418         chgrp $RUNAS_GID $DIR/$tfile1
17419         wait_delete_completed
17420         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17421         touch $DIR/$tfile2
17422         chgrp $RUNAS_GID $DIR/$tfile2
17423         wait_delete_completed
17424 }
17425 run_test 239b "process osp sync record with ENOMEM error correctly"
17426
17427 test_240() {
17428         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17429         remote_mds_nodsh && skip "remote MDS with nodsh"
17430
17431         mkdir -p $DIR/$tdir
17432
17433         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17434                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17435         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17436                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17437
17438         umount_client $MOUNT || error "umount failed"
17439         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17440         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17441         mount_client $MOUNT || error "failed to mount client"
17442
17443         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17444         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17445 }
17446 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17447
17448 test_241_bio() {
17449         local count=$1
17450         local bsize=$2
17451
17452         for LOOP in $(seq $count); do
17453                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17454                 cancel_lru_locks $OSC || true
17455         done
17456 }
17457
17458 test_241_dio() {
17459         local count=$1
17460         local bsize=$2
17461
17462         for LOOP in $(seq $1); do
17463                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17464                         2>/dev/null
17465         done
17466 }
17467
17468 test_241a() { # was test_241
17469         local bsize=$PAGE_SIZE
17470
17471         (( bsize < 40960 )) && bsize=40960
17472         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17473         ls -la $DIR/$tfile
17474         cancel_lru_locks $OSC
17475         test_241_bio 1000 $bsize &
17476         PID=$!
17477         test_241_dio 1000 $bsize
17478         wait $PID
17479 }
17480 run_test 241a "bio vs dio"
17481
17482 test_241b() {
17483         local bsize=$PAGE_SIZE
17484
17485         (( bsize < 40960 )) && bsize=40960
17486         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17487         ls -la $DIR/$tfile
17488         test_241_dio 1000 $bsize &
17489         PID=$!
17490         test_241_dio 1000 $bsize
17491         wait $PID
17492 }
17493 run_test 241b "dio vs dio"
17494
17495 test_242() {
17496         remote_mds_nodsh && skip "remote MDS with nodsh"
17497
17498         mkdir -p $DIR/$tdir
17499         touch $DIR/$tdir/$tfile
17500
17501         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17502         do_facet mds1 lctl set_param fail_loc=0x105
17503         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17504
17505         do_facet mds1 lctl set_param fail_loc=0
17506         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17507 }
17508 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17509
17510 test_243()
17511 {
17512         test_mkdir $DIR/$tdir
17513         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17514 }
17515 run_test 243 "various group lock tests"
17516
17517 test_244a()
17518 {
17519         test_mkdir $DIR/$tdir
17520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17521         sendfile_grouplock $DIR/$tdir/$tfile || \
17522                 error "sendfile+grouplock failed"
17523         rm -rf $DIR/$tdir
17524 }
17525 run_test 244a "sendfile with group lock tests"
17526
17527 test_244b()
17528 {
17529         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17530
17531         local threads=50
17532         local size=$((1024*1024))
17533
17534         test_mkdir $DIR/$tdir
17535         for i in $(seq 1 $threads); do
17536                 local file=$DIR/$tdir/file_$((i / 10))
17537                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17538                 local pids[$i]=$!
17539         done
17540         for i in $(seq 1 $threads); do
17541                 wait ${pids[$i]}
17542         done
17543 }
17544 run_test 244b "multi-threaded write with group lock"
17545
17546 test_245() {
17547         local flagname="multi_mod_rpcs"
17548         local connect_data_name="max_mod_rpcs"
17549         local out
17550
17551         # check if multiple modify RPCs flag is set
17552         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17553                 grep "connect_flags:")
17554         echo "$out"
17555
17556         echo "$out" | grep -qw $flagname
17557         if [ $? -ne 0 ]; then
17558                 echo "connect flag $flagname is not set"
17559                 return
17560         fi
17561
17562         # check if multiple modify RPCs data is set
17563         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17564         echo "$out"
17565
17566         echo "$out" | grep -qw $connect_data_name ||
17567                 error "import should have connect data $connect_data_name"
17568 }
17569 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17570
17571 cleanup_247() {
17572         local submount=$1
17573
17574         trap 0
17575         umount_client $submount
17576         rmdir $submount
17577 }
17578
17579 test_247a() {
17580         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17581                 grep -q subtree ||
17582                 skip_env "Fileset feature is not supported"
17583
17584         local submount=${MOUNT}_$tdir
17585
17586         mkdir $MOUNT/$tdir
17587         mkdir -p $submount || error "mkdir $submount failed"
17588         FILESET="$FILESET/$tdir" mount_client $submount ||
17589                 error "mount $submount failed"
17590         trap "cleanup_247 $submount" EXIT
17591         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17592         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17593                 error "read $MOUNT/$tdir/$tfile failed"
17594         cleanup_247 $submount
17595 }
17596 run_test 247a "mount subdir as fileset"
17597
17598 test_247b() {
17599         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17600                 skip_env "Fileset feature is not supported"
17601
17602         local submount=${MOUNT}_$tdir
17603
17604         rm -rf $MOUNT/$tdir
17605         mkdir -p $submount || error "mkdir $submount failed"
17606         SKIP_FILESET=1
17607         FILESET="$FILESET/$tdir" mount_client $submount &&
17608                 error "mount $submount should fail"
17609         rmdir $submount
17610 }
17611 run_test 247b "mount subdir that dose not exist"
17612
17613 test_247c() {
17614         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17615                 skip_env "Fileset feature is not supported"
17616
17617         local submount=${MOUNT}_$tdir
17618
17619         mkdir -p $MOUNT/$tdir/dir1
17620         mkdir -p $submount || error "mkdir $submount failed"
17621         trap "cleanup_247 $submount" EXIT
17622         FILESET="$FILESET/$tdir" mount_client $submount ||
17623                 error "mount $submount failed"
17624         local fid=$($LFS path2fid $MOUNT/)
17625         $LFS fid2path $submount $fid && error "fid2path should fail"
17626         cleanup_247 $submount
17627 }
17628 run_test 247c "running fid2path outside root"
17629
17630 test_247d() {
17631         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17632                 skip "Fileset feature is not supported"
17633
17634         local submount=${MOUNT}_$tdir
17635
17636         mkdir -p $MOUNT/$tdir/dir1
17637         mkdir -p $submount || error "mkdir $submount failed"
17638         FILESET="$FILESET/$tdir" mount_client $submount ||
17639                 error "mount $submount failed"
17640         trap "cleanup_247 $submount" EXIT
17641         local fid=$($LFS path2fid $submount/dir1)
17642         $LFS fid2path $submount $fid || error "fid2path should succeed"
17643         cleanup_247 $submount
17644 }
17645 run_test 247d "running fid2path inside root"
17646
17647 # LU-8037
17648 test_247e() {
17649         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17650                 grep -q subtree ||
17651                 skip "Fileset feature is not supported"
17652
17653         local submount=${MOUNT}_$tdir
17654
17655         mkdir $MOUNT/$tdir
17656         mkdir -p $submount || error "mkdir $submount failed"
17657         FILESET="$FILESET/.." mount_client $submount &&
17658                 error "mount $submount should fail"
17659         rmdir $submount
17660 }
17661 run_test 247e "mount .. as fileset"
17662
17663 test_248a() {
17664         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17665         [ -z "$fast_read_sav" ] && skip "no fast read support"
17666
17667         # create a large file for fast read verification
17668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17669
17670         # make sure the file is created correctly
17671         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17672                 { rm -f $DIR/$tfile; skip "file creation error"; }
17673
17674         echo "Test 1: verify that fast read is 4 times faster on cache read"
17675
17676         # small read with fast read enabled
17677         $LCTL set_param -n llite.*.fast_read=1
17678         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17679                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17680                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17681         # small read with fast read disabled
17682         $LCTL set_param -n llite.*.fast_read=0
17683         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17684                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17685                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17686
17687         # verify that fast read is 4 times faster for cache read
17688         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17689                 error_not_in_vm "fast read was not 4 times faster: " \
17690                            "$t_fast vs $t_slow"
17691
17692         echo "Test 2: verify the performance between big and small read"
17693         $LCTL set_param -n llite.*.fast_read=1
17694
17695         # 1k non-cache read
17696         cancel_lru_locks osc
17697         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17698                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17699                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17700
17701         # 1M non-cache read
17702         cancel_lru_locks osc
17703         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17704                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17705                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17706
17707         # verify that big IO is not 4 times faster than small IO
17708         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17709                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17710
17711         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17712         rm -f $DIR/$tfile
17713 }
17714 run_test 248a "fast read verification"
17715
17716 test_248b() {
17717         # Default short_io_bytes=16384, try both smaller and larger sizes.
17718         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
17719         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
17720         echo "bs=53248 count=113 normal buffered write"
17721         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
17722                 error "dd of initial data file failed"
17723         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
17724
17725         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
17726         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
17727                 error "dd with sync normal writes failed"
17728         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
17729
17730         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
17731         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
17732                 error "dd with sync small writes failed"
17733         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
17734
17735         cancel_lru_locks osc
17736
17737         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
17738         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
17739         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
17740         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
17741                 iflag=direct || error "dd with O_DIRECT small read failed"
17742         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
17743         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
17744                 error "compare $TMP/$tfile.1 failed"
17745
17746         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
17747         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
17748
17749         # just to see what the maximum tunable value is, and test parsing
17750         echo "test invalid parameter 2MB"
17751         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
17752                 error "too-large short_io_bytes allowed"
17753         echo "test maximum parameter 512KB"
17754         # if we can set a larger short_io_bytes, run test regardless of version
17755         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
17756                 # older clients may not allow setting it this large, that's OK
17757                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
17758                         skip "Need at least client version 2.13.50"
17759                 error "medium short_io_bytes failed"
17760         fi
17761         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17762         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
17763
17764         echo "test large parameter 64KB"
17765         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
17766         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17767
17768         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
17769         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
17770                 error "dd with sync large writes failed"
17771         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
17772
17773         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
17774         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
17775         num=$((113 * 4096 / PAGE_SIZE))
17776         echo "bs=$size count=$num oflag=direct large write $tfile.3"
17777         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
17778                 error "dd with O_DIRECT large writes failed"
17779         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
17780                 error "compare $DIR/$tfile.3 failed"
17781
17782         cancel_lru_locks osc
17783
17784         echo "bs=$size count=$num iflag=direct large read $tfile.2"
17785         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
17786                 error "dd with O_DIRECT large read failed"
17787         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
17788                 error "compare $TMP/$tfile.2 failed"
17789
17790         echo "bs=$size count=$num iflag=direct large read $tfile.3"
17791         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
17792                 error "dd with O_DIRECT large read failed"
17793         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
17794                 error "compare $TMP/$tfile.3 failed"
17795 }
17796 run_test 248b "test short_io read and write for both small and large sizes"
17797
17798 test_249() { # LU-7890
17799         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17800                 skip "Need at least version 2.8.54"
17801
17802         rm -f $DIR/$tfile
17803         $LFS setstripe -c 1 $DIR/$tfile
17804         # Offset 2T == 4k * 512M
17805         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17806                 error "dd to 2T offset failed"
17807 }
17808 run_test 249 "Write above 2T file size"
17809
17810 test_250() {
17811         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17812          && skip "no 16TB file size limit on ZFS"
17813
17814         $LFS setstripe -c 1 $DIR/$tfile
17815         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17816         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17817         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17818         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17819                 conv=notrunc,fsync && error "append succeeded"
17820         return 0
17821 }
17822 run_test 250 "Write above 16T limit"
17823
17824 test_251() {
17825         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17826
17827         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17828         #Skip once - writing the first stripe will succeed
17829         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17830         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17831                 error "short write happened"
17832
17833         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17834         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17835                 error "short read happened"
17836
17837         rm -f $DIR/$tfile
17838 }
17839 run_test 251 "Handling short read and write correctly"
17840
17841 test_252() {
17842         remote_mds_nodsh && skip "remote MDS with nodsh"
17843         remote_ost_nodsh && skip "remote OST with nodsh"
17844         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17845                 skip_env "ldiskfs only test"
17846         fi
17847
17848         local tgt
17849         local dev
17850         local out
17851         local uuid
17852         local num
17853         local gen
17854
17855         # check lr_reader on OST0000
17856         tgt=ost1
17857         dev=$(facet_device $tgt)
17858         out=$(do_facet $tgt $LR_READER $dev)
17859         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17860         echo "$out"
17861         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17862         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17863                 error "Invalid uuid returned by $LR_READER on target $tgt"
17864         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17865
17866         # check lr_reader -c on MDT0000
17867         tgt=mds1
17868         dev=$(facet_device $tgt)
17869         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17870                 skip "$LR_READER does not support additional options"
17871         fi
17872         out=$(do_facet $tgt $LR_READER -c $dev)
17873         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17874         echo "$out"
17875         num=$(echo "$out" | grep -c "mdtlov")
17876         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17877                 error "Invalid number of mdtlov clients returned by $LR_READER"
17878         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17879
17880         # check lr_reader -cr on MDT0000
17881         out=$(do_facet $tgt $LR_READER -cr $dev)
17882         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17883         echo "$out"
17884         echo "$out" | grep -q "^reply_data:$" ||
17885                 error "$LR_READER should have returned 'reply_data' section"
17886         num=$(echo "$out" | grep -c "client_generation")
17887         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17888 }
17889 run_test 252 "check lr_reader tool"
17890
17891 test_253() {
17892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17893         remote_mds_nodsh && skip "remote MDS with nodsh"
17894         remote_mgs_nodsh && skip "remote MGS with nodsh"
17895
17896         local ostidx=0
17897         local rc=0
17898         local ost_name=$(ostname_from_index $ostidx)
17899
17900         # on the mdt's osc
17901         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17902         do_facet $SINGLEMDS $LCTL get_param -n \
17903                 osp.$mdtosc_proc1.reserved_mb_high ||
17904                 skip  "remote MDS does not support reserved_mb_high"
17905
17906         rm -rf $DIR/$tdir
17907         wait_mds_ost_sync
17908         wait_delete_completed
17909         mkdir $DIR/$tdir
17910
17911         pool_add $TESTNAME || error "Pool creation failed"
17912         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17913
17914         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17915                 error "Setstripe failed"
17916
17917         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17918
17919         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17920                     grep "watermarks")
17921         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17922
17923         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17924                         osp.$mdtosc_proc1.prealloc_status)
17925         echo "prealloc_status $oa_status"
17926
17927         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17928                 error "File creation should fail"
17929
17930         #object allocation was stopped, but we still able to append files
17931         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17932                 oflag=append || error "Append failed"
17933
17934         rm -f $DIR/$tdir/$tfile.0
17935
17936         # For this test, we want to delete the files we created to go out of
17937         # space but leave the watermark, so we remain nearly out of space
17938         ost_watermarks_enospc_delete_files $tfile $ostidx
17939
17940         wait_delete_completed
17941
17942         sleep_maxage
17943
17944         for i in $(seq 10 12); do
17945                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17946                         2>/dev/null || error "File creation failed after rm"
17947         done
17948
17949         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17950                         osp.$mdtosc_proc1.prealloc_status)
17951         echo "prealloc_status $oa_status"
17952
17953         if (( oa_status != 0 )); then
17954                 error "Object allocation still disable after rm"
17955         fi
17956 }
17957 run_test 253 "Check object allocation limit"
17958
17959 test_254() {
17960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17961         remote_mds_nodsh && skip "remote MDS with nodsh"
17962         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17963                 skip "MDS does not support changelog_size"
17964
17965         local cl_user
17966         local MDT0=$(facet_svc $SINGLEMDS)
17967
17968         changelog_register || error "changelog_register failed"
17969
17970         changelog_clear 0 || error "changelog_clear failed"
17971
17972         local size1=$(do_facet $SINGLEMDS \
17973                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17974         echo "Changelog size $size1"
17975
17976         rm -rf $DIR/$tdir
17977         $LFS mkdir -i 0 $DIR/$tdir
17978         # change something
17979         mkdir -p $DIR/$tdir/pics/2008/zachy
17980         touch $DIR/$tdir/pics/2008/zachy/timestamp
17981         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17982         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17983         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17984         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17985         rm $DIR/$tdir/pics/desktop.jpg
17986
17987         local size2=$(do_facet $SINGLEMDS \
17988                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17989         echo "Changelog size after work $size2"
17990
17991         (( $size2 > $size1 )) ||
17992                 error "new Changelog size=$size2 less than old size=$size1"
17993 }
17994 run_test 254 "Check changelog size"
17995
17996 ladvise_no_type()
17997 {
17998         local type=$1
17999         local file=$2
18000
18001         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
18002                 awk -F: '{print $2}' | grep $type > /dev/null
18003         if [ $? -ne 0 ]; then
18004                 return 0
18005         fi
18006         return 1
18007 }
18008
18009 ladvise_no_ioctl()
18010 {
18011         local file=$1
18012
18013         lfs ladvise -a willread $file > /dev/null 2>&1
18014         if [ $? -eq 0 ]; then
18015                 return 1
18016         fi
18017
18018         lfs ladvise -a willread $file 2>&1 |
18019                 grep "Inappropriate ioctl for device" > /dev/null
18020         if [ $? -eq 0 ]; then
18021                 return 0
18022         fi
18023         return 1
18024 }
18025
18026 percent() {
18027         bc <<<"scale=2; ($1 - $2) * 100 / $2"
18028 }
18029
18030 # run a random read IO workload
18031 # usage: random_read_iops <filename> <filesize> <iosize>
18032 random_read_iops() {
18033         local file=$1
18034         local fsize=$2
18035         local iosize=${3:-4096}
18036
18037         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
18038                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
18039 }
18040
18041 drop_file_oss_cache() {
18042         local file="$1"
18043         local nodes="$2"
18044
18045         $LFS ladvise -a dontneed $file 2>/dev/null ||
18046                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
18047 }
18048
18049 ladvise_willread_performance()
18050 {
18051         local repeat=10
18052         local average_origin=0
18053         local average_cache=0
18054         local average_ladvise=0
18055
18056         for ((i = 1; i <= $repeat; i++)); do
18057                 echo "Iter $i/$repeat: reading without willread hint"
18058                 cancel_lru_locks osc
18059                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18060                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
18061                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
18062                 average_origin=$(bc <<<"$average_origin + $speed_origin")
18063
18064                 cancel_lru_locks osc
18065                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
18066                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
18067                 average_cache=$(bc <<<"$average_cache + $speed_cache")
18068
18069                 cancel_lru_locks osc
18070                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18071                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
18072                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
18073                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
18074                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
18075         done
18076         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
18077         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
18078         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
18079
18080         speedup_cache=$(percent $average_cache $average_origin)
18081         speedup_ladvise=$(percent $average_ladvise $average_origin)
18082
18083         echo "Average uncached read: $average_origin"
18084         echo "Average speedup with OSS cached read: " \
18085                 "$average_cache = +$speedup_cache%"
18086         echo "Average speedup with ladvise willread: " \
18087                 "$average_ladvise = +$speedup_ladvise%"
18088
18089         local lowest_speedup=20
18090         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
18091                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
18092                         "got $average_cache%. Skipping ladvise willread check."
18093                 return 0
18094         fi
18095
18096         # the test won't work on ZFS until it supports 'ladvise dontneed', but
18097         # it is still good to run until then to exercise 'ladvise willread'
18098         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18099                 [ "$ost1_FSTYPE" = "zfs" ] &&
18100                 echo "osd-zfs does not support dontneed or drop_caches" &&
18101                 return 0
18102
18103         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
18104         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
18105                 error_not_in_vm "Speedup with willread is less than " \
18106                         "$lowest_speedup%, got $average_ladvise%"
18107 }
18108
18109 test_255a() {
18110         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18111                 skip "lustre < 2.8.54 does not support ladvise "
18112         remote_ost_nodsh && skip "remote OST with nodsh"
18113
18114         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
18115
18116         ladvise_no_type willread $DIR/$tfile &&
18117                 skip "willread ladvise is not supported"
18118
18119         ladvise_no_ioctl $DIR/$tfile &&
18120                 skip "ladvise ioctl is not supported"
18121
18122         local size_mb=100
18123         local size=$((size_mb * 1048576))
18124         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18125                 error "dd to $DIR/$tfile failed"
18126
18127         lfs ladvise -a willread $DIR/$tfile ||
18128                 error "Ladvise failed with no range argument"
18129
18130         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18131                 error "Ladvise failed with no -l or -e argument"
18132
18133         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18134                 error "Ladvise failed with only -e argument"
18135
18136         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18137                 error "Ladvise failed with only -l argument"
18138
18139         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18140                 error "End offset should not be smaller than start offset"
18141
18142         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18143                 error "End offset should not be equal to start offset"
18144
18145         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18146                 error "Ladvise failed with overflowing -s argument"
18147
18148         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18149                 error "Ladvise failed with overflowing -e argument"
18150
18151         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18152                 error "Ladvise failed with overflowing -l argument"
18153
18154         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18155                 error "Ladvise succeeded with conflicting -l and -e arguments"
18156
18157         echo "Synchronous ladvise should wait"
18158         local delay=4
18159 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18160         do_nodes $(comma_list $(osts_nodes)) \
18161                 $LCTL set_param fail_val=$delay fail_loc=0x237
18162
18163         local start_ts=$SECONDS
18164         lfs ladvise -a willread $DIR/$tfile ||
18165                 error "Ladvise failed with no range argument"
18166         local end_ts=$SECONDS
18167         local inteval_ts=$((end_ts - start_ts))
18168
18169         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18170                 error "Synchronous advice didn't wait reply"
18171         fi
18172
18173         echo "Asynchronous ladvise shouldn't wait"
18174         local start_ts=$SECONDS
18175         lfs ladvise -a willread -b $DIR/$tfile ||
18176                 error "Ladvise failed with no range argument"
18177         local end_ts=$SECONDS
18178         local inteval_ts=$((end_ts - start_ts))
18179
18180         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18181                 error "Asynchronous advice blocked"
18182         fi
18183
18184         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18185         ladvise_willread_performance
18186 }
18187 run_test 255a "check 'lfs ladvise -a willread'"
18188
18189 facet_meminfo() {
18190         local facet=$1
18191         local info=$2
18192
18193         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18194 }
18195
18196 test_255b() {
18197         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18198                 skip "lustre < 2.8.54 does not support ladvise "
18199         remote_ost_nodsh && skip "remote OST with nodsh"
18200
18201         lfs setstripe -c 1 -i 0 $DIR/$tfile
18202
18203         ladvise_no_type dontneed $DIR/$tfile &&
18204                 skip "dontneed ladvise is not supported"
18205
18206         ladvise_no_ioctl $DIR/$tfile &&
18207                 skip "ladvise ioctl is not supported"
18208
18209         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18210                 [ "$ost1_FSTYPE" = "zfs" ] &&
18211                 skip "zfs-osd does not support 'ladvise dontneed'"
18212
18213         local size_mb=100
18214         local size=$((size_mb * 1048576))
18215         # In order to prevent disturbance of other processes, only check 3/4
18216         # of the memory usage
18217         local kibibytes=$((size_mb * 1024 * 3 / 4))
18218
18219         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18220                 error "dd to $DIR/$tfile failed"
18221
18222         #force write to complete before dropping OST cache & checking memory
18223         sync
18224
18225         local total=$(facet_meminfo ost1 MemTotal)
18226         echo "Total memory: $total KiB"
18227
18228         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18229         local before_read=$(facet_meminfo ost1 Cached)
18230         echo "Cache used before read: $before_read KiB"
18231
18232         lfs ladvise -a willread $DIR/$tfile ||
18233                 error "Ladvise willread failed"
18234         local after_read=$(facet_meminfo ost1 Cached)
18235         echo "Cache used after read: $after_read KiB"
18236
18237         lfs ladvise -a dontneed $DIR/$tfile ||
18238                 error "Ladvise dontneed again failed"
18239         local no_read=$(facet_meminfo ost1 Cached)
18240         echo "Cache used after dontneed ladvise: $no_read KiB"
18241
18242         if [ $total -lt $((before_read + kibibytes)) ]; then
18243                 echo "Memory is too small, abort checking"
18244                 return 0
18245         fi
18246
18247         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18248                 error "Ladvise willread should use more memory" \
18249                         "than $kibibytes KiB"
18250         fi
18251
18252         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18253                 error "Ladvise dontneed should release more memory" \
18254                         "than $kibibytes KiB"
18255         fi
18256 }
18257 run_test 255b "check 'lfs ladvise -a dontneed'"
18258
18259 test_255c() {
18260         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18261                 skip "lustre < 2.10.50 does not support lockahead"
18262
18263         local count
18264         local new_count
18265         local difference
18266         local i
18267         local rc
18268
18269         test_mkdir -p $DIR/$tdir
18270         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18271
18272         #test 10 returns only success/failure
18273         i=10
18274         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18275         rc=$?
18276         if [ $rc -eq 255 ]; then
18277                 error "Ladvise test${i} failed, ${rc}"
18278         fi
18279
18280         #test 11 counts lock enqueue requests, all others count new locks
18281         i=11
18282         count=$(do_facet ost1 \
18283                 $LCTL get_param -n ost.OSS.ost.stats)
18284         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18285
18286         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18287         rc=$?
18288         if [ $rc -eq 255 ]; then
18289                 error "Ladvise test${i} failed, ${rc}"
18290         fi
18291
18292         new_count=$(do_facet ost1 \
18293                 $LCTL get_param -n ost.OSS.ost.stats)
18294         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18295                    awk '{ print $2 }')
18296
18297         difference="$((new_count - count))"
18298         if [ $difference -ne $rc ]; then
18299                 error "Ladvise test${i}, bad enqueue count, returned " \
18300                       "${rc}, actual ${difference}"
18301         fi
18302
18303         for i in $(seq 12 21); do
18304                 # If we do not do this, we run the risk of having too many
18305                 # locks and starting lock cancellation while we are checking
18306                 # lock counts.
18307                 cancel_lru_locks osc
18308
18309                 count=$($LCTL get_param -n \
18310                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18311
18312                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18313                 rc=$?
18314                 if [ $rc -eq 255 ]; then
18315                         error "Ladvise test ${i} failed, ${rc}"
18316                 fi
18317
18318                 new_count=$($LCTL get_param -n \
18319                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18320                 difference="$((new_count - count))"
18321
18322                 # Test 15 output is divided by 100 to map down to valid return
18323                 if [ $i -eq 15 ]; then
18324                         rc="$((rc * 100))"
18325                 fi
18326
18327                 if [ $difference -ne $rc ]; then
18328                         error "Ladvise test ${i}, bad lock count, returned " \
18329                               "${rc}, actual ${difference}"
18330                 fi
18331         done
18332
18333         #test 22 returns only success/failure
18334         i=22
18335         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18336         rc=$?
18337         if [ $rc -eq 255 ]; then
18338                 error "Ladvise test${i} failed, ${rc}"
18339         fi
18340 }
18341 run_test 255c "suite of ladvise lockahead tests"
18342
18343 test_256() {
18344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18345         remote_mds_nodsh && skip "remote MDS with nodsh"
18346         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18347         changelog_users $SINGLEMDS | grep "^cl" &&
18348                 skip "active changelog user"
18349
18350         local cl_user
18351         local cat_sl
18352         local mdt_dev
18353
18354         mdt_dev=$(mdsdevname 1)
18355         echo $mdt_dev
18356
18357         changelog_register || error "changelog_register failed"
18358
18359         rm -rf $DIR/$tdir
18360         mkdir -p $DIR/$tdir
18361
18362         changelog_clear 0 || error "changelog_clear failed"
18363
18364         # change something
18365         touch $DIR/$tdir/{1..10}
18366
18367         # stop the MDT
18368         stop $SINGLEMDS || error "Fail to stop MDT"
18369
18370         # remount the MDT
18371
18372         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18373
18374         #after mount new plainllog is used
18375         touch $DIR/$tdir/{11..19}
18376         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18377         stack_trap "rm -f $tmpfile"
18378         cat_sl=$(do_facet $SINGLEMDS "sync; \
18379                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18380                  llog_reader $tmpfile | grep -c type=1064553b")
18381         do_facet $SINGLEMDS llog_reader $tmpfile
18382
18383         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18384
18385         changelog_clear 0 || error "changelog_clear failed"
18386
18387         cat_sl=$(do_facet $SINGLEMDS "sync; \
18388                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18389                  llog_reader $tmpfile | grep -c type=1064553b")
18390
18391         if (( cat_sl == 2 )); then
18392                 error "Empty plain llog was not deleted from changelog catalog"
18393         elif (( cat_sl != 1 )); then
18394                 error "Active plain llog shouldn't be deleted from catalog"
18395         fi
18396 }
18397 run_test 256 "Check llog delete for empty and not full state"
18398
18399 test_257() {
18400         remote_mds_nodsh && skip "remote MDS with nodsh"
18401         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18402                 skip "Need MDS version at least 2.8.55"
18403
18404         test_mkdir $DIR/$tdir
18405
18406         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18407                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18408         stat $DIR/$tdir
18409
18410 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18411         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18412         local facet=mds$((mdtidx + 1))
18413         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18414         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18415
18416         stop $facet || error "stop MDS failed"
18417         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18418                 error "start MDS fail"
18419         wait_recovery_complete $facet
18420 }
18421 run_test 257 "xattr locks are not lost"
18422
18423 # Verify we take the i_mutex when security requires it
18424 test_258a() {
18425 #define OBD_FAIL_IMUTEX_SEC 0x141c
18426         $LCTL set_param fail_loc=0x141c
18427         touch $DIR/$tfile
18428         chmod u+s $DIR/$tfile
18429         chmod a+rwx $DIR/$tfile
18430         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18431         RC=$?
18432         if [ $RC -ne 0 ]; then
18433                 error "error, failed to take i_mutex, rc=$?"
18434         fi
18435         rm -f $DIR/$tfile
18436 }
18437 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18438
18439 # Verify we do NOT take the i_mutex in the normal case
18440 test_258b() {
18441 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18442         $LCTL set_param fail_loc=0x141d
18443         touch $DIR/$tfile
18444         chmod a+rwx $DIR
18445         chmod a+rw $DIR/$tfile
18446         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18447         RC=$?
18448         if [ $RC -ne 0 ]; then
18449                 error "error, took i_mutex unnecessarily, rc=$?"
18450         fi
18451         rm -f $DIR/$tfile
18452
18453 }
18454 run_test 258b "verify i_mutex security behavior"
18455
18456 test_259() {
18457         local file=$DIR/$tfile
18458         local before
18459         local after
18460
18461         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18462
18463         stack_trap "rm -f $file" EXIT
18464
18465         wait_delete_completed
18466         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18467         echo "before: $before"
18468
18469         $LFS setstripe -i 0 -c 1 $file
18470         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18471         sync_all_data
18472         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18473         echo "after write: $after"
18474
18475 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18476         do_facet ost1 $LCTL set_param fail_loc=0x2301
18477         $TRUNCATE $file 0
18478         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18479         echo "after truncate: $after"
18480
18481         stop ost1
18482         do_facet ost1 $LCTL set_param fail_loc=0
18483         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18484         sleep 2
18485         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18486         echo "after restart: $after"
18487         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18488                 error "missing truncate?"
18489
18490         return 0
18491 }
18492 run_test 259 "crash at delayed truncate"
18493
18494 test_260() {
18495 #define OBD_FAIL_MDC_CLOSE               0x806
18496         $LCTL set_param fail_loc=0x80000806
18497         touch $DIR/$tfile
18498
18499 }
18500 run_test 260 "Check mdc_close fail"
18501
18502 ### Data-on-MDT sanity tests ###
18503 test_270a() {
18504         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18505                 skip "Need MDS version at least 2.10.55 for DoM"
18506
18507         # create DoM file
18508         local dom=$DIR/$tdir/dom_file
18509         local tmp=$DIR/$tdir/tmp_file
18510
18511         mkdir -p $DIR/$tdir
18512
18513         # basic checks for DoM component creation
18514         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18515                 error "Can set MDT layout to non-first entry"
18516
18517         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18518                 error "Can define multiple entries as MDT layout"
18519
18520         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18521
18522         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18523         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18524         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18525
18526         local mdtidx=$($LFS getstripe -m $dom)
18527         local mdtname=MDT$(printf %04x $mdtidx)
18528         local facet=mds$((mdtidx + 1))
18529         local space_check=1
18530
18531         # Skip free space checks with ZFS
18532         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18533
18534         # write
18535         sync
18536         local size_tmp=$((65536 * 3))
18537         local mdtfree1=$(do_facet $facet \
18538                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18539
18540         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18541         # check also direct IO along write
18542         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18543         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18544         sync
18545         cmp $tmp $dom || error "file data is different"
18546         [ $(stat -c%s $dom) == $size_tmp ] ||
18547                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18548         if [ $space_check == 1 ]; then
18549                 local mdtfree2=$(do_facet $facet \
18550                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18551
18552                 # increase in usage from by $size_tmp
18553                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18554                         error "MDT free space wrong after write: " \
18555                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18556         fi
18557
18558         # truncate
18559         local size_dom=10000
18560
18561         $TRUNCATE $dom $size_dom
18562         [ $(stat -c%s $dom) == $size_dom ] ||
18563                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18564         if [ $space_check == 1 ]; then
18565                 mdtfree1=$(do_facet $facet \
18566                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18567                 # decrease in usage from $size_tmp to new $size_dom
18568                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18569                   $(((size_tmp - size_dom) / 1024)) ] ||
18570                         error "MDT free space is wrong after truncate: " \
18571                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18572         fi
18573
18574         # append
18575         cat $tmp >> $dom
18576         sync
18577         size_dom=$((size_dom + size_tmp))
18578         [ $(stat -c%s $dom) == $size_dom ] ||
18579                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18580         if [ $space_check == 1 ]; then
18581                 mdtfree2=$(do_facet $facet \
18582                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18583                 # increase in usage by $size_tmp from previous
18584                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18585                         error "MDT free space is wrong after append: " \
18586                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18587         fi
18588
18589         # delete
18590         rm $dom
18591         if [ $space_check == 1 ]; then
18592                 mdtfree1=$(do_facet $facet \
18593                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18594                 # decrease in usage by $size_dom from previous
18595                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18596                         error "MDT free space is wrong after removal: " \
18597                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18598         fi
18599
18600         # combined striping
18601         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18602                 error "Can't create DoM + OST striping"
18603
18604         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18605         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18606         # check also direct IO along write
18607         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18608         sync
18609         cmp $tmp $dom || error "file data is different"
18610         [ $(stat -c%s $dom) == $size_tmp ] ||
18611                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18612         rm $dom $tmp
18613
18614         return 0
18615 }
18616 run_test 270a "DoM: basic functionality tests"
18617
18618 test_270b() {
18619         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18620                 skip "Need MDS version at least 2.10.55"
18621
18622         local dom=$DIR/$tdir/dom_file
18623         local max_size=1048576
18624
18625         mkdir -p $DIR/$tdir
18626         $LFS setstripe -E $max_size -L mdt $dom
18627
18628         # truncate over the limit
18629         $TRUNCATE $dom $(($max_size + 1)) &&
18630                 error "successful truncate over the maximum size"
18631         # write over the limit
18632         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18633                 error "successful write over the maximum size"
18634         # append over the limit
18635         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18636         echo "12345" >> $dom && error "successful append over the maximum size"
18637         rm $dom
18638
18639         return 0
18640 }
18641 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18642
18643 test_270c() {
18644         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18645                 skip "Need MDS version at least 2.10.55"
18646
18647         mkdir -p $DIR/$tdir
18648         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18649
18650         # check files inherit DoM EA
18651         touch $DIR/$tdir/first
18652         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18653                 error "bad pattern"
18654         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18655                 error "bad stripe count"
18656         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18657                 error "bad stripe size"
18658
18659         # check directory inherits DoM EA and uses it as default
18660         mkdir $DIR/$tdir/subdir
18661         touch $DIR/$tdir/subdir/second
18662         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18663                 error "bad pattern in sub-directory"
18664         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18665                 error "bad stripe count in sub-directory"
18666         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18667                 error "bad stripe size in sub-directory"
18668         return 0
18669 }
18670 run_test 270c "DoM: DoM EA inheritance tests"
18671
18672 test_270d() {
18673         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18674                 skip "Need MDS version at least 2.10.55"
18675
18676         mkdir -p $DIR/$tdir
18677         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18678
18679         # inherit default DoM striping
18680         mkdir $DIR/$tdir/subdir
18681         touch $DIR/$tdir/subdir/f1
18682
18683         # change default directory striping
18684         $LFS setstripe -c 1 $DIR/$tdir/subdir
18685         touch $DIR/$tdir/subdir/f2
18686         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18687                 error "wrong default striping in file 2"
18688         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18689                 error "bad pattern in file 2"
18690         return 0
18691 }
18692 run_test 270d "DoM: change striping from DoM to RAID0"
18693
18694 test_270e() {
18695         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18696                 skip "Need MDS version at least 2.10.55"
18697
18698         mkdir -p $DIR/$tdir/dom
18699         mkdir -p $DIR/$tdir/norm
18700         DOMFILES=20
18701         NORMFILES=10
18702         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18703         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18704
18705         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18706         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18707
18708         # find DoM files by layout
18709         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18710         [ $NUM -eq  $DOMFILES ] ||
18711                 error "lfs find -L: found $NUM, expected $DOMFILES"
18712         echo "Test 1: lfs find 20 DOM files by layout: OK"
18713
18714         # there should be 1 dir with default DOM striping
18715         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18716         [ $NUM -eq  1 ] ||
18717                 error "lfs find -L: found $NUM, expected 1 dir"
18718         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18719
18720         # find DoM files by stripe size
18721         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18722         [ $NUM -eq  $DOMFILES ] ||
18723                 error "lfs find -S: found $NUM, expected $DOMFILES"
18724         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18725
18726         # find files by stripe offset except DoM files
18727         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18728         [ $NUM -eq  $NORMFILES ] ||
18729                 error "lfs find -i: found $NUM, expected $NORMFILES"
18730         echo "Test 5: lfs find no DOM files by stripe index: OK"
18731         return 0
18732 }
18733 run_test 270e "DoM: lfs find with DoM files test"
18734
18735 test_270f() {
18736         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18737                 skip "Need MDS version at least 2.10.55"
18738
18739         local mdtname=${FSNAME}-MDT0000-mdtlov
18740         local dom=$DIR/$tdir/dom_file
18741         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18742                                                 lod.$mdtname.dom_stripesize)
18743         local dom_limit=131072
18744
18745         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18746         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18747                                                 lod.$mdtname.dom_stripesize)
18748         [ ${dom_limit} -eq ${dom_current} ] ||
18749                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18750
18751         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18752         $LFS setstripe -d $DIR/$tdir
18753         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18754                 error "Can't set directory default striping"
18755
18756         # exceed maximum stripe size
18757         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18758                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18759         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18760                 error "Able to create DoM component size more than LOD limit"
18761
18762         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18763         dom_current=$(do_facet mds1 $LCTL get_param -n \
18764                                                 lod.$mdtname.dom_stripesize)
18765         [ 0 -eq ${dom_current} ] ||
18766                 error "Can't set zero DoM stripe limit"
18767         rm $dom
18768
18769         # attempt to create DoM file on server with disabled DoM should
18770         # remove DoM entry from layout and be succeed
18771         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18772                 error "Can't create DoM file (DoM is disabled)"
18773         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18774                 error "File has DoM component while DoM is disabled"
18775         rm $dom
18776
18777         # attempt to create DoM file with only DoM stripe should return error
18778         $LFS setstripe -E $dom_limit -L mdt $dom &&
18779                 error "Able to create DoM-only file while DoM is disabled"
18780
18781         # too low values to be aligned with smallest stripe size 64K
18782         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18783         dom_current=$(do_facet mds1 $LCTL get_param -n \
18784                                                 lod.$mdtname.dom_stripesize)
18785         [ 30000 -eq ${dom_current} ] &&
18786                 error "Can set too small DoM stripe limit"
18787
18788         # 64K is a minimal stripe size in Lustre, expect limit of that size
18789         [ 65536 -eq ${dom_current} ] ||
18790                 error "Limit is not set to 64K but ${dom_current}"
18791
18792         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18793         dom_current=$(do_facet mds1 $LCTL get_param -n \
18794                                                 lod.$mdtname.dom_stripesize)
18795         echo $dom_current
18796         [ 2147483648 -eq ${dom_current} ] &&
18797                 error "Can set too large DoM stripe limit"
18798
18799         do_facet mds1 $LCTL set_param -n \
18800                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18801         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18802                 error "Can't create DoM component size after limit change"
18803         do_facet mds1 $LCTL set_param -n \
18804                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18805         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18806                 error "Can't create DoM file after limit decrease"
18807         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18808                 error "Can create big DoM component after limit decrease"
18809         touch ${dom}_def ||
18810                 error "Can't create file with old default layout"
18811
18812         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18813         return 0
18814 }
18815 run_test 270f "DoM: maximum DoM stripe size checks"
18816
18817 test_271a() {
18818         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18819                 skip "Need MDS version at least 2.10.55"
18820
18821         local dom=$DIR/$tdir/dom
18822
18823         mkdir -p $DIR/$tdir
18824
18825         $LFS setstripe -E 1024K -L mdt $dom
18826
18827         lctl set_param -n mdc.*.stats=clear
18828         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18829         cat $dom > /dev/null
18830         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18831         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18832         ls $dom
18833         rm -f $dom
18834 }
18835 run_test 271a "DoM: data is cached for read after write"
18836
18837 test_271b() {
18838         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18839                 skip "Need MDS version at least 2.10.55"
18840
18841         local dom=$DIR/$tdir/dom
18842
18843         mkdir -p $DIR/$tdir
18844
18845         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18846
18847         lctl set_param -n mdc.*.stats=clear
18848         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18849         cancel_lru_locks mdc
18850         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18851         # second stat to check size is cached on client
18852         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18853         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18854         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18855         rm -f $dom
18856 }
18857 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18858
18859 test_271ba() {
18860         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18861                 skip "Need MDS version at least 2.10.55"
18862
18863         local dom=$DIR/$tdir/dom
18864
18865         mkdir -p $DIR/$tdir
18866
18867         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18868
18869         lctl set_param -n mdc.*.stats=clear
18870         lctl set_param -n osc.*.stats=clear
18871         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18872         cancel_lru_locks mdc
18873         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18874         # second stat to check size is cached on client
18875         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18876         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18877         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18878         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18879         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18880         rm -f $dom
18881 }
18882 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18883
18884
18885 get_mdc_stats() {
18886         local mdtidx=$1
18887         local param=$2
18888         local mdt=MDT$(printf %04x $mdtidx)
18889
18890         if [ -z $param ]; then
18891                 lctl get_param -n mdc.*$mdt*.stats
18892         else
18893                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18894         fi
18895 }
18896
18897 test_271c() {
18898         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18899                 skip "Need MDS version at least 2.10.55"
18900
18901         local dom=$DIR/$tdir/dom
18902
18903         mkdir -p $DIR/$tdir
18904
18905         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18906
18907         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18908         local facet=mds$((mdtidx + 1))
18909
18910         cancel_lru_locks mdc
18911         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18912         createmany -o $dom 1000
18913         lctl set_param -n mdc.*.stats=clear
18914         smalliomany -w $dom 1000 200
18915         get_mdc_stats $mdtidx
18916         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18917         # Each file has 1 open, 1 IO enqueues, total 2000
18918         # but now we have also +1 getxattr for security.capability, total 3000
18919         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18920         unlinkmany $dom 1000
18921
18922         cancel_lru_locks mdc
18923         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18924         createmany -o $dom 1000
18925         lctl set_param -n mdc.*.stats=clear
18926         smalliomany -w $dom 1000 200
18927         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18928         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18929         # for OPEN and IO lock.
18930         [ $((enq - enq_2)) -ge 1000 ] ||
18931                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18932         unlinkmany $dom 1000
18933         return 0
18934 }
18935 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18936
18937 cleanup_271def_tests() {
18938         trap 0
18939         rm -f $1
18940 }
18941
18942 test_271d() {
18943         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18944                 skip "Need MDS version at least 2.10.57"
18945
18946         local dom=$DIR/$tdir/dom
18947         local tmp=$TMP/$tfile
18948         trap "cleanup_271def_tests $tmp" EXIT
18949
18950         mkdir -p $DIR/$tdir
18951
18952         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18953
18954         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18955
18956         cancel_lru_locks mdc
18957         dd if=/dev/urandom of=$tmp bs=1000 count=1
18958         dd if=$tmp of=$dom bs=1000 count=1
18959         cancel_lru_locks mdc
18960
18961         cat /etc/hosts >> $tmp
18962         lctl set_param -n mdc.*.stats=clear
18963
18964         # append data to the same file it should update local page
18965         echo "Append to the same page"
18966         cat /etc/hosts >> $dom
18967         local num=$(get_mdc_stats $mdtidx ost_read)
18968         local ra=$(get_mdc_stats $mdtidx req_active)
18969         local rw=$(get_mdc_stats $mdtidx req_waittime)
18970
18971         [ -z $num ] || error "$num READ RPC occured"
18972         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18973         echo "... DONE"
18974
18975         # compare content
18976         cmp $tmp $dom || error "file miscompare"
18977
18978         cancel_lru_locks mdc
18979         lctl set_param -n mdc.*.stats=clear
18980
18981         echo "Open and read file"
18982         cat $dom > /dev/null
18983         local num=$(get_mdc_stats $mdtidx ost_read)
18984         local ra=$(get_mdc_stats $mdtidx req_active)
18985         local rw=$(get_mdc_stats $mdtidx req_waittime)
18986
18987         [ -z $num ] || error "$num READ RPC occured"
18988         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18989         echo "... DONE"
18990
18991         # compare content
18992         cmp $tmp $dom || error "file miscompare"
18993
18994         return 0
18995 }
18996 run_test 271d "DoM: read on open (1K file in reply buffer)"
18997
18998 test_271f() {
18999         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19000                 skip "Need MDS version at least 2.10.57"
19001
19002         local dom=$DIR/$tdir/dom
19003         local tmp=$TMP/$tfile
19004         trap "cleanup_271def_tests $tmp" EXIT
19005
19006         mkdir -p $DIR/$tdir
19007
19008         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19009
19010         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19011
19012         cancel_lru_locks mdc
19013         dd if=/dev/urandom of=$tmp bs=265000 count=1
19014         dd if=$tmp of=$dom bs=265000 count=1
19015         cancel_lru_locks mdc
19016         cat /etc/hosts >> $tmp
19017         lctl set_param -n mdc.*.stats=clear
19018
19019         echo "Append to the same page"
19020         cat /etc/hosts >> $dom
19021         local num=$(get_mdc_stats $mdtidx ost_read)
19022         local ra=$(get_mdc_stats $mdtidx req_active)
19023         local rw=$(get_mdc_stats $mdtidx req_waittime)
19024
19025         [ -z $num ] || error "$num READ RPC occured"
19026         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19027         echo "... DONE"
19028
19029         # compare content
19030         cmp $tmp $dom || error "file miscompare"
19031
19032         cancel_lru_locks mdc
19033         lctl set_param -n mdc.*.stats=clear
19034
19035         echo "Open and read file"
19036         cat $dom > /dev/null
19037         local num=$(get_mdc_stats $mdtidx ost_read)
19038         local ra=$(get_mdc_stats $mdtidx req_active)
19039         local rw=$(get_mdc_stats $mdtidx req_waittime)
19040
19041         [ -z $num ] && num=0
19042         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
19043         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19044         echo "... DONE"
19045
19046         # compare content
19047         cmp $tmp $dom || error "file miscompare"
19048
19049         return 0
19050 }
19051 run_test 271f "DoM: read on open (200K file and read tail)"
19052
19053 test_271g() {
19054         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
19055                 skip "Skipping due to old client or server version"
19056
19057         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
19058         # to get layout
19059         $CHECKSTAT -t file $DIR1/$tfile
19060
19061         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
19062         MULTIOP_PID=$!
19063         sleep 1
19064         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
19065         $LCTL set_param fail_loc=0x80000314
19066         rm $DIR1/$tfile || error "Unlink fails"
19067         RC=$?
19068         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
19069         [ $RC -eq 0 ] || error "Failed write to stale object"
19070 }
19071 run_test 271g "Discard DoM data vs client flush race"
19072
19073 test_272a() {
19074         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19075                 skip "Need MDS version at least 2.11.50"
19076
19077         local dom=$DIR/$tdir/dom
19078         mkdir -p $DIR/$tdir
19079
19080         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
19081         dd if=/dev/urandom of=$dom bs=512K count=1 ||
19082                 error "failed to write data into $dom"
19083         local old_md5=$(md5sum $dom)
19084
19085         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
19086                 error "failed to migrate to the same DoM component"
19087
19088         local new_md5=$(md5sum $dom)
19089
19090         [ "$old_md5" == "$new_md5" ] ||
19091                 error "md5sum differ: $old_md5, $new_md5"
19092
19093         [ $($LFS getstripe -c $dom) -eq 2 ] ||
19094                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
19095 }
19096 run_test 272a "DoM migration: new layout with the same DOM component"
19097
19098 test_272b() {
19099         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19100                 skip "Need MDS version at least 2.11.50"
19101
19102         local dom=$DIR/$tdir/dom
19103         mkdir -p $DIR/$tdir
19104         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19105
19106         local mdtidx=$($LFS getstripe -m $dom)
19107         local mdtname=MDT$(printf %04x $mdtidx)
19108         local facet=mds$((mdtidx + 1))
19109
19110         local mdtfree1=$(do_facet $facet \
19111                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19112         dd if=/dev/urandom of=$dom bs=2M count=1 ||
19113                 error "failed to write data into $dom"
19114         local old_md5=$(md5sum $dom)
19115         cancel_lru_locks mdc
19116         local mdtfree1=$(do_facet $facet \
19117                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19118
19119         $LFS migrate -c2 $dom ||
19120                 error "failed to migrate to the new composite layout"
19121         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19122                 error "MDT stripe was not removed"
19123
19124         cancel_lru_locks mdc
19125         local new_md5=$(md5sum $dom)
19126         [ "$old_md5" == "$new_md5" ] ||
19127                 error "$old_md5 != $new_md5"
19128
19129         # Skip free space checks with ZFS
19130         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19131                 local mdtfree2=$(do_facet $facet \
19132                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19133                 [ $mdtfree2 -gt $mdtfree1 ] ||
19134                         error "MDT space is not freed after migration"
19135         fi
19136         return 0
19137 }
19138 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19139
19140 test_272c() {
19141         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19142                 skip "Need MDS version at least 2.11.50"
19143
19144         local dom=$DIR/$tdir/$tfile
19145         mkdir -p $DIR/$tdir
19146         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19147
19148         local mdtidx=$($LFS getstripe -m $dom)
19149         local mdtname=MDT$(printf %04x $mdtidx)
19150         local facet=mds$((mdtidx + 1))
19151
19152         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19153                 error "failed to write data into $dom"
19154         local old_md5=$(md5sum $dom)
19155         cancel_lru_locks mdc
19156         local mdtfree1=$(do_facet $facet \
19157                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19158
19159         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19160                 error "failed to migrate to the new composite layout"
19161         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19162                 error "MDT stripe was not removed"
19163
19164         cancel_lru_locks mdc
19165         local new_md5=$(md5sum $dom)
19166         [ "$old_md5" == "$new_md5" ] ||
19167                 error "$old_md5 != $new_md5"
19168
19169         # Skip free space checks with ZFS
19170         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19171                 local mdtfree2=$(do_facet $facet \
19172                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19173                 [ $mdtfree2 -gt $mdtfree1 ] ||
19174                         error "MDS space is not freed after migration"
19175         fi
19176         return 0
19177 }
19178 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19179
19180 test_272d() {
19181         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19182                 skip "Need MDS version at least 2.12.55"
19183
19184         local dom=$DIR/$tdir/$tfile
19185         mkdir -p $DIR/$tdir
19186         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19187
19188         local mdtidx=$($LFS getstripe -m $dom)
19189         local mdtname=MDT$(printf %04x $mdtidx)
19190         local facet=mds$((mdtidx + 1))
19191
19192         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19193                 error "failed to write data into $dom"
19194         local old_md5=$(md5sum $dom)
19195         cancel_lru_locks mdc
19196         local mdtfree1=$(do_facet $facet \
19197                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19198
19199         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19200                 error "failed mirroring to the new composite layout"
19201         $LFS mirror resync $dom ||
19202                 error "failed mirror resync"
19203         $LFS mirror split --mirror-id 1 -d $dom ||
19204                 error "failed mirror split"
19205
19206         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19207                 error "MDT stripe was not removed"
19208
19209         cancel_lru_locks mdc
19210         local new_md5=$(md5sum $dom)
19211         [ "$old_md5" == "$new_md5" ] ||
19212                 error "$old_md5 != $new_md5"
19213
19214         # Skip free space checks with ZFS
19215         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19216                 local mdtfree2=$(do_facet $facet \
19217                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19218                 [ $mdtfree2 -gt $mdtfree1 ] ||
19219                         error "MDS space is not freed after DOM mirror deletion"
19220         fi
19221         return 0
19222 }
19223 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19224
19225 test_272e() {
19226         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19227                 skip "Need MDS version at least 2.12.55"
19228
19229         local dom=$DIR/$tdir/$tfile
19230         mkdir -p $DIR/$tdir
19231         $LFS setstripe -c 2 $dom
19232
19233         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19234                 error "failed to write data into $dom"
19235         local old_md5=$(md5sum $dom)
19236         cancel_lru_locks mdc
19237
19238         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19239                 error "failed mirroring to the DOM layout"
19240         $LFS mirror resync $dom ||
19241                 error "failed mirror resync"
19242         $LFS mirror split --mirror-id 1 -d $dom ||
19243                 error "failed mirror split"
19244
19245         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19246                 error "MDT stripe was not removed"
19247
19248         cancel_lru_locks mdc
19249         local new_md5=$(md5sum $dom)
19250         [ "$old_md5" == "$new_md5" ] ||
19251                 error "$old_md5 != $new_md5"
19252
19253         return 0
19254 }
19255 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19256
19257 test_272f() {
19258         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19259                 skip "Need MDS version at least 2.12.55"
19260
19261         local dom=$DIR/$tdir/$tfile
19262         mkdir -p $DIR/$tdir
19263         $LFS setstripe -c 2 $dom
19264
19265         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19266                 error "failed to write data into $dom"
19267         local old_md5=$(md5sum $dom)
19268         cancel_lru_locks mdc
19269
19270         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19271                 error "failed migrating to the DOM file"
19272
19273         cancel_lru_locks mdc
19274         local new_md5=$(md5sum $dom)
19275         [ "$old_md5" != "$new_md5" ] &&
19276                 error "$old_md5 != $new_md5"
19277
19278         return 0
19279 }
19280 run_test 272f "DoM migration: OST-striped file to DOM file"
19281
19282 test_273a() {
19283         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19284                 skip "Need MDS version at least 2.11.50"
19285
19286         # Layout swap cannot be done if either file has DOM component,
19287         # this will never be supported, migration should be used instead
19288
19289         local dom=$DIR/$tdir/$tfile
19290         mkdir -p $DIR/$tdir
19291
19292         $LFS setstripe -c2 ${dom}_plain
19293         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19294         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19295                 error "can swap layout with DoM component"
19296         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19297                 error "can swap layout with DoM component"
19298
19299         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19300         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19301                 error "can swap layout with DoM component"
19302         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19303                 error "can swap layout with DoM component"
19304         return 0
19305 }
19306 run_test 273a "DoM: layout swapping should fail with DOM"
19307
19308 test_275() {
19309         remote_ost_nodsh && skip "remote OST with nodsh"
19310         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19311                 skip "Need OST version >= 2.10.57"
19312
19313         local file=$DIR/$tfile
19314         local oss
19315
19316         oss=$(comma_list $(osts_nodes))
19317
19318         dd if=/dev/urandom of=$file bs=1M count=2 ||
19319                 error "failed to create a file"
19320         cancel_lru_locks osc
19321
19322         #lock 1
19323         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19324                 error "failed to read a file"
19325
19326 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19327         $LCTL set_param fail_loc=0x8000031f
19328
19329         cancel_lru_locks osc &
19330         sleep 1
19331
19332 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19333         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19334         #IO takes another lock, but matches the PENDING one
19335         #and places it to the IO RPC
19336         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19337                 error "failed to read a file with PENDING lock"
19338 }
19339 run_test 275 "Read on a canceled duplicate lock"
19340
19341 test_276() {
19342         remote_ost_nodsh && skip "remote OST with nodsh"
19343         local pid
19344
19345         do_facet ost1 "(while true; do \
19346                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19347                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19348         pid=$!
19349
19350         for LOOP in $(seq 20); do
19351                 stop ost1
19352                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19353         done
19354         kill -9 $pid
19355         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19356                 rm $TMP/sanity_276_pid"
19357 }
19358 run_test 276 "Race between mount and obd_statfs"
19359
19360 test_277() {
19361         $LCTL set_param ldlm.namespaces.*.lru_size=0
19362         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19363         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19364                         grep ^used_mb | awk '{print $2}')
19365         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19367                 oflag=direct conv=notrunc
19368         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19369                         grep ^used_mb | awk '{print $2}')
19370         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19371 }
19372 run_test 277 "Direct IO shall drop page cache"
19373
19374 test_278() {
19375         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19376         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19377         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19378                 skip "needs the same host for mdt1 mdt2" && return
19379
19380         local pid1
19381         local pid2
19382
19383 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19384         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19385         stop mds2 &
19386         pid2=$!
19387
19388         stop mds1
19389
19390         echo "Starting MDTs"
19391         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19392         wait $pid2
19393 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19394 #will return NULL
19395         do_facet mds2 $LCTL set_param fail_loc=0
19396
19397         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19398         wait_recovery_complete mds2
19399 }
19400 run_test 278 "Race starting MDS between MDTs stop/start"
19401
19402 cleanup_test_300() {
19403         trap 0
19404         umask $SAVE_UMASK
19405 }
19406 test_striped_dir() {
19407         local mdt_index=$1
19408         local stripe_count
19409         local stripe_index
19410
19411         mkdir -p $DIR/$tdir
19412
19413         SAVE_UMASK=$(umask)
19414         trap cleanup_test_300 RETURN EXIT
19415
19416         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19417                                                 $DIR/$tdir/striped_dir ||
19418                 error "set striped dir error"
19419
19420         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19421         [ "$mode" = "755" ] || error "expect 755 got $mode"
19422
19423         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19424                 error "getdirstripe failed"
19425         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19426         if [ "$stripe_count" != "2" ]; then
19427                 error "1:stripe_count is $stripe_count, expect 2"
19428         fi
19429         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19430         if [ "$stripe_count" != "2" ]; then
19431                 error "2:stripe_count is $stripe_count, expect 2"
19432         fi
19433
19434         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19435         if [ "$stripe_index" != "$mdt_index" ]; then
19436                 error "stripe_index is $stripe_index, expect $mdt_index"
19437         fi
19438
19439         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19440                 error "nlink error after create striped dir"
19441
19442         mkdir $DIR/$tdir/striped_dir/a
19443         mkdir $DIR/$tdir/striped_dir/b
19444
19445         stat $DIR/$tdir/striped_dir/a ||
19446                 error "create dir under striped dir failed"
19447         stat $DIR/$tdir/striped_dir/b ||
19448                 error "create dir under striped dir failed"
19449
19450         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19451                 error "nlink error after mkdir"
19452
19453         rmdir $DIR/$tdir/striped_dir/a
19454         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19455                 error "nlink error after rmdir"
19456
19457         rmdir $DIR/$tdir/striped_dir/b
19458         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19459                 error "nlink error after rmdir"
19460
19461         chattr +i $DIR/$tdir/striped_dir
19462         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19463                 error "immutable flags not working under striped dir!"
19464         chattr -i $DIR/$tdir/striped_dir
19465
19466         rmdir $DIR/$tdir/striped_dir ||
19467                 error "rmdir striped dir error"
19468
19469         cleanup_test_300
19470
19471         true
19472 }
19473
19474 test_300a() {
19475         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19476                 skip "skipped for lustre < 2.7.0"
19477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19478         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19479
19480         test_striped_dir 0 || error "failed on striped dir on MDT0"
19481         test_striped_dir 1 || error "failed on striped dir on MDT0"
19482 }
19483 run_test 300a "basic striped dir sanity test"
19484
19485 test_300b() {
19486         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19487                 skip "skipped for lustre < 2.7.0"
19488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19489         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19490
19491         local i
19492         local mtime1
19493         local mtime2
19494         local mtime3
19495
19496         test_mkdir $DIR/$tdir || error "mkdir fail"
19497         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19498                 error "set striped dir error"
19499         for i in {0..9}; do
19500                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19501                 sleep 1
19502                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19503                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19504                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19505                 sleep 1
19506                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19507                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19508                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19509         done
19510         true
19511 }
19512 run_test 300b "check ctime/mtime for striped dir"
19513
19514 test_300c() {
19515         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19516                 skip "skipped for lustre < 2.7.0"
19517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19519
19520         local file_count
19521
19522         mkdir -p $DIR/$tdir
19523         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19524                 error "set striped dir error"
19525
19526         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19527                 error "chown striped dir failed"
19528
19529         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19530                 error "create 5k files failed"
19531
19532         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19533
19534         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19535
19536         rm -rf $DIR/$tdir
19537 }
19538 run_test 300c "chown && check ls under striped directory"
19539
19540 test_300d() {
19541         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19542                 skip "skipped for lustre < 2.7.0"
19543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19545
19546         local stripe_count
19547         local file
19548
19549         mkdir -p $DIR/$tdir
19550         $LFS setstripe -c 2 $DIR/$tdir
19551
19552         #local striped directory
19553         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19554                 error "set striped dir error"
19555         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19556                 error "create 10 files failed"
19557
19558         #remote striped directory
19559         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19560                 error "set striped dir error"
19561         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19562                 error "create 10 files failed"
19563
19564         for file in $(find $DIR/$tdir); do
19565                 stripe_count=$($LFS getstripe -c $file)
19566                 [ $stripe_count -eq 2 ] ||
19567                         error "wrong stripe $stripe_count for $file"
19568         done
19569
19570         rm -rf $DIR/$tdir
19571 }
19572 run_test 300d "check default stripe under striped directory"
19573
19574 test_300e() {
19575         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19576                 skip "Need MDS version at least 2.7.55"
19577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19579
19580         local stripe_count
19581         local file
19582
19583         mkdir -p $DIR/$tdir
19584
19585         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19586                 error "set striped dir error"
19587
19588         touch $DIR/$tdir/striped_dir/a
19589         touch $DIR/$tdir/striped_dir/b
19590         touch $DIR/$tdir/striped_dir/c
19591
19592         mkdir $DIR/$tdir/striped_dir/dir_a
19593         mkdir $DIR/$tdir/striped_dir/dir_b
19594         mkdir $DIR/$tdir/striped_dir/dir_c
19595
19596         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19597                 error "set striped adir under striped dir error"
19598
19599         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19600                 error "set striped bdir under striped dir error"
19601
19602         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19603                 error "set striped cdir under striped dir error"
19604
19605         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19606                 error "rename dir under striped dir fails"
19607
19608         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19609                 error "rename dir under different stripes fails"
19610
19611         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19612                 error "rename file under striped dir should succeed"
19613
19614         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19615                 error "rename dir under striped dir should succeed"
19616
19617         rm -rf $DIR/$tdir
19618 }
19619 run_test 300e "check rename under striped directory"
19620
19621 test_300f() {
19622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19623         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19624         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19625                 skip "Need MDS version at least 2.7.55"
19626
19627         local stripe_count
19628         local file
19629
19630         rm -rf $DIR/$tdir
19631         mkdir -p $DIR/$tdir
19632
19633         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19634                 error "set striped dir error"
19635
19636         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19637                 error "set striped dir error"
19638
19639         touch $DIR/$tdir/striped_dir/a
19640         mkdir $DIR/$tdir/striped_dir/dir_a
19641         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19642                 error "create striped dir under striped dir fails"
19643
19644         touch $DIR/$tdir/striped_dir1/b
19645         mkdir $DIR/$tdir/striped_dir1/dir_b
19646         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19647                 error "create striped dir under striped dir fails"
19648
19649         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19650                 error "rename dir under different striped dir should fail"
19651
19652         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19653                 error "rename striped dir under diff striped dir should fail"
19654
19655         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19656                 error "rename file under diff striped dirs fails"
19657
19658         rm -rf $DIR/$tdir
19659 }
19660 run_test 300f "check rename cross striped directory"
19661
19662 test_300_check_default_striped_dir()
19663 {
19664         local dirname=$1
19665         local default_count=$2
19666         local default_index=$3
19667         local stripe_count
19668         local stripe_index
19669         local dir_stripe_index
19670         local dir
19671
19672         echo "checking $dirname $default_count $default_index"
19673         $LFS setdirstripe -D -c $default_count -i $default_index \
19674                                 -t all_char $DIR/$tdir/$dirname ||
19675                 error "set default stripe on striped dir error"
19676         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19677         [ $stripe_count -eq $default_count ] ||
19678                 error "expect $default_count get $stripe_count for $dirname"
19679
19680         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19681         [ $stripe_index -eq $default_index ] ||
19682                 error "expect $default_index get $stripe_index for $dirname"
19683
19684         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19685                                                 error "create dirs failed"
19686
19687         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19688         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19689         for dir in $(find $DIR/$tdir/$dirname/*); do
19690                 stripe_count=$($LFS getdirstripe -c $dir)
19691                 [ $stripe_count -eq $default_count ] ||
19692                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19693                 error "stripe count $default_count != $stripe_count for $dir"
19694
19695                 stripe_index=$($LFS getdirstripe -i $dir)
19696                 [ $default_index -eq -1 ] ||
19697                         [ $stripe_index -eq $default_index ] ||
19698                         error "$stripe_index != $default_index for $dir"
19699
19700                 #check default stripe
19701                 stripe_count=$($LFS getdirstripe -D -c $dir)
19702                 [ $stripe_count -eq $default_count ] ||
19703                 error "default count $default_count != $stripe_count for $dir"
19704
19705                 stripe_index=$($LFS getdirstripe -D -i $dir)
19706                 [ $stripe_index -eq $default_index ] ||
19707                 error "default index $default_index != $stripe_index for $dir"
19708         done
19709         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19710 }
19711
19712 test_300g() {
19713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19714         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19715                 skip "Need MDS version at least 2.7.55"
19716
19717         local dir
19718         local stripe_count
19719         local stripe_index
19720
19721         mkdir $DIR/$tdir
19722         mkdir $DIR/$tdir/normal_dir
19723
19724         #Checking when client cache stripe index
19725         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19726         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19727                 error "create striped_dir failed"
19728
19729         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19730                 error "create dir0 fails"
19731         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19732         [ $stripe_index -eq 0 ] ||
19733                 error "dir0 expect index 0 got $stripe_index"
19734
19735         mkdir $DIR/$tdir/striped_dir/dir1 ||
19736                 error "create dir1 fails"
19737         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19738         [ $stripe_index -eq 1 ] ||
19739                 error "dir1 expect index 1 got $stripe_index"
19740
19741         #check default stripe count/stripe index
19742         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19743         test_300_check_default_striped_dir normal_dir 1 0
19744         test_300_check_default_striped_dir normal_dir 2 1
19745         test_300_check_default_striped_dir normal_dir 2 -1
19746
19747         #delete default stripe information
19748         echo "delete default stripeEA"
19749         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19750                 error "set default stripe on striped dir error"
19751
19752         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19753         for dir in $(find $DIR/$tdir/normal_dir/*); do
19754                 stripe_count=$($LFS getdirstripe -c $dir)
19755                 [ $stripe_count -eq 0 ] ||
19756                         error "expect 1 get $stripe_count for $dir"
19757                 stripe_index=$($LFS getdirstripe -i $dir)
19758                 [ $stripe_index -eq 0 ] ||
19759                         error "expect 0 get $stripe_index for $dir"
19760         done
19761 }
19762 run_test 300g "check default striped directory for normal directory"
19763
19764 test_300h() {
19765         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19766         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19767                 skip "Need MDS version at least 2.7.55"
19768
19769         local dir
19770         local stripe_count
19771
19772         mkdir $DIR/$tdir
19773         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19774                 error "set striped dir error"
19775
19776         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19777         test_300_check_default_striped_dir striped_dir 1 0
19778         test_300_check_default_striped_dir striped_dir 2 1
19779         test_300_check_default_striped_dir striped_dir 2 -1
19780
19781         #delete default stripe information
19782         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19783                 error "set default stripe on striped dir error"
19784
19785         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19786         for dir in $(find $DIR/$tdir/striped_dir/*); do
19787                 stripe_count=$($LFS getdirstripe -c $dir)
19788                 [ $stripe_count -eq 0 ] ||
19789                         error "expect 1 get $stripe_count for $dir"
19790         done
19791 }
19792 run_test 300h "check default striped directory for striped directory"
19793
19794 test_300i() {
19795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19796         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19797         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19798                 skip "Need MDS version at least 2.7.55"
19799
19800         local stripe_count
19801         local file
19802
19803         mkdir $DIR/$tdir
19804
19805         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19806                 error "set striped dir error"
19807
19808         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19809                 error "create files under striped dir failed"
19810
19811         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19812                 error "set striped hashdir error"
19813
19814         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19815                 error "create dir0 under hash dir failed"
19816         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19817                 error "create dir1 under hash dir failed"
19818
19819         # unfortunately, we need to umount to clear dir layout cache for now
19820         # once we fully implement dir layout, we can drop this
19821         umount_client $MOUNT || error "umount failed"
19822         mount_client $MOUNT || error "mount failed"
19823
19824         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19825         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19826         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19827
19828         #set the stripe to be unknown hash type
19829         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19830         $LCTL set_param fail_loc=0x1901
19831         for ((i = 0; i < 10; i++)); do
19832                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19833                         error "stat f-$i failed"
19834                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19835         done
19836
19837         touch $DIR/$tdir/striped_dir/f0 &&
19838                 error "create under striped dir with unknown hash should fail"
19839
19840         $LCTL set_param fail_loc=0
19841
19842         umount_client $MOUNT || error "umount failed"
19843         mount_client $MOUNT || error "mount failed"
19844
19845         return 0
19846 }
19847 run_test 300i "client handle unknown hash type striped directory"
19848
19849 test_300j() {
19850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19852         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19853                 skip "Need MDS version at least 2.7.55"
19854
19855         local stripe_count
19856         local file
19857
19858         mkdir $DIR/$tdir
19859
19860         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19861         $LCTL set_param fail_loc=0x1702
19862         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19863                 error "set striped dir error"
19864
19865         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19866                 error "create files under striped dir failed"
19867
19868         $LCTL set_param fail_loc=0
19869
19870         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19871
19872         return 0
19873 }
19874 run_test 300j "test large update record"
19875
19876 test_300k() {
19877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19879         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19880                 skip "Need MDS version at least 2.7.55"
19881
19882         # this test needs a huge transaction
19883         local kb
19884         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19885              osd*.$FSNAME-MDT0000.kbytestotal")
19886         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
19887
19888         local stripe_count
19889         local file
19890
19891         mkdir $DIR/$tdir
19892
19893         #define OBD_FAIL_LARGE_STRIPE   0x1703
19894         $LCTL set_param fail_loc=0x1703
19895         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19896                 error "set striped dir error"
19897         $LCTL set_param fail_loc=0
19898
19899         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19900                 error "getstripeddir fails"
19901         rm -rf $DIR/$tdir/striped_dir ||
19902                 error "unlink striped dir fails"
19903
19904         return 0
19905 }
19906 run_test 300k "test large striped directory"
19907
19908 test_300l() {
19909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19910         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19911         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19912                 skip "Need MDS version at least 2.7.55"
19913
19914         local stripe_index
19915
19916         test_mkdir -p $DIR/$tdir/striped_dir
19917         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19918                         error "chown $RUNAS_ID failed"
19919         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19920                 error "set default striped dir failed"
19921
19922         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19923         $LCTL set_param fail_loc=0x80000158
19924         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19925
19926         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19927         [ $stripe_index -eq 1 ] ||
19928                 error "expect 1 get $stripe_index for $dir"
19929 }
19930 run_test 300l "non-root user to create dir under striped dir with stale layout"
19931
19932 test_300m() {
19933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19934         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19935         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19936                 skip "Need MDS version at least 2.7.55"
19937
19938         mkdir -p $DIR/$tdir/striped_dir
19939         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19940                 error "set default stripes dir error"
19941
19942         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19943
19944         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19945         [ $stripe_count -eq 0 ] ||
19946                         error "expect 0 get $stripe_count for a"
19947
19948         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19949                 error "set default stripes dir error"
19950
19951         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19952
19953         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19954         [ $stripe_count -eq 0 ] ||
19955                         error "expect 0 get $stripe_count for b"
19956
19957         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19958                 error "set default stripes dir error"
19959
19960         mkdir $DIR/$tdir/striped_dir/c &&
19961                 error "default stripe_index is invalid, mkdir c should fails"
19962
19963         rm -rf $DIR/$tdir || error "rmdir fails"
19964 }
19965 run_test 300m "setstriped directory on single MDT FS"
19966
19967 cleanup_300n() {
19968         local list=$(comma_list $(mdts_nodes))
19969
19970         trap 0
19971         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19972 }
19973
19974 test_300n() {
19975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19977         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19978                 skip "Need MDS version at least 2.7.55"
19979         remote_mds_nodsh && skip "remote MDS with nodsh"
19980
19981         local stripe_index
19982         local list=$(comma_list $(mdts_nodes))
19983
19984         trap cleanup_300n RETURN EXIT
19985         mkdir -p $DIR/$tdir
19986         chmod 777 $DIR/$tdir
19987         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19988                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19989                 error "create striped dir succeeds with gid=0"
19990
19991         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19992         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19993                 error "create striped dir fails with gid=-1"
19994
19995         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19996         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19997                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19998                 error "set default striped dir succeeds with gid=0"
19999
20000
20001         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20002         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
20003                 error "set default striped dir fails with gid=-1"
20004
20005
20006         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20007         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
20008                                         error "create test_dir fails"
20009         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
20010                                         error "create test_dir1 fails"
20011         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
20012                                         error "create test_dir2 fails"
20013         cleanup_300n
20014 }
20015 run_test 300n "non-root user to create dir under striped dir with default EA"
20016
20017 test_300o() {
20018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20020         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20021                 skip "Need MDS version at least 2.7.55"
20022
20023         local numfree1
20024         local numfree2
20025
20026         mkdir -p $DIR/$tdir
20027
20028         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
20029         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
20030         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
20031                 skip "not enough free inodes $numfree1 $numfree2"
20032         fi
20033
20034         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
20035         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
20036         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
20037                 skip "not enough free space $numfree1 $numfree2"
20038         fi
20039
20040         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
20041                 error "setdirstripe fails"
20042
20043         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
20044                 error "create dirs fails"
20045
20046         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
20047         ls $DIR/$tdir/striped_dir > /dev/null ||
20048                 error "ls striped dir fails"
20049         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
20050                 error "unlink big striped dir fails"
20051 }
20052 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
20053
20054 test_300p() {
20055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20057         remote_mds_nodsh && skip "remote MDS with nodsh"
20058
20059         mkdir -p $DIR/$tdir
20060
20061         #define OBD_FAIL_OUT_ENOSPC     0x1704
20062         do_facet mds2 lctl set_param fail_loc=0x80001704
20063         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
20064                  && error "create striped directory should fail"
20065
20066         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
20067
20068         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
20069         true
20070 }
20071 run_test 300p "create striped directory without space"
20072
20073 test_300q() {
20074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20075         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20076
20077         local fd=$(free_fd)
20078         local cmd="exec $fd<$tdir"
20079         cd $DIR
20080         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
20081         eval $cmd
20082         cmd="exec $fd<&-"
20083         trap "eval $cmd" EXIT
20084         cd $tdir || error "cd $tdir fails"
20085         rmdir  ../$tdir || error "rmdir $tdir fails"
20086         mkdir local_dir && error "create dir succeeds"
20087         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
20088         eval $cmd
20089         return 0
20090 }
20091 run_test 300q "create remote directory under orphan directory"
20092
20093 test_300r() {
20094         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
20095                 skip "Need MDS version at least 2.7.55" && return
20096         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20097
20098         mkdir $DIR/$tdir
20099
20100         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
20101                 error "set striped dir error"
20102
20103         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20104                 error "getstripeddir fails"
20105
20106         local stripe_count
20107         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
20108                       awk '/lmv_stripe_count:/ { print $2 }')
20109
20110         [ $MDSCOUNT -ne $stripe_count ] &&
20111                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
20112
20113         rm -rf $DIR/$tdir/striped_dir ||
20114                 error "unlink striped dir fails"
20115 }
20116 run_test 300r "test -1 striped directory"
20117
20118 prepare_remote_file() {
20119         mkdir $DIR/$tdir/src_dir ||
20120                 error "create remote source failed"
20121
20122         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20123                  error "cp to remote source failed"
20124         touch $DIR/$tdir/src_dir/a
20125
20126         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20127                 error "create remote target dir failed"
20128
20129         touch $DIR/$tdir/tgt_dir/b
20130
20131         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20132                 error "rename dir cross MDT failed!"
20133
20134         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20135                 error "src_child still exists after rename"
20136
20137         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20138                 error "missing file(a) after rename"
20139
20140         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20141                 error "diff after rename"
20142 }
20143
20144 test_310a() {
20145         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20147
20148         local remote_file=$DIR/$tdir/tgt_dir/b
20149
20150         mkdir -p $DIR/$tdir
20151
20152         prepare_remote_file || error "prepare remote file failed"
20153
20154         #open-unlink file
20155         $OPENUNLINK $remote_file $remote_file ||
20156                 error "openunlink $remote_file failed"
20157         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20158 }
20159 run_test 310a "open unlink remote file"
20160
20161 test_310b() {
20162         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20164
20165         local remote_file=$DIR/$tdir/tgt_dir/b
20166
20167         mkdir -p $DIR/$tdir
20168
20169         prepare_remote_file || error "prepare remote file failed"
20170
20171         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20172         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20173         $CHECKSTAT -t file $remote_file || error "check file failed"
20174 }
20175 run_test 310b "unlink remote file with multiple links while open"
20176
20177 test_310c() {
20178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20179         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20180
20181         local remote_file=$DIR/$tdir/tgt_dir/b
20182
20183         mkdir -p $DIR/$tdir
20184
20185         prepare_remote_file || error "prepare remote file failed"
20186
20187         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20188         multiop_bg_pause $remote_file O_uc ||
20189                         error "mulitop failed for remote file"
20190         MULTIPID=$!
20191         $MULTIOP $DIR/$tfile Ouc
20192         kill -USR1 $MULTIPID
20193         wait $MULTIPID
20194 }
20195 run_test 310c "open-unlink remote file with multiple links"
20196
20197 #LU-4825
20198 test_311() {
20199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20200         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20201         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20202                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20203         remote_mds_nodsh && skip "remote MDS with nodsh"
20204
20205         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20206         local mdts=$(comma_list $(mdts_nodes))
20207
20208         mkdir -p $DIR/$tdir
20209         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20210         createmany -o $DIR/$tdir/$tfile. 1000
20211
20212         # statfs data is not real time, let's just calculate it
20213         old_iused=$((old_iused + 1000))
20214
20215         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20216                         osp.*OST0000*MDT0000.create_count")
20217         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20218                                 osp.*OST0000*MDT0000.max_create_count")
20219         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20220
20221         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20222         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20223         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20224
20225         unlinkmany $DIR/$tdir/$tfile. 1000
20226
20227         do_nodes $mdts "$LCTL set_param -n \
20228                         osp.*OST0000*.max_create_count=$max_count"
20229         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20230                 do_nodes $mdts "$LCTL set_param -n \
20231                                 osp.*OST0000*.create_count=$count"
20232         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20233                         grep "=0" && error "create_count is zero"
20234
20235         local new_iused
20236         for i in $(seq 120); do
20237                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20238                 # system may be too busy to destroy all objs in time, use
20239                 # a somewhat small value to not fail autotest
20240                 [ $((old_iused - new_iused)) -gt 400 ] && break
20241                 sleep 1
20242         done
20243
20244         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20245         [ $((old_iused - new_iused)) -gt 400 ] ||
20246                 error "objs not destroyed after unlink"
20247 }
20248 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20249
20250 zfs_oid_to_objid()
20251 {
20252         local ost=$1
20253         local objid=$2
20254
20255         local vdevdir=$(dirname $(facet_vdevice $ost))
20256         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20257         local zfs_zapid=$(do_facet $ost $cmd |
20258                           grep -w "/O/0/d$((objid%32))" -C 5 |
20259                           awk '/Object/{getline; print $1}')
20260         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20261                           awk "/$objid = /"'{printf $3}')
20262
20263         echo $zfs_objid
20264 }
20265
20266 zfs_object_blksz() {
20267         local ost=$1
20268         local objid=$2
20269
20270         local vdevdir=$(dirname $(facet_vdevice $ost))
20271         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20272         local blksz=$(do_facet $ost $cmd $objid |
20273                       awk '/dblk/{getline; printf $4}')
20274
20275         case "${blksz: -1}" in
20276                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20277                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20278                 *) ;;
20279         esac
20280
20281         echo $blksz
20282 }
20283
20284 test_312() { # LU-4856
20285         remote_ost_nodsh && skip "remote OST with nodsh"
20286         [ "$ost1_FSTYPE" = "zfs" ] ||
20287                 skip_env "the test only applies to zfs"
20288
20289         local max_blksz=$(do_facet ost1 \
20290                           $ZFS get -p recordsize $(facet_device ost1) |
20291                           awk '!/VALUE/{print $3}')
20292
20293         # to make life a little bit easier
20294         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20295         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20296
20297         local tf=$DIR/$tdir/$tfile
20298         touch $tf
20299         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20300
20301         # Get ZFS object id
20302         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20303         # block size change by sequential overwrite
20304         local bs
20305
20306         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20307                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20308
20309                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20310                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20311         done
20312         rm -f $tf
20313
20314         # block size change by sequential append write
20315         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20316         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20317         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20318         local count
20319
20320         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20321                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20322                         oflag=sync conv=notrunc
20323
20324                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20325                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20326                         error "blksz error, actual $blksz, " \
20327                                 "expected: 2 * $count * $PAGE_SIZE"
20328         done
20329         rm -f $tf
20330
20331         # random write
20332         touch $tf
20333         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20334         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20335
20336         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20337         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20338         [ $blksz -eq $PAGE_SIZE ] ||
20339                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20340
20341         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20342         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20343         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20344
20345         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20346         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20347         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20348 }
20349 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20350
20351 test_313() {
20352         remote_ost_nodsh && skip "remote OST with nodsh"
20353
20354         local file=$DIR/$tfile
20355
20356         rm -f $file
20357         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20358
20359         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20360         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20361         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20362                 error "write should failed"
20363         do_facet ost1 "$LCTL set_param fail_loc=0"
20364         rm -f $file
20365 }
20366 run_test 313 "io should fail after last_rcvd update fail"
20367
20368 test_314() {
20369         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20370
20371         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20372         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20373         rm -f $DIR/$tfile
20374         wait_delete_completed
20375         do_facet ost1 "$LCTL set_param fail_loc=0"
20376 }
20377 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20378
20379 test_315() { # LU-618
20380         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20381
20382         local file=$DIR/$tfile
20383         rm -f $file
20384
20385         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20386                 error "multiop file write failed"
20387         $MULTIOP $file oO_RDONLY:r4063232_c &
20388         PID=$!
20389
20390         sleep 2
20391
20392         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20393         kill -USR1 $PID
20394
20395         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20396         rm -f $file
20397 }
20398 run_test 315 "read should be accounted"
20399
20400 test_316() {
20401         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20402         large_xattr_enabled || skip_env "ea_inode feature disabled"
20403
20404         rm -rf $DIR/$tdir/d
20405         mkdir -p $DIR/$tdir/d
20406         chown nobody $DIR/$tdir/d
20407         touch $DIR/$tdir/d/file
20408
20409         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20410 }
20411 run_test 316 "lfs mv"
20412
20413 test_317() {
20414         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20415                 skip "Need MDS version at least 2.11.53"
20416         if [ "$ost1_FSTYPE" == "zfs" ]; then
20417                 skip "LU-10370: no implementation for ZFS"
20418         fi
20419
20420         local trunc_sz
20421         local grant_blk_size
20422
20423         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20424                         awk '/grant_block_size:/ { print $2; exit; }')
20425         #
20426         # Create File of size 5M. Truncate it to below size's and verify
20427         # blocks count.
20428         #
20429         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20430                 error "Create file $DIR/$tfile failed"
20431         stack_trap "rm -f $DIR/$tfile" EXIT
20432
20433         for trunc_sz in 2097152 4097 4000 509 0; do
20434                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20435                         error "truncate $tfile to $trunc_sz failed"
20436                 local sz=$(stat --format=%s $DIR/$tfile)
20437                 local blk=$(stat --format=%b $DIR/$tfile)
20438                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20439                                      grant_blk_size) * 8))
20440
20441                 if [[ $blk -ne $trunc_blk ]]; then
20442                         $(which stat) $DIR/$tfile
20443                         error "Expected Block $trunc_blk got $blk for $tfile"
20444                 fi
20445
20446                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20447                         error "Expected Size $trunc_sz got $sz for $tfile"
20448         done
20449
20450         #
20451         # sparse file test
20452         # Create file with a hole and write actual two blocks. Block count
20453         # must be 16.
20454         #
20455         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20456                 conv=fsync || error "Create file : $DIR/$tfile"
20457
20458         # Calculate the final truncate size.
20459         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20460
20461         #
20462         # truncate to size $trunc_sz bytes. Strip the last block
20463         # The block count must drop to 8
20464         #
20465         $TRUNCATE $DIR/$tfile $trunc_sz ||
20466                 error "truncate $tfile to $trunc_sz failed"
20467
20468         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20469         sz=$(stat --format=%s $DIR/$tfile)
20470         blk=$(stat --format=%b $DIR/$tfile)
20471
20472         if [[ $blk -ne $trunc_bsz ]]; then
20473                 $(which stat) $DIR/$tfile
20474                 error "Expected Block $trunc_bsz got $blk for $tfile"
20475         fi
20476
20477         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20478                 error "Expected Size $trunc_sz got $sz for $tfile"
20479 }
20480 run_test 317 "Verify blocks get correctly update after truncate"
20481
20482 test_318() {
20483         local old_max_active=$($LCTL get_param -n \
20484                             llite.*.max_read_ahead_async_active 2>/dev/null)
20485
20486         $LCTL set_param llite.*.max_read_ahead_async_active=256
20487         local max_active=$($LCTL get_param -n \
20488                            llite.*.max_read_ahead_async_active 2>/dev/null)
20489         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20490
20491         # currently reset to 0 is unsupported, leave it 512 for now.
20492         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20493                 error "set max_read_ahead_async_active should fail"
20494
20495         $LCTL set_param llite.*.max_read_ahead_async_active=512
20496         max_active=$($LCTL get_param -n \
20497                      llite.*.max_read_ahead_async_active 2>/dev/null)
20498         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20499
20500         # restore @max_active
20501         [ $old_max_active -ne 0 ] && $LCTL set_param \
20502                 llite.*.max_read_ahead_async_active=$old_max_active
20503
20504         local old_threshold=$($LCTL get_param -n \
20505                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20506         local max_per_file_mb=$($LCTL get_param -n \
20507                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20508
20509         local invalid=$(($max_per_file_mb + 1))
20510         $LCTL set_param \
20511                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20512                         && error "set $invalid should fail"
20513
20514         local valid=$(($invalid - 1))
20515         $LCTL set_param \
20516                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20517                         error "set $valid should succeed"
20518         local threshold=$($LCTL get_param -n \
20519                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20520         [ $threshold -eq $valid ] || error \
20521                 "expect threshold $valid got $threshold"
20522         $LCTL set_param \
20523                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20524 }
20525 run_test 318 "Verify async readahead tunables"
20526
20527 test_319() {
20528         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20529
20530         local before=$(date +%s)
20531         local evict
20532         local mdir=$DIR/$tdir
20533         local file=$mdir/xxx
20534
20535         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20536         touch $file
20537
20538 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20539         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20540         $LFS mv -m1 $file &
20541
20542         sleep 1
20543         dd if=$file of=/dev/null
20544         wait
20545         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20546           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20547
20548         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20549 }
20550 run_test 319 "lost lease lock on migrate error"
20551
20552 test_fake_rw() {
20553         local read_write=$1
20554         if [ "$read_write" = "write" ]; then
20555                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20556         elif [ "$read_write" = "read" ]; then
20557                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20558         else
20559                 error "argument error"
20560         fi
20561
20562         # turn off debug for performance testing
20563         local saved_debug=$($LCTL get_param -n debug)
20564         $LCTL set_param debug=0
20565
20566         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20567
20568         # get ost1 size - $FSNAME-OST0000
20569         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20570         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20571         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20572
20573         if [ "$read_write" = "read" ]; then
20574                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20575         fi
20576
20577         local start_time=$(date +%s.%N)
20578         $dd_cmd bs=1M count=$blocks oflag=sync ||
20579                 error "real dd $read_write error"
20580         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20581
20582         if [ "$read_write" = "write" ]; then
20583                 rm -f $DIR/$tfile
20584         fi
20585
20586         # define OBD_FAIL_OST_FAKE_RW           0x238
20587         do_facet ost1 $LCTL set_param fail_loc=0x238
20588
20589         local start_time=$(date +%s.%N)
20590         $dd_cmd bs=1M count=$blocks oflag=sync ||
20591                 error "fake dd $read_write error"
20592         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20593
20594         if [ "$read_write" = "write" ]; then
20595                 # verify file size
20596                 cancel_lru_locks osc
20597                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20598                         error "$tfile size not $blocks MB"
20599         fi
20600         do_facet ost1 $LCTL set_param fail_loc=0
20601
20602         echo "fake $read_write $duration_fake vs. normal $read_write" \
20603                 "$duration in seconds"
20604         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20605                 error_not_in_vm "fake write is slower"
20606
20607         $LCTL set_param -n debug="$saved_debug"
20608         rm -f $DIR/$tfile
20609 }
20610 test_399a() { # LU-7655 for OST fake write
20611         remote_ost_nodsh && skip "remote OST with nodsh"
20612
20613         test_fake_rw write
20614 }
20615 run_test 399a "fake write should not be slower than normal write"
20616
20617 test_399b() { # LU-8726 for OST fake read
20618         remote_ost_nodsh && skip "remote OST with nodsh"
20619         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20620                 skip_env "ldiskfs only test"
20621         fi
20622
20623         test_fake_rw read
20624 }
20625 run_test 399b "fake read should not be slower than normal read"
20626
20627 test_400a() { # LU-1606, was conf-sanity test_74
20628         if ! which $CC > /dev/null 2>&1; then
20629                 skip_env "$CC is not installed"
20630         fi
20631
20632         local extra_flags=''
20633         local out=$TMP/$tfile
20634         local prefix=/usr/include/lustre
20635         local prog
20636
20637         if ! [[ -d $prefix ]]; then
20638                 # Assume we're running in tree and fixup the include path.
20639                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20640                 extra_flags+=" -L$LUSTRE/utils/.lib"
20641         fi
20642
20643         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20644                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20645                         error "client api broken"
20646         done
20647         rm -f $out
20648 }
20649 run_test 400a "Lustre client api program can compile and link"
20650
20651 test_400b() { # LU-1606, LU-5011
20652         local header
20653         local out=$TMP/$tfile
20654         local prefix=/usr/include/linux/lustre
20655
20656         # We use a hard coded prefix so that this test will not fail
20657         # when run in tree. There are headers in lustre/include/lustre/
20658         # that are not packaged (like lustre_idl.h) and have more
20659         # complicated include dependencies (like config.h and lnet/types.h).
20660         # Since this test about correct packaging we just skip them when
20661         # they don't exist (see below) rather than try to fixup cppflags.
20662
20663         if ! which $CC > /dev/null 2>&1; then
20664                 skip_env "$CC is not installed"
20665         fi
20666
20667         for header in $prefix/*.h; do
20668                 if ! [[ -f "$header" ]]; then
20669                         continue
20670                 fi
20671
20672                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20673                         continue # lustre_ioctl.h is internal header
20674                 fi
20675
20676                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20677                         error "cannot compile '$header'"
20678         done
20679         rm -f $out
20680 }
20681 run_test 400b "packaged headers can be compiled"
20682
20683 test_401a() { #LU-7437
20684         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20685         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20686
20687         #count the number of parameters by "list_param -R"
20688         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20689         #count the number of parameters by listing proc files
20690         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20691         echo "proc_dirs='$proc_dirs'"
20692         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20693         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20694                       sort -u | wc -l)
20695
20696         [ $params -eq $procs ] ||
20697                 error "found $params parameters vs. $procs proc files"
20698
20699         # test the list_param -D option only returns directories
20700         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20701         #count the number of parameters by listing proc directories
20702         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20703                 sort -u | wc -l)
20704
20705         [ $params -eq $procs ] ||
20706                 error "found $params parameters vs. $procs proc files"
20707 }
20708 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20709
20710 test_401b() {
20711         local save=$($LCTL get_param -n jobid_var)
20712         local tmp=testing
20713
20714         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20715                 error "no error returned when setting bad parameters"
20716
20717         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20718         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20719
20720         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20721         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20722         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20723 }
20724 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20725
20726 test_401c() {
20727         local jobid_var_old=$($LCTL get_param -n jobid_var)
20728         local jobid_var_new
20729
20730         $LCTL set_param jobid_var= &&
20731                 error "no error returned for 'set_param a='"
20732
20733         jobid_var_new=$($LCTL get_param -n jobid_var)
20734         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20735                 error "jobid_var was changed by setting without value"
20736
20737         $LCTL set_param jobid_var &&
20738                 error "no error returned for 'set_param a'"
20739
20740         jobid_var_new=$($LCTL get_param -n jobid_var)
20741         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20742                 error "jobid_var was changed by setting without value"
20743 }
20744 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20745
20746 test_401d() {
20747         local jobid_var_old=$($LCTL get_param -n jobid_var)
20748         local jobid_var_new
20749         local new_value="foo=bar"
20750
20751         $LCTL set_param jobid_var=$new_value ||
20752                 error "'set_param a=b' did not accept a value containing '='"
20753
20754         jobid_var_new=$($LCTL get_param -n jobid_var)
20755         [[ "$jobid_var_new" == "$new_value" ]] ||
20756                 error "'set_param a=b' failed on a value containing '='"
20757
20758         # Reset the jobid_var to test the other format
20759         $LCTL set_param jobid_var=$jobid_var_old
20760         jobid_var_new=$($LCTL get_param -n jobid_var)
20761         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20762                 error "failed to reset jobid_var"
20763
20764         $LCTL set_param jobid_var $new_value ||
20765                 error "'set_param a b' did not accept a value containing '='"
20766
20767         jobid_var_new=$($LCTL get_param -n jobid_var)
20768         [[ "$jobid_var_new" == "$new_value" ]] ||
20769                 error "'set_param a b' failed on a value containing '='"
20770
20771         $LCTL set_param jobid_var $jobid_var_old
20772         jobid_var_new=$($LCTL get_param -n jobid_var)
20773         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20774                 error "failed to reset jobid_var"
20775 }
20776 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20777
20778 test_402() {
20779         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20780         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20781                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20782         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20783                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20784                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20785         remote_mds_nodsh && skip "remote MDS with nodsh"
20786
20787         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20788 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20789         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20790         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20791                 echo "Touch failed - OK"
20792 }
20793 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20794
20795 test_403() {
20796         local file1=$DIR/$tfile.1
20797         local file2=$DIR/$tfile.2
20798         local tfile=$TMP/$tfile
20799
20800         rm -f $file1 $file2 $tfile
20801
20802         touch $file1
20803         ln $file1 $file2
20804
20805         # 30 sec OBD_TIMEOUT in ll_getattr()
20806         # right before populating st_nlink
20807         $LCTL set_param fail_loc=0x80001409
20808         stat -c %h $file1 > $tfile &
20809
20810         # create an alias, drop all locks and reclaim the dentry
20811         < $file2
20812         cancel_lru_locks mdc
20813         cancel_lru_locks osc
20814         sysctl -w vm.drop_caches=2
20815
20816         wait
20817
20818         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20819
20820         rm -f $tfile $file1 $file2
20821 }
20822 run_test 403 "i_nlink should not drop to zero due to aliasing"
20823
20824 test_404() { # LU-6601
20825         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20826                 skip "Need server version newer than 2.8.52"
20827         remote_mds_nodsh && skip "remote MDS with nodsh"
20828
20829         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20830                 awk '/osp .*-osc-MDT/ { print $4}')
20831
20832         local osp
20833         for osp in $mosps; do
20834                 echo "Deactivate: " $osp
20835                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20836                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20837                         awk -vp=$osp '$4 == p { print $2 }')
20838                 [ $stat = IN ] || {
20839                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20840                         error "deactivate error"
20841                 }
20842                 echo "Activate: " $osp
20843                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20844                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20845                         awk -vp=$osp '$4 == p { print $2 }')
20846                 [ $stat = UP ] || {
20847                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20848                         error "activate error"
20849                 }
20850         done
20851 }
20852 run_test 404 "validate manual {de}activated works properly for OSPs"
20853
20854 test_405() {
20855         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20856         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20857                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20858                         skip "Layout swap lock is not supported"
20859
20860         check_swap_layouts_support
20861
20862         test_mkdir $DIR/$tdir
20863         swap_lock_test -d $DIR/$tdir ||
20864                 error "One layout swap locked test failed"
20865 }
20866 run_test 405 "Various layout swap lock tests"
20867
20868 test_406() {
20869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20870         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20871         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20873         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20874                 skip "Need MDS version at least 2.8.50"
20875
20876         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20877         local test_pool=$TESTNAME
20878
20879         pool_add $test_pool || error "pool_add failed"
20880         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20881                 error "pool_add_targets failed"
20882
20883         save_layout_restore_at_exit $MOUNT
20884
20885         # parent set default stripe count only, child will stripe from both
20886         # parent and fs default
20887         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20888                 error "setstripe $MOUNT failed"
20889         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20890         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20891         for i in $(seq 10); do
20892                 local f=$DIR/$tdir/$tfile.$i
20893                 touch $f || error "touch failed"
20894                 local count=$($LFS getstripe -c $f)
20895                 [ $count -eq $OSTCOUNT ] ||
20896                         error "$f stripe count $count != $OSTCOUNT"
20897                 local offset=$($LFS getstripe -i $f)
20898                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20899                 local size=$($LFS getstripe -S $f)
20900                 [ $size -eq $((def_stripe_size * 2)) ] ||
20901                         error "$f stripe size $size != $((def_stripe_size * 2))"
20902                 local pool=$($LFS getstripe -p $f)
20903                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20904         done
20905
20906         # change fs default striping, delete parent default striping, now child
20907         # will stripe from new fs default striping only
20908         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20909                 error "change $MOUNT default stripe failed"
20910         $LFS setstripe -c 0 $DIR/$tdir ||
20911                 error "delete $tdir default stripe failed"
20912         for i in $(seq 11 20); do
20913                 local f=$DIR/$tdir/$tfile.$i
20914                 touch $f || error "touch $f failed"
20915                 local count=$($LFS getstripe -c $f)
20916                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20917                 local offset=$($LFS getstripe -i $f)
20918                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20919                 local size=$($LFS getstripe -S $f)
20920                 [ $size -eq $def_stripe_size ] ||
20921                         error "$f stripe size $size != $def_stripe_size"
20922                 local pool=$($LFS getstripe -p $f)
20923                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20924         done
20925
20926         unlinkmany $DIR/$tdir/$tfile. 1 20
20927
20928         local f=$DIR/$tdir/$tfile
20929         pool_remove_all_targets $test_pool $f
20930         pool_remove $test_pool $f
20931 }
20932 run_test 406 "DNE support fs default striping"
20933
20934 test_407() {
20935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20936         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20937                 skip "Need MDS version at least 2.8.55"
20938         remote_mds_nodsh && skip "remote MDS with nodsh"
20939
20940         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20941                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20942         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20943                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20944         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20945
20946         #define OBD_FAIL_DT_TXN_STOP    0x2019
20947         for idx in $(seq $MDSCOUNT); do
20948                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20949         done
20950         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20951         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20952                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20953         true
20954 }
20955 run_test 407 "transaction fail should cause operation fail"
20956
20957 test_408() {
20958         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20959
20960         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20961         lctl set_param fail_loc=0x8000040a
20962         # let ll_prepare_partial_page() fail
20963         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20964
20965         rm -f $DIR/$tfile
20966
20967         # create at least 100 unused inodes so that
20968         # shrink_icache_memory(0) should not return 0
20969         touch $DIR/$tfile-{0..100}
20970         rm -f $DIR/$tfile-{0..100}
20971         sync
20972
20973         echo 2 > /proc/sys/vm/drop_caches
20974 }
20975 run_test 408 "drop_caches should not hang due to page leaks"
20976
20977 test_409()
20978 {
20979         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20980
20981         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20982         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20983         touch $DIR/$tdir/guard || error "(2) Fail to create"
20984
20985         local PREFIX=$(str_repeat 'A' 128)
20986         echo "Create 1K hard links start at $(date)"
20987         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20988                 error "(3) Fail to hard link"
20989
20990         echo "Links count should be right although linkEA overflow"
20991         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20992         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20993         [ $linkcount -eq 1001 ] ||
20994                 error "(5) Unexpected hard links count: $linkcount"
20995
20996         echo "List all links start at $(date)"
20997         ls -l $DIR/$tdir/foo > /dev/null ||
20998                 error "(6) Fail to list $DIR/$tdir/foo"
20999
21000         echo "Unlink hard links start at $(date)"
21001         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21002                 error "(7) Fail to unlink"
21003         echo "Unlink hard links finished at $(date)"
21004 }
21005 run_test 409 "Large amount of cross-MDTs hard links on the same file"
21006
21007 test_410()
21008 {
21009         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
21010                 skip "Need client version at least 2.9.59"
21011
21012         # Create a file, and stat it from the kernel
21013         local testfile=$DIR/$tfile
21014         touch $testfile
21015
21016         local run_id=$RANDOM
21017         local my_ino=$(stat --format "%i" $testfile)
21018
21019         # Try to insert the module. This will always fail as the
21020         # module is designed to not be inserted.
21021         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
21022             &> /dev/null
21023
21024         # Anything but success is a test failure
21025         dmesg | grep -q \
21026             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
21027             error "no inode match"
21028 }
21029 run_test 410 "Test inode number returned from kernel thread"
21030
21031 cleanup_test411_cgroup() {
21032         trap 0
21033         rmdir "$1"
21034 }
21035
21036 test_411() {
21037         local cg_basedir=/sys/fs/cgroup/memory
21038         # LU-9966
21039         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
21040                 skip "no setup for cgroup"
21041
21042         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
21043                 error "test file creation failed"
21044         cancel_lru_locks osc
21045
21046         # Create a very small memory cgroup to force a slab allocation error
21047         local cgdir=$cg_basedir/osc_slab_alloc
21048         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
21049         trap "cleanup_test411_cgroup $cgdir" EXIT
21050         echo 2M > $cgdir/memory.kmem.limit_in_bytes
21051         echo 1M > $cgdir/memory.limit_in_bytes
21052
21053         # Should not LBUG, just be killed by oom-killer
21054         # dd will return 0 even allocation failure in some environment.
21055         # So don't check return value
21056         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
21057         cleanup_test411_cgroup $cgdir
21058
21059         return 0
21060 }
21061 run_test 411 "Slab allocation error with cgroup does not LBUG"
21062
21063 test_412() {
21064         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21065         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
21066                 skip "Need server version at least 2.10.55"
21067         fi
21068
21069         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
21070                 error "mkdir failed"
21071         $LFS getdirstripe $DIR/$tdir
21072         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21073         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
21074                 error "expect $((MDSCOUT - 1)) get $stripe_index"
21075         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
21076         [ $stripe_count -eq 2 ] ||
21077                 error "expect 2 get $stripe_count"
21078 }
21079 run_test 412 "mkdir on specific MDTs"
21080
21081 test_qos_mkdir() {
21082         local mkdir_cmd=$1
21083         local stripe_count=$2
21084         local mdts=$(comma_list $(mdts_nodes))
21085
21086         local testdir
21087         local lmv_qos_prio_free
21088         local lmv_qos_threshold_rr
21089         local lmv_qos_maxage
21090         local lod_qos_prio_free
21091         local lod_qos_threshold_rr
21092         local lod_qos_maxage
21093         local count
21094         local i
21095
21096         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
21097         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
21098         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
21099                 head -n1)
21100         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
21101         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
21102         stack_trap "$LCTL set_param \
21103                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
21104         stack_trap "$LCTL set_param \
21105                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
21106         stack_trap "$LCTL set_param \
21107                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
21108
21109         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
21110                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
21111         lod_qos_prio_free=${lod_qos_prio_free%%%}
21112         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
21113                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
21114         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
21115         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
21116                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
21117         stack_trap "do_nodes $mdts $LCTL set_param \
21118                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21119         stack_trap "do_nodes $mdts $LCTL set_param \
21120                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21121                 EXIT
21122         stack_trap "do_nodes $mdts $LCTL set_param \
21123                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21124
21125         echo
21126         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21127
21128         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21129         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21130
21131         testdir=$DIR/$tdir-s$stripe_count/rr
21132
21133         for i in $(seq $((100 * MDSCOUNT))); do
21134                 eval $mkdir_cmd $testdir/subdir$i ||
21135                         error "$mkdir_cmd subdir$i failed"
21136         done
21137
21138         for i in $(seq $MDSCOUNT); do
21139                 count=$($LFS getdirstripe -i $testdir/* |
21140                                 grep ^$((i - 1))$ | wc -l)
21141                 echo "$count directories created on MDT$((i - 1))"
21142                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21143
21144                 if [ $stripe_count -gt 1 ]; then
21145                         count=$($LFS getdirstripe $testdir/* |
21146                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21147                         echo "$count stripes created on MDT$((i - 1))"
21148                         # deviation should < 5% of average
21149                         [ $count -lt $((95 * stripe_count)) ] ||
21150                         [ $count -gt $((105 * stripe_count)) ] &&
21151                                 error "stripes are not evenly distributed"
21152                 fi
21153         done
21154
21155         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21156         do_nodes $mdts $LCTL set_param \
21157                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21158
21159         echo
21160         echo "Check for uneven MDTs: "
21161
21162         local ffree
21163         local bavail
21164         local max
21165         local min
21166         local max_index
21167         local min_index
21168         local tmp
21169
21170         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21171         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21172         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21173
21174         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21175         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21176         max_index=0
21177         min_index=0
21178         for ((i = 1; i < ${#ffree[@]}; i++)); do
21179                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21180                 if [ $tmp -gt $max ]; then
21181                         max=$tmp
21182                         max_index=$i
21183                 fi
21184                 if [ $tmp -lt $min ]; then
21185                         min=$tmp
21186                         min_index=$i
21187                 fi
21188         done
21189
21190         [ ${ffree[min_index]} -eq 0 ] &&
21191                 skip "no free files in MDT$min_index"
21192         [ ${ffree[min_index]} -gt 100000000 ] &&
21193                 skip "too much free files in MDT$min_index"
21194
21195         # Check if we need to generate uneven MDTs
21196         local threshold=50
21197         local diff=$(((max - min) * 100 / min))
21198         local value="$(generate_string 1024)"
21199
21200         while [ $diff -lt $threshold ]; do
21201                 # generate uneven MDTs, create till $threshold% diff
21202                 echo -n "weight diff=$diff% must be > $threshold% ..."
21203                 count=$((${ffree[min_index]} / 10))
21204                 # 50 sec per 10000 files in vm
21205                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21206                         skip "$count files to create"
21207                 echo "Fill MDT$min_index with $count files"
21208                 [ -d $DIR/$tdir-MDT$min_index ] ||
21209                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21210                         error "mkdir $tdir-MDT$min_index failed"
21211                 for i in $(seq $count); do
21212                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21213                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21214                                 error "create f$j_$i failed"
21215                         setfattr -n user.413b -v $value \
21216                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21217                                 error "setfattr f$j_$i failed"
21218                 done
21219
21220                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21221                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21222                 max=$(((${ffree[max_index]} >> 8) * \
21223                         (${bavail[max_index]} * bsize >> 16)))
21224                 min=$(((${ffree[min_index]} >> 8) * \
21225                         (${bavail[min_index]} * bsize >> 16)))
21226                 diff=$(((max - min) * 100 / min))
21227         done
21228
21229         echo "MDT filesfree available: ${ffree[@]}"
21230         echo "MDT blocks available: ${bavail[@]}"
21231         echo "weight diff=$diff%"
21232
21233         echo
21234         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21235
21236         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21237         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21238         # decrease statfs age, so that it can be updated in time
21239         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21240         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21241
21242         sleep 1
21243
21244         testdir=$DIR/$tdir-s$stripe_count/qos
21245
21246         for i in $(seq $((100 * MDSCOUNT))); do
21247                 eval $mkdir_cmd $testdir/subdir$i ||
21248                         error "$mkdir_cmd subdir$i failed"
21249         done
21250
21251         for i in $(seq $MDSCOUNT); do
21252                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21253                         wc -l)
21254                 echo "$count directories created on MDT$((i - 1))"
21255
21256                 if [ $stripe_count -gt 1 ]; then
21257                         count=$($LFS getdirstripe $testdir/* |
21258                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21259                         echo "$count stripes created on MDT$((i - 1))"
21260                 fi
21261         done
21262
21263         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21264         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21265
21266         # D-value should > 10% of averge
21267         [ $((max - min)) -lt 10 ] &&
21268                 error "subdirs shouldn't be evenly distributed"
21269
21270         # ditto
21271         if [ $stripe_count -gt 1 ]; then
21272                 max=$($LFS getdirstripe $testdir/* |
21273                         grep -P "^\s+$max_index\t" | wc -l)
21274                 min=$($LFS getdirstripe $testdir/* |
21275                         grep -P "^\s+$min_index\t" | wc -l)
21276                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21277                         error "stripes shouldn't be evenly distributed"|| true
21278         fi
21279 }
21280
21281 test_413a() {
21282         [ $MDSCOUNT -lt 2 ] &&
21283                 skip "We need at least 2 MDTs for this test"
21284
21285         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21286                 skip "Need server version at least 2.12.52"
21287
21288         local stripe_count
21289
21290         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21291                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21292                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21293                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21294                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21295         done
21296 }
21297 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21298
21299 test_413b() {
21300         [ $MDSCOUNT -lt 2 ] &&
21301                 skip "We need at least 2 MDTs for this test"
21302
21303         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21304                 skip "Need server version at least 2.12.52"
21305
21306         local stripe_count
21307
21308         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21309                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21310                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21311                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21312                 $LFS setdirstripe -D -c $stripe_count \
21313                         $DIR/$tdir-s$stripe_count/rr ||
21314                         error "setdirstripe failed"
21315                 $LFS setdirstripe -D -c $stripe_count \
21316                         $DIR/$tdir-s$stripe_count/qos ||
21317                         error "setdirstripe failed"
21318                 test_qos_mkdir "mkdir" $stripe_count
21319         done
21320 }
21321 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21322
21323 test_414() {
21324 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21325         $LCTL set_param fail_loc=0x80000521
21326         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21327         rm -f $DIR/$tfile
21328 }
21329 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21330
21331 test_415() {
21332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21333         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
21334                 skip "Need server version at least 2.11.52"
21335
21336         # LU-11102
21337         local total
21338         local setattr_pid
21339         local start_time
21340         local end_time
21341         local duration
21342
21343         total=500
21344         # this test may be slow on ZFS
21345         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21346
21347         # though this test is designed for striped directory, let's test normal
21348         # directory too since lock is always saved as CoS lock.
21349         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21350         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21351
21352         (
21353                 while true; do
21354                         touch $DIR/$tdir
21355                 done
21356         ) &
21357         setattr_pid=$!
21358
21359         start_time=$(date +%s)
21360         for i in $(seq $total); do
21361                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21362                         > /dev/null
21363         done
21364         end_time=$(date +%s)
21365         duration=$((end_time - start_time))
21366
21367         kill -9 $setattr_pid
21368
21369         echo "rename $total files took $duration sec"
21370         [ $duration -lt 100 ] || error "rename took $duration sec"
21371 }
21372 run_test 415 "lock revoke is not missing"
21373
21374 test_416() {
21375         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
21376                 skip "Need server version at least 2.11.55"
21377
21378         # define OBD_FAIL_OSD_TXN_START    0x19a
21379         do_facet mds1 lctl set_param fail_loc=0x19a
21380
21381         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21382
21383         true
21384 }
21385 run_test 416 "transaction start failure won't cause system hung"
21386
21387 cleanup_417() {
21388         trap 0
21389         do_nodes $(comma_list $(mdts_nodes)) \
21390                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21391         do_nodes $(comma_list $(mdts_nodes)) \
21392                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21393         do_nodes $(comma_list $(mdts_nodes)) \
21394                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21395 }
21396
21397 test_417() {
21398         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21399         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21400                 skip "Need MDS version at least 2.11.56"
21401
21402         trap cleanup_417 RETURN EXIT
21403
21404         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21405         do_nodes $(comma_list $(mdts_nodes)) \
21406                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21407         $LFS migrate -m 0 $DIR/$tdir.1 &&
21408                 error "migrate dir $tdir.1 should fail"
21409
21410         do_nodes $(comma_list $(mdts_nodes)) \
21411                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21412         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21413                 error "create remote dir $tdir.2 should fail"
21414
21415         do_nodes $(comma_list $(mdts_nodes)) \
21416                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21417         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21418                 error "create striped dir $tdir.3 should fail"
21419         true
21420 }
21421 run_test 417 "disable remote dir, striped dir and dir migration"
21422
21423 # Checks that the outputs of df [-i] and lfs df [-i] match
21424 #
21425 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21426 check_lfs_df() {
21427         local dir=$2
21428         local inodes
21429         local df_out
21430         local lfs_df_out
21431         local count
21432         local passed=false
21433
21434         # blocks or inodes
21435         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21436
21437         for count in {1..100}; do
21438                 cancel_lru_locks
21439                 sync; sleep 0.2
21440
21441                 # read the lines of interest
21442                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21443                         error "df $inodes $dir | tail -n +2 failed"
21444                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21445                         error "lfs df $inodes $dir | grep summary: failed"
21446
21447                 # skip first substrings of each output as they are different
21448                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21449                 # compare the two outputs
21450                 passed=true
21451                 for i in {1..5}; do
21452                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21453                 done
21454                 $passed && break
21455         done
21456
21457         if ! $passed; then
21458                 df -P $inodes $dir
21459                 echo
21460                 lfs df $inodes $dir
21461                 error "df and lfs df $1 output mismatch: "      \
21462                       "df ${inodes}: ${df_out[*]}, "            \
21463                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21464         fi
21465 }
21466
21467 test_418() {
21468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21469
21470         local dir=$DIR/$tdir
21471         local numfiles=$((RANDOM % 4096 + 2))
21472         local numblocks=$((RANDOM % 256 + 1))
21473
21474         wait_delete_completed
21475         test_mkdir $dir
21476
21477         # check block output
21478         check_lfs_df blocks $dir
21479         # check inode output
21480         check_lfs_df inodes $dir
21481
21482         # create a single file and retest
21483         echo "Creating a single file and testing"
21484         createmany -o $dir/$tfile- 1 &>/dev/null ||
21485                 error "creating 1 file in $dir failed"
21486         check_lfs_df blocks $dir
21487         check_lfs_df inodes $dir
21488
21489         # create a random number of files
21490         echo "Creating $((numfiles - 1)) files and testing"
21491         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21492                 error "creating $((numfiles - 1)) files in $dir failed"
21493
21494         # write a random number of blocks to the first test file
21495         echo "Writing $numblocks 4K blocks and testing"
21496         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21497                 count=$numblocks &>/dev/null ||
21498                 error "dd to $dir/${tfile}-0 failed"
21499
21500         # retest
21501         check_lfs_df blocks $dir
21502         check_lfs_df inodes $dir
21503
21504         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21505                 error "unlinking $numfiles files in $dir failed"
21506 }
21507 run_test 418 "df and lfs df outputs match"
21508
21509 test_419()
21510 {
21511         local dir=$DIR/$tdir
21512
21513         mkdir -p $dir
21514         touch $dir/file
21515
21516         cancel_lru_locks mdc
21517
21518         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21519         $LCTL set_param fail_loc=0x1410
21520         cat $dir/file
21521         $LCTL set_param fail_loc=0
21522         rm -rf $dir
21523 }
21524 run_test 419 "Verify open file by name doesn't crash kernel"
21525
21526 test_420()
21527 {
21528         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21529                 skip "Need MDS version at least 2.12.53"
21530
21531         local SAVE_UMASK=$(umask)
21532         local dir=$DIR/$tdir
21533         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21534
21535         mkdir -p $dir
21536         umask 0000
21537         mkdir -m03777 $dir/testdir
21538         ls -dn $dir/testdir
21539         # Need to remove trailing '.' when SELinux is enabled
21540         local dirperms=$(ls -dn $dir/testdir |
21541                          awk '{ sub(/\.$/, "", $1); print $1}')
21542         [ $dirperms == "drwxrwsrwt" ] ||
21543                 error "incorrect perms on $dir/testdir"
21544
21545         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21546                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21547         ls -n $dir/testdir/testfile
21548         local fileperms=$(ls -n $dir/testdir/testfile |
21549                           awk '{ sub(/\.$/, "", $1); print $1}')
21550         [ $fileperms == "-rwxr-xr-x" ] ||
21551                 error "incorrect perms on $dir/testdir/testfile"
21552
21553         umask $SAVE_UMASK
21554 }
21555 run_test 420 "clear SGID bit on non-directories for non-members"
21556
21557 test_421a() {
21558         local cnt
21559         local fid1
21560         local fid2
21561
21562         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21563                 skip "Need MDS version at least 2.12.54"
21564
21565         test_mkdir $DIR/$tdir
21566         createmany -o $DIR/$tdir/f 3
21567         cnt=$(ls -1 $DIR/$tdir | wc -l)
21568         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21569
21570         fid1=$(lfs path2fid $DIR/$tdir/f1)
21571         fid2=$(lfs path2fid $DIR/$tdir/f2)
21572         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21573
21574         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21575         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21576
21577         cnt=$(ls -1 $DIR/$tdir | wc -l)
21578         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21579
21580         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21581         createmany -o $DIR/$tdir/f 3
21582         cnt=$(ls -1 $DIR/$tdir | wc -l)
21583         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21584
21585         fid1=$(lfs path2fid $DIR/$tdir/f1)
21586         fid2=$(lfs path2fid $DIR/$tdir/f2)
21587         echo "remove using fsname $FSNAME"
21588         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21589
21590         cnt=$(ls -1 $DIR/$tdir | wc -l)
21591         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21592 }
21593 run_test 421a "simple rm by fid"
21594
21595 test_421b() {
21596         local cnt
21597         local FID1
21598         local FID2
21599
21600         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21601                 skip "Need MDS version at least 2.12.54"
21602
21603         test_mkdir $DIR/$tdir
21604         createmany -o $DIR/$tdir/f 3
21605         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21606         MULTIPID=$!
21607
21608         FID1=$(lfs path2fid $DIR/$tdir/f1)
21609         FID2=$(lfs path2fid $DIR/$tdir/f2)
21610         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21611
21612         kill -USR1 $MULTIPID
21613         wait
21614
21615         cnt=$(ls $DIR/$tdir | wc -l)
21616         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21617 }
21618 run_test 421b "rm by fid on open file"
21619
21620 test_421c() {
21621         local cnt
21622         local FIDS
21623
21624         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21625                 skip "Need MDS version at least 2.12.54"
21626
21627         test_mkdir $DIR/$tdir
21628         createmany -o $DIR/$tdir/f 3
21629         touch $DIR/$tdir/$tfile
21630         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21631         cnt=$(ls -1 $DIR/$tdir | wc -l)
21632         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21633
21634         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21635         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21636
21637         cnt=$(ls $DIR/$tdir | wc -l)
21638         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21639 }
21640 run_test 421c "rm by fid against hardlinked files"
21641
21642 test_421d() {
21643         local cnt
21644         local FIDS
21645
21646         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21647                 skip "Need MDS version at least 2.12.54"
21648
21649         test_mkdir $DIR/$tdir
21650         createmany -o $DIR/$tdir/f 4097
21651         cnt=$(ls -1 $DIR/$tdir | wc -l)
21652         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21653
21654         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21655         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21656
21657         cnt=$(ls $DIR/$tdir | wc -l)
21658         rm -rf $DIR/$tdir
21659         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21660 }
21661 run_test 421d "rmfid en masse"
21662
21663 test_421e() {
21664         local cnt
21665         local FID
21666
21667         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21668         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21669                 skip "Need MDS version at least 2.12.54"
21670
21671         mkdir -p $DIR/$tdir
21672         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21673         createmany -o $DIR/$tdir/striped_dir/f 512
21674         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21675         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21676
21677         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21678                 sed "s/[/][^:]*://g")
21679         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21680
21681         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21682         rm -rf $DIR/$tdir
21683         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21684 }
21685 run_test 421e "rmfid in DNE"
21686
21687 test_421f() {
21688         local cnt
21689         local FID
21690
21691         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21692                 skip "Need MDS version at least 2.12.54"
21693
21694         test_mkdir $DIR/$tdir
21695         touch $DIR/$tdir/f
21696         cnt=$(ls -1 $DIR/$tdir | wc -l)
21697         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21698
21699         FID=$(lfs path2fid $DIR/$tdir/f)
21700         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21701         # rmfid should fail
21702         cnt=$(ls -1 $DIR/$tdir | wc -l)
21703         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21704
21705         chmod a+rw $DIR/$tdir
21706         ls -la $DIR/$tdir
21707         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21708         # rmfid should fail
21709         cnt=$(ls -1 $DIR/$tdir | wc -l)
21710         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21711
21712         rm -f $DIR/$tdir/f
21713         $RUNAS touch $DIR/$tdir/f
21714         FID=$(lfs path2fid $DIR/$tdir/f)
21715         echo "rmfid as root"
21716         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21717         cnt=$(ls -1 $DIR/$tdir | wc -l)
21718         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21719
21720         rm -f $DIR/$tdir/f
21721         $RUNAS touch $DIR/$tdir/f
21722         cnt=$(ls -1 $DIR/$tdir | wc -l)
21723         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21724         FID=$(lfs path2fid $DIR/$tdir/f)
21725         # rmfid w/o user_fid2path mount option should fail
21726         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21727         cnt=$(ls -1 $DIR/$tdir | wc -l)
21728         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21729
21730         umount_client $MOUNT || error "failed to umount client"
21731         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21732                 error "failed to mount client'"
21733
21734         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21735         # rmfid should succeed
21736         cnt=$(ls -1 $DIR/$tdir | wc -l)
21737         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21738
21739         # rmfid shouldn't allow to remove files due to dir's permission
21740         chmod a+rwx $DIR/$tdir
21741         touch $DIR/$tdir/f
21742         ls -la $DIR/$tdir
21743         FID=$(lfs path2fid $DIR/$tdir/f)
21744         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21745
21746         umount_client $MOUNT || error "failed to umount client"
21747         mount_client $MOUNT "$MOUNT_OPTS" ||
21748                 error "failed to mount client'"
21749
21750 }
21751 run_test 421f "rmfid checks permissions"
21752
21753 test_421g() {
21754         local cnt
21755         local FIDS
21756
21757         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21758         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21759                 skip "Need MDS version at least 2.12.54"
21760
21761         mkdir -p $DIR/$tdir
21762         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21763         createmany -o $DIR/$tdir/striped_dir/f 512
21764         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21765         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21766
21767         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21768                 sed "s/[/][^:]*://g")
21769
21770         rm -f $DIR/$tdir/striped_dir/f1*
21771         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21772         removed=$((512 - cnt))
21773
21774         # few files have been just removed, so we expect
21775         # rmfid to fail on their fids
21776         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21777         [ $removed != $errors ] && error "$errors != $removed"
21778
21779         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21780         rm -rf $DIR/$tdir
21781         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21782 }
21783 run_test 421g "rmfid to return errors properly"
21784
21785 test_422() {
21786         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21787         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21788         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21789         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21790         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21791
21792         local amc=$(at_max_get client)
21793         local amo=$(at_max_get mds1)
21794         local timeout=`lctl get_param -n timeout`
21795
21796         at_max_set 0 client
21797         at_max_set 0 mds1
21798
21799 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21800         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21801                         fail_val=$(((2*timeout + 10)*1000))
21802         touch $DIR/$tdir/d3/file &
21803         sleep 2
21804 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21805         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21806                         fail_val=$((2*timeout + 5))
21807         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21808         local pid=$!
21809         sleep 1
21810         kill -9 $pid
21811         sleep $((2 * timeout))
21812         echo kill $pid
21813         kill -9 $pid
21814         lctl mark touch
21815         touch $DIR/$tdir/d2/file3
21816         touch $DIR/$tdir/d2/file4
21817         touch $DIR/$tdir/d2/file5
21818
21819         wait
21820         at_max_set $amc client
21821         at_max_set $amo mds1
21822
21823         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
21824         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
21825                 error "Watchdog is always throttled"
21826 }
21827 run_test 422 "kill a process with RPC in progress"
21828
21829 prep_801() {
21830         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21831         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21832                 skip "Need server version at least 2.9.55"
21833
21834         start_full_debug_logging
21835 }
21836
21837 post_801() {
21838         stop_full_debug_logging
21839 }
21840
21841 barrier_stat() {
21842         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21843                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21844                            awk '/The barrier for/ { print $7 }')
21845                 echo $st
21846         else
21847                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21848                 echo \'$st\'
21849         fi
21850 }
21851
21852 barrier_expired() {
21853         local expired
21854
21855         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21856                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21857                           awk '/will be expired/ { print $7 }')
21858         else
21859                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21860         fi
21861
21862         echo $expired
21863 }
21864
21865 test_801a() {
21866         prep_801
21867
21868         echo "Start barrier_freeze at: $(date)"
21869         #define OBD_FAIL_BARRIER_DELAY          0x2202
21870         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21871         # Do not reduce barrier time - See LU-11873
21872         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21873
21874         sleep 2
21875         local b_status=$(barrier_stat)
21876         echo "Got barrier status at: $(date)"
21877         [ "$b_status" = "'freezing_p1'" ] ||
21878                 error "(1) unexpected barrier status $b_status"
21879
21880         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21881         wait
21882         b_status=$(barrier_stat)
21883         [ "$b_status" = "'frozen'" ] ||
21884                 error "(2) unexpected barrier status $b_status"
21885
21886         local expired=$(barrier_expired)
21887         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21888         sleep $((expired + 3))
21889
21890         b_status=$(barrier_stat)
21891         [ "$b_status" = "'expired'" ] ||
21892                 error "(3) unexpected barrier status $b_status"
21893
21894         # Do not reduce barrier time - See LU-11873
21895         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21896                 error "(4) fail to freeze barrier"
21897
21898         b_status=$(barrier_stat)
21899         [ "$b_status" = "'frozen'" ] ||
21900                 error "(5) unexpected barrier status $b_status"
21901
21902         echo "Start barrier_thaw at: $(date)"
21903         #define OBD_FAIL_BARRIER_DELAY          0x2202
21904         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21905         do_facet mgs $LCTL barrier_thaw $FSNAME &
21906
21907         sleep 2
21908         b_status=$(barrier_stat)
21909         echo "Got barrier status at: $(date)"
21910         [ "$b_status" = "'thawing'" ] ||
21911                 error "(6) unexpected barrier status $b_status"
21912
21913         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21914         wait
21915         b_status=$(barrier_stat)
21916         [ "$b_status" = "'thawed'" ] ||
21917                 error "(7) unexpected barrier status $b_status"
21918
21919         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21920         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21921         do_facet mgs $LCTL barrier_freeze $FSNAME
21922
21923         b_status=$(barrier_stat)
21924         [ "$b_status" = "'failed'" ] ||
21925                 error "(8) unexpected barrier status $b_status"
21926
21927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21928         do_facet mgs $LCTL barrier_thaw $FSNAME
21929
21930         post_801
21931 }
21932 run_test 801a "write barrier user interfaces and stat machine"
21933
21934 test_801b() {
21935         prep_801
21936
21937         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21938         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21939         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21940         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21941         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21942
21943         cancel_lru_locks mdc
21944
21945         # 180 seconds should be long enough
21946         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21947
21948         local b_status=$(barrier_stat)
21949         [ "$b_status" = "'frozen'" ] ||
21950                 error "(6) unexpected barrier status $b_status"
21951
21952         mkdir $DIR/$tdir/d0/d10 &
21953         mkdir_pid=$!
21954
21955         touch $DIR/$tdir/d1/f13 &
21956         touch_pid=$!
21957
21958         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21959         ln_pid=$!
21960
21961         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21962         mv_pid=$!
21963
21964         rm -f $DIR/$tdir/d4/f12 &
21965         rm_pid=$!
21966
21967         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21968
21969         # To guarantee taht the 'stat' is not blocked
21970         b_status=$(barrier_stat)
21971         [ "$b_status" = "'frozen'" ] ||
21972                 error "(8) unexpected barrier status $b_status"
21973
21974         # let above commands to run at background
21975         sleep 5
21976
21977         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21978         ps -p $touch_pid || error "(10) touch should be blocked"
21979         ps -p $ln_pid || error "(11) link should be blocked"
21980         ps -p $mv_pid || error "(12) rename should be blocked"
21981         ps -p $rm_pid || error "(13) unlink should be blocked"
21982
21983         b_status=$(barrier_stat)
21984         [ "$b_status" = "'frozen'" ] ||
21985                 error "(14) unexpected barrier status $b_status"
21986
21987         do_facet mgs $LCTL barrier_thaw $FSNAME
21988         b_status=$(barrier_stat)
21989         [ "$b_status" = "'thawed'" ] ||
21990                 error "(15) unexpected barrier status $b_status"
21991
21992         wait $mkdir_pid || error "(16) mkdir should succeed"
21993         wait $touch_pid || error "(17) touch should succeed"
21994         wait $ln_pid || error "(18) link should succeed"
21995         wait $mv_pid || error "(19) rename should succeed"
21996         wait $rm_pid || error "(20) unlink should succeed"
21997
21998         post_801
21999 }
22000 run_test 801b "modification will be blocked by write barrier"
22001
22002 test_801c() {
22003         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22004
22005         prep_801
22006
22007         stop mds2 || error "(1) Fail to stop mds2"
22008
22009         do_facet mgs $LCTL barrier_freeze $FSNAME 30
22010
22011         local b_status=$(barrier_stat)
22012         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
22013                 do_facet mgs $LCTL barrier_thaw $FSNAME
22014                 error "(2) unexpected barrier status $b_status"
22015         }
22016
22017         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22018                 error "(3) Fail to rescan barrier bitmap"
22019
22020         # Do not reduce barrier time - See LU-11873
22021         do_facet mgs $LCTL barrier_freeze $FSNAME 20
22022
22023         b_status=$(barrier_stat)
22024         [ "$b_status" = "'frozen'" ] ||
22025                 error "(4) unexpected barrier status $b_status"
22026
22027         do_facet mgs $LCTL barrier_thaw $FSNAME
22028         b_status=$(barrier_stat)
22029         [ "$b_status" = "'thawed'" ] ||
22030                 error "(5) unexpected barrier status $b_status"
22031
22032         local devname=$(mdsdevname 2)
22033
22034         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
22035
22036         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22037                 error "(7) Fail to rescan barrier bitmap"
22038
22039         post_801
22040 }
22041 run_test 801c "rescan barrier bitmap"
22042
22043 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
22044 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
22045 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
22046 saved_MOUNT_OPTS=$MOUNT_OPTS
22047
22048 cleanup_802a() {
22049         trap 0
22050
22051         stopall
22052         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
22053         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
22054         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
22055         MOUNT_OPTS=$saved_MOUNT_OPTS
22056         setupall
22057 }
22058
22059 test_802a() {
22060         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
22061         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
22062         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22063                 skip "Need server version at least 2.9.55"
22064
22065         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
22066
22067         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22068
22069         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22070                 error "(2) Fail to copy"
22071
22072         trap cleanup_802a EXIT
22073
22074         # sync by force before remount as readonly
22075         sync; sync_all_data; sleep 3; sync_all_data
22076
22077         stopall
22078
22079         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
22080         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
22081         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
22082
22083         echo "Mount the server as read only"
22084         setupall server_only || error "(3) Fail to start servers"
22085
22086         echo "Mount client without ro should fail"
22087         mount_client $MOUNT &&
22088                 error "(4) Mount client without 'ro' should fail"
22089
22090         echo "Mount client with ro should succeed"
22091         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
22092         mount_client $MOUNT ||
22093                 error "(5) Mount client with 'ro' should succeed"
22094
22095         echo "Modify should be refused"
22096         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22097
22098         echo "Read should be allowed"
22099         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22100                 error "(7) Read should succeed under ro mode"
22101
22102         cleanup_802a
22103 }
22104 run_test 802a "simulate readonly device"
22105
22106 test_802b() {
22107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22108         remote_mds_nodsh && skip "remote MDS with nodsh"
22109
22110         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
22111                 skip "readonly option not available"
22112
22113         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
22114
22115         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22116                 error "(2) Fail to copy"
22117
22118         # write back all cached data before setting MDT to readonly
22119         cancel_lru_locks
22120         sync_all_data
22121
22122         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22123         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22124
22125         echo "Modify should be refused"
22126         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22127
22128         echo "Read should be allowed"
22129         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22130                 error "(7) Read should succeed under ro mode"
22131
22132         # disable readonly
22133         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22134 }
22135 run_test 802b "be able to set MDTs to readonly"
22136
22137 test_803() {
22138         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22139         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22140                 skip "MDS needs to be newer than 2.10.54"
22141
22142         mkdir -p $DIR/$tdir
22143         # Create some objects on all MDTs to trigger related logs objects
22144         for idx in $(seq $MDSCOUNT); do
22145                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22146                         $DIR/$tdir/dir${idx} ||
22147                         error "Fail to create $DIR/$tdir/dir${idx}"
22148         done
22149
22150         sync; sleep 3
22151         wait_delete_completed # ensure old test cleanups are finished
22152         echo "before create:"
22153         $LFS df -i $MOUNT
22154         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22155
22156         for i in {1..10}; do
22157                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22158                         error "Fail to create $DIR/$tdir/foo$i"
22159         done
22160
22161         sync; sleep 3
22162         echo "after create:"
22163         $LFS df -i $MOUNT
22164         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22165
22166         # allow for an llog to be cleaned up during the test
22167         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22168                 error "before ($before_used) + 10 > after ($after_used)"
22169
22170         for i in {1..10}; do
22171                 rm -rf $DIR/$tdir/foo$i ||
22172                         error "Fail to remove $DIR/$tdir/foo$i"
22173         done
22174
22175         sleep 3 # avoid MDT return cached statfs
22176         wait_delete_completed
22177         echo "after unlink:"
22178         $LFS df -i $MOUNT
22179         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22180
22181         # allow for an llog to be created during the test
22182         [ $after_used -le $((before_used + 1)) ] ||
22183                 error "after ($after_used) > before ($before_used) + 1"
22184 }
22185 run_test 803 "verify agent object for remote object"
22186
22187 test_804() {
22188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22189         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22190                 skip "MDS needs to be newer than 2.10.54"
22191         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22192
22193         mkdir -p $DIR/$tdir
22194         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22195                 error "Fail to create $DIR/$tdir/dir0"
22196
22197         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22198         local dev=$(mdsdevname 2)
22199
22200         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22201                 grep ${fid} || error "NOT found agent entry for dir0"
22202
22203         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22204                 error "Fail to create $DIR/$tdir/dir1"
22205
22206         touch $DIR/$tdir/dir1/foo0 ||
22207                 error "Fail to create $DIR/$tdir/dir1/foo0"
22208         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22209         local rc=0
22210
22211         for idx in $(seq $MDSCOUNT); do
22212                 dev=$(mdsdevname $idx)
22213                 do_facet mds${idx} \
22214                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22215                         grep ${fid} && rc=$idx
22216         done
22217
22218         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22219                 error "Fail to rename foo0 to foo1"
22220         if [ $rc -eq 0 ]; then
22221                 for idx in $(seq $MDSCOUNT); do
22222                         dev=$(mdsdevname $idx)
22223                         do_facet mds${idx} \
22224                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22225                         grep ${fid} && rc=$idx
22226                 done
22227         fi
22228
22229         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22230                 error "Fail to rename foo1 to foo2"
22231         if [ $rc -eq 0 ]; then
22232                 for idx in $(seq $MDSCOUNT); do
22233                         dev=$(mdsdevname $idx)
22234                         do_facet mds${idx} \
22235                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22236                         grep ${fid} && rc=$idx
22237                 done
22238         fi
22239
22240         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22241
22242         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22243                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22244         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22245                 error "Fail to rename foo2 to foo0"
22246         unlink $DIR/$tdir/dir1/foo0 ||
22247                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22248         rm -rf $DIR/$tdir/dir0 ||
22249                 error "Fail to rm $DIR/$tdir/dir0"
22250
22251         for idx in $(seq $MDSCOUNT); do
22252                 dev=$(mdsdevname $idx)
22253                 rc=0
22254
22255                 stop mds${idx}
22256                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22257                         rc=$?
22258                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22259                         error "mount mds$idx failed"
22260                 df $MOUNT > /dev/null 2>&1
22261
22262                 # e2fsck should not return error
22263                 [ $rc -eq 0 ] ||
22264                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22265         done
22266 }
22267 run_test 804 "verify agent entry for remote entry"
22268
22269 cleanup_805() {
22270         do_facet $SINGLEMDS zfs set quota=$old $fsset
22271         unlinkmany $DIR/$tdir/f- 1000000
22272         trap 0
22273 }
22274
22275 test_805() {
22276         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22277         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22278         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22279                 skip "netfree not implemented before 0.7"
22280         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22281                 skip "Need MDS version at least 2.10.57"
22282
22283         local fsset
22284         local freekb
22285         local usedkb
22286         local old
22287         local quota
22288         local pref="osd-zfs.$FSNAME-MDT0000."
22289
22290         # limit available space on MDS dataset to meet nospace issue
22291         # quickly. then ZFS 0.7.2 can use reserved space if asked
22292         # properly (using netfree flag in osd_declare_destroy()
22293         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22294         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22295                 gawk '{print $3}')
22296         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22297         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22298         let "usedkb=usedkb-freekb"
22299         let "freekb=freekb/2"
22300         if let "freekb > 5000"; then
22301                 let "freekb=5000"
22302         fi
22303         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22304         trap cleanup_805 EXIT
22305         mkdir $DIR/$tdir
22306         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
22307         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22308         rm -rf $DIR/$tdir || error "not able to remove"
22309         do_facet $SINGLEMDS zfs set quota=$old $fsset
22310         trap 0
22311 }
22312 run_test 805 "ZFS can remove from full fs"
22313
22314 # Size-on-MDS test
22315 check_lsom_data()
22316 {
22317         local file=$1
22318         local size=$($LFS getsom -s $file)
22319         local expect=$(stat -c %s $file)
22320
22321         [[ $size == $expect ]] ||
22322                 error "$file expected size: $expect, got: $size"
22323
22324         local blocks=$($LFS getsom -b $file)
22325         expect=$(stat -c %b $file)
22326         [[ $blocks == $expect ]] ||
22327                 error "$file expected blocks: $expect, got: $blocks"
22328 }
22329
22330 check_lsom_size()
22331 {
22332         local size=$($LFS getsom -s $1)
22333         local expect=$2
22334
22335         [[ $size == $expect ]] ||
22336                 error "$file expected size: $expect, got: $size"
22337 }
22338
22339 test_806() {
22340         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22341                 skip "Need MDS version at least 2.11.52"
22342
22343         local bs=1048576
22344
22345         touch $DIR/$tfile || error "touch $tfile failed"
22346
22347         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22348         save_lustre_params client "llite.*.xattr_cache" > $save
22349         lctl set_param llite.*.xattr_cache=0
22350         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22351
22352         # single-threaded write
22353         echo "Test SOM for single-threaded write"
22354         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22355                 error "write $tfile failed"
22356         check_lsom_size $DIR/$tfile $bs
22357
22358         local num=32
22359         local size=$(($num * $bs))
22360         local offset=0
22361         local i
22362
22363         echo "Test SOM for single client multi-threaded($num) write"
22364         $TRUNCATE $DIR/$tfile 0
22365         for ((i = 0; i < $num; i++)); do
22366                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22367                 local pids[$i]=$!
22368                 offset=$((offset + $bs))
22369         done
22370         for (( i=0; i < $num; i++ )); do
22371                 wait ${pids[$i]}
22372         done
22373         check_lsom_size $DIR/$tfile $size
22374
22375         $TRUNCATE $DIR/$tfile 0
22376         for ((i = 0; i < $num; i++)); do
22377                 offset=$((offset - $bs))
22378                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22379                 local pids[$i]=$!
22380         done
22381         for (( i=0; i < $num; i++ )); do
22382                 wait ${pids[$i]}
22383         done
22384         check_lsom_size $DIR/$tfile $size
22385
22386         # multi-client writes
22387         num=$(get_node_count ${CLIENTS//,/ })
22388         size=$(($num * $bs))
22389         offset=0
22390         i=0
22391
22392         echo "Test SOM for multi-client ($num) writes"
22393         $TRUNCATE $DIR/$tfile 0
22394         for client in ${CLIENTS//,/ }; do
22395                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22396                 local pids[$i]=$!
22397                 i=$((i + 1))
22398                 offset=$((offset + $bs))
22399         done
22400         for (( i=0; i < $num; i++ )); do
22401                 wait ${pids[$i]}
22402         done
22403         check_lsom_size $DIR/$tfile $offset
22404
22405         i=0
22406         $TRUNCATE $DIR/$tfile 0
22407         for client in ${CLIENTS//,/ }; do
22408                 offset=$((offset - $bs))
22409                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22410                 local pids[$i]=$!
22411                 i=$((i + 1))
22412         done
22413         for (( i=0; i < $num; i++ )); do
22414                 wait ${pids[$i]}
22415         done
22416         check_lsom_size $DIR/$tfile $size
22417
22418         # verify truncate
22419         echo "Test SOM for truncate"
22420         $TRUNCATE $DIR/$tfile 1048576
22421         check_lsom_size $DIR/$tfile 1048576
22422         $TRUNCATE $DIR/$tfile 1234
22423         check_lsom_size $DIR/$tfile 1234
22424
22425         # verify SOM blocks count
22426         echo "Verify SOM block count"
22427         $TRUNCATE $DIR/$tfile 0
22428         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22429                 error "failed to write file $tfile"
22430         check_lsom_data $DIR/$tfile
22431 }
22432 run_test 806 "Verify Lazy Size on MDS"
22433
22434 test_807() {
22435         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22436         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22437                 skip "Need MDS version at least 2.11.52"
22438
22439         # Registration step
22440         changelog_register || error "changelog_register failed"
22441         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22442         changelog_users $SINGLEMDS | grep -q $cl_user ||
22443                 error "User $cl_user not found in changelog_users"
22444
22445         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22446         save_lustre_params client "llite.*.xattr_cache" > $save
22447         lctl set_param llite.*.xattr_cache=0
22448         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22449
22450         rm -rf $DIR/$tdir || error "rm $tdir failed"
22451         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22452         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22453         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22454         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22455                 error "truncate $tdir/trunc failed"
22456
22457         local bs=1048576
22458         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22459                 error "write $tfile failed"
22460
22461         # multi-client wirtes
22462         local num=$(get_node_count ${CLIENTS//,/ })
22463         local offset=0
22464         local i=0
22465
22466         echo "Test SOM for multi-client ($num) writes"
22467         touch $DIR/$tfile || error "touch $tfile failed"
22468         $TRUNCATE $DIR/$tfile 0
22469         for client in ${CLIENTS//,/ }; do
22470                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22471                 local pids[$i]=$!
22472                 i=$((i + 1))
22473                 offset=$((offset + $bs))
22474         done
22475         for (( i=0; i < $num; i++ )); do
22476                 wait ${pids[$i]}
22477         done
22478
22479         sleep 5
22480         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22481         check_lsom_data $DIR/$tdir/trunc
22482         check_lsom_data $DIR/$tdir/single_dd
22483         check_lsom_data $DIR/$tfile
22484
22485         rm -rf $DIR/$tdir
22486         # Deregistration step
22487         changelog_deregister || error "changelog_deregister failed"
22488 }
22489 run_test 807 "verify LSOM syncing tool"
22490
22491 check_som_nologged()
22492 {
22493         local lines=$($LFS changelog $FSNAME-MDT0000 |
22494                 grep 'x=trusted.som' | wc -l)
22495         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22496 }
22497
22498 test_808() {
22499         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22500                 skip "Need MDS version at least 2.11.55"
22501
22502         # Registration step
22503         changelog_register || error "changelog_register failed"
22504
22505         touch $DIR/$tfile || error "touch $tfile failed"
22506         check_som_nologged
22507
22508         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22509                 error "write $tfile failed"
22510         check_som_nologged
22511
22512         $TRUNCATE $DIR/$tfile 1234
22513         check_som_nologged
22514
22515         $TRUNCATE $DIR/$tfile 1048576
22516         check_som_nologged
22517
22518         # Deregistration step
22519         changelog_deregister || error "changelog_deregister failed"
22520 }
22521 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22522
22523 check_som_nodata()
22524 {
22525         $LFS getsom $1
22526         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22527 }
22528
22529 test_809() {
22530         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22531                 skip "Need MDS version at least 2.11.56"
22532
22533         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22534                 error "failed to create DoM-only file $DIR/$tfile"
22535         touch $DIR/$tfile || error "touch $tfile failed"
22536         check_som_nodata $DIR/$tfile
22537
22538         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22539                 error "write $tfile failed"
22540         check_som_nodata $DIR/$tfile
22541
22542         $TRUNCATE $DIR/$tfile 1234
22543         check_som_nodata $DIR/$tfile
22544
22545         $TRUNCATE $DIR/$tfile 4097
22546         check_som_nodata $DIR/$file
22547 }
22548 run_test 809 "Verify no SOM xattr store for DoM-only files"
22549
22550 test_810() {
22551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22552         $GSS && skip_env "could not run with gss"
22553         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22554                 skip "OST < 2.12.58 doesn't align checksum"
22555
22556         set_checksums 1
22557         stack_trap "set_checksums $ORIG_CSUM" EXIT
22558         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22559
22560         local csum
22561         local before
22562         local after
22563         for csum in $CKSUM_TYPES; do
22564                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22565                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22566                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22567                         eval set -- $i
22568                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22569                         before=$(md5sum $DIR/$tfile)
22570                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22571                         after=$(md5sum $DIR/$tfile)
22572                         [ "$before" == "$after" ] ||
22573                                 error "$csum: $before != $after bs=$1 seek=$2"
22574                 done
22575         done
22576 }
22577 run_test 810 "partial page writes on ZFS (LU-11663)"
22578
22579 test_811() {
22580         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22581                 skip "Need MDS version at least 2.11.56"
22582
22583         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22584         do_facet mds1 $LCTL set_param fail_loc=0x165
22585         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22586
22587         stop mds1
22588         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22589
22590         sleep 5
22591         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22592                 error "MDD orphan cleanup thread not quit"
22593 }
22594 run_test 811 "orphan name stub can be cleaned up in startup"
22595
22596 test_812a() {
22597         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22598                 skip "OST < 2.12.51 doesn't support this fail_loc"
22599         [ "$SHARED_KEY" = true ] &&
22600                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22601
22602         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22603         # ensure ost1 is connected
22604         stat $DIR/$tfile >/dev/null || error "can't stat"
22605         wait_osc_import_state client ost1 FULL
22606         # no locks, no reqs to let the connection idle
22607         cancel_lru_locks osc
22608
22609         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22610 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22611         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22612         wait_osc_import_state client ost1 CONNECTING
22613         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22614
22615         stat $DIR/$tfile >/dev/null || error "can't stat file"
22616 }
22617 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
22618
22619 test_812b() { # LU-12378
22620         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22621                 skip "OST < 2.12.51 doesn't support this fail_loc"
22622         [ "$SHARED_KEY" = true ] &&
22623                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22624
22625         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
22626         # ensure ost1 is connected
22627         stat $DIR/$tfile >/dev/null || error "can't stat"
22628         wait_osc_import_state client ost1 FULL
22629         # no locks, no reqs to let the connection idle
22630         cancel_lru_locks osc
22631
22632         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22633 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22634         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22635         wait_osc_import_state client ost1 CONNECTING
22636         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22637
22638         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
22639         wait_osc_import_state client ost1 IDLE
22640 }
22641 run_test 812b "do not drop no resend request for idle connect"
22642
22643 test_813() {
22644         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22645         [ -z "$file_heat_sav" ] && skip "no file heat support"
22646
22647         local readsample
22648         local writesample
22649         local readbyte
22650         local writebyte
22651         local readsample1
22652         local writesample1
22653         local readbyte1
22654         local writebyte1
22655
22656         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22657         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22658
22659         $LCTL set_param -n llite.*.file_heat=1
22660         echo "Turn on file heat"
22661         echo "Period second: $period_second, Decay percentage: $decay_pct"
22662
22663         echo "QQQQ" > $DIR/$tfile
22664         echo "QQQQ" > $DIR/$tfile
22665         echo "QQQQ" > $DIR/$tfile
22666         cat $DIR/$tfile > /dev/null
22667         cat $DIR/$tfile > /dev/null
22668         cat $DIR/$tfile > /dev/null
22669         cat $DIR/$tfile > /dev/null
22670
22671         local out=$($LFS heat_get $DIR/$tfile)
22672
22673         $LFS heat_get $DIR/$tfile
22674         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22675         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22676         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22677         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22678
22679         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22680         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22681         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22682         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22683
22684         sleep $((period_second + 3))
22685         echo "Sleep $((period_second + 3)) seconds..."
22686         # The recursion formula to calculate the heat of the file f is as
22687         # follow:
22688         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22689         # Where Hi is the heat value in the period between time points i*I and
22690         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22691         # to the weight of Ci.
22692         out=$($LFS heat_get $DIR/$tfile)
22693         $LFS heat_get $DIR/$tfile
22694         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22695         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22696         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22697         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22698
22699         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22700                 error "read sample ($readsample) is wrong"
22701         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22702                 error "write sample ($writesample) is wrong"
22703         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22704                 error "read bytes ($readbyte) is wrong"
22705         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22706                 error "write bytes ($writebyte) is wrong"
22707
22708         echo "QQQQ" > $DIR/$tfile
22709         echo "QQQQ" > $DIR/$tfile
22710         echo "QQQQ" > $DIR/$tfile
22711         cat $DIR/$tfile > /dev/null
22712         cat $DIR/$tfile > /dev/null
22713         cat $DIR/$tfile > /dev/null
22714         cat $DIR/$tfile > /dev/null
22715
22716         sleep $((period_second + 3))
22717         echo "Sleep $((period_second + 3)) seconds..."
22718
22719         out=$($LFS heat_get $DIR/$tfile)
22720         $LFS heat_get $DIR/$tfile
22721         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22722         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22723         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22724         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22725
22726         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22727                 4 * $decay_pct) / 100") -eq 1 ] ||
22728                 error "read sample ($readsample1) is wrong"
22729         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22730                 3 * $decay_pct) / 100") -eq 1 ] ||
22731                 error "write sample ($writesample1) is wrong"
22732         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22733                 20 * $decay_pct) / 100") -eq 1 ] ||
22734                 error "read bytes ($readbyte1) is wrong"
22735         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22736                 15 * $decay_pct) / 100") -eq 1 ] ||
22737                 error "write bytes ($writebyte1) is wrong"
22738
22739         echo "Turn off file heat for the file $DIR/$tfile"
22740         $LFS heat_set -o $DIR/$tfile
22741
22742         echo "QQQQ" > $DIR/$tfile
22743         echo "QQQQ" > $DIR/$tfile
22744         echo "QQQQ" > $DIR/$tfile
22745         cat $DIR/$tfile > /dev/null
22746         cat $DIR/$tfile > /dev/null
22747         cat $DIR/$tfile > /dev/null
22748         cat $DIR/$tfile > /dev/null
22749
22750         out=$($LFS heat_get $DIR/$tfile)
22751         $LFS heat_get $DIR/$tfile
22752         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22753         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22754         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22755         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22756
22757         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22758         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22759         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22760         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22761
22762         echo "Trun on file heat for the file $DIR/$tfile"
22763         $LFS heat_set -O $DIR/$tfile
22764
22765         echo "QQQQ" > $DIR/$tfile
22766         echo "QQQQ" > $DIR/$tfile
22767         echo "QQQQ" > $DIR/$tfile
22768         cat $DIR/$tfile > /dev/null
22769         cat $DIR/$tfile > /dev/null
22770         cat $DIR/$tfile > /dev/null
22771         cat $DIR/$tfile > /dev/null
22772
22773         out=$($LFS heat_get $DIR/$tfile)
22774         $LFS heat_get $DIR/$tfile
22775         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22776         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22777         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22778         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22779
22780         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22781         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22782         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22783         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22784
22785         $LFS heat_set -c $DIR/$tfile
22786         $LCTL set_param -n llite.*.file_heat=0
22787         echo "Turn off file heat support for the Lustre filesystem"
22788
22789         echo "QQQQ" > $DIR/$tfile
22790         echo "QQQQ" > $DIR/$tfile
22791         echo "QQQQ" > $DIR/$tfile
22792         cat $DIR/$tfile > /dev/null
22793         cat $DIR/$tfile > /dev/null
22794         cat $DIR/$tfile > /dev/null
22795         cat $DIR/$tfile > /dev/null
22796
22797         out=$($LFS heat_get $DIR/$tfile)
22798         $LFS heat_get $DIR/$tfile
22799         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22800         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22801         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22802         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22803
22804         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22805         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22806         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22807         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22808
22809         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22810         rm -f $DIR/$tfile
22811 }
22812 run_test 813 "File heat verfication"
22813
22814 test_814()
22815 {
22816         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22817         echo -n y >> $DIR/$tfile
22818         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22819         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22820 }
22821 run_test 814 "sparse cp works as expected (LU-12361)"
22822
22823 test_815()
22824 {
22825         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22826         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22827 }
22828 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22829
22830 test_816() {
22831         [ "$SHARED_KEY" = true ] &&
22832                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22833
22834         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22835         # ensure ost1 is connected
22836         stat $DIR/$tfile >/dev/null || error "can't stat"
22837         wait_osc_import_state client ost1 FULL
22838         # no locks, no reqs to let the connection idle
22839         cancel_lru_locks osc
22840         lru_resize_disable osc
22841         local before
22842         local now
22843         before=$($LCTL get_param -n \
22844                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22845
22846         wait_osc_import_state client ost1 IDLE
22847         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22848         now=$($LCTL get_param -n \
22849               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22850         [ $before == $now ] || error "lru_size changed $before != $now"
22851 }
22852 run_test 816 "do not reset lru_resize on idle reconnect"
22853
22854 cleanup_817() {
22855         umount $tmpdir
22856         exportfs -u localhost:$DIR/nfsexp
22857         rm -rf $DIR/nfsexp
22858 }
22859
22860 test_817() {
22861         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22862
22863         mkdir -p $DIR/nfsexp
22864         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22865                 error "failed to export nfs"
22866
22867         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22868         stack_trap cleanup_817 EXIT
22869
22870         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22871                 error "failed to mount nfs to $tmpdir"
22872
22873         cp /bin/true $tmpdir
22874         $DIR/nfsexp/true || error "failed to execute 'true' command"
22875 }
22876 run_test 817 "nfsd won't cache write lock for exec file"
22877
22878 test_818() {
22879         mkdir $DIR/$tdir
22880         $LFS setstripe -c1 -i0 $DIR/$tfile
22881         $LFS setstripe -c1 -i1 $DIR/$tfile
22882         stop $SINGLEMDS
22883         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22884         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22885         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22886                 error "start $SINGLEMDS failed"
22887         rm -rf $DIR/$tdir
22888 }
22889 run_test 818 "unlink with failed llog"
22890
22891 test_819a() {
22892         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22893         cancel_lru_locks osc
22894         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22895         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22896         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22897         rm -f $TDIR/$tfile
22898 }
22899 run_test 819a "too big niobuf in read"
22900
22901 test_819b() {
22902         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22903         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22904         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22905         cancel_lru_locks osc
22906         sleep 1
22907         rm -f $TDIR/$tfile
22908 }
22909 run_test 819b "too big niobuf in write"
22910
22911 #
22912 # tests that do cleanup/setup should be run at the end
22913 #
22914
22915 test_900() {
22916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22917         local ls
22918
22919         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22920         $LCTL set_param fail_loc=0x903
22921
22922         cancel_lru_locks MGC
22923
22924         FAIL_ON_ERROR=true cleanup
22925         FAIL_ON_ERROR=true setup
22926 }
22927 run_test 900 "umount should not race with any mgc requeue thread"
22928
22929 # LUS-6253/LU-11185
22930 test_901() {
22931         local oldc
22932         local newc
22933         local olds
22934         local news
22935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22936
22937         # some get_param have a bug to handle dot in param name
22938         cancel_lru_locks MGC
22939         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
22940         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
22941         umount_client $MOUNT || error "umount failed"
22942         mount_client $MOUNT || error "mount failed"
22943         cancel_lru_locks MGC
22944         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
22945         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
22946
22947         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
22948         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
22949
22950         return 0
22951 }
22952 run_test 901 "don't leak a mgc lock on client umount"
22953
22954 complete $SECONDS
22955 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22956 check_and_cleanup_lustre
22957 if [ "$I_MOUNTED" != "yes" ]; then
22958         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22959 fi
22960 exit_status