Whamcloud - gitweb
LU-13474 gss: do not return -ERESTART when gss rpc times out
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 selinux_status=$(getenforce)
48 if [ "$selinux_status" != "Disabled" ]; then
49         # bug number:
50         ALWAYS_EXCEPT+=""
51 fi
52
53 # skip the grant tests for ARM until they are fixed
54 if [[ $(uname -m) = aarch64 ]]; then
55         # bug number:    LU-11596
56         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
57         # bug number:    LU-11671 LU-11667
58         ALWAYS_EXCEPT+=" 45       317"
59         # bug number:    LU-14067 LU-14067
60         ALWAYS_EXCEPT+=" 400a     400b"
61 fi
62
63 # skip nfs tests on kernels >= 4.12.0 until they are fixed
64 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
65         # bug number:   LU-12661
66         ALWAYS_EXCEPT+=" 817"
67 fi
68 # skip cgroup tests on RHEL8.1 kernels until they are fixed
69 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
70       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
71         # bug number:   LU-13063
72         ALWAYS_EXCEPT+=" 411"
73 fi
74
75 #                                  5          12     8   12  (min)"
76 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
77
78 if [ "$mds1_FSTYPE" = "zfs" ]; then
79         # bug number for skipped test:
80         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
81         #                                               13    (min)"
82         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
83 fi
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 # bug number for skipped test: LU-4341
104                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 # bug number for skipped test: LU-3703
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
108 elif [ -r /etc/os-release ]; then
109         if grep -qi ubuntu /etc/os-release; then
110                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
111                                                 -e 's/^VERSION=//p' \
112                                                 /etc/os-release |
113                                                 awk '{ print $1 }'))
114
115                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
116                         # bug number for skipped test:
117                         #                LU-10334 LU-10366
118                         ALWAYS_EXCEPT+=" 103a     410"
119                 fi
120         fi
121 fi
122
123 build_test_filter
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_swap_layout_no_dom()
145 {
146         local FOLDER=$1
147         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
148         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
149 }
150
151 check_and_setup_lustre
152 DIR=${DIR:-$MOUNT}
153 assert_DIR
154
155 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
156
157 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
158 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
159 rm -rf $DIR/[Rdfs][0-9]*
160
161 # $RUNAS_ID may get set incorrectly somewhere else
162 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
163         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
164
165 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
166
167 if [ "${ONLY}" = "MOUNT" ] ; then
168         echo "Lustre is up, please go on"
169         exit
170 fi
171
172 echo "preparing for tests involving mounts"
173 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
174 touch $EXT2_DEV
175 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
176 echo # add a newline after mke2fs.
177
178 umask 077
179
180 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
181 lctl set_param debug=-1 2> /dev/null || true
182 test_0a() {
183         touch $DIR/$tfile
184         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
185         rm $DIR/$tfile
186         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
187 }
188 run_test 0a "touch; rm ====================="
189
190 test_0b() {
191         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
192         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
193 }
194 run_test 0b "chmod 0755 $DIR ============================="
195
196 test_0c() {
197         $LCTL get_param mdc.*.import | grep "state: FULL" ||
198                 error "import not FULL"
199         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
200                 error "bad target"
201 }
202 run_test 0c "check import proc"
203
204 test_0d() { # LU-3397
205         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
206                 skip "proc exports not supported before 2.10.57"
207
208         local mgs_exp="mgs.MGS.exports"
209         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
210         local exp_client_nid
211         local exp_client_version
212         local exp_val
213         local imp_val
214         local temp_imp=$DIR/$tfile.import
215         local temp_exp=$DIR/$tfile.export
216
217         # save mgc import file to $temp_imp
218         $LCTL get_param mgc.*.import | tee $temp_imp
219         # Check if client uuid is found in MGS export
220         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
221                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
222                         $client_uuid ] &&
223                         break;
224         done
225         # save mgs export file to $temp_exp
226         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
227
228         # Compare the value of field "connect_flags"
229         imp_val=$(grep "connect_flags" $temp_imp)
230         exp_val=$(grep "connect_flags" $temp_exp)
231         [ "$exp_val" == "$imp_val" ] ||
232                 error "export flags '$exp_val' != import flags '$imp_val'"
233
234         # Compare the value of client version
235         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
236         exp_val=$(version_code $exp_client_version)
237         imp_val=$CLIENT_VERSION
238         [ "$exp_val" == "$imp_val" ] ||
239                 error "export client version '$exp_val' != '$imp_val'"
240 }
241 run_test 0d "check export proc ============================="
242
243 test_1() {
244         test_mkdir $DIR/$tdir
245         test_mkdir $DIR/$tdir/d2
246         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
247         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
248         rmdir $DIR/$tdir/d2
249         rmdir $DIR/$tdir
250         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
251 }
252 run_test 1 "mkdir; remkdir; rmdir"
253
254 test_2() {
255         test_mkdir $DIR/$tdir
256         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
257         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
258         rm -r $DIR/$tdir
259         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
260 }
261 run_test 2 "mkdir; touch; rmdir; check file"
262
263 test_3() {
264         test_mkdir $DIR/$tdir
265         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
266         touch $DIR/$tdir/$tfile
267         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
268         rm -r $DIR/$tdir
269         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
270 }
271 run_test 3 "mkdir; touch; rmdir; check dir"
272
273 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
274 test_4() {
275         test_mkdir -i 1 $DIR/$tdir
276
277         touch $DIR/$tdir/$tfile ||
278                 error "Create file under remote directory failed"
279
280         rmdir $DIR/$tdir &&
281                 error "Expect error removing in-use dir $DIR/$tdir"
282
283         test -d $DIR/$tdir || error "Remote directory disappeared"
284
285         rm -rf $DIR/$tdir || error "remove remote dir error"
286 }
287 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
288
289 test_5() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
293         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
294         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
295 }
296 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
297
298 test_6a() {
299         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
300         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
301         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
302                 error "$tfile does not have perm 0666 or UID $UID"
303         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile should be 0666 and owned by UID $UID"
306 }
307 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
308
309 test_6c() {
310         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
311
312         touch $DIR/$tfile
313         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
314         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
315                 error "$tfile should be owned by UID $RUNAS_ID"
316         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319 }
320 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
321
322 test_6e() {
323         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
324
325         touch $DIR/$tfile
326         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
327         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
328                 error "$tfile should be owned by GID $UID"
329         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
332 }
333 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
334
335 test_6g() {
336         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
337
338         test_mkdir $DIR/$tdir
339         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
340         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
341         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
342         test_mkdir $DIR/$tdir/d/subdir
343         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
344                 error "$tdir/d/subdir should be GID $RUNAS_GID"
345         if [[ $MDSCOUNT -gt 1 ]]; then
346                 # check remote dir sgid inherite
347                 $LFS mkdir -i 0 $DIR/$tdir.local ||
348                         error "mkdir $tdir.local failed"
349                 chmod g+s $DIR/$tdir.local ||
350                         error "chmod $tdir.local failed"
351                 chgrp $RUNAS_GID $DIR/$tdir.local ||
352                         error "chgrp $tdir.local failed"
353                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
354                         error "mkdir $tdir.remote failed"
355                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
356                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
357                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
358                         error "$tdir.remote should be mode 02755"
359         fi
360 }
361 run_test 6g "verify new dir in sgid dir inherits group"
362
363 test_6h() { # bug 7331
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         touch $DIR/$tfile || error "touch failed"
367         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
368         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
369                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
370         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
371                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
372 }
373 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
374
375 test_7a() {
376         test_mkdir $DIR/$tdir
377         $MCREATE $DIR/$tdir/$tfile
378         chmod 0666 $DIR/$tdir/$tfile
379         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
380                 error "$tdir/$tfile should be mode 0666"
381 }
382 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
383
384 test_7b() {
385         if [ ! -d $DIR/$tdir ]; then
386                 test_mkdir $DIR/$tdir
387         fi
388         $MCREATE $DIR/$tdir/$tfile
389         echo -n foo > $DIR/$tdir/$tfile
390         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
391         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
392 }
393 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
394
395 test_8() {
396         test_mkdir $DIR/$tdir
397         touch $DIR/$tdir/$tfile
398         chmod 0666 $DIR/$tdir/$tfile
399         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
400                 error "$tfile mode not 0666"
401 }
402 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
403
404 test_9() {
405         test_mkdir $DIR/$tdir
406         test_mkdir $DIR/$tdir/d2
407         test_mkdir $DIR/$tdir/d2/d3
408         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
409 }
410 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
411
412 test_10() {
413         test_mkdir $DIR/$tdir
414         test_mkdir $DIR/$tdir/d2
415         touch $DIR/$tdir/d2/$tfile
416         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
417                 error "$tdir/d2/$tfile not a file"
418 }
419 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
420
421 test_11() {
422         test_mkdir $DIR/$tdir
423         test_mkdir $DIR/$tdir/d2
424         chmod 0666 $DIR/$tdir/d2
425         chmod 0705 $DIR/$tdir/d2
426         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
427                 error "$tdir/d2 mode not 0705"
428 }
429 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
430
431 test_12() {
432         test_mkdir $DIR/$tdir
433         touch $DIR/$tdir/$tfile
434         chmod 0666 $DIR/$tdir/$tfile
435         chmod 0654 $DIR/$tdir/$tfile
436         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
437                 error "$tdir/d2 mode not 0654"
438 }
439 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
440
441 test_13() {
442         test_mkdir $DIR/$tdir
443         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
444         >  $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
446                 error "$tdir/$tfile size not 0 after truncate"
447 }
448 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
449
450 test_14() {
451         test_mkdir $DIR/$tdir
452         touch $DIR/$tdir/$tfile
453         rm $DIR/$tdir/$tfile
454         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
455 }
456 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
457
458 test_15() {
459         test_mkdir $DIR/$tdir
460         touch $DIR/$tdir/$tfile
461         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
462         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
463                 error "$tdir/${tfile_2} not a file after rename"
464         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
465 }
466 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
467
468 test_16() {
469         test_mkdir $DIR/$tdir
470         touch $DIR/$tdir/$tfile
471         rm -rf $DIR/$tdir/$tfile
472         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
473 }
474 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
475
476 test_17a() {
477         test_mkdir $DIR/$tdir
478         touch $DIR/$tdir/$tfile
479         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
480         ls -l $DIR/$tdir
481         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
482                 error "$tdir/l-exist not a symlink"
483         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
484                 error "$tdir/l-exist not referencing a file"
485         rm -f $DIR/$tdir/l-exist
486         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
487 }
488 run_test 17a "symlinks: create, remove (real)"
489
490 test_17b() {
491         test_mkdir $DIR/$tdir
492         ln -s no-such-file $DIR/$tdir/l-dangle
493         ls -l $DIR/$tdir
494         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
495                 error "$tdir/l-dangle not referencing no-such-file"
496         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
497                 error "$tdir/l-dangle not referencing non-existent file"
498         rm -f $DIR/$tdir/l-dangle
499         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
500 }
501 run_test 17b "symlinks: create, remove (dangling)"
502
503 test_17c() { # bug 3440 - don't save failed open RPC for replay
504         test_mkdir $DIR/$tdir
505         ln -s foo $DIR/$tdir/$tfile
506         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
507 }
508 run_test 17c "symlinks: open dangling (should return error)"
509
510 test_17d() {
511         test_mkdir $DIR/$tdir
512         ln -s foo $DIR/$tdir/$tfile
513         touch $DIR/$tdir/$tfile || error "creating to new symlink"
514 }
515 run_test 17d "symlinks: create dangling"
516
517 test_17e() {
518         test_mkdir $DIR/$tdir
519         local foo=$DIR/$tdir/$tfile
520         ln -s $foo $foo || error "create symlink failed"
521         ls -l $foo || error "ls -l failed"
522         ls $foo && error "ls not failed" || true
523 }
524 run_test 17e "symlinks: create recursive symlink (should return error)"
525
526 test_17f() {
527         test_mkdir $DIR/$tdir
528         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
529         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
530         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
531         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
533         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
534         ls -l  $DIR/$tdir
535 }
536 run_test 17f "symlinks: long and very long symlink name"
537
538 # str_repeat(S, N) generate a string that is string S repeated N times
539 str_repeat() {
540         local s=$1
541         local n=$2
542         local ret=''
543         while [ $((n -= 1)) -ge 0 ]; do
544                 ret=$ret$s
545         done
546         echo $ret
547 }
548
549 # Long symlinks and LU-2241
550 test_17g() {
551         test_mkdir $DIR/$tdir
552         local TESTS="59 60 61 4094 4095"
553
554         # Fix for inode size boundary in 2.1.4
555         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
556                 TESTS="4094 4095"
557
558         # Patch not applied to 2.2 or 2.3 branches
559         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
560         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
561                 TESTS="4094 4095"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1190                 [ $num_all -ne $((nrfiles + 2)) ]; then
1191                         error "Expected $nrfiles files, got $num_ls " \
1192                                 "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_24G () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1445
1446         local ino1
1447         local ino2
1448
1449         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1450         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1451         touch $DIR/$tdir-0/f1 || error "touch f1"
1452         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1453         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1454         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1455         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1456         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1457 }
1458 run_test 24G "migrate symlink in rename"
1459
1460 test_25a() {
1461         echo '== symlink sanity ============================================='
1462
1463         test_mkdir $DIR/d25
1464         ln -s d25 $DIR/s25
1465         touch $DIR/s25/foo ||
1466                 error "File creation in symlinked directory failed"
1467 }
1468 run_test 25a "create file in symlinked directory ==============="
1469
1470 test_25b() {
1471         [ ! -d $DIR/d25 ] && test_25a
1472         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1473 }
1474 run_test 25b "lookup file in symlinked directory ==============="
1475
1476 test_26a() {
1477         test_mkdir $DIR/d26
1478         test_mkdir $DIR/d26/d26-2
1479         ln -s d26/d26-2 $DIR/s26
1480         touch $DIR/s26/foo || error "File creation failed"
1481 }
1482 run_test 26a "multiple component symlink ======================="
1483
1484 test_26b() {
1485         test_mkdir -p $DIR/$tdir/d26-2
1486         ln -s $tdir/d26-2/foo $DIR/s26-2
1487         touch $DIR/s26-2 || error "File creation failed"
1488 }
1489 run_test 26b "multiple component symlink at end of lookup ======"
1490
1491 test_26c() {
1492         test_mkdir $DIR/d26.2
1493         touch $DIR/d26.2/foo
1494         ln -s d26.2 $DIR/s26.2-1
1495         ln -s s26.2-1 $DIR/s26.2-2
1496         ln -s s26.2-2 $DIR/s26.2-3
1497         chmod 0666 $DIR/s26.2-3/foo
1498 }
1499 run_test 26c "chain of symlinks"
1500
1501 # recursive symlinks (bug 439)
1502 test_26d() {
1503         ln -s d26-3/foo $DIR/d26-3
1504 }
1505 run_test 26d "create multiple component recursive symlink"
1506
1507 test_26e() {
1508         [ ! -h $DIR/d26-3 ] && test_26d
1509         rm $DIR/d26-3
1510 }
1511 run_test 26e "unlink multiple component recursive symlink"
1512
1513 # recursive symlinks (bug 7022)
1514 test_26f() {
1515         test_mkdir $DIR/$tdir
1516         test_mkdir $DIR/$tdir/$tfile
1517         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1518         test_mkdir -p lndir/bar1
1519         test_mkdir $DIR/$tdir/$tfile/$tfile
1520         cd $tfile                || error "cd $tfile failed"
1521         ln -s .. dotdot          || error "ln dotdot failed"
1522         ln -s dotdot/lndir lndir || error "ln lndir failed"
1523         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1524         output=`ls $tfile/$tfile/lndir/bar1`
1525         [ "$output" = bar1 ] && error "unexpected output"
1526         rm -r $tfile             || error "rm $tfile failed"
1527         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1528 }
1529 run_test 26f "rm -r of a directory which has recursive symlink"
1530
1531 test_27a() {
1532         test_mkdir $DIR/$tdir
1533         $LFS getstripe $DIR/$tdir
1534         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1535         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1536         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1537 }
1538 run_test 27a "one stripe file"
1539
1540 test_27b() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1542
1543         test_mkdir $DIR/$tdir
1544         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1545         $LFS getstripe -c $DIR/$tdir/$tfile
1546         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1547                 error "two-stripe file doesn't have two stripes"
1548
1549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1550 }
1551 run_test 27b "create and write to two stripe file"
1552
1553 # 27c family tests specific striping, setstripe -o
1554 test_27ca() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1"
1558
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1560         $LFS getstripe -i $DIR/$tdir/$tfile
1561         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1562                 error "stripe not on specified OST"
1563
1564         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1565 }
1566 run_test 27ca "one stripe on specified OST"
1567
1568 test_27cb() {
1569         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1570         test_mkdir -p $DIR/$tdir
1571         local osts="1,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cb "two stripes on specified OSTs"
1585
1586 test_27cc() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590
1591         test_mkdir -p $DIR/$tdir
1592         local osts="0,0"
1593         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1594         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1595         echo "$getstripe"
1596
1597         # Strip getstripe output to a space separated list of OSTs
1598         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1599                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1600         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1601                 error "stripes not on specified OSTs"
1602
1603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1604 }
1605 run_test 27cc "two stripes on the same OST"
1606
1607 test_27cd() {
1608         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="0,1,1,0"
1613         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1614         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1615         echo "$getstripe"
1616
1617         # Strip getstripe output to a space separated list of OSTs
1618         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1619                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1620         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1621                 error "stripes not on specified OSTs"
1622
1623         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1624 }
1625 run_test 27cd "four stripes on two OSTs"
1626
1627 test_27ce() {
1628         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1629                 skip_env "too many osts, skipping"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632         # We do one more stripe than we have OSTs
1633         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1634                 skip_env "ea_inode feature disabled"
1635
1636         test_mkdir -p $DIR/$tdir
1637         local osts=""
1638         for i in $(seq 0 $OSTCOUNT);
1639         do
1640                 osts=$osts"0"
1641                 if [ $i -ne $OSTCOUNT ]; then
1642                         osts=$osts","
1643                 fi
1644         done
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27ce "more stripes than OSTs with -o"
1658
1659 test_27cf() {
1660         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1661         local pid=0
1662
1663         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1664         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1665         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1666         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1667                 error "failed to set $osp_proc=0"
1668
1669         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1670         pid=$!
1671         sleep 1
1672         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1673         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1674                 error "failed to set $osp_proc=1"
1675         wait $pid
1676         [[ $pid -ne 0 ]] ||
1677                 error "should return error due to $osp_proc=0"
1678 }
1679 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1680
1681 test_27d() {
1682         test_mkdir $DIR/$tdir
1683         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1684                 error "setstripe failed"
1685         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1687 }
1688 run_test 27d "create file with default settings"
1689
1690 test_27e() {
1691         # LU-5839 adds check for existed layout before setting it
1692         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1693                 skip "Need MDS version at least 2.7.56"
1694
1695         test_mkdir $DIR/$tdir
1696         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1697         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1698         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1699 }
1700 run_test 27e "setstripe existing file (should return error)"
1701
1702 test_27f() {
1703         test_mkdir $DIR/$tdir
1704         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1705                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1706         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1707                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1708         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1709         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1710 }
1711 run_test 27f "setstripe with bad stripe size (should return error)"
1712
1713 test_27g() {
1714         test_mkdir $DIR/$tdir
1715         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1716         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1717                 error "$DIR/$tdir/$tfile has object"
1718 }
1719 run_test 27g "$LFS getstripe with no objects"
1720
1721 test_27ga() {
1722         test_mkdir $DIR/$tdir
1723         touch $DIR/$tdir/$tfile || error "touch failed"
1724         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1725         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1726         local rc=$?
1727         (( rc == 2 )) || error "getstripe did not return ENOENT"
1728 }
1729 run_test 27ga "$LFS getstripe with missing file (should return error)"
1730
1731 test_27i() {
1732         test_mkdir $DIR/$tdir
1733         touch $DIR/$tdir/$tfile || error "touch failed"
1734         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1735                 error "missing objects"
1736 }
1737 run_test 27i "$LFS getstripe with some objects"
1738
1739 test_27j() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1742                 error "setstripe failed" || true
1743 }
1744 run_test 27j "setstripe with bad stripe offset (should return error)"
1745
1746 test_27k() { # bug 2844
1747         test_mkdir $DIR/$tdir
1748         local file=$DIR/$tdir/$tfile
1749         local ll_max_blksize=$((4 * 1024 * 1024))
1750         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1751         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1752         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1753         dd if=/dev/zero of=$file bs=4k count=1
1754         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1755         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1756 }
1757 run_test 27k "limit i_blksize for broken user apps"
1758
1759 test_27l() {
1760         mcreate $DIR/$tfile || error "creating file"
1761         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1762                 error "setstripe should have failed" || true
1763 }
1764 run_test 27l "check setstripe permissions (should return error)"
1765
1766 test_27m() {
1767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1768
1769         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1770                 skip_env "multiple clients -- skipping"
1771
1772         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1773                    head -n1)
1774         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1775                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1776         fi
1777         trap simple_cleanup_common EXIT
1778         test_mkdir $DIR/$tdir
1779         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1780         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1781                 error "dd should fill OST0"
1782         i=2
1783         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1784                 i=$((i + 1))
1785                 [ $i -gt 256 ] && break
1786         done
1787         i=$((i + 1))
1788         touch $DIR/$tdir/$tfile.$i
1789         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1790             awk '{print $1}'| grep -w "0") ] &&
1791                 error "OST0 was full but new created file still use it"
1792         i=$((i + 1))
1793         touch $DIR/$tdir/$tfile.$i
1794         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1795             awk '{print $1}'| grep -w "0") ] &&
1796                 error "OST0 was full but new created file still use it"
1797         simple_cleanup_common
1798 }
1799 run_test 27m "create file while OST0 was full"
1800
1801 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1802 # if the OST isn't full anymore.
1803 reset_enospc() {
1804         local ostidx=${1:-""}
1805         local delay
1806         local ready
1807         local get_prealloc
1808
1809         local list=$(comma_list $(osts_nodes))
1810         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1811
1812         do_nodes $list lctl set_param fail_loc=0
1813         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1814         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1815                 awk '{print $1 * 2;exit;}')
1816         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1817                         grep -v \"^0$\""
1818         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1819 }
1820
1821 __exhaust_precreations() {
1822         local OSTIDX=$1
1823         local FAILLOC=$2
1824         local FAILIDX=${3:-$OSTIDX}
1825         local ofacet=ost$((OSTIDX + 1))
1826
1827         test_mkdir -p -c1 $DIR/$tdir
1828         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1829         local mfacet=mds$((mdtidx + 1))
1830         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1831
1832         local OST=$(ostname_from_index $OSTIDX)
1833
1834         # on the mdt's osc
1835         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1836         local last_id=$(do_facet $mfacet lctl get_param -n \
1837                         osp.$mdtosc_proc1.prealloc_last_id)
1838         local next_id=$(do_facet $mfacet lctl get_param -n \
1839                         osp.$mdtosc_proc1.prealloc_next_id)
1840
1841         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1842         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1843
1844         test_mkdir -p $DIR/$tdir/${OST}
1845         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1846 #define OBD_FAIL_OST_ENOSPC              0x215
1847         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1848         echo "Creating to objid $last_id on ost $OST..."
1849         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1850         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1851         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1852 }
1853
1854 exhaust_precreations() {
1855         __exhaust_precreations $1 $2 $3
1856         sleep_maxage
1857 }
1858
1859 exhaust_all_precreations() {
1860         local i
1861         for (( i=0; i < OSTCOUNT; i++ )) ; do
1862                 __exhaust_precreations $i $1 -1
1863         done
1864         sleep_maxage
1865 }
1866
1867 test_27n() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875         exhaust_precreations 0 0x80000215
1876         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1877         touch $DIR/$tdir/$tfile || error "touch failed"
1878         $LFS getstripe $DIR/$tdir/$tfile
1879         reset_enospc
1880 }
1881 run_test 27n "create file with some full OSTs"
1882
1883 test_27o() {
1884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1886         remote_mds_nodsh && skip "remote MDS with nodsh"
1887         remote_ost_nodsh && skip "remote OST with nodsh"
1888
1889         reset_enospc
1890         rm -f $DIR/$tdir/$tfile
1891         exhaust_all_precreations 0x215
1892
1893         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1894
1895         reset_enospc
1896         rm -rf $DIR/$tdir/*
1897 }
1898 run_test 27o "create file with all full OSTs (should error)"
1899
1900 test_27p() {
1901         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1903         remote_mds_nodsh && skip "remote MDS with nodsh"
1904         remote_ost_nodsh && skip "remote OST with nodsh"
1905
1906         reset_enospc
1907         rm -f $DIR/$tdir/$tfile
1908         test_mkdir $DIR/$tdir
1909
1910         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1911         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1912         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1913
1914         exhaust_precreations 0 0x80000215
1915         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1916         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1917         $LFS getstripe $DIR/$tdir/$tfile
1918
1919         reset_enospc
1920 }
1921 run_test 27p "append to a truncated file with some full OSTs"
1922
1923 test_27q() {
1924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1926         remote_mds_nodsh && skip "remote MDS with nodsh"
1927         remote_ost_nodsh && skip "remote OST with nodsh"
1928
1929         reset_enospc
1930         rm -f $DIR/$tdir/$tfile
1931
1932         test_mkdir $DIR/$tdir
1933         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1934         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1935                 error "truncate $DIR/$tdir/$tfile failed"
1936         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1937
1938         exhaust_all_precreations 0x215
1939
1940         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1941         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1942
1943         reset_enospc
1944 }
1945 run_test 27q "append to truncated file with all OSTs full (should error)"
1946
1947 test_27r() {
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         reset_enospc
1954         rm -f $DIR/$tdir/$tfile
1955         exhaust_precreations 0 0x80000215
1956
1957         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1958
1959         reset_enospc
1960 }
1961 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1962
1963 test_27s() { # bug 10725
1964         test_mkdir $DIR/$tdir
1965         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1966         local stripe_count=0
1967         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1968         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1969                 error "stripe width >= 2^32 succeeded" || true
1970
1971 }
1972 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1973
1974 test_27t() { # bug 10864
1975         WDIR=$(pwd)
1976         WLFS=$(which lfs)
1977         cd $DIR
1978         touch $tfile
1979         $WLFS getstripe $tfile
1980         cd $WDIR
1981 }
1982 run_test 27t "check that utils parse path correctly"
1983
1984 test_27u() { # bug 4900
1985         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987
1988         local index
1989         local list=$(comma_list $(mdts_nodes))
1990
1991 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1992         do_nodes $list $LCTL set_param fail_loc=0x139
1993         test_mkdir -p $DIR/$tdir
1994         trap simple_cleanup_common EXIT
1995         createmany -o $DIR/$tdir/t- 1000
1996         do_nodes $list $LCTL set_param fail_loc=0
1997
1998         TLOG=$TMP/$tfile.getstripe
1999         $LFS getstripe $DIR/$tdir > $TLOG
2000         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2001         unlinkmany $DIR/$tdir/t- 1000
2002         trap 0
2003         [[ $OBJS -gt 0 ]] &&
2004                 error "$OBJS objects created on OST-0. See $TLOG" ||
2005                 rm -f $TLOG
2006 }
2007 run_test 27u "skip object creation on OSC w/o objects"
2008
2009 test_27v() { # bug 4900
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         exhaust_all_precreations 0x215
2016         reset_enospc
2017
2018         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2019
2020         touch $DIR/$tdir/$tfile
2021         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2022         # all except ost1
2023         for (( i=1; i < OSTCOUNT; i++ )); do
2024                 do_facet ost$i lctl set_param fail_loc=0x705
2025         done
2026         local START=`date +%s`
2027         createmany -o $DIR/$tdir/$tfile 32
2028
2029         local FINISH=`date +%s`
2030         local TIMEOUT=`lctl get_param -n timeout`
2031         local PROCESS=$((FINISH - START))
2032         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2033                error "$FINISH - $START >= $TIMEOUT / 2"
2034         sleep $((TIMEOUT / 2 - PROCESS))
2035         reset_enospc
2036 }
2037 run_test 27v "skip object creation on slow OST"
2038
2039 test_27w() { # bug 10997
2040         test_mkdir $DIR/$tdir
2041         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2042         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2043                 error "stripe size $size != 65536" || true
2044         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2045                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2046 }
2047 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2048
2049 test_27wa() {
2050         [[ $OSTCOUNT -lt 2 ]] &&
2051                 skip_env "skipping multiple stripe count/offset test"
2052
2053         test_mkdir $DIR/$tdir
2054         for i in $(seq 1 $OSTCOUNT); do
2055                 offset=$((i - 1))
2056                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2057                         error "setstripe -c $i -i $offset failed"
2058                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2059                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2060                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2061                 [ $index -ne $offset ] &&
2062                         error "stripe offset $index != $offset" || true
2063         done
2064 }
2065 run_test 27wa "check $LFS setstripe -c -i options"
2066
2067 test_27x() {
2068         remote_ost_nodsh && skip "remote OST with nodsh"
2069         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2071
2072         OFFSET=$(($OSTCOUNT - 1))
2073         OSTIDX=0
2074         local OST=$(ostname_from_index $OSTIDX)
2075
2076         test_mkdir $DIR/$tdir
2077         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2078         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2079         sleep_maxage
2080         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2081         for i in $(seq 0 $OFFSET); do
2082                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2083                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2084                 error "OST0 was degraded but new created file still use it"
2085         done
2086         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2087 }
2088 run_test 27x "create files while OST0 is degraded"
2089
2090 test_27y() {
2091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2092         remote_mds_nodsh && skip "remote MDS with nodsh"
2093         remote_ost_nodsh && skip "remote OST with nodsh"
2094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2095
2096         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2097         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2098                 osp.$mdtosc.prealloc_last_id)
2099         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2100                 osp.$mdtosc.prealloc_next_id)
2101         local fcount=$((last_id - next_id))
2102         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2103         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2104
2105         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2106                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2107         local OST_DEACTIVE_IDX=-1
2108         local OSC
2109         local OSTIDX
2110         local OST
2111
2112         for OSC in $MDS_OSCS; do
2113                 OST=$(osc_to_ost $OSC)
2114                 OSTIDX=$(index_from_ostuuid $OST)
2115                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2116                         OST_DEACTIVE_IDX=$OSTIDX
2117                 fi
2118                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2119                         echo $OSC "is Deactivated:"
2120                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2121                 fi
2122         done
2123
2124         OSTIDX=$(index_from_ostuuid $OST)
2125         test_mkdir $DIR/$tdir
2126         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2127
2128         for OSC in $MDS_OSCS; do
2129                 OST=$(osc_to_ost $OSC)
2130                 OSTIDX=$(index_from_ostuuid $OST)
2131                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2132                         echo $OST "is degraded:"
2133                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2134                                                 obdfilter.$OST.degraded=1
2135                 fi
2136         done
2137
2138         sleep_maxage
2139         createmany -o $DIR/$tdir/$tfile $fcount
2140
2141         for OSC in $MDS_OSCS; do
2142                 OST=$(osc_to_ost $OSC)
2143                 OSTIDX=$(index_from_ostuuid $OST)
2144                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2145                         echo $OST "is recovered from degraded:"
2146                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2147                                                 obdfilter.$OST.degraded=0
2148                 else
2149                         do_facet $SINGLEMDS lctl --device %$OSC activate
2150                 fi
2151         done
2152
2153         # all osp devices get activated, hence -1 stripe count restored
2154         local stripe_count=0
2155
2156         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2157         # devices get activated.
2158         sleep_maxage
2159         $LFS setstripe -c -1 $DIR/$tfile
2160         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2161         rm -f $DIR/$tfile
2162         [ $stripe_count -ne $OSTCOUNT ] &&
2163                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2164         return 0
2165 }
2166 run_test 27y "create files while OST0 is degraded and the rest inactive"
2167
2168 check_seq_oid()
2169 {
2170         log "check file $1"
2171
2172         lmm_count=$($LFS getstripe -c $1)
2173         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2174         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2175
2176         local old_ifs="$IFS"
2177         IFS=$'[:]'
2178         fid=($($LFS path2fid $1))
2179         IFS="$old_ifs"
2180
2181         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2182         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2183
2184         # compare lmm_seq and lu_fid->f_seq
2185         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2186         # compare lmm_object_id and lu_fid->oid
2187         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2188
2189         # check the trusted.fid attribute of the OST objects of the file
2190         local have_obdidx=false
2191         local stripe_nr=0
2192         $LFS getstripe $1 | while read obdidx oid hex seq; do
2193                 # skip lines up to and including "obdidx"
2194                 [ -z "$obdidx" ] && break
2195                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2196                 $have_obdidx || continue
2197
2198                 local ost=$((obdidx + 1))
2199                 local dev=$(ostdevname $ost)
2200                 local oid_hex
2201
2202                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2203
2204                 seq=$(echo $seq | sed -e "s/^0x//g")
2205                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2206                         oid_hex=$(echo $oid)
2207                 else
2208                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2209                 fi
2210                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2211
2212                 local ff=""
2213                 #
2214                 # Don't unmount/remount the OSTs if we don't need to do that.
2215                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2216                 # update too, until that use mount/ll_decode_filter_fid/mount.
2217                 # Re-enable when debugfs will understand new filter_fid.
2218                 #
2219                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2220                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2221                                 $dev 2>/dev/null" | grep "parent=")
2222                 fi
2223                 if [ -z "$ff" ]; then
2224                         stop ost$ost
2225                         mount_fstype ost$ost
2226                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2227                                 $(facet_mntpt ost$ost)/$obj_file)
2228                         unmount_fstype ost$ost
2229                         start ost$ost $dev $OST_MOUNT_OPTS
2230                         clients_up
2231                 fi
2232
2233                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2234
2235                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2236
2237                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2238                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2239                 #
2240                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2241                 #       stripe_size=1048576 component_id=1 component_start=0 \
2242                 #       component_end=33554432
2243                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2244                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2245                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2246                 local ff_pstripe
2247                 if grep -q 'stripe=' <<<$ff; then
2248                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2249                 else
2250                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2251                         # into f_ver in this case.  See comment on ff_parent.
2252                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2253                 fi
2254
2255                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2256                 [ $ff_pseq = $lmm_seq ] ||
2257                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2258                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2259                 [ $ff_poid = $lmm_oid ] ||
2260                         error "FF parent OID $ff_poid != $lmm_oid"
2261                 (($ff_pstripe == $stripe_nr)) ||
2262                         error "FF stripe $ff_pstripe != $stripe_nr"
2263
2264                 stripe_nr=$((stripe_nr + 1))
2265                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2266                         continue
2267                 if grep -q 'stripe_count=' <<<$ff; then
2268                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2269                                             -e 's/ .*//' <<<$ff)
2270                         [ $lmm_count = $ff_scnt ] ||
2271                                 error "FF stripe count $lmm_count != $ff_scnt"
2272                 fi
2273         done
2274 }
2275
2276 test_27z() {
2277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2278         remote_ost_nodsh && skip "remote OST with nodsh"
2279
2280         test_mkdir $DIR/$tdir
2281         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2282                 { error "setstripe -c -1 failed"; return 1; }
2283         # We need to send a write to every object to get parent FID info set.
2284         # This _should_ also work for setattr, but does not currently.
2285         # touch $DIR/$tdir/$tfile-1 ||
2286         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2287                 { error "dd $tfile-1 failed"; return 2; }
2288         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2289                 { error "setstripe -c -1 failed"; return 3; }
2290         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2291                 { error "dd $tfile-2 failed"; return 4; }
2292
2293         # make sure write RPCs have been sent to OSTs
2294         sync; sleep 5; sync
2295
2296         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2297         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2298 }
2299 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2300
2301 test_27A() { # b=19102
2302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2303
2304         save_layout_restore_at_exit $MOUNT
2305         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2306         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2307                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2308         local default_size=$($LFS getstripe -S $MOUNT)
2309         local default_offset=$($LFS getstripe -i $MOUNT)
2310         local dsize=$(do_facet $SINGLEMDS \
2311                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2312         [ $default_size -eq $dsize ] ||
2313                 error "stripe size $default_size != $dsize"
2314         [ $default_offset -eq -1 ] ||
2315                 error "stripe offset $default_offset != -1"
2316 }
2317 run_test 27A "check filesystem-wide default LOV EA values"
2318
2319 test_27B() { # LU-2523
2320         test_mkdir $DIR/$tdir
2321         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2322         touch $DIR/$tdir/f0
2323         # open f1 with O_LOV_DELAY_CREATE
2324         # rename f0 onto f1
2325         # call setstripe ioctl on open file descriptor for f1
2326         # close
2327         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2328                 $DIR/$tdir/f0
2329
2330         rm -f $DIR/$tdir/f1
2331         # open f1 with O_LOV_DELAY_CREATE
2332         # unlink f1
2333         # call setstripe ioctl on open file descriptor for f1
2334         # close
2335         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2336
2337         # Allow multiop to fail in imitation of NFS's busted semantics.
2338         true
2339 }
2340 run_test 27B "call setstripe on open unlinked file/rename victim"
2341
2342 # 27C family tests full striping and overstriping
2343 test_27Ca() { #LU-2871
2344         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2345
2346         declare -a ost_idx
2347         local index
2348         local found
2349         local i
2350         local j
2351
2352         test_mkdir $DIR/$tdir
2353         cd $DIR/$tdir
2354         for i in $(seq 0 $((OSTCOUNT - 1))); do
2355                 # set stripe across all OSTs starting from OST$i
2356                 $LFS setstripe -i $i -c -1 $tfile$i
2357                 # get striping information
2358                 ost_idx=($($LFS getstripe $tfile$i |
2359                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2360                 echo ${ost_idx[@]}
2361
2362                 # check the layout
2363                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2364                         error "${#ost_idx[@]} != $OSTCOUNT"
2365
2366                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2367                         found=0
2368                         for j in $(echo ${ost_idx[@]}); do
2369                                 if [ $index -eq $j ]; then
2370                                         found=1
2371                                         break
2372                                 fi
2373                         done
2374                         [ $found = 1 ] ||
2375                                 error "Can not find $index in ${ost_idx[@]}"
2376                 done
2377         done
2378 }
2379 run_test 27Ca "check full striping across all OSTs"
2380
2381 test_27Cb() {
2382         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2383                 skip "server does not support overstriping"
2384         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2385                 skip_env "too many osts, skipping"
2386
2387         test_mkdir -p $DIR/$tdir
2388         local setcount=$(($OSTCOUNT * 2))
2389         [ $setcount -ge 160 ] || large_xattr_enabled ||
2390                 skip_env "ea_inode feature disabled"
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 run_test 27Cb "more stripes than OSTs with -C"
2406
2407 test_27Cc() {
2408         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2409                 skip "server does not support overstriping"
2410         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2411
2412         test_mkdir -p $DIR/$tdir
2413         local setcount=$(($OSTCOUNT - 1))
2414
2415         [ $setcount -ge 160 ] || large_xattr_enabled ||
2416                 skip_env "ea_inode feature disabled"
2417
2418         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2419                 error "setstripe failed"
2420
2421         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2422         [ $count -eq $setcount ] ||
2423                 error "stripe count $count, should be $setcount"
2424
2425         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2426                 error "overstriped should not be set in pattern"
2427
2428         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2429                 error "dd failed"
2430 }
2431 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2432
2433 test_27Cd() {
2434         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2435                 skip "server does not support overstriping"
2436         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2437         large_xattr_enabled || skip_env "ea_inode feature disabled"
2438
2439         test_mkdir -p $DIR/$tdir
2440         local setcount=$LOV_MAX_STRIPE_COUNT
2441
2442         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2443                 error "setstripe failed"
2444
2445         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2446         [ $count -eq $setcount ] ||
2447                 error "stripe count $count, should be $setcount"
2448
2449         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2450                 error "overstriped should be set in pattern"
2451
2452         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2453                 error "dd failed"
2454
2455         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2456 }
2457 run_test 27Cd "test maximum stripe count"
2458
2459 test_27Ce() {
2460         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2461                 skip "server does not support overstriping"
2462         test_mkdir -p $DIR/$tdir
2463
2464         pool_add $TESTNAME || error "Pool creation failed"
2465         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2466
2467         local setcount=8
2468
2469         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2470                 error "setstripe failed"
2471
2472         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2473         [ $count -eq $setcount ] ||
2474                 error "stripe count $count, should be $setcount"
2475
2476         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2477                 error "overstriped should be set in pattern"
2478
2479         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2480                 error "dd failed"
2481
2482         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2483 }
2484 run_test 27Ce "test pool with overstriping"
2485
2486 test_27Cf() {
2487         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2488                 skip "server does not support overstriping"
2489         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2490                 skip_env "too many osts, skipping"
2491
2492         test_mkdir -p $DIR/$tdir
2493
2494         local setcount=$(($OSTCOUNT * 2))
2495         [ $setcount -ge 160 ] || large_xattr_enabled ||
2496                 skip_env "ea_inode feature disabled"
2497
2498         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2499                 error "setstripe failed"
2500
2501         echo 1 > $DIR/$tdir/$tfile
2502
2503         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2504         [ $count -eq $setcount ] ||
2505                 error "stripe count $count, should be $setcount"
2506
2507         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2508                 error "overstriped should be set in pattern"
2509
2510         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2511                 error "dd failed"
2512
2513         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2514 }
2515 run_test 27Cf "test default inheritance with overstriping"
2516
2517 test_27D() {
2518         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2519         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2520         remote_mds_nodsh && skip "remote MDS with nodsh"
2521
2522         local POOL=${POOL:-testpool}
2523         local first_ost=0
2524         local last_ost=$(($OSTCOUNT - 1))
2525         local ost_step=1
2526         local ost_list=$(seq $first_ost $ost_step $last_ost)
2527         local ost_range="$first_ost $last_ost $ost_step"
2528
2529         test_mkdir $DIR/$tdir
2530         pool_add $POOL || error "pool_add failed"
2531         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2532
2533         local skip27D
2534         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2535                 skip27D+="-s 29"
2536         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2537                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2538                         skip27D+=" -s 30,31"
2539         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2540           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2541                 skip27D+=" -s 32,33"
2542         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2543                 skip27D+=" -s 34"
2544         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2545                 error "llapi_layout_test failed"
2546
2547         destroy_test_pools || error "destroy test pools failed"
2548 }
2549 run_test 27D "validate llapi_layout API"
2550
2551 # Verify that default_easize is increased from its initial value after
2552 # accessing a widely striped file.
2553 test_27E() {
2554         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2555         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2556                 skip "client does not have LU-3338 fix"
2557
2558         # 72 bytes is the minimum space required to store striping
2559         # information for a file striped across one OST:
2560         # (sizeof(struct lov_user_md_v3) +
2561         #  sizeof(struct lov_user_ost_data_v1))
2562         local min_easize=72
2563         $LCTL set_param -n llite.*.default_easize $min_easize ||
2564                 error "lctl set_param failed"
2565         local easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -eq $min_easize ] ||
2568                 error "failed to set default_easize"
2569
2570         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2571                 error "setstripe failed"
2572         # In order to ensure stat() call actually talks to MDS we need to
2573         # do something drastic to this file to shake off all lock, e.g.
2574         # rename it (kills lookup lock forcing cache cleaning)
2575         mv $DIR/$tfile $DIR/${tfile}-1
2576         ls -l $DIR/${tfile}-1
2577         rm $DIR/${tfile}-1
2578
2579         easize=$($LCTL get_param -n llite.*.default_easize)
2580
2581         [ $easize -gt $min_easize ] ||
2582                 error "default_easize not updated"
2583 }
2584 run_test 27E "check that default extended attribute size properly increases"
2585
2586 test_27F() { # LU-5346/LU-7975
2587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2588         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2589         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2590                 skip "Need MDS version at least 2.8.51"
2591         remote_ost_nodsh && skip "remote OST with nodsh"
2592
2593         test_mkdir $DIR/$tdir
2594         rm -f $DIR/$tdir/f0
2595         $LFS setstripe -c 2 $DIR/$tdir
2596
2597         # stop all OSTs to reproduce situation for LU-7975 ticket
2598         for num in $(seq $OSTCOUNT); do
2599                 stop ost$num
2600         done
2601
2602         # open/create f0 with O_LOV_DELAY_CREATE
2603         # truncate f0 to a non-0 size
2604         # close
2605         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2606
2607         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2608         # open/write it again to force delayed layout creation
2609         cat /etc/hosts > $DIR/$tdir/f0 &
2610         catpid=$!
2611
2612         # restart OSTs
2613         for num in $(seq $OSTCOUNT); do
2614                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2615                         error "ost$num failed to start"
2616         done
2617
2618         wait $catpid || error "cat failed"
2619
2620         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2621         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2622                 error "wrong stripecount"
2623
2624 }
2625 run_test 27F "Client resend delayed layout creation with non-zero size"
2626
2627 test_27G() { #LU-10629
2628         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2629                 skip "Need MDS version at least 2.11.51"
2630         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2631         remote_mds_nodsh && skip "remote MDS with nodsh"
2632         local POOL=${POOL:-testpool}
2633         local ostrange="0 0 1"
2634
2635         test_mkdir $DIR/$tdir
2636         touch $DIR/$tdir/$tfile.nopool
2637         pool_add $POOL || error "pool_add failed"
2638         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2639         $LFS setstripe -p $POOL $DIR/$tdir
2640
2641         local pool=$($LFS getstripe -p $DIR/$tdir)
2642
2643         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2644         touch $DIR/$tdir/$tfile.default
2645         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2646         $LFS find $DIR/$tdir -type f --pool $POOL
2647         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2648         [[ "$found" == "2" ]] ||
2649                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2650
2651         $LFS setstripe -d $DIR/$tdir
2652
2653         pool=$($LFS getstripe -p -d $DIR/$tdir)
2654
2655         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2656 }
2657 run_test 27G "Clear OST pool from stripe"
2658
2659 test_27H() {
2660         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2661                 skip "Need MDS version newer than 2.11.54"
2662         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2663         test_mkdir $DIR/$tdir
2664         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2665         touch $DIR/$tdir/$tfile
2666         $LFS getstripe -c $DIR/$tdir/$tfile
2667         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2668                 error "two-stripe file doesn't have two stripes"
2669
2670         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2671         $LFS getstripe -y $DIR/$tdir/$tfile
2672         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2673              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2674                 error "expected l_ost_idx: [02]$ not matched"
2675
2676         # make sure ost list has been cleared
2677         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2678         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2679                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2680         touch $DIR/$tdir/f3
2681         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2682 }
2683 run_test 27H "Set specific OSTs stripe"
2684
2685 test_27I() {
2686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2687         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2688         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2689                 skip "Need MDS version newer than 2.12.52"
2690         local pool=$TESTNAME
2691         local ostrange="1 1 1"
2692
2693         save_layout_restore_at_exit $MOUNT
2694         $LFS setstripe -c 2 -i 0 $MOUNT
2695         pool_add $pool || error "pool_add failed"
2696         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -p $pool $DIR/$tdir
2699         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2700         $LFS getstripe $DIR/$tdir/$tfile
2701 }
2702 run_test 27I "check that root dir striping does not break parent dir one"
2703
2704 test_27J() {
2705         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2706                 skip "Need MDS version newer than 2.12.51"
2707
2708         test_mkdir $DIR/$tdir
2709         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2710         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2711
2712         # create foreign file (raw way)
2713         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2714                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2715
2716         # verify foreign file (raw way)
2717         parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2719                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2720         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2721                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2722         parse_foreign_file -f $DIR/$tdir/$tfile |
2723                 grep "lov_foreign_size: 73" ||
2724                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2725         parse_foreign_file -f $DIR/$tdir/$tfile |
2726                 grep "lov_foreign_type: 1" ||
2727                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2728         parse_foreign_file -f $DIR/$tdir/$tfile |
2729                 grep "lov_foreign_flags: 0x0000DA08" ||
2730                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2731         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2732                 grep "lov_foreign_value: 0x" |
2733                 sed -e 's/lov_foreign_value: 0x//')
2734         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2735         [[ $lov = ${lov2// /} ]] ||
2736                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2737
2738         # create foreign file (lfs + API)
2739         $LFS setstripe --foreign=daos --flags 0xda08 \
2740                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2741                 error "$DIR/$tdir/${tfile}2: create failed"
2742
2743         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2744                 grep "lfm_magic:.*0x0BD70BD0" ||
2745                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2746         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2747         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2748                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2749         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2750                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2751         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2752                 grep "lfm_flags:.*0x0000DA08" ||
2753                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2754         $LFS getstripe $DIR/$tdir/${tfile}2 |
2755                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2756                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2757
2758         # modify striping should fail
2759         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2760                 error "$DIR/$tdir/$tfile: setstripe should fail"
2761         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2762                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2763
2764         # R/W should fail
2765         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2766         cat $DIR/$tdir/${tfile}2 &&
2767                 error "$DIR/$tdir/${tfile}2: read should fail"
2768         cat /etc/passwd > $DIR/$tdir/$tfile &&
2769                 error "$DIR/$tdir/$tfile: write should fail"
2770         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2771                 error "$DIR/$tdir/${tfile}2: write should fail"
2772
2773         # chmod should work
2774         chmod 222 $DIR/$tdir/$tfile ||
2775                 error "$DIR/$tdir/$tfile: chmod failed"
2776         chmod 222 $DIR/$tdir/${tfile}2 ||
2777                 error "$DIR/$tdir/${tfile}2: chmod failed"
2778
2779         # chown should work
2780         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2781                 error "$DIR/$tdir/$tfile: chown failed"
2782         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2783                 error "$DIR/$tdir/${tfile}2: chown failed"
2784
2785         # rename should work
2786         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2787                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2788         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2789                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2790
2791         #remove foreign file
2792         rm $DIR/$tdir/${tfile}.new ||
2793                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2794         rm $DIR/$tdir/${tfile}2.new ||
2795                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2796 }
2797 run_test 27J "basic ops on file with foreign LOV"
2798
2799 test_27K() {
2800         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2801                 skip "Need MDS version newer than 2.12.49"
2802
2803         test_mkdir $DIR/$tdir
2804         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2805         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2806
2807         # create foreign dir (raw way)
2808         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2809                 error "create_foreign_dir FAILED"
2810
2811         # verify foreign dir (raw way)
2812         parse_foreign_dir -d $DIR/$tdir/$tdir |
2813                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2814                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2815         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2816                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2817         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2818                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2819         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2820                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2821         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2822                 grep "lmv_foreign_value: 0x" |
2823                 sed 's/lmv_foreign_value: 0x//')
2824         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2825                 sed 's/ //g')
2826         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2827
2828         # create foreign dir (lfs + API)
2829         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2830                 $DIR/$tdir/${tdir}2 ||
2831                 error "$DIR/$tdir/${tdir}2: create failed"
2832
2833         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2834                 grep "lfm_magic:.*0x0CD50CD0" ||
2835                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2836         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2837         # - sizeof(lfm_type) - sizeof(lfm_flags)
2838         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2839                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2840         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2841                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2842         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2843                 grep "lfm_flags:.*0x0000DA05" ||
2844                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2845         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2846                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2847                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2848
2849         # file create in dir should fail
2850         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2851         touch $DIR/$tdir/${tdir}2/$tfile &&
2852                 "$DIR/${tdir}2: file create should fail"
2853
2854         # chmod should work
2855         chmod 777 $DIR/$tdir/$tdir ||
2856                 error "$DIR/$tdir: chmod failed"
2857         chmod 777 $DIR/$tdir/${tdir}2 ||
2858                 error "$DIR/${tdir}2: chmod failed"
2859
2860         # chown should work
2861         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2862                 error "$DIR/$tdir: chown failed"
2863         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2864                 error "$DIR/${tdir}2: chown failed"
2865
2866         # rename should work
2867         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2868                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2869         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2870                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2871
2872         #remove foreign dir
2873         rmdir $DIR/$tdir/${tdir}.new ||
2874                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2875         rmdir $DIR/$tdir/${tdir}2.new ||
2876                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2877 }
2878 run_test 27K "basic ops on dir with foreign LMV"
2879
2880 test_27L() {
2881         remote_mds_nodsh && skip "remote MDS with nodsh"
2882
2883         local POOL=${POOL:-$TESTNAME}
2884
2885         pool_add $POOL || error "pool_add failed"
2886
2887         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2888                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2889                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2890 }
2891 run_test 27L "lfs pool_list gives correct pool name"
2892
2893 test_27M() {
2894         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2895                 skip "Need MDS version >= than 2.12.57"
2896         remote_mds_nodsh && skip "remote MDS with nodsh"
2897         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2898
2899         test_mkdir $DIR/$tdir
2900
2901         # Set default striping on directory
2902         $LFS setstripe -C 4 $DIR/$tdir
2903
2904         echo 1 > $DIR/$tdir/${tfile}.1
2905         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2906         local setcount=4
2907         [ $count -eq $setcount ] ||
2908                 error "(1) stripe count $count, should be $setcount"
2909
2910         # Capture existing append_stripe_count setting for restore
2911         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2912         local mdts=$(comma_list $(mdts_nodes))
2913         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2914
2915         local appendcount=$orig_count
2916         echo 1 >> $DIR/$tdir/${tfile}.2_append
2917         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2918         [ $count -eq $appendcount ] ||
2919                 error "(2)stripe count $count, should be $appendcount for append"
2920
2921         # Disable O_APPEND striping, verify it works
2922         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2923
2924         # Should now get the default striping, which is 4
2925         setcount=4
2926         echo 1 >> $DIR/$tdir/${tfile}.3_append
2927         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2928         [ $count -eq $setcount ] ||
2929                 error "(3) stripe count $count, should be $setcount"
2930
2931         # Try changing the stripe count for append files
2932         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2933
2934         # Append striping is now 2 (directory default is still 4)
2935         appendcount=2
2936         echo 1 >> $DIR/$tdir/${tfile}.4_append
2937         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2938         [ $count -eq $appendcount ] ||
2939                 error "(4) stripe count $count, should be $appendcount for append"
2940
2941         # Test append stripe count of -1
2942         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2943         appendcount=$OSTCOUNT
2944         echo 1 >> $DIR/$tdir/${tfile}.5
2945         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2946         [ $count -eq $appendcount ] ||
2947                 error "(5) stripe count $count, should be $appendcount for append"
2948
2949         # Set append striping back to default of 1
2950         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2951
2952         # Try a new default striping, PFL + DOM
2953         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2954
2955         # Create normal DOM file, DOM returns stripe count == 0
2956         setcount=0
2957         touch $DIR/$tdir/${tfile}.6
2958         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2959         [ $count -eq $setcount ] ||
2960                 error "(6) stripe count $count, should be $setcount"
2961
2962         # Show
2963         appendcount=1
2964         echo 1 >> $DIR/$tdir/${tfile}.7_append
2965         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2966         [ $count -eq $appendcount ] ||
2967                 error "(7) stripe count $count, should be $appendcount for append"
2968
2969         # Clean up DOM layout
2970         $LFS setstripe -d $DIR/$tdir
2971
2972         # Now test that append striping works when layout is from root
2973         $LFS setstripe -c 2 $MOUNT
2974         # Make a special directory for this
2975         mkdir $DIR/${tdir}/${tdir}.2
2976         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2977
2978         # Verify for normal file
2979         setcount=2
2980         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2981         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2982         [ $count -eq $setcount ] ||
2983                 error "(8) stripe count $count, should be $setcount"
2984
2985         appendcount=1
2986         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2987         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2988         [ $count -eq $appendcount ] ||
2989                 error "(9) stripe count $count, should be $appendcount for append"
2990
2991         # Now test O_APPEND striping with pools
2992         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2993         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2994
2995         # Create the pool
2996         pool_add $TESTNAME || error "pool creation failed"
2997         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2998
2999         echo 1 >> $DIR/$tdir/${tfile}.10_append
3000
3001         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3002         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3003
3004         # Check that count is still correct
3005         appendcount=1
3006         echo 1 >> $DIR/$tdir/${tfile}.11_append
3007         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3008         [ $count -eq $appendcount ] ||
3009                 error "(11) stripe count $count, should be $appendcount for append"
3010
3011         # Disable O_APPEND stripe count, verify pool works separately
3012         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3013
3014         echo 1 >> $DIR/$tdir/${tfile}.12_append
3015
3016         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3017         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3018
3019         # Remove pool setting, verify it's not applied
3020         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3021
3022         echo 1 >> $DIR/$tdir/${tfile}.13_append
3023
3024         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3025         [ "$pool" = "" ] || error "(13) pool found: $pool"
3026 }
3027 run_test 27M "test O_APPEND striping"
3028
3029 test_27N() {
3030         combined_mgs_mds && skip "needs separate MGS/MDT"
3031
3032         pool_add $TESTNAME || error "pool_add failed"
3033         do_facet mgs "$LCTL pool_list $FSNAME" |
3034                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3035                 error "lctl pool_list on MGS failed"
3036 }
3037 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3038
3039 # createtest also checks that device nodes are created and
3040 # then visible correctly (#2091)
3041 test_28() { # bug 2091
3042         test_mkdir $DIR/d28
3043         $CREATETEST $DIR/d28/ct || error "createtest failed"
3044 }
3045 run_test 28 "create/mknod/mkdir with bad file types ============"
3046
3047 test_29() {
3048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3049
3050         sync; sleep 1; sync # flush out any dirty pages from previous tests
3051         cancel_lru_locks
3052         test_mkdir $DIR/d29
3053         touch $DIR/d29/foo
3054         log 'first d29'
3055         ls -l $DIR/d29
3056
3057         declare -i LOCKCOUNTORIG=0
3058         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3059                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3060         done
3061         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3062
3063         declare -i LOCKUNUSEDCOUNTORIG=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3066         done
3067
3068         log 'second d29'
3069         ls -l $DIR/d29
3070         log 'done'
3071
3072         declare -i LOCKCOUNTCURRENT=0
3073         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3074                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3075         done
3076
3077         declare -i LOCKUNUSEDCOUNTCURRENT=0
3078         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3079                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3080         done
3081
3082         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3083                 $LCTL set_param -n ldlm.dump_namespaces ""
3084                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3085                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3086                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3087                 return 2
3088         fi
3089         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3090                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3091                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3092                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3093                 return 3
3094         fi
3095 }
3096 run_test 29 "IT_GETATTR regression  ============================"
3097
3098 test_30a() { # was test_30
3099         cp $(which ls) $DIR || cp /bin/ls $DIR
3100         $DIR/ls / || error "Can't execute binary from lustre"
3101         rm $DIR/ls
3102 }
3103 run_test 30a "execute binary from Lustre (execve) =============="
3104
3105 test_30b() {
3106         cp `which ls` $DIR || cp /bin/ls $DIR
3107         chmod go+rx $DIR/ls
3108         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3109         rm $DIR/ls
3110 }
3111 run_test 30b "execute binary from Lustre as non-root ==========="
3112
3113 test_30c() { # b=22376
3114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3115
3116         cp $(which ls) $DIR || cp /bin/ls $DIR
3117         chmod a-rw $DIR/ls
3118         cancel_lru_locks mdc
3119         cancel_lru_locks osc
3120         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3121         rm -f $DIR/ls
3122 }
3123 run_test 30c "execute binary from Lustre without read perms ===="
3124
3125 test_30d() {
3126         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3127
3128         for i in {1..10}; do
3129                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3130                 local PID=$!
3131                 sleep 1
3132                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3133                 wait $PID || error "executing dd from Lustre failed"
3134                 rm -f $DIR/$tfile
3135         done
3136
3137         rm -f $DIR/dd
3138 }
3139 run_test 30d "execute binary from Lustre while clear locks"
3140
3141 test_31a() {
3142         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3143         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3144 }
3145 run_test 31a "open-unlink file =================================="
3146
3147 test_31b() {
3148         touch $DIR/f31 || error "touch $DIR/f31 failed"
3149         ln $DIR/f31 $DIR/f31b || error "ln failed"
3150         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3151         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3152 }
3153 run_test 31b "unlink file with multiple links while open ======="
3154
3155 test_31c() {
3156         touch $DIR/f31 || error "touch $DIR/f31 failed"
3157         ln $DIR/f31 $DIR/f31c || error "ln failed"
3158         multiop_bg_pause $DIR/f31 O_uc ||
3159                 error "multiop_bg_pause for $DIR/f31 failed"
3160         MULTIPID=$!
3161         $MULTIOP $DIR/f31c Ouc
3162         kill -USR1 $MULTIPID
3163         wait $MULTIPID
3164 }
3165 run_test 31c "open-unlink file with multiple links ============="
3166
3167 test_31d() {
3168         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3169         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3170 }
3171 run_test 31d "remove of open directory ========================="
3172
3173 test_31e() { # bug 2904
3174         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3175 }
3176 run_test 31e "remove of open non-empty directory ==============="
3177
3178 test_31f() { # bug 4554
3179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3180
3181         set -vx
3182         test_mkdir $DIR/d31f
3183         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3184         cp /etc/hosts $DIR/d31f
3185         ls -l $DIR/d31f
3186         $LFS getstripe $DIR/d31f/hosts
3187         multiop_bg_pause $DIR/d31f D_c || return 1
3188         MULTIPID=$!
3189
3190         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3191         test_mkdir $DIR/d31f
3192         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3193         cp /etc/hosts $DIR/d31f
3194         ls -l $DIR/d31f
3195         $LFS getstripe $DIR/d31f/hosts
3196         multiop_bg_pause $DIR/d31f D_c || return 1
3197         MULTIPID2=$!
3198
3199         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3200         wait $MULTIPID || error "first opendir $MULTIPID failed"
3201
3202         sleep 6
3203
3204         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3205         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3206         set +vx
3207 }
3208 run_test 31f "remove of open directory with open-unlink file ==="
3209
3210 test_31g() {
3211         echo "-- cross directory link --"
3212         test_mkdir -c1 $DIR/${tdir}ga
3213         test_mkdir -c1 $DIR/${tdir}gb
3214         touch $DIR/${tdir}ga/f
3215         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3216         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3217         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3218         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3219         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3220 }
3221 run_test 31g "cross directory link==============="
3222
3223 test_31h() {
3224         echo "-- cross directory link --"
3225         test_mkdir -c1 $DIR/${tdir}
3226         test_mkdir -c1 $DIR/${tdir}/dir
3227         touch $DIR/${tdir}/f
3228         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3229         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3230         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3231         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3232         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3233 }
3234 run_test 31h "cross directory link under child==============="
3235
3236 test_31i() {
3237         echo "-- cross directory link --"
3238         test_mkdir -c1 $DIR/$tdir
3239         test_mkdir -c1 $DIR/$tdir/dir
3240         touch $DIR/$tdir/dir/f
3241         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3242         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3243         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3244         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3245         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3246 }
3247 run_test 31i "cross directory link under parent==============="
3248
3249 test_31j() {
3250         test_mkdir -c1 -p $DIR/$tdir
3251         test_mkdir -c1 -p $DIR/$tdir/dir1
3252         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3253         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3254         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3255         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3256         return 0
3257 }
3258 run_test 31j "link for directory==============="
3259
3260 test_31k() {
3261         test_mkdir -c1 -p $DIR/$tdir
3262         touch $DIR/$tdir/s
3263         touch $DIR/$tdir/exist
3264         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3265         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3266         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3267         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3268         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3269         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3270         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3271         return 0
3272 }
3273 run_test 31k "link to file: the same, non-existing, dir==============="
3274
3275 test_31m() {
3276         mkdir $DIR/d31m
3277         touch $DIR/d31m/s
3278         mkdir $DIR/d31m2
3279         touch $DIR/d31m2/exist
3280         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3281         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3282         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3283         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3284         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3285         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3286         return 0
3287 }
3288 run_test 31m "link to file: the same, non-existing, dir==============="
3289
3290 test_31n() {
3291         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3292         nlink=$(stat --format=%h $DIR/$tfile)
3293         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3294         local fd=$(free_fd)
3295         local cmd="exec $fd<$DIR/$tfile"
3296         eval $cmd
3297         cmd="exec $fd<&-"
3298         trap "eval $cmd" EXIT
3299         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3300         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3301         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3302         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3303         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3304         eval $cmd
3305 }
3306 run_test 31n "check link count of unlinked file"
3307
3308 link_one() {
3309         local tempfile=$(mktemp $1_XXXXXX)
3310         mlink $tempfile $1 2> /dev/null &&
3311                 echo "$BASHPID: link $tempfile to $1 succeeded"
3312         munlink $tempfile
3313 }
3314
3315 test_31o() { # LU-2901
3316         test_mkdir $DIR/$tdir
3317         for LOOP in $(seq 100); do
3318                 rm -f $DIR/$tdir/$tfile*
3319                 for THREAD in $(seq 8); do
3320                         link_one $DIR/$tdir/$tfile.$LOOP &
3321                 done
3322                 wait
3323                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3324                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3325                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3326                         break || true
3327         done
3328 }
3329 run_test 31o "duplicate hard links with same filename"
3330
3331 test_31p() {
3332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3333
3334         test_mkdir $DIR/$tdir
3335         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3336         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3337
3338         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3339                 error "open unlink test1 failed"
3340         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3341                 error "open unlink test2 failed"
3342
3343         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3344                 error "test1 still exists"
3345         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3346                 error "test2 still exists"
3347 }
3348 run_test 31p "remove of open striped directory"
3349
3350 test_31q() {
3351         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3352
3353         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3354         index=$($LFS getdirstripe -i $DIR/$tdir)
3355         [ $index -eq 3 ] || error "first stripe index $index != 3"
3356         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3357         [ $index -eq 1 ] || error "second stripe index $index != 1"
3358
3359         # when "-c <stripe_count>" is set, the number of MDTs specified after
3360         # "-i" should equal to the stripe count
3361         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3362 }
3363 run_test 31q "create striped directory on specific MDTs"
3364
3365 cleanup_test32_mount() {
3366         local rc=0
3367         trap 0
3368         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3369         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3370         losetup -d $loopdev || true
3371         rm -rf $DIR/$tdir
3372         return $rc
3373 }
3374
3375 test_32a() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         echo "== more mountpoints and symlinks ================="
3379         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3380         trap cleanup_test32_mount EXIT
3381         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3382         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3383                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3385                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3389
3390 test_32b() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3399                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3400         cleanup_test32_mount
3401 }
3402 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3403
3404 test_32c() {
3405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3406
3407         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3408         trap cleanup_test32_mount EXIT
3409         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3410         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3411                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3412         test_mkdir -p $DIR/$tdir/d2/test_dir
3413         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3414                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3415         cleanup_test32_mount
3416 }
3417 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3418
3419 test_32d() {
3420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3421
3422         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3423         trap cleanup_test32_mount EXIT
3424         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3425         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3426                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3427         test_mkdir -p $DIR/$tdir/d2/test_dir
3428         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3429                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3430         cleanup_test32_mount
3431 }
3432 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3433
3434 test_32e() {
3435         rm -fr $DIR/$tdir
3436         test_mkdir -p $DIR/$tdir/tmp
3437         local tmp_dir=$DIR/$tdir/tmp
3438         ln -s $DIR/$tdir $tmp_dir/symlink11
3439         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3440         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3441         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3442 }
3443 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3444
3445 test_32f() {
3446         rm -fr $DIR/$tdir
3447         test_mkdir -p $DIR/$tdir/tmp
3448         local tmp_dir=$DIR/$tdir/tmp
3449         ln -s $DIR/$tdir $tmp_dir/symlink11
3450         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3451         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3452         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3453 }
3454 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3455
3456 test_32g() {
3457         local tmp_dir=$DIR/$tdir/tmp
3458         test_mkdir -p $tmp_dir
3459         test_mkdir $DIR/${tdir}2
3460         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3461         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3462         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3463         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3464         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3465         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3466 }
3467 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3468
3469 test_32h() {
3470         rm -fr $DIR/$tdir $DIR/${tdir}2
3471         tmp_dir=$DIR/$tdir/tmp
3472         test_mkdir -p $tmp_dir
3473         test_mkdir $DIR/${tdir}2
3474         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3475         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3476         ls $tmp_dir/symlink12 || error "listing symlink12"
3477         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3478 }
3479 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3480
3481 test_32i() {
3482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3483
3484         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3485         trap cleanup_test32_mount EXIT
3486         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3487         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3488                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3489         touch $DIR/$tdir/test_file
3490         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3491                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3492         cleanup_test32_mount
3493 }
3494 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3495
3496 test_32j() {
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3500         trap cleanup_test32_mount EXIT
3501         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3502         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3503                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3504         touch $DIR/$tdir/test_file
3505         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3506                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3507         cleanup_test32_mount
3508 }
3509 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3510
3511 test_32k() {
3512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3513
3514         rm -fr $DIR/$tdir
3515         trap cleanup_test32_mount EXIT
3516         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3517         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3518                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3519         test_mkdir -p $DIR/$tdir/d2
3520         touch $DIR/$tdir/d2/test_file || error "touch failed"
3521         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3522                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3523         cleanup_test32_mount
3524 }
3525 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3526
3527 test_32l() {
3528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3529
3530         rm -fr $DIR/$tdir
3531         trap cleanup_test32_mount EXIT
3532         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3533         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3534                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3535         test_mkdir -p $DIR/$tdir/d2
3536         touch $DIR/$tdir/d2/test_file || error "touch failed"
3537         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3538                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3539         cleanup_test32_mount
3540 }
3541 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3542
3543 test_32m() {
3544         rm -fr $DIR/d32m
3545         test_mkdir -p $DIR/d32m/tmp
3546         TMP_DIR=$DIR/d32m/tmp
3547         ln -s $DIR $TMP_DIR/symlink11
3548         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3549         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3550                 error "symlink11 not a link"
3551         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3552                 error "symlink01 not a link"
3553 }
3554 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3555
3556 test_32n() {
3557         rm -fr $DIR/d32n
3558         test_mkdir -p $DIR/d32n/tmp
3559         TMP_DIR=$DIR/d32n/tmp
3560         ln -s $DIR $TMP_DIR/symlink11
3561         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3562         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3563         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3564 }
3565 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3566
3567 test_32o() {
3568         touch $DIR/$tfile
3569         test_mkdir -p $DIR/d32o/tmp
3570         TMP_DIR=$DIR/d32o/tmp
3571         ln -s $DIR/$tfile $TMP_DIR/symlink12
3572         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3573         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3574                 error "symlink12 not a link"
3575         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3576         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3577                 error "$DIR/d32o/tmp/symlink12 not file type"
3578         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3579                 error "$DIR/d32o/symlink02 not file type"
3580 }
3581 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3582
3583 test_32p() {
3584         log 32p_1
3585         rm -fr $DIR/d32p
3586         log 32p_2
3587         rm -f $DIR/$tfile
3588         log 32p_3
3589         touch $DIR/$tfile
3590         log 32p_4
3591         test_mkdir -p $DIR/d32p/tmp
3592         log 32p_5
3593         TMP_DIR=$DIR/d32p/tmp
3594         log 32p_6
3595         ln -s $DIR/$tfile $TMP_DIR/symlink12
3596         log 32p_7
3597         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3598         log 32p_8
3599         cat $DIR/d32p/tmp/symlink12 ||
3600                 error "Can't open $DIR/d32p/tmp/symlink12"
3601         log 32p_9
3602         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3603         log 32p_10
3604 }
3605 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3606
3607 test_32q() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3611         trap cleanup_test32_mount EXIT
3612         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3613         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3614         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3615                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3616         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3617         cleanup_test32_mount
3618 }
3619 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3620
3621 test_32r() {
3622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3623
3624         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3625         trap cleanup_test32_mount EXIT
3626         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3627         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3628         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3629                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3630         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3631         cleanup_test32_mount
3632 }
3633 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3634
3635 test_33aa() {
3636         rm -f $DIR/$tfile
3637         touch $DIR/$tfile
3638         chmod 444 $DIR/$tfile
3639         chown $RUNAS_ID $DIR/$tfile
3640         log 33_1
3641         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3642         log 33_2
3643 }
3644 run_test 33aa "write file with mode 444 (should return error)"
3645
3646 test_33a() {
3647         rm -fr $DIR/$tdir
3648         test_mkdir $DIR/$tdir
3649         chown $RUNAS_ID $DIR/$tdir
3650         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3651                 error "$RUNAS create $tdir/$tfile failed"
3652         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3653                 error "open RDWR" || true
3654 }
3655 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3656
3657 test_33b() {
3658         rm -fr $DIR/$tdir
3659         test_mkdir $DIR/$tdir
3660         chown $RUNAS_ID $DIR/$tdir
3661         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3662 }
3663 run_test 33b "test open file with malformed flags (No panic)"
3664
3665 test_33c() {
3666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3667         remote_ost_nodsh && skip "remote OST with nodsh"
3668
3669         local ostnum
3670         local ostname
3671         local write_bytes
3672         local all_zeros
3673
3674         all_zeros=:
3675         rm -fr $DIR/$tdir
3676         test_mkdir $DIR/$tdir
3677         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3678
3679         sync
3680         for ostnum in $(seq $OSTCOUNT); do
3681                 # test-framework's OST numbering is one-based, while Lustre's
3682                 # is zero-based
3683                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3684                 # Parsing llobdstat's output sucks; we could grep the /proc
3685                 # path, but that's likely to not be as portable as using the
3686                 # llobdstat utility.  So we parse lctl output instead.
3687                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3688                         obdfilter/$ostname/stats |
3689                         awk '/^write_bytes/ {print $7}' )
3690                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3691                 if (( ${write_bytes:-0} > 0 ))
3692                 then
3693                         all_zeros=false
3694                         break;
3695                 fi
3696         done
3697
3698         $all_zeros || return 0
3699
3700         # Write four bytes
3701         echo foo > $DIR/$tdir/bar
3702         # Really write them
3703         sync
3704
3705         # Total up write_bytes after writing.  We'd better find non-zeros.
3706         for ostnum in $(seq $OSTCOUNT); do
3707                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3708                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3709                         obdfilter/$ostname/stats |
3710                         awk '/^write_bytes/ {print $7}' )
3711                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3712                 if (( ${write_bytes:-0} > 0 ))
3713                 then
3714                         all_zeros=false
3715                         break;
3716                 fi
3717         done
3718
3719         if $all_zeros
3720         then
3721                 for ostnum in $(seq $OSTCOUNT); do
3722                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3723                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3724                         do_facet ost$ostnum lctl get_param -n \
3725                                 obdfilter/$ostname/stats
3726                 done
3727                 error "OST not keeping write_bytes stats (b22312)"
3728         fi
3729 }
3730 run_test 33c "test llobdstat and write_bytes"
3731
3732 test_33d() {
3733         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3735
3736         local MDTIDX=1
3737         local remote_dir=$DIR/$tdir/remote_dir
3738
3739         test_mkdir $DIR/$tdir
3740         $LFS mkdir -i $MDTIDX $remote_dir ||
3741                 error "create remote directory failed"
3742
3743         touch $remote_dir/$tfile
3744         chmod 444 $remote_dir/$tfile
3745         chown $RUNAS_ID $remote_dir/$tfile
3746
3747         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3748
3749         chown $RUNAS_ID $remote_dir
3750         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3751                                         error "create" || true
3752         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3753                                     error "open RDWR" || true
3754         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3755 }
3756 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3757
3758 test_33e() {
3759         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3760
3761         mkdir $DIR/$tdir
3762
3763         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3764         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3765         mkdir $DIR/$tdir/local_dir
3766
3767         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3768         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3769         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3770
3771         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3772                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3773
3774         rmdir $DIR/$tdir/* || error "rmdir failed"
3775
3776         umask 777
3777         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3778         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3779         mkdir $DIR/$tdir/local_dir
3780
3781         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3782         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3783         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3784
3785         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3786                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3787
3788         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3789
3790         umask 000
3791         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3792         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3793         mkdir $DIR/$tdir/local_dir
3794
3795         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3796         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3797         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3798
3799         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3800                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3801 }
3802 run_test 33e "mkdir and striped directory should have same mode"
3803
3804 cleanup_33f() {
3805         trap 0
3806         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3807 }
3808
3809 test_33f() {
3810         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3811         remote_mds_nodsh && skip "remote MDS with nodsh"
3812
3813         mkdir $DIR/$tdir
3814         chmod go+rwx $DIR/$tdir
3815         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3816         trap cleanup_33f EXIT
3817
3818         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3819                 error "cannot create striped directory"
3820
3821         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3822                 error "cannot create files in striped directory"
3823
3824         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3825                 error "cannot remove files in striped directory"
3826
3827         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3828                 error "cannot remove striped directory"
3829
3830         cleanup_33f
3831 }
3832 run_test 33f "nonroot user can create, access, and remove a striped directory"
3833
3834 test_33g() {
3835         mkdir -p $DIR/$tdir/dir2
3836
3837         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3838         echo $err
3839         [[ $err =~ "exists" ]] || error "Not exists error"
3840 }
3841 run_test 33g "nonroot user create already existing root created file"
3842
3843 test_33h() {
3844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3845         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3846                 skip "Need MDS version at least 2.13.50"
3847
3848         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3849                 error "mkdir $tdir failed"
3850         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3851
3852         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3853         local index2
3854
3855         for fname in $DIR/$tdir/$tfile.bak \
3856                      $DIR/$tdir/$tfile.SAV \
3857                      $DIR/$tdir/$tfile.orig \
3858                      $DIR/$tdir/$tfile~; do
3859                 touch $fname  || error "touch $fname failed"
3860                 index2=$($LFS getstripe -m $fname)
3861                 [ $index -eq $index2 ] ||
3862                         error "$fname MDT index mismatch $index != $index2"
3863         done
3864
3865         local failed=0
3866         for i in {1..250}; do
3867                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3868                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3869                         touch $fname  || error "touch $fname failed"
3870                         index2=$($LFS getstripe -m $fname)
3871                         if [[ $index != $index2 ]]; then
3872                                 failed=$((failed + 1))
3873                                 echo "$fname MDT index mismatch $index != $index2"
3874                         fi
3875                 done
3876         done
3877         echo "$failed MDT index mismatches"
3878         (( failed < 20 )) || error "MDT index mismatch $failed times"
3879
3880 }
3881 run_test 33h "temp file is located on the same MDT as target"
3882
3883 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3884 test_34a() {
3885         rm -f $DIR/f34
3886         $MCREATE $DIR/f34 || error "mcreate failed"
3887         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3888                 error "getstripe failed"
3889         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3890         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3891                 error "getstripe failed"
3892         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3893                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3894 }
3895 run_test 34a "truncate file that has not been opened ==========="
3896
3897 test_34b() {
3898         [ ! -f $DIR/f34 ] && test_34a
3899         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3900                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3901         $OPENFILE -f O_RDONLY $DIR/f34
3902         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3903                 error "getstripe failed"
3904         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3905                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3906 }
3907 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3908
3909 test_34c() {
3910         [ ! -f $DIR/f34 ] && test_34a
3911         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3912                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3913         $OPENFILE -f O_RDWR $DIR/f34
3914         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3915                 error "$LFS getstripe failed"
3916         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3917                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3918 }
3919 run_test 34c "O_RDWR opening file-with-size works =============="
3920
3921 test_34d() {
3922         [ ! -f $DIR/f34 ] && test_34a
3923         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3924                 error "dd failed"
3925         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3926                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3927         rm $DIR/f34
3928 }
3929 run_test 34d "write to sparse file ============================="
3930
3931 test_34e() {
3932         rm -f $DIR/f34e
3933         $MCREATE $DIR/f34e || error "mcreate failed"
3934         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3935         $CHECKSTAT -s 1000 $DIR/f34e ||
3936                 error "Size of $DIR/f34e not equal to 1000 bytes"
3937         $OPENFILE -f O_RDWR $DIR/f34e
3938         $CHECKSTAT -s 1000 $DIR/f34e ||
3939                 error "Size of $DIR/f34e not equal to 1000 bytes"
3940 }
3941 run_test 34e "create objects, some with size and some without =="
3942
3943 test_34f() { # bug 6242, 6243
3944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3945
3946         SIZE34F=48000
3947         rm -f $DIR/f34f
3948         $MCREATE $DIR/f34f || error "mcreate failed"
3949         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3950         dd if=$DIR/f34f of=$TMP/f34f
3951         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3952         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3953         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3954         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3955         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3956 }
3957 run_test 34f "read from a file with no objects until EOF ======="
3958
3959 test_34g() {
3960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3961
3962         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3963                 error "dd failed"
3964         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3965         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3966                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3967         cancel_lru_locks osc
3968         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3969                 error "wrong size after lock cancel"
3970
3971         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3972         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3973                 error "expanding truncate failed"
3974         cancel_lru_locks osc
3975         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3976                 error "wrong expanded size after lock cancel"
3977 }
3978 run_test 34g "truncate long file ==============================="
3979
3980 test_34h() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982
3983         local gid=10
3984         local sz=1000
3985
3986         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3987         sync # Flush the cache so that multiop below does not block on cache
3988              # flush when getting the group lock
3989         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3990         MULTIPID=$!
3991
3992         # Since just timed wait is not good enough, let's do a sync write
3993         # that way we are sure enough time for a roundtrip + processing
3994         # passed + 2 seconds of extra margin.
3995         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3996         rm $DIR/${tfile}-1
3997         sleep 2
3998
3999         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4000                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4001                 kill -9 $MULTIPID
4002         fi
4003         wait $MULTIPID
4004         local nsz=`stat -c %s $DIR/$tfile`
4005         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4006 }
4007 run_test 34h "ftruncate file under grouplock should not block"
4008
4009 test_35a() {
4010         cp /bin/sh $DIR/f35a
4011         chmod 444 $DIR/f35a
4012         chown $RUNAS_ID $DIR/f35a
4013         $RUNAS $DIR/f35a && error || true
4014         rm $DIR/f35a
4015 }
4016 run_test 35a "exec file with mode 444 (should return and not leak)"
4017
4018 test_36a() {
4019         rm -f $DIR/f36
4020         utime $DIR/f36 || error "utime failed for MDS"
4021 }
4022 run_test 36a "MDS utime check (mknod, utime)"
4023
4024 test_36b() {
4025         echo "" > $DIR/f36
4026         utime $DIR/f36 || error "utime failed for OST"
4027 }
4028 run_test 36b "OST utime check (open, utime)"
4029
4030 test_36c() {
4031         rm -f $DIR/d36/f36
4032         test_mkdir $DIR/d36
4033         chown $RUNAS_ID $DIR/d36
4034         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4035 }
4036 run_test 36c "non-root MDS utime check (mknod, utime)"
4037
4038 test_36d() {
4039         [ ! -d $DIR/d36 ] && test_36c
4040         echo "" > $DIR/d36/f36
4041         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4042 }
4043 run_test 36d "non-root OST utime check (open, utime)"
4044
4045 test_36e() {
4046         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4047
4048         test_mkdir $DIR/$tdir
4049         touch $DIR/$tdir/$tfile
4050         $RUNAS utime $DIR/$tdir/$tfile &&
4051                 error "utime worked, expected failure" || true
4052 }
4053 run_test 36e "utime on non-owned file (should return error)"
4054
4055 subr_36fh() {
4056         local fl="$1"
4057         local LANG_SAVE=$LANG
4058         local LC_LANG_SAVE=$LC_LANG
4059         export LANG=C LC_LANG=C # for date language
4060
4061         DATESTR="Dec 20  2000"
4062         test_mkdir $DIR/$tdir
4063         lctl set_param fail_loc=$fl
4064         date; date +%s
4065         cp /etc/hosts $DIR/$tdir/$tfile
4066         sync & # write RPC generated with "current" inode timestamp, but delayed
4067         sleep 1
4068         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4069         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4070         cancel_lru_locks $OSC
4071         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4072         date; date +%s
4073         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4074                 echo "BEFORE: $LS_BEFORE" && \
4075                 echo "AFTER : $LS_AFTER" && \
4076                 echo "WANT  : $DATESTR" && \
4077                 error "$DIR/$tdir/$tfile timestamps changed" || true
4078
4079         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4080 }
4081
4082 test_36f() {
4083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4084
4085         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4086         subr_36fh "0x80000214"
4087 }
4088 run_test 36f "utime on file racing with OST BRW write =========="
4089
4090 test_36g() {
4091         remote_ost_nodsh && skip "remote OST with nodsh"
4092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4093         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4094                 skip "Need MDS version at least 2.12.51"
4095
4096         local fmd_max_age
4097         local fmd
4098         local facet="ost1"
4099         local tgt="obdfilter"
4100
4101         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4102
4103         test_mkdir $DIR/$tdir
4104         fmd_max_age=$(do_facet $facet \
4105                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4106                 head -n 1")
4107
4108         echo "FMD max age: ${fmd_max_age}s"
4109         touch $DIR/$tdir/$tfile
4110         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4111                 gawk '{cnt=cnt+$1}  END{print cnt}')
4112         echo "FMD before: $fmd"
4113         [[ $fmd == 0 ]] &&
4114                 error "FMD wasn't create by touch"
4115         sleep $((fmd_max_age + 12))
4116         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4117                 gawk '{cnt=cnt+$1}  END{print cnt}')
4118         echo "FMD after: $fmd"
4119         [[ $fmd == 0 ]] ||
4120                 error "FMD wasn't expired by ping"
4121 }
4122 run_test 36g "FMD cache expiry ====================="
4123
4124 test_36h() {
4125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4126
4127         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4128         subr_36fh "0x80000227"
4129 }
4130 run_test 36h "utime on file racing with OST BRW write =========="
4131
4132 test_36i() {
4133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4134
4135         test_mkdir $DIR/$tdir
4136         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4137
4138         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4139         local new_mtime=$((mtime + 200))
4140
4141         #change Modify time of striped dir
4142         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4143                         error "change mtime failed"
4144
4145         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4146
4147         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4148 }
4149 run_test 36i "change mtime on striped directory"
4150
4151 # test_37 - duplicate with tests 32q 32r
4152
4153 test_38() {
4154         local file=$DIR/$tfile
4155         touch $file
4156         openfile -f O_DIRECTORY $file
4157         local RC=$?
4158         local ENOTDIR=20
4159         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4160         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4161 }
4162 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4163
4164 test_39a() { # was test_39
4165         touch $DIR/$tfile
4166         touch $DIR/${tfile}2
4167 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4168 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4169 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4170         sleep 2
4171         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4172         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4173                 echo "mtime"
4174                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4175                 echo "atime"
4176                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4177                 echo "ctime"
4178                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4179                 error "O_TRUNC didn't change timestamps"
4180         fi
4181 }
4182 run_test 39a "mtime changed on create"
4183
4184 test_39b() {
4185         test_mkdir -c1 $DIR/$tdir
4186         cp -p /etc/passwd $DIR/$tdir/fopen
4187         cp -p /etc/passwd $DIR/$tdir/flink
4188         cp -p /etc/passwd $DIR/$tdir/funlink
4189         cp -p /etc/passwd $DIR/$tdir/frename
4190         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4191
4192         sleep 1
4193         echo "aaaaaa" >> $DIR/$tdir/fopen
4194         echo "aaaaaa" >> $DIR/$tdir/flink
4195         echo "aaaaaa" >> $DIR/$tdir/funlink
4196         echo "aaaaaa" >> $DIR/$tdir/frename
4197
4198         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4199         local link_new=`stat -c %Y $DIR/$tdir/flink`
4200         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4201         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4202
4203         cat $DIR/$tdir/fopen > /dev/null
4204         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4205         rm -f $DIR/$tdir/funlink2
4206         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4207
4208         for (( i=0; i < 2; i++ )) ; do
4209                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4210                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4211                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4212                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4213
4214                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4215                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4216                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4217                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4218
4219                 cancel_lru_locks $OSC
4220                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4221         done
4222 }
4223 run_test 39b "mtime change on open, link, unlink, rename  ======"
4224
4225 # this should be set to past
4226 TEST_39_MTIME=`date -d "1 year ago" +%s`
4227
4228 # bug 11063
4229 test_39c() {
4230         touch $DIR1/$tfile
4231         sleep 2
4232         local mtime0=`stat -c %Y $DIR1/$tfile`
4233
4234         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4235         local mtime1=`stat -c %Y $DIR1/$tfile`
4236         [ "$mtime1" = $TEST_39_MTIME ] || \
4237                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4238
4239         local d1=`date +%s`
4240         echo hello >> $DIR1/$tfile
4241         local d2=`date +%s`
4242         local mtime2=`stat -c %Y $DIR1/$tfile`
4243         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4244                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4245
4246         mv $DIR1/$tfile $DIR1/$tfile-1
4247
4248         for (( i=0; i < 2; i++ )) ; do
4249                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4250                 [ "$mtime2" = "$mtime3" ] || \
4251                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4252
4253                 cancel_lru_locks $OSC
4254                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4255         done
4256 }
4257 run_test 39c "mtime change on rename ==========================="
4258
4259 # bug 21114
4260 test_39d() {
4261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4262
4263         touch $DIR1/$tfile
4264         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4265
4266         for (( i=0; i < 2; i++ )) ; do
4267                 local mtime=`stat -c %Y $DIR1/$tfile`
4268                 [ $mtime = $TEST_39_MTIME ] || \
4269                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4270
4271                 cancel_lru_locks $OSC
4272                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4273         done
4274 }
4275 run_test 39d "create, utime, stat =============================="
4276
4277 # bug 21114
4278 test_39e() {
4279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4280
4281         touch $DIR1/$tfile
4282         local mtime1=`stat -c %Y $DIR1/$tfile`
4283
4284         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4285
4286         for (( i=0; i < 2; i++ )) ; do
4287                 local mtime2=`stat -c %Y $DIR1/$tfile`
4288                 [ $mtime2 = $TEST_39_MTIME ] || \
4289                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4290
4291                 cancel_lru_locks $OSC
4292                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4293         done
4294 }
4295 run_test 39e "create, stat, utime, stat ========================"
4296
4297 # bug 21114
4298 test_39f() {
4299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4300
4301         touch $DIR1/$tfile
4302         mtime1=`stat -c %Y $DIR1/$tfile`
4303
4304         sleep 2
4305         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4306
4307         for (( i=0; i < 2; i++ )) ; do
4308                 local mtime2=`stat -c %Y $DIR1/$tfile`
4309                 [ $mtime2 = $TEST_39_MTIME ] || \
4310                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4311
4312                 cancel_lru_locks $OSC
4313                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4314         done
4315 }
4316 run_test 39f "create, stat, sleep, utime, stat ================="
4317
4318 # bug 11063
4319 test_39g() {
4320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4321
4322         echo hello >> $DIR1/$tfile
4323         local mtime1=`stat -c %Y $DIR1/$tfile`
4324
4325         sleep 2
4326         chmod o+r $DIR1/$tfile
4327
4328         for (( i=0; i < 2; i++ )) ; do
4329                 local mtime2=`stat -c %Y $DIR1/$tfile`
4330                 [ "$mtime1" = "$mtime2" ] || \
4331                         error "lost mtime: $mtime2, should be $mtime1"
4332
4333                 cancel_lru_locks $OSC
4334                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4335         done
4336 }
4337 run_test 39g "write, chmod, stat ==============================="
4338
4339 # bug 11063
4340 test_39h() {
4341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4342
4343         touch $DIR1/$tfile
4344         sleep 1
4345
4346         local d1=`date`
4347         echo hello >> $DIR1/$tfile
4348         local mtime1=`stat -c %Y $DIR1/$tfile`
4349
4350         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4351         local d2=`date`
4352         if [ "$d1" != "$d2" ]; then
4353                 echo "write and touch not within one second"
4354         else
4355                 for (( i=0; i < 2; i++ )) ; do
4356                         local mtime2=`stat -c %Y $DIR1/$tfile`
4357                         [ "$mtime2" = $TEST_39_MTIME ] || \
4358                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4359
4360                         cancel_lru_locks $OSC
4361                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4362                 done
4363         fi
4364 }
4365 run_test 39h "write, utime within one second, stat ============="
4366
4367 test_39i() {
4368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4369
4370         touch $DIR1/$tfile
4371         sleep 1
4372
4373         echo hello >> $DIR1/$tfile
4374         local mtime1=`stat -c %Y $DIR1/$tfile`
4375
4376         mv $DIR1/$tfile $DIR1/$tfile-1
4377
4378         for (( i=0; i < 2; i++ )) ; do
4379                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4380
4381                 [ "$mtime1" = "$mtime2" ] || \
4382                         error "lost mtime: $mtime2, should be $mtime1"
4383
4384                 cancel_lru_locks $OSC
4385                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4386         done
4387 }
4388 run_test 39i "write, rename, stat =============================="
4389
4390 test_39j() {
4391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4392
4393         start_full_debug_logging
4394         touch $DIR1/$tfile
4395         sleep 1
4396
4397         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4398         lctl set_param fail_loc=0x80000412
4399         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4400                 error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         mv $DIR1/$tfile $DIR1/$tfile-1
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4411                 [ "$mtime1" = "$mtime2" ] ||
4412                         error "mtime is lost on close: $mtime2, " \
4413                               "should be $mtime1"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418         lctl set_param fail_loc=0
4419         stop_full_debug_logging
4420 }
4421 run_test 39j "write, rename, close, stat ======================="
4422
4423 test_39k() {
4424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4425
4426         touch $DIR1/$tfile
4427         sleep 1
4428
4429         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4430         local multipid=$!
4431         local mtime1=`stat -c %Y $DIR1/$tfile`
4432
4433         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4434
4435         kill -USR1 $multipid
4436         wait $multipid || error "multiop close failed"
4437
4438         for (( i=0; i < 2; i++ )) ; do
4439                 local mtime2=`stat -c %Y $DIR1/$tfile`
4440
4441                 [ "$mtime2" = $TEST_39_MTIME ] || \
4442                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4443
4444                 cancel_lru_locks
4445                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4446         done
4447 }
4448 run_test 39k "write, utime, close, stat ========================"
4449
4450 # this should be set to future
4451 TEST_39_ATIME=`date -d "1 year" +%s`
4452
4453 test_39l() {
4454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4455         remote_mds_nodsh && skip "remote MDS with nodsh"
4456
4457         local atime_diff=$(do_facet $SINGLEMDS \
4458                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4459         rm -rf $DIR/$tdir
4460         mkdir -p $DIR/$tdir
4461
4462         # test setting directory atime to future
4463         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4464         local atime=$(stat -c %X $DIR/$tdir)
4465         [ "$atime" = $TEST_39_ATIME ] ||
4466                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4467
4468         # test setting directory atime from future to now
4469         local now=$(date +%s)
4470         touch -a -d @$now $DIR/$tdir
4471
4472         atime=$(stat -c %X $DIR/$tdir)
4473         [ "$atime" -eq "$now"  ] ||
4474                 error "atime is not updated from future: $atime, $now"
4475
4476         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4477         sleep 3
4478
4479         # test setting directory atime when now > dir atime + atime_diff
4480         local d1=$(date +%s)
4481         ls $DIR/$tdir
4482         local d2=$(date +%s)
4483         cancel_lru_locks mdc
4484         atime=$(stat -c %X $DIR/$tdir)
4485         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4486                 error "atime is not updated  : $atime, should be $d2"
4487
4488         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4489         sleep 3
4490
4491         # test not setting directory atime when now < dir atime + atime_diff
4492         ls $DIR/$tdir
4493         cancel_lru_locks mdc
4494         atime=$(stat -c %X $DIR/$tdir)
4495         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4496                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4497
4498         do_facet $SINGLEMDS \
4499                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4500 }
4501 run_test 39l "directory atime update ==========================="
4502
4503 test_39m() {
4504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4505
4506         touch $DIR1/$tfile
4507         sleep 2
4508         local far_past_mtime=$(date -d "May 29 1953" +%s)
4509         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4510
4511         touch -m -d @$far_past_mtime $DIR1/$tfile
4512         touch -a -d @$far_past_atime $DIR1/$tfile
4513
4514         for (( i=0; i < 2; i++ )) ; do
4515                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4516                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4517                         error "atime or mtime set incorrectly"
4518
4519                 cancel_lru_locks $OSC
4520                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4521         done
4522 }
4523 run_test 39m "test atime and mtime before 1970"
4524
4525 test_39n() { # LU-3832
4526         remote_mds_nodsh && skip "remote MDS with nodsh"
4527
4528         local atime_diff=$(do_facet $SINGLEMDS \
4529                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4530         local atime0
4531         local atime1
4532         local atime2
4533
4534         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4535
4536         rm -rf $DIR/$tfile
4537         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4538         atime0=$(stat -c %X $DIR/$tfile)
4539
4540         sleep 5
4541         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4542         atime1=$(stat -c %X $DIR/$tfile)
4543
4544         sleep 5
4545         cancel_lru_locks mdc
4546         cancel_lru_locks osc
4547         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4548         atime2=$(stat -c %X $DIR/$tfile)
4549
4550         do_facet $SINGLEMDS \
4551                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4552
4553         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4554         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4555 }
4556 run_test 39n "check that O_NOATIME is honored"
4557
4558 test_39o() {
4559         TESTDIR=$DIR/$tdir/$tfile
4560         [ -e $TESTDIR ] && rm -rf $TESTDIR
4561         mkdir -p $TESTDIR
4562         cd $TESTDIR
4563         links1=2
4564         ls
4565         mkdir a b
4566         ls
4567         links2=$(stat -c %h .)
4568         [ $(($links1 + 2)) != $links2 ] &&
4569                 error "wrong links count $(($links1 + 2)) != $links2"
4570         rmdir b
4571         links3=$(stat -c %h .)
4572         [ $(($links1 + 1)) != $links3 ] &&
4573                 error "wrong links count $links1 != $links3"
4574         return 0
4575 }
4576 run_test 39o "directory cached attributes updated after create"
4577
4578 test_39p() {
4579         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4580
4581         local MDTIDX=1
4582         TESTDIR=$DIR/$tdir/$tdir
4583         [ -e $TESTDIR ] && rm -rf $TESTDIR
4584         test_mkdir -p $TESTDIR
4585         cd $TESTDIR
4586         links1=2
4587         ls
4588         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4589         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4590         ls
4591         links2=$(stat -c %h .)
4592         [ $(($links1 + 2)) != $links2 ] &&
4593                 error "wrong links count $(($links1 + 2)) != $links2"
4594         rmdir remote_dir2
4595         links3=$(stat -c %h .)
4596         [ $(($links1 + 1)) != $links3 ] &&
4597                 error "wrong links count $links1 != $links3"
4598         return 0
4599 }
4600 run_test 39p "remote directory cached attributes updated after create ========"
4601
4602 test_39r() {
4603         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4604                 skip "no atime update on old OST"
4605         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4606                 skip_env "ldiskfs only test"
4607         fi
4608
4609         local saved_adiff
4610         saved_adiff=$(do_facet ost1 \
4611                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4612         stack_trap "do_facet ost1 \
4613                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4614
4615         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4616
4617         $LFS setstripe -i 0 $DIR/$tfile
4618         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4619                 error "can't write initial file"
4620         cancel_lru_locks osc
4621
4622         # exceed atime_diff and access file
4623         sleep 6
4624         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4625
4626         local atime_cli=$(stat -c %X $DIR/$tfile)
4627         echo "client atime: $atime_cli"
4628         # allow atime update to be written to device
4629         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4630         sleep 5
4631
4632         local ostdev=$(ostdevname 1)
4633         local fid=($(lfs getstripe -y $DIR/$tfile |
4634                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4635         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4636         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4637
4638         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4639         local atime_ost=$(do_facet ost1 "$cmd" |&
4640                           awk -F'[: ]' '/atime:/ { print $4 }')
4641         (( atime_cli == atime_ost )) ||
4642                 error "atime on client $atime_cli != ost $atime_ost"
4643 }
4644 run_test 39r "lazy atime update on OST"
4645
4646 test_39q() { # LU-8041
4647         local testdir=$DIR/$tdir
4648         mkdir -p $testdir
4649         multiop_bg_pause $testdir D_c || error "multiop failed"
4650         local multipid=$!
4651         cancel_lru_locks mdc
4652         kill -USR1 $multipid
4653         local atime=$(stat -c %X $testdir)
4654         [ "$atime" -ne 0 ] || error "atime is zero"
4655 }
4656 run_test 39q "close won't zero out atime"
4657
4658 test_40() {
4659         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4660         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4661                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4662         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4663                 error "$tfile is not 4096 bytes in size"
4664 }
4665 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4666
4667 test_41() {
4668         # bug 1553
4669         small_write $DIR/f41 18
4670 }
4671 run_test 41 "test small file write + fstat ====================="
4672
4673 count_ost_writes() {
4674         lctl get_param -n ${OSC}.*.stats |
4675                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4676                         END { printf("%0.0f", writes) }'
4677 }
4678
4679 # decent default
4680 WRITEBACK_SAVE=500
4681 DIRTY_RATIO_SAVE=40
4682 MAX_DIRTY_RATIO=50
4683 BG_DIRTY_RATIO_SAVE=10
4684 MAX_BG_DIRTY_RATIO=25
4685
4686 start_writeback() {
4687         trap 0
4688         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4689         # dirty_ratio, dirty_background_ratio
4690         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4691                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4692                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4693                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4694         else
4695                 # if file not here, we are a 2.4 kernel
4696                 kill -CONT `pidof kupdated`
4697         fi
4698 }
4699
4700 stop_writeback() {
4701         # setup the trap first, so someone cannot exit the test at the
4702         # exact wrong time and mess up a machine
4703         trap start_writeback EXIT
4704         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4705         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4706                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4707                 sysctl -w vm.dirty_writeback_centisecs=0
4708                 sysctl -w vm.dirty_writeback_centisecs=0
4709                 # save and increase /proc/sys/vm/dirty_ratio
4710                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4711                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4712                 # save and increase /proc/sys/vm/dirty_background_ratio
4713                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4714                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4715         else
4716                 # if file not here, we are a 2.4 kernel
4717                 kill -STOP `pidof kupdated`
4718         fi
4719 }
4720
4721 # ensure that all stripes have some grant before we test client-side cache
4722 setup_test42() {
4723         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4724                 dd if=/dev/zero of=$i bs=4k count=1
4725                 rm $i
4726         done
4727 }
4728
4729 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4730 # file truncation, and file removal.
4731 test_42a() {
4732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4733
4734         setup_test42
4735         cancel_lru_locks $OSC
4736         stop_writeback
4737         sync; sleep 1; sync # just to be safe
4738         BEFOREWRITES=`count_ost_writes`
4739         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4740         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4741         AFTERWRITES=`count_ost_writes`
4742         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4743                 error "$BEFOREWRITES < $AFTERWRITES"
4744         start_writeback
4745 }
4746 run_test 42a "ensure that we don't flush on close"
4747
4748 test_42b() {
4749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4750
4751         setup_test42
4752         cancel_lru_locks $OSC
4753         stop_writeback
4754         sync
4755         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4756         BEFOREWRITES=$(count_ost_writes)
4757         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4758         AFTERWRITES=$(count_ost_writes)
4759         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4760                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4761         fi
4762         BEFOREWRITES=$(count_ost_writes)
4763         sync || error "sync: $?"
4764         AFTERWRITES=$(count_ost_writes)
4765         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4766                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4767         fi
4768         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4769         start_writeback
4770         return 0
4771 }
4772 run_test 42b "test destroy of file with cached dirty data ======"
4773
4774 # if these tests just want to test the effect of truncation,
4775 # they have to be very careful.  consider:
4776 # - the first open gets a {0,EOF}PR lock
4777 # - the first write conflicts and gets a {0, count-1}PW
4778 # - the rest of the writes are under {count,EOF}PW
4779 # - the open for truncate tries to match a {0,EOF}PR
4780 #   for the filesize and cancels the PWs.
4781 # any number of fixes (don't get {0,EOF} on open, match
4782 # composite locks, do smarter file size management) fix
4783 # this, but for now we want these tests to verify that
4784 # the cancellation with truncate intent works, so we
4785 # start the file with a full-file pw lock to match against
4786 # until the truncate.
4787 trunc_test() {
4788         test=$1
4789         file=$DIR/$test
4790         offset=$2
4791         cancel_lru_locks $OSC
4792         stop_writeback
4793         # prime the file with 0,EOF PW to match
4794         touch $file
4795         $TRUNCATE $file 0
4796         sync; sync
4797         # now the real test..
4798         dd if=/dev/zero of=$file bs=1024 count=100
4799         BEFOREWRITES=`count_ost_writes`
4800         $TRUNCATE $file $offset
4801         cancel_lru_locks $OSC
4802         AFTERWRITES=`count_ost_writes`
4803         start_writeback
4804 }
4805
4806 test_42c() {
4807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4808
4809         trunc_test 42c 1024
4810         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4811                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4812         rm $file
4813 }
4814 run_test 42c "test partial truncate of file with cached dirty data"
4815
4816 test_42d() {
4817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4818
4819         trunc_test 42d 0
4820         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4821                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4822         rm $file
4823 }
4824 run_test 42d "test complete truncate of file with cached dirty data"
4825
4826 test_42e() { # bug22074
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         local TDIR=$DIR/${tdir}e
4830         local pages=16 # hardcoded 16 pages, don't change it.
4831         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4832         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4833         local max_dirty_mb
4834         local warmup_files
4835
4836         test_mkdir $DIR/${tdir}e
4837         $LFS setstripe -c 1 $TDIR
4838         createmany -o $TDIR/f $files
4839
4840         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4841
4842         # we assume that with $OSTCOUNT files, at least one of them will
4843         # be allocated on OST0.
4844         warmup_files=$((OSTCOUNT * max_dirty_mb))
4845         createmany -o $TDIR/w $warmup_files
4846
4847         # write a large amount of data into one file and sync, to get good
4848         # avail_grant number from OST.
4849         for ((i=0; i<$warmup_files; i++)); do
4850                 idx=$($LFS getstripe -i $TDIR/w$i)
4851                 [ $idx -ne 0 ] && continue
4852                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4853                 break
4854         done
4855         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4856         sync
4857         $LCTL get_param $proc_osc0/cur_dirty_bytes
4858         $LCTL get_param $proc_osc0/cur_grant_bytes
4859
4860         # create as much dirty pages as we can while not to trigger the actual
4861         # RPCs directly. but depends on the env, VFS may trigger flush during this
4862         # period, hopefully we are good.
4863         for ((i=0; i<$warmup_files; i++)); do
4864                 idx=$($LFS getstripe -i $TDIR/w$i)
4865                 [ $idx -ne 0 ] && continue
4866                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4867         done
4868         $LCTL get_param $proc_osc0/cur_dirty_bytes
4869         $LCTL get_param $proc_osc0/cur_grant_bytes
4870
4871         # perform the real test
4872         $LCTL set_param $proc_osc0/rpc_stats 0
4873         for ((;i<$files; i++)); do
4874                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4875                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4876         done
4877         sync
4878         $LCTL get_param $proc_osc0/rpc_stats
4879
4880         local percent=0
4881         local have_ppr=false
4882         $LCTL get_param $proc_osc0/rpc_stats |
4883                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4884                         # skip lines until we are at the RPC histogram data
4885                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4886                         $have_ppr || continue
4887
4888                         # we only want the percent stat for < 16 pages
4889                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4890
4891                         percent=$((percent + WPCT))
4892                         if [[ $percent -gt 15 ]]; then
4893                                 error "less than 16-pages write RPCs" \
4894                                       "$percent% > 15%"
4895                                 break
4896                         fi
4897                 done
4898         rm -rf $TDIR
4899 }
4900 run_test 42e "verify sub-RPC writes are not done synchronously"
4901
4902 test_43A() { # was test_43
4903         test_mkdir $DIR/$tdir
4904         cp -p /bin/ls $DIR/$tdir/$tfile
4905         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4906         pid=$!
4907         # give multiop a chance to open
4908         sleep 1
4909
4910         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4911         kill -USR1 $pid
4912         # Wait for multiop to exit
4913         wait $pid
4914 }
4915 run_test 43A "execution of file opened for write should return -ETXTBSY"
4916
4917 test_43a() {
4918         test_mkdir $DIR/$tdir
4919         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4920         $DIR/$tdir/sleep 60 &
4921         SLEEP_PID=$!
4922         # Make sure exec of $tdir/sleep wins race with truncate
4923         sleep 1
4924         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4925         kill $SLEEP_PID
4926 }
4927 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4928
4929 test_43b() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         test_mkdir $DIR/$tdir
4933         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4934         $DIR/$tdir/sleep 60 &
4935         SLEEP_PID=$!
4936         # Make sure exec of $tdir/sleep wins race with truncate
4937         sleep 1
4938         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4939         kill $SLEEP_PID
4940 }
4941 run_test 43b "truncate of file being executed should return -ETXTBSY"
4942
4943 test_43c() {
4944         local testdir="$DIR/$tdir"
4945         test_mkdir $testdir
4946         cp $SHELL $testdir/
4947         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4948                 ( cd $testdir && md5sum -c )
4949 }
4950 run_test 43c "md5sum of copy into lustre"
4951
4952 test_44A() { # was test_44
4953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4954
4955         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4956         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4957 }
4958 run_test 44A "zero length read from a sparse stripe"
4959
4960 test_44a() {
4961         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4962                 awk '{ print $2 }')
4963         [ -z "$nstripe" ] && skip "can't get stripe info"
4964         [[ $nstripe -gt $OSTCOUNT ]] &&
4965                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4966
4967         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4968                 awk '{ print $2 }')
4969         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4970                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4971                         awk '{ print $2 }')
4972         fi
4973
4974         OFFSETS="0 $((stride/2)) $((stride-1))"
4975         for offset in $OFFSETS; do
4976                 for i in $(seq 0 $((nstripe-1))); do
4977                         local GLOBALOFFSETS=""
4978                         # size in Bytes
4979                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4980                         local myfn=$DIR/d44a-$size
4981                         echo "--------writing $myfn at $size"
4982                         ll_sparseness_write $myfn $size ||
4983                                 error "ll_sparseness_write"
4984                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4985                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4986                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4987
4988                         for j in $(seq 0 $((nstripe-1))); do
4989                                 # size in Bytes
4990                                 size=$((((j + $nstripe )*$stride + $offset)))
4991                                 ll_sparseness_write $myfn $size ||
4992                                         error "ll_sparseness_write"
4993                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4994                         done
4995                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4996                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4997                         rm -f $myfn
4998                 done
4999         done
5000 }
5001 run_test 44a "test sparse pwrite ==============================="
5002
5003 dirty_osc_total() {
5004         tot=0
5005         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5006                 tot=$(($tot + $d))
5007         done
5008         echo $tot
5009 }
5010 do_dirty_record() {
5011         before=`dirty_osc_total`
5012         echo executing "\"$*\""
5013         eval $*
5014         after=`dirty_osc_total`
5015         echo before $before, after $after
5016 }
5017 test_45() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f45"
5021         # Obtain grants from OST if it supports it
5022         echo blah > ${f}_grant
5023         stop_writeback
5024         sync
5025         do_dirty_record "echo blah > $f"
5026         [[ $before -eq $after ]] && error "write wasn't cached"
5027         do_dirty_record "> $f"
5028         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5029         do_dirty_record "echo blah > $f"
5030         [[ $before -eq $after ]] && error "write wasn't cached"
5031         do_dirty_record "sync"
5032         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5033         do_dirty_record "echo blah > $f"
5034         [[ $before -eq $after ]] && error "write wasn't cached"
5035         do_dirty_record "cancel_lru_locks osc"
5036         [[ $before -gt $after ]] ||
5037                 error "lock cancellation didn't lower dirty count"
5038         start_writeback
5039 }
5040 run_test 45 "osc io page accounting ============================"
5041
5042 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5043 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5044 # objects offset and an assert hit when an rpc was built with 1023's mapped
5045 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5046 test_46() {
5047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5048
5049         f="$DIR/f46"
5050         stop_writeback
5051         sync
5052         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5053         sync
5054         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5055         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5056         sync
5057         start_writeback
5058 }
5059 run_test 46 "dirtying a previously written page ================"
5060
5061 # test_47 is removed "Device nodes check" is moved to test_28
5062
5063 test_48a() { # bug 2399
5064         [ "$mds1_FSTYPE" = "zfs" ] &&
5065         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5066                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5067
5068         test_mkdir $DIR/$tdir
5069         cd $DIR/$tdir
5070         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5071         test_mkdir $DIR/$tdir
5072         touch foo || error "'touch foo' failed after recreating cwd"
5073         test_mkdir bar
5074         touch .foo || error "'touch .foo' failed after recreating cwd"
5075         test_mkdir .bar
5076         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5077         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5078         cd . || error "'cd .' failed after recreating cwd"
5079         mkdir . && error "'mkdir .' worked after recreating cwd"
5080         rmdir . && error "'rmdir .' worked after recreating cwd"
5081         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5082         cd .. || error "'cd ..' failed after recreating cwd"
5083 }
5084 run_test 48a "Access renamed working dir (should return errors)="
5085
5086 test_48b() { # bug 2399
5087         rm -rf $DIR/$tdir
5088         test_mkdir $DIR/$tdir
5089         cd $DIR/$tdir
5090         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5091         touch foo && error "'touch foo' worked after removing cwd"
5092         mkdir foo && error "'mkdir foo' worked after removing cwd"
5093         touch .foo && error "'touch .foo' worked after removing cwd"
5094         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5095         ls . > /dev/null && error "'ls .' worked after removing cwd"
5096         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5097         mkdir . && error "'mkdir .' worked after removing cwd"
5098         rmdir . && error "'rmdir .' worked after removing cwd"
5099         ln -s . foo && error "'ln -s .' worked after removing cwd"
5100         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5101 }
5102 run_test 48b "Access removed working dir (should return errors)="
5103
5104 test_48c() { # bug 2350
5105         #lctl set_param debug=-1
5106         #set -vx
5107         rm -rf $DIR/$tdir
5108         test_mkdir -p $DIR/$tdir/dir
5109         cd $DIR/$tdir/dir
5110         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5111         $TRACE touch foo && error "touch foo worked after removing cwd"
5112         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5113         touch .foo && error "touch .foo worked after removing cwd"
5114         mkdir .foo && error "mkdir .foo worked after removing cwd"
5115         $TRACE ls . && error "'ls .' worked after removing cwd"
5116         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5117         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5118         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5119         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5120         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5121 }
5122 run_test 48c "Access removed working subdir (should return errors)"
5123
5124 test_48d() { # bug 2350
5125         #lctl set_param debug=-1
5126         #set -vx
5127         rm -rf $DIR/$tdir
5128         test_mkdir -p $DIR/$tdir/dir
5129         cd $DIR/$tdir/dir
5130         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5131         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5132         $TRACE touch foo && error "'touch foo' worked after removing parent"
5133         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5134         touch .foo && error "'touch .foo' worked after removing parent"
5135         mkdir .foo && error "mkdir .foo worked after removing parent"
5136         $TRACE ls . && error "'ls .' worked after removing parent"
5137         $TRACE ls .. && error "'ls ..' worked after removing parent"
5138         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5139         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5140         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5141         true
5142 }
5143 run_test 48d "Access removed parent subdir (should return errors)"
5144
5145 test_48e() { # bug 4134
5146         #lctl set_param debug=-1
5147         #set -vx
5148         rm -rf $DIR/$tdir
5149         test_mkdir -p $DIR/$tdir/dir
5150         cd $DIR/$tdir/dir
5151         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5152         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5153         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5154         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5155         # On a buggy kernel addition of "touch foo" after cd .. will
5156         # produce kernel oops in lookup_hash_it
5157         touch ../foo && error "'cd ..' worked after recreate parent"
5158         cd $DIR
5159         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5160 }
5161 run_test 48e "Access to recreated parent subdir (should return errors)"
5162
5163 test_48f() {
5164         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5165                 skip "need MDS >= 2.13.55"
5166         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5167         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5168                 skip "needs different host for mdt1 mdt2"
5169         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5170
5171         $LFS mkdir -i0 $DIR/$tdir
5172         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5173
5174         for d in sub1 sub2 sub3; do
5175                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5176                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5177                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5178         done
5179
5180         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5181 }
5182 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5183
5184 test_49() { # LU-1030
5185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5186         remote_ost_nodsh && skip "remote OST with nodsh"
5187
5188         # get ost1 size - $FSNAME-OST0000
5189         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5190                 awk '{ print $4 }')
5191         # write 800M at maximum
5192         [[ $ost1_size -lt 2 ]] && ost1_size=2
5193         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5194
5195         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5196         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5197         local dd_pid=$!
5198
5199         # change max_pages_per_rpc while writing the file
5200         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5201         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5202         # loop until dd process exits
5203         while ps ax -opid | grep -wq $dd_pid; do
5204                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5205                 sleep $((RANDOM % 5 + 1))
5206         done
5207         # restore original max_pages_per_rpc
5208         $LCTL set_param $osc1_mppc=$orig_mppc
5209         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5210 }
5211 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5212
5213 test_50() {
5214         # bug 1485
5215         test_mkdir $DIR/$tdir
5216         cd $DIR/$tdir
5217         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5218 }
5219 run_test 50 "special situations: /proc symlinks  ==============="
5220
5221 test_51a() {    # was test_51
5222         # bug 1516 - create an empty entry right after ".." then split dir
5223         test_mkdir -c1 $DIR/$tdir
5224         touch $DIR/$tdir/foo
5225         $MCREATE $DIR/$tdir/bar
5226         rm $DIR/$tdir/foo
5227         createmany -m $DIR/$tdir/longfile 201
5228         FNUM=202
5229         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5230                 $MCREATE $DIR/$tdir/longfile$FNUM
5231                 FNUM=$(($FNUM + 1))
5232                 echo -n "+"
5233         done
5234         echo
5235         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5236 }
5237 run_test 51a "special situations: split htree with empty entry =="
5238
5239 cleanup_print_lfs_df () {
5240         trap 0
5241         $LFS df
5242         $LFS df -i
5243 }
5244
5245 test_51b() {
5246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5247
5248         local dir=$DIR/$tdir
5249         local nrdirs=$((65536 + 100))
5250
5251         # cleanup the directory
5252         rm -fr $dir
5253
5254         test_mkdir -c1 $dir
5255
5256         $LFS df
5257         $LFS df -i
5258         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5259         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5260         [[ $numfree -lt $nrdirs ]] &&
5261                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5262
5263         # need to check free space for the directories as well
5264         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5265         numfree=$(( blkfree / $(fs_inode_ksize) ))
5266         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5267
5268         trap cleanup_print_lfs_df EXIT
5269
5270         # create files
5271         createmany -d $dir/d $nrdirs || {
5272                 unlinkmany $dir/d $nrdirs
5273                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5274         }
5275
5276         # really created :
5277         nrdirs=$(ls -U $dir | wc -l)
5278
5279         # unlink all but 100 subdirectories, then check it still works
5280         local left=100
5281         local delete=$((nrdirs - left))
5282
5283         $LFS df
5284         $LFS df -i
5285
5286         # for ldiskfs the nlink count should be 1, but this is OSD specific
5287         # and so this is listed for informational purposes only
5288         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5289         unlinkmany -d $dir/d $delete ||
5290                 error "unlink of first $delete subdirs failed"
5291
5292         echo "nlink between: $(stat -c %h $dir)"
5293         local found=$(ls -U $dir | wc -l)
5294         [ $found -ne $left ] &&
5295                 error "can't find subdirs: found only $found, expected $left"
5296
5297         unlinkmany -d $dir/d $delete $left ||
5298                 error "unlink of second $left subdirs failed"
5299         # regardless of whether the backing filesystem tracks nlink accurately
5300         # or not, the nlink count shouldn't be more than "." and ".." here
5301         local after=$(stat -c %h $dir)
5302         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5303                 echo "nlink after: $after"
5304
5305         cleanup_print_lfs_df
5306 }
5307 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5308
5309 test_51d() {
5310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5311         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5312
5313         test_mkdir $DIR/$tdir
5314         createmany -o $DIR/$tdir/t- 1000
5315         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5316         for N in $(seq 0 $((OSTCOUNT - 1))); do
5317                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5318                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5319                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5320                         '($1 == '$N') { objs += 1 } \
5321                         END { printf("%0.0f", objs) }')
5322                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5323         done
5324         unlinkmany $DIR/$tdir/t- 1000
5325
5326         NLAST=0
5327         for N in $(seq 1 $((OSTCOUNT - 1))); do
5328                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5329                         error "OST $N has less objects vs OST $NLAST" \
5330                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5331                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5332                         error "OST $N has less objects vs OST $NLAST" \
5333                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5334
5335                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5336                         error "OST $N has less #0 objects vs OST $NLAST" \
5337                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5338                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5339                         error "OST $N has less #0 objects vs OST $NLAST" \
5340                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5341                 NLAST=$N
5342         done
5343         rm -f $TMP/$tfile
5344 }
5345 run_test 51d "check object distribution"
5346
5347 test_51e() {
5348         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5349                 skip_env "ldiskfs only test"
5350         fi
5351
5352         test_mkdir -c1 $DIR/$tdir
5353         test_mkdir -c1 $DIR/$tdir/d0
5354
5355         touch $DIR/$tdir/d0/foo
5356         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5357                 error "file exceed 65000 nlink limit!"
5358         unlinkmany $DIR/$tdir/d0/f- 65001
5359         return 0
5360 }
5361 run_test 51e "check file nlink limit"
5362
5363 test_51f() {
5364         test_mkdir $DIR/$tdir
5365
5366         local max=100000
5367         local ulimit_old=$(ulimit -n)
5368         local spare=20 # number of spare fd's for scripts/libraries, etc.
5369         local mdt=$($LFS getstripe -m $DIR/$tdir)
5370         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5371
5372         echo "MDT$mdt numfree=$numfree, max=$max"
5373         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5374         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5375                 while ! ulimit -n $((numfree + spare)); do
5376                         numfree=$((numfree * 3 / 4))
5377                 done
5378                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5379         else
5380                 echo "left ulimit at $ulimit_old"
5381         fi
5382
5383         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5384                 unlinkmany $DIR/$tdir/f $numfree
5385                 error "create+open $numfree files in $DIR/$tdir failed"
5386         }
5387         ulimit -n $ulimit_old
5388
5389         # if createmany exits at 120s there will be fewer than $numfree files
5390         unlinkmany $DIR/$tdir/f $numfree || true
5391 }
5392 run_test 51f "check many open files limit"
5393
5394 test_52a() {
5395         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5396         test_mkdir $DIR/$tdir
5397         touch $DIR/$tdir/foo
5398         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5399         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5400         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5401         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5402         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5403                                         error "link worked"
5404         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5405         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5406         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5407                                                      error "lsattr"
5408         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5409         cp -r $DIR/$tdir $TMP/
5410         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5411 }
5412 run_test 52a "append-only flag test (should return errors)"
5413
5414 test_52b() {
5415         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5416         test_mkdir $DIR/$tdir
5417         touch $DIR/$tdir/foo
5418         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5419         cat test > $DIR/$tdir/foo && error "cat test worked"
5420         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5421         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5422         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5423                                         error "link worked"
5424         echo foo >> $DIR/$tdir/foo && error "echo worked"
5425         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5426         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5427         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5428         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5429                                                         error "lsattr"
5430         chattr -i $DIR/$tdir/foo || error "chattr failed"
5431
5432         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5433 }
5434 run_test 52b "immutable flag test (should return errors) ======="
5435
5436 test_53() {
5437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5438         remote_mds_nodsh && skip "remote MDS with nodsh"
5439         remote_ost_nodsh && skip "remote OST with nodsh"
5440
5441         local param
5442         local param_seq
5443         local ostname
5444         local mds_last
5445         local mds_last_seq
5446         local ost_last
5447         local ost_last_seq
5448         local ost_last_id
5449         local ostnum
5450         local node
5451         local found=false
5452         local support_last_seq=true
5453
5454         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5455                 support_last_seq=false
5456
5457         # only test MDT0000
5458         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5459         local value
5460         for value in $(do_facet $SINGLEMDS \
5461                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5462                 param=$(echo ${value[0]} | cut -d "=" -f1)
5463                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5464
5465                 if $support_last_seq; then
5466                         param_seq=$(echo $param |
5467                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5468                         mds_last_seq=$(do_facet $SINGLEMDS \
5469                                        $LCTL get_param -n $param_seq)
5470                 fi
5471                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5472
5473                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5474                 node=$(facet_active_host ost$((ostnum+1)))
5475                 param="obdfilter.$ostname.last_id"
5476                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5477                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5478                         ost_last_id=$ost_last
5479
5480                         if $support_last_seq; then
5481                                 ost_last_id=$(echo $ost_last |
5482                                               awk -F':' '{print $2}' |
5483                                               sed -e "s/^0x//g")
5484                                 ost_last_seq=$(echo $ost_last |
5485                                                awk -F':' '{print $1}')
5486                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5487                         fi
5488
5489                         if [[ $ost_last_id != $mds_last ]]; then
5490                                 error "$ost_last_id != $mds_last"
5491                         else
5492                                 found=true
5493                                 break
5494                         fi
5495                 done
5496         done
5497         $found || error "can not match last_seq/last_id for $mdtosc"
5498         return 0
5499 }
5500 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5501
5502 test_54a() {
5503         perl -MSocket -e ';' || skip "no Socket perl module installed"
5504
5505         $SOCKETSERVER $DIR/socket ||
5506                 error "$SOCKETSERVER $DIR/socket failed: $?"
5507         $SOCKETCLIENT $DIR/socket ||
5508                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5509         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5510 }
5511 run_test 54a "unix domain socket test =========================="
5512
5513 test_54b() {
5514         f="$DIR/f54b"
5515         mknod $f c 1 3
5516         chmod 0666 $f
5517         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5518 }
5519 run_test 54b "char device works in lustre ======================"
5520
5521 find_loop_dev() {
5522         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5523         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5524         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5525
5526         for i in $(seq 3 7); do
5527                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5528                 LOOPDEV=$LOOPBASE$i
5529                 LOOPNUM=$i
5530                 break
5531         done
5532 }
5533
5534 cleanup_54c() {
5535         local rc=0
5536         loopdev="$DIR/loop54c"
5537
5538         trap 0
5539         $UMOUNT $DIR/$tdir || rc=$?
5540         losetup -d $loopdev || true
5541         losetup -d $LOOPDEV || true
5542         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5543         return $rc
5544 }
5545
5546 test_54c() {
5547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5548
5549         loopdev="$DIR/loop54c"
5550
5551         find_loop_dev
5552         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5553         trap cleanup_54c EXIT
5554         mknod $loopdev b 7 $LOOPNUM
5555         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5556         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5557         losetup $loopdev $DIR/$tfile ||
5558                 error "can't set up $loopdev for $DIR/$tfile"
5559         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5560         test_mkdir $DIR/$tdir
5561         mount -t ext2 $loopdev $DIR/$tdir ||
5562                 error "error mounting $loopdev on $DIR/$tdir"
5563         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5564                 error "dd write"
5565         df $DIR/$tdir
5566         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5567                 error "dd read"
5568         cleanup_54c
5569 }
5570 run_test 54c "block device works in lustre ====================="
5571
5572 test_54d() {
5573         f="$DIR/f54d"
5574         string="aaaaaa"
5575         mknod $f p
5576         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5577 }
5578 run_test 54d "fifo device works in lustre ======================"
5579
5580 test_54e() {
5581         f="$DIR/f54e"
5582         string="aaaaaa"
5583         cp -aL /dev/console $f
5584         echo $string > $f || error "echo $string to $f failed"
5585 }
5586 run_test 54e "console/tty device works in lustre ======================"
5587
5588 test_56a() {
5589         local numfiles=3
5590         local dir=$DIR/$tdir
5591
5592         rm -rf $dir
5593         test_mkdir -p $dir/dir
5594         for i in $(seq $numfiles); do
5595                 touch $dir/file$i
5596                 touch $dir/dir/file$i
5597         done
5598
5599         local numcomp=$($LFS getstripe --component-count $dir)
5600
5601         [[ $numcomp == 0 ]] && numcomp=1
5602
5603         # test lfs getstripe with --recursive
5604         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5605
5606         [[ $filenum -eq $((numfiles * 2)) ]] ||
5607                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5608         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5609         [[ $filenum -eq $numfiles ]] ||
5610                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5611         echo "$LFS getstripe showed obdidx or l_ost_idx"
5612
5613         # test lfs getstripe with file instead of dir
5614         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5615         [[ $filenum -eq 1 ]] ||
5616                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5617         echo "$LFS getstripe file1 passed"
5618
5619         #test lfs getstripe with --verbose
5620         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5621         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5622                 error "$LFS getstripe --verbose $dir: "\
5623                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5624         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5625                 error "$LFS getstripe $dir: showed lmm_magic"
5626
5627         #test lfs getstripe with -v prints lmm_fid
5628         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5629         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5630                 error "$LFS getstripe -v $dir: "\
5631                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5632         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5633                 error "$LFS getstripe $dir: showed lmm_fid by default"
5634         echo "$LFS getstripe --verbose passed"
5635
5636         #check for FID information
5637         local fid1=$($LFS getstripe --fid $dir/file1)
5638         local fid2=$($LFS getstripe --verbose $dir/file1 |
5639                      awk '/lmm_fid: / { print $2; exit; }')
5640         local fid3=$($LFS path2fid $dir/file1)
5641
5642         [ "$fid1" != "$fid2" ] &&
5643                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5644         [ "$fid1" != "$fid3" ] &&
5645                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5646         echo "$LFS getstripe --fid passed"
5647
5648         #test lfs getstripe with --obd
5649         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5650                 error "$LFS getstripe --obd wrong_uuid: should return error"
5651
5652         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5653
5654         local ostidx=1
5655         local obduuid=$(ostuuid_from_index $ostidx)
5656         local found=$($LFS getstripe -r --obd $obduuid $dir |
5657                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5658
5659         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5660         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5661                 ((filenum--))
5662         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5663                 ((filenum--))
5664
5665         [[ $found -eq $filenum ]] ||
5666                 error "$LFS getstripe --obd: found $found expect $filenum"
5667         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5668                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5669                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5670                 error "$LFS getstripe --obd: should not show file on other obd"
5671         echo "$LFS getstripe --obd passed"
5672 }
5673 run_test 56a "check $LFS getstripe"
5674
5675 test_56b() {
5676         local dir=$DIR/$tdir
5677         local numdirs=3
5678
5679         test_mkdir $dir
5680         for i in $(seq $numdirs); do
5681                 test_mkdir $dir/dir$i
5682         done
5683
5684         # test lfs getdirstripe default mode is non-recursion, which is
5685         # different from lfs getstripe
5686         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5687
5688         [[ $dircnt -eq 1 ]] ||
5689                 error "$LFS getdirstripe: found $dircnt, not 1"
5690         dircnt=$($LFS getdirstripe --recursive $dir |
5691                 grep -c lmv_stripe_count)
5692         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5693                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5694 }
5695 run_test 56b "check $LFS getdirstripe"
5696
5697 test_56c() {
5698         remote_ost_nodsh && skip "remote OST with nodsh"
5699
5700         local ost_idx=0
5701         local ost_name=$(ostname_from_index $ost_idx)
5702         local old_status=$(ost_dev_status $ost_idx)
5703         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5704
5705         [[ -z "$old_status" ]] ||
5706                 skip_env "OST $ost_name is in $old_status status"
5707
5708         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5709         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5710                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5711         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5712                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5713                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5714         fi
5715
5716         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5717                 error "$LFS df -v showing inactive devices"
5718         sleep_maxage
5719
5720         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5721
5722         [[ "$new_status" =~ "D" ]] ||
5723                 error "$ost_name status is '$new_status', missing 'D'"
5724         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5725                 [[ "$new_status" =~ "N" ]] ||
5726                         error "$ost_name status is '$new_status', missing 'N'"
5727         fi
5728         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5729                 [[ "$new_status" =~ "f" ]] ||
5730                         error "$ost_name status is '$new_status', missing 'f'"
5731         fi
5732
5733         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5734         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5735                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5736         [[ -z "$p" ]] && restore_lustre_params < $p || true
5737         sleep_maxage
5738
5739         new_status=$(ost_dev_status $ost_idx)
5740         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5741                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5742         # can't check 'f' as devices may actually be on flash
5743 }
5744 run_test 56c "check 'lfs df' showing device status"
5745
5746 test_56d() {
5747         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5748         local osts=$($LFS df -v $MOUNT | grep -c OST)
5749
5750         $LFS df $MOUNT
5751
5752         (( mdts == MDSCOUNT )) ||
5753                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5754         (( osts == OSTCOUNT )) ||
5755                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5756 }
5757 run_test 56d "'lfs df -v' prints only configured devices"
5758
5759 NUMFILES=3
5760 NUMDIRS=3
5761 setup_56() {
5762         local local_tdir="$1"
5763         local local_numfiles="$2"
5764         local local_numdirs="$3"
5765         local dir_params="$4"
5766         local dir_stripe_params="$5"
5767
5768         if [ ! -d "$local_tdir" ] ; then
5769                 test_mkdir -p $dir_stripe_params $local_tdir
5770                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5771                 for i in $(seq $local_numfiles) ; do
5772                         touch $local_tdir/file$i
5773                 done
5774                 for i in $(seq $local_numdirs) ; do
5775                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5776                         for j in $(seq $local_numfiles) ; do
5777                                 touch $local_tdir/dir$i/file$j
5778                         done
5779                 done
5780         fi
5781 }
5782
5783 setup_56_special() {
5784         local local_tdir=$1
5785         local local_numfiles=$2
5786         local local_numdirs=$3
5787
5788         setup_56 $local_tdir $local_numfiles $local_numdirs
5789
5790         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5791                 for i in $(seq $local_numfiles) ; do
5792                         mknod $local_tdir/loop${i}b b 7 $i
5793                         mknod $local_tdir/null${i}c c 1 3
5794                         ln -s $local_tdir/file1 $local_tdir/link${i}
5795                 done
5796                 for i in $(seq $local_numdirs) ; do
5797                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5798                         mknod $local_tdir/dir$i/null${i}c c 1 3
5799                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5800                 done
5801         fi
5802 }
5803
5804 test_56g() {
5805         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5806         local expected=$(($NUMDIRS + 2))
5807
5808         setup_56 $dir $NUMFILES $NUMDIRS
5809
5810         # test lfs find with -name
5811         for i in $(seq $NUMFILES) ; do
5812                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5813
5814                 [ $nums -eq $expected ] ||
5815                         error "lfs find -name '*$i' $dir wrong: "\
5816                               "found $nums, expected $expected"
5817         done
5818 }
5819 run_test 56g "check lfs find -name"
5820
5821 test_56h() {
5822         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5823         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5824
5825         setup_56 $dir $NUMFILES $NUMDIRS
5826
5827         # test lfs find with ! -name
5828         for i in $(seq $NUMFILES) ; do
5829                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5830
5831                 [ $nums -eq $expected ] ||
5832                         error "lfs find ! -name '*$i' $dir wrong: "\
5833                               "found $nums, expected $expected"
5834         done
5835 }
5836 run_test 56h "check lfs find ! -name"
5837
5838 test_56i() {
5839         local dir=$DIR/$tdir
5840
5841         test_mkdir $dir
5842
5843         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5844         local out=$($cmd)
5845
5846         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5847 }
5848 run_test 56i "check 'lfs find -ost UUID' skips directories"
5849
5850 test_56j() {
5851         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5852
5853         setup_56_special $dir $NUMFILES $NUMDIRS
5854
5855         local expected=$((NUMDIRS + 1))
5856         local cmd="$LFS find -type d $dir"
5857         local nums=$($cmd | wc -l)
5858
5859         [ $nums -eq $expected ] ||
5860                 error "'$cmd' wrong: found $nums, expected $expected"
5861 }
5862 run_test 56j "check lfs find -type d"
5863
5864 test_56k() {
5865         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5866
5867         setup_56_special $dir $NUMFILES $NUMDIRS
5868
5869         local expected=$(((NUMDIRS + 1) * NUMFILES))
5870         local cmd="$LFS find -type f $dir"
5871         local nums=$($cmd | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "'$cmd' wrong: found $nums, expected $expected"
5875 }
5876 run_test 56k "check lfs find -type f"
5877
5878 test_56l() {
5879         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5880
5881         setup_56_special $dir $NUMFILES $NUMDIRS
5882
5883         local expected=$((NUMDIRS + NUMFILES))
5884         local cmd="$LFS find -type b $dir"
5885         local nums=$($cmd | wc -l)
5886
5887         [ $nums -eq $expected ] ||
5888                 error "'$cmd' wrong: found $nums, expected $expected"
5889 }
5890 run_test 56l "check lfs find -type b"
5891
5892 test_56m() {
5893         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5894
5895         setup_56_special $dir $NUMFILES $NUMDIRS
5896
5897         local expected=$((NUMDIRS + NUMFILES))
5898         local cmd="$LFS find -type c $dir"
5899         local nums=$($cmd | wc -l)
5900         [ $nums -eq $expected ] ||
5901                 error "'$cmd' wrong: found $nums, expected $expected"
5902 }
5903 run_test 56m "check lfs find -type c"
5904
5905 test_56n() {
5906         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5907         setup_56_special $dir $NUMFILES $NUMDIRS
5908
5909         local expected=$((NUMDIRS + NUMFILES))
5910         local cmd="$LFS find -type l $dir"
5911         local nums=$($cmd | wc -l)
5912
5913         [ $nums -eq $expected ] ||
5914                 error "'$cmd' wrong: found $nums, expected $expected"
5915 }
5916 run_test 56n "check lfs find -type l"
5917
5918 test_56o() {
5919         local dir=$DIR/$tdir
5920
5921         setup_56 $dir $NUMFILES $NUMDIRS
5922         utime $dir/file1 > /dev/null || error "utime (1)"
5923         utime $dir/file2 > /dev/null || error "utime (2)"
5924         utime $dir/dir1 > /dev/null || error "utime (3)"
5925         utime $dir/dir2 > /dev/null || error "utime (4)"
5926         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5927         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5928
5929         local expected=4
5930         local nums=$($LFS find -mtime +0 $dir | wc -l)
5931
5932         [ $nums -eq $expected ] ||
5933                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5934
5935         expected=12
5936         cmd="$LFS find -mtime 0 $dir"
5937         nums=$($cmd | wc -l)
5938         [ $nums -eq $expected ] ||
5939                 error "'$cmd' wrong: found $nums, expected $expected"
5940 }
5941 run_test 56o "check lfs find -mtime for old files"
5942
5943 test_56ob() {
5944         local dir=$DIR/$tdir
5945         local expected=1
5946         local count=0
5947
5948         # just to make sure there is something that won't be found
5949         test_mkdir $dir
5950         touch $dir/$tfile.now
5951
5952         for age in year week day hour min; do
5953                 count=$((count + 1))
5954
5955                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5956                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5957                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5958
5959                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5960                 local nums=$($cmd | wc -l)
5961                 [ $nums -eq $expected ] ||
5962                         error "'$cmd' wrong: found $nums, expected $expected"
5963
5964                 cmd="$LFS find $dir -atime $count${age:0:1}"
5965                 nums=$($cmd | wc -l)
5966                 [ $nums -eq $expected ] ||
5967                         error "'$cmd' wrong: found $nums, expected $expected"
5968         done
5969
5970         sleep 2
5971         cmd="$LFS find $dir -ctime +1s -type f"
5972         nums=$($cmd | wc -l)
5973         (( $nums == $count * 2 + 1)) ||
5974                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5975 }
5976 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5977
5978 test_newerXY_base() {
5979         local x=$1
5980         local y=$2
5981         local dir=$DIR/$tdir
5982         local ref
5983         local negref
5984
5985         if [ $y == "t" ]; then
5986                 if [ $x == "b" ]; then
5987                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5988                 else
5989                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5990                 fi
5991         else
5992                 ref=$DIR/$tfile.newer.$x$y
5993                 touch $ref || error "touch $ref failed"
5994         fi
5995
5996         echo "before = $ref"
5997         sleep 2
5998         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5999         sleep 2
6000         if [ $y == "t" ]; then
6001                 if [ $x == "b" ]; then
6002                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6003                 else
6004                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6005                 fi
6006         else
6007                 negref=$DIR/$tfile.negnewer.$x$y
6008                 touch $negref || error "touch $negref failed"
6009         fi
6010
6011         echo "after = $negref"
6012         local cmd="$LFS find $dir -newer$x$y $ref"
6013         local nums=$(eval $cmd | wc -l)
6014         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6015
6016         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6017                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6018
6019         cmd="$LFS find $dir ! -newer$x$y $negref"
6020         nums=$(eval $cmd | wc -l)
6021         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6022                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6023
6024         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6025         nums=$(eval $cmd | wc -l)
6026         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6027                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6028
6029         rm -rf $DIR/*
6030 }
6031
6032 test_56oc() {
6033         test_newerXY_base "a" "a"
6034         test_newerXY_base "a" "m"
6035         test_newerXY_base "a" "c"
6036         test_newerXY_base "m" "a"
6037         test_newerXY_base "m" "m"
6038         test_newerXY_base "m" "c"
6039         test_newerXY_base "c" "a"
6040         test_newerXY_base "c" "m"
6041         test_newerXY_base "c" "c"
6042
6043         [[ -n "$sles_version" ]] &&
6044                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6045
6046         test_newerXY_base "a" "t"
6047         test_newerXY_base "m" "t"
6048         test_newerXY_base "c" "t"
6049
6050         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6051            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6052                 ! btime_supported && echo "btime unsupported" && return 0
6053
6054         test_newerXY_base "b" "b"
6055         test_newerXY_base "b" "t"
6056 }
6057 run_test 56oc "check lfs find -newerXY work"
6058
6059 btime_supported() {
6060         local dir=$DIR/$tdir
6061         local rc
6062
6063         mkdir -p $dir
6064         touch $dir/$tfile
6065         $LFS find $dir -btime -1d -type f
6066         rc=$?
6067         rm -rf $dir
6068         return $rc
6069 }
6070
6071 test_56od() {
6072         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6073                 ! btime_supported && skip "btime unsupported on MDS"
6074
6075         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6076                 ! btime_supported && skip "btime unsupported on clients"
6077
6078         local dir=$DIR/$tdir
6079         local ref=$DIR/$tfile.ref
6080         local negref=$DIR/$tfile.negref
6081
6082         mkdir $dir || error "mkdir $dir failed"
6083         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6084         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6085         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6086         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6087         touch $ref || error "touch $ref failed"
6088         # sleep 3 seconds at least
6089         sleep 3
6090
6091         local before=$(do_facet mds1 date +%s)
6092         local skew=$(($(date +%s) - before + 1))
6093
6094         if (( skew < 0 && skew > -5 )); then
6095                 sleep $((0 - skew + 1))
6096                 skew=0
6097         fi
6098
6099         # Set the dir stripe params to limit files all on MDT0,
6100         # otherwise we need to calc the max clock skew between
6101         # the client and MDTs.
6102         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6103         sleep 2
6104         touch $negref || error "touch $negref failed"
6105
6106         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6107         local nums=$($cmd | wc -l)
6108         local expected=$(((NUMFILES + 1) * NUMDIRS))
6109
6110         [ $nums -eq $expected ] ||
6111                 error "'$cmd' wrong: found $nums, expected $expected"
6112
6113         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6114         nums=$($cmd | wc -l)
6115         expected=$((NUMFILES + 1))
6116         [ $nums -eq $expected ] ||
6117                 error "'$cmd' wrong: found $nums, expected $expected"
6118
6119         [ $skew -lt 0 ] && return
6120
6121         local after=$(do_facet mds1 date +%s)
6122         local age=$((after - before + 1 + skew))
6123
6124         cmd="$LFS find $dir -btime -${age}s -type f"
6125         nums=$($cmd | wc -l)
6126         expected=$(((NUMFILES + 1) * NUMDIRS))
6127
6128         echo "Clock skew between client and server: $skew, age:$age"
6129         [ $nums -eq $expected ] ||
6130                 error "'$cmd' wrong: found $nums, expected $expected"
6131
6132         expected=$(($NUMDIRS + 1))
6133         cmd="$LFS find $dir -btime -${age}s -type d"
6134         nums=$($cmd | wc -l)
6135         [ $nums -eq $expected ] ||
6136                 error "'$cmd' wrong: found $nums, expected $expected"
6137         rm -f $ref $negref || error "Failed to remove $ref $negref"
6138 }
6139 run_test 56od "check lfs find -btime with units"
6140
6141 test_56p() {
6142         [ $RUNAS_ID -eq $UID ] &&
6143                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6144
6145         local dir=$DIR/$tdir
6146
6147         setup_56 $dir $NUMFILES $NUMDIRS
6148         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6149
6150         local expected=$NUMFILES
6151         local cmd="$LFS find -uid $RUNAS_ID $dir"
6152         local nums=$($cmd | wc -l)
6153
6154         [ $nums -eq $expected ] ||
6155                 error "'$cmd' wrong: found $nums, expected $expected"
6156
6157         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6158         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6159         nums=$($cmd | wc -l)
6160         [ $nums -eq $expected ] ||
6161                 error "'$cmd' wrong: found $nums, expected $expected"
6162 }
6163 run_test 56p "check lfs find -uid and ! -uid"
6164
6165 test_56q() {
6166         [ $RUNAS_ID -eq $UID ] &&
6167                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6168
6169         local dir=$DIR/$tdir
6170
6171         setup_56 $dir $NUMFILES $NUMDIRS
6172         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6173
6174         local expected=$NUMFILES
6175         local cmd="$LFS find -gid $RUNAS_GID $dir"
6176         local nums=$($cmd | wc -l)
6177
6178         [ $nums -eq $expected ] ||
6179                 error "'$cmd' wrong: found $nums, expected $expected"
6180
6181         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6182         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186 }
6187 run_test 56q "check lfs find -gid and ! -gid"
6188
6189 test_56r() {
6190         local dir=$DIR/$tdir
6191
6192         setup_56 $dir $NUMFILES $NUMDIRS
6193
6194         local expected=12
6195         local cmd="$LFS find -size 0 -type f -lazy $dir"
6196         local nums=$($cmd | wc -l)
6197
6198         [ $nums -eq $expected ] ||
6199                 error "'$cmd' wrong: found $nums, expected $expected"
6200         cmd="$LFS find -size 0 -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 ! -size 0 -type f -lazy $dir"
6207         nums=$($cmd | wc -l)
6208         [ $nums -eq $expected ] ||
6209                 error "'$cmd' wrong: found $nums, expected $expected"
6210         cmd="$LFS find ! -size 0 -type f $dir"
6211         nums=$($cmd | wc -l)
6212         [ $nums -eq $expected ] ||
6213                 error "'$cmd' wrong: found $nums, expected $expected"
6214
6215         echo "test" > $dir/$tfile
6216         echo "test2" > $dir/$tfile.2 && sync
6217         expected=1
6218         cmd="$LFS find -size 5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size 5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226
6227         expected=1
6228         cmd="$LFS find -size +5 -type f -lazy $dir"
6229         nums=$($cmd | wc -l)
6230         [ $nums -eq $expected ] ||
6231                 error "'$cmd' wrong: found $nums, expected $expected"
6232         cmd="$LFS find -size +5 -type f $dir"
6233         nums=$($cmd | wc -l)
6234         [ $nums -eq $expected ] ||
6235                 error "'$cmd' wrong: found $nums, expected $expected"
6236
6237         expected=2
6238         cmd="$LFS find -size +0 -type f -lazy $dir"
6239         nums=$($cmd | wc -l)
6240         [ $nums -eq $expected ] ||
6241                 error "'$cmd' wrong: found $nums, expected $expected"
6242         cmd="$LFS find -size +0 -type f $dir"
6243         nums=$($cmd | wc -l)
6244         [ $nums -eq $expected ] ||
6245                 error "'$cmd' wrong: found $nums, expected $expected"
6246
6247         expected=2
6248         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6249         nums=$($cmd | wc -l)
6250         [ $nums -eq $expected ] ||
6251                 error "'$cmd' wrong: found $nums, expected $expected"
6252         cmd="$LFS find ! -size -5 -type f $dir"
6253         nums=$($cmd | wc -l)
6254         [ $nums -eq $expected ] ||
6255                 error "'$cmd' wrong: found $nums, expected $expected"
6256
6257         expected=12
6258         cmd="$LFS find -size -5 -type f -lazy $dir"
6259         nums=$($cmd | wc -l)
6260         [ $nums -eq $expected ] ||
6261                 error "'$cmd' wrong: found $nums, expected $expected"
6262         cmd="$LFS find -size -5 -type f $dir"
6263         nums=$($cmd | wc -l)
6264         [ $nums -eq $expected ] ||
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266 }
6267 run_test 56r "check lfs find -size works"
6268
6269 test_56ra_sub() {
6270         local expected=$1
6271         local glimpses=$2
6272         local cmd="$3"
6273
6274         cancel_lru_locks $OSC
6275
6276         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6277         local nums=$($cmd | wc -l)
6278
6279         [ $nums -eq $expected ] ||
6280                 error "'$cmd' wrong: found $nums, expected $expected"
6281
6282         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6283
6284         if (( rpcs_before + glimpses != rpcs_after )); then
6285                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6286                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6287
6288                 if [[ $glimpses == 0 ]]; then
6289                         error "'$cmd' should not send glimpse RPCs to OST"
6290                 else
6291                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6292                 fi
6293         fi
6294 }
6295
6296 test_56ra() {
6297         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6298                 skip "MDS < 2.12.58 doesn't return LSOM data"
6299         local dir=$DIR/$tdir
6300         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6301
6302         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6303
6304         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6305         $LCTL set_param -n llite.*.statahead_agl=0
6306         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6307
6308         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6309         # open and close all files to ensure LSOM is updated
6310         cancel_lru_locks $OSC
6311         find $dir -type f | xargs cat > /dev/null
6312
6313         #   expect_found  glimpse_rpcs  command_to_run
6314         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6315         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6316         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6317         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6318
6319         echo "test" > $dir/$tfile
6320         echo "test2" > $dir/$tfile.2 && sync
6321         cancel_lru_locks $OSC
6322         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6323
6324         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6325         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6326         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6327         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6328
6329         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6330         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6331         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6332         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6333         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6334         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6335 }
6336 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6337
6338 test_56rb() {
6339         local dir=$DIR/$tdir
6340         local tmp=$TMP/$tfile.log
6341         local mdt_idx;
6342
6343         test_mkdir -p $dir || error "failed to mkdir $dir"
6344         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6345                 error "failed to setstripe $dir/$tfile"
6346         mdt_idx=$($LFS getdirstripe -i $dir)
6347         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6348
6349         stack_trap "rm -f $tmp" EXIT
6350         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6351         ! grep -q obd_uuid $tmp ||
6352                 error "failed to find --size +100K --ost 0 $dir"
6353         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6354         ! grep -q obd_uuid $tmp ||
6355                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6356 }
6357 run_test 56rb "check lfs find --size --ost/--mdt works"
6358
6359 test_56s() { # LU-611 #LU-9369
6360         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6361
6362         local dir=$DIR/$tdir
6363         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6364
6365         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6366         for i in $(seq $NUMDIRS); do
6367                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6368         done
6369
6370         local expected=$NUMDIRS
6371         local cmd="$LFS find -c $OSTCOUNT $dir"
6372         local nums=$($cmd | wc -l)
6373
6374         [ $nums -eq $expected ] || {
6375                 $LFS getstripe -R $dir
6376                 error "'$cmd' wrong: found $nums, expected $expected"
6377         }
6378
6379         expected=$((NUMDIRS + onestripe))
6380         cmd="$LFS find -stripe-count +0 -type f $dir"
6381         nums=$($cmd | wc -l)
6382         [ $nums -eq $expected ] || {
6383                 $LFS getstripe -R $dir
6384                 error "'$cmd' wrong: found $nums, expected $expected"
6385         }
6386
6387         expected=$onestripe
6388         cmd="$LFS find -stripe-count 1 -type f $dir"
6389         nums=$($cmd | wc -l)
6390         [ $nums -eq $expected ] || {
6391                 $LFS getstripe -R $dir
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393         }
6394
6395         cmd="$LFS find -stripe-count -2 -type f $dir"
6396         nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] || {
6398                 $LFS getstripe -R $dir
6399                 error "'$cmd' wrong: found $nums, expected $expected"
6400         }
6401
6402         expected=0
6403         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6404         nums=$($cmd | wc -l)
6405         [ $nums -eq $expected ] || {
6406                 $LFS getstripe -R $dir
6407                 error "'$cmd' wrong: found $nums, expected $expected"
6408         }
6409 }
6410 run_test 56s "check lfs find -stripe-count works"
6411
6412 test_56t() { # LU-611 #LU-9369
6413         local dir=$DIR/$tdir
6414
6415         setup_56 $dir 0 $NUMDIRS
6416         for i in $(seq $NUMDIRS); do
6417                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6418         done
6419
6420         local expected=$NUMDIRS
6421         local cmd="$LFS find -S 8M $dir"
6422         local nums=$($cmd | wc -l)
6423
6424         [ $nums -eq $expected ] || {
6425                 $LFS getstripe -R $dir
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427         }
6428         rm -rf $dir
6429
6430         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6431
6432         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6433
6434         expected=$(((NUMDIRS + 1) * NUMFILES))
6435         cmd="$LFS find -stripe-size 512k -type f $dir"
6436         nums=$($cmd | wc -l)
6437         [ $nums -eq $expected ] ||
6438                 error "'$cmd' wrong: found $nums, expected $expected"
6439
6440         cmd="$LFS find -stripe-size +320k -type f $dir"
6441         nums=$($cmd | wc -l)
6442         [ $nums -eq $expected ] ||
6443                 error "'$cmd' wrong: found $nums, expected $expected"
6444
6445         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6446         cmd="$LFS find -stripe-size +200k -type f $dir"
6447         nums=$($cmd | wc -l)
6448         [ $nums -eq $expected ] ||
6449                 error "'$cmd' wrong: found $nums, expected $expected"
6450
6451         cmd="$LFS find -stripe-size -640k -type f $dir"
6452         nums=$($cmd | wc -l)
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         expected=4
6457         cmd="$LFS find -stripe-size 256k -type f $dir"
6458         nums=$($cmd | wc -l)
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461
6462         cmd="$LFS find -stripe-size -320k -type f $dir"
6463         nums=$($cmd | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         expected=0
6468         cmd="$LFS find -stripe-size 1024k -type f $dir"
6469         nums=$($cmd | wc -l)
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472 }
6473 run_test 56t "check lfs find -stripe-size works"
6474
6475 test_56u() { # LU-611
6476         local dir=$DIR/$tdir
6477
6478         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6479
6480         if [[ $OSTCOUNT -gt 1 ]]; then
6481                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6482                 onestripe=4
6483         else
6484                 onestripe=0
6485         fi
6486
6487         local expected=$(((NUMDIRS + 1) * NUMFILES))
6488         local cmd="$LFS find -stripe-index 0 -type f $dir"
6489         local nums=$($cmd | wc -l)
6490
6491         [ $nums -eq $expected ] ||
6492                 error "'$cmd' wrong: found $nums, expected $expected"
6493
6494         expected=$onestripe
6495         cmd="$LFS find -stripe-index 1 -type f $dir"
6496         nums=$($cmd | wc -l)
6497         [ $nums -eq $expected ] ||
6498                 error "'$cmd' wrong: found $nums, expected $expected"
6499
6500         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6501         nums=$($cmd | wc -l)
6502         [ $nums -eq $expected ] ||
6503                 error "'$cmd' wrong: found $nums, expected $expected"
6504
6505         expected=0
6506         # This should produce an error and not return any files
6507         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6508         nums=$($cmd 2>/dev/null | wc -l)
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511
6512         if [[ $OSTCOUNT -gt 1 ]]; then
6513                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6514                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6515                 nums=$($cmd | wc -l)
6516                 [ $nums -eq $expected ] ||
6517                         error "'$cmd' wrong: found $nums, expected $expected"
6518         fi
6519 }
6520 run_test 56u "check lfs find -stripe-index works"
6521
6522 test_56v() {
6523         local mdt_idx=0
6524         local dir=$DIR/$tdir
6525
6526         setup_56 $dir $NUMFILES $NUMDIRS
6527
6528         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6529         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6530
6531         for file in $($LFS find -m $UUID $dir); do
6532                 file_midx=$($LFS getstripe -m $file)
6533                 [ $file_midx -eq $mdt_idx ] ||
6534                         error "lfs find -m $UUID != getstripe -m $file_midx"
6535         done
6536 }
6537 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6538
6539 test_56w() {
6540         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6542
6543         local dir=$DIR/$tdir
6544
6545         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6546
6547         local stripe_size=$($LFS getstripe -S -d $dir) ||
6548                 error "$LFS getstripe -S -d $dir failed"
6549         stripe_size=${stripe_size%% *}
6550
6551         local file_size=$((stripe_size * OSTCOUNT))
6552         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6553         local required_space=$((file_num * file_size))
6554         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6555                            head -n1)
6556         [[ $free_space -le $((required_space / 1024)) ]] &&
6557                 skip_env "need $required_space, have $free_space kbytes"
6558
6559         local dd_bs=65536
6560         local dd_count=$((file_size / dd_bs))
6561
6562         # write data into the files
6563         local i
6564         local j
6565         local file
6566
6567         for i in $(seq $NUMFILES); do
6568                 file=$dir/file$i
6569                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6570                         error "write data into $file failed"
6571         done
6572         for i in $(seq $NUMDIRS); do
6573                 for j in $(seq $NUMFILES); do
6574                         file=$dir/dir$i/file$j
6575                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6576                                 error "write data into $file failed"
6577                 done
6578         done
6579
6580         # $LFS_MIGRATE will fail if hard link migration is unsupported
6581         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6582                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6583                         error "creating links to $dir/dir1/file1 failed"
6584         fi
6585
6586         local expected=-1
6587
6588         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6589
6590         # lfs_migrate file
6591         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6592
6593         echo "$cmd"
6594         eval $cmd || error "$cmd failed"
6595
6596         check_stripe_count $dir/file1 $expected
6597
6598         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6599         then
6600                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6601                 # OST 1 if it is on OST 0. This file is small enough to
6602                 # be on only one stripe.
6603                 file=$dir/migr_1_ost
6604                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6605                         error "write data into $file failed"
6606                 local obdidx=$($LFS getstripe -i $file)
6607                 local oldmd5=$(md5sum $file)
6608                 local newobdidx=0
6609
6610                 [[ $obdidx -eq 0 ]] && newobdidx=1
6611                 cmd="$LFS migrate -i $newobdidx $file"
6612                 echo $cmd
6613                 eval $cmd || error "$cmd failed"
6614
6615                 local realobdix=$($LFS getstripe -i $file)
6616                 local newmd5=$(md5sum $file)
6617
6618                 [[ $newobdidx -ne $realobdix ]] &&
6619                         error "new OST is different (was=$obdidx, "\
6620                               "wanted=$newobdidx, got=$realobdix)"
6621                 [[ "$oldmd5" != "$newmd5" ]] &&
6622                         error "md5sum differ: $oldmd5, $newmd5"
6623         fi
6624
6625         # lfs_migrate dir
6626         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6627         echo "$cmd"
6628         eval $cmd || error "$cmd failed"
6629
6630         for j in $(seq $NUMFILES); do
6631                 check_stripe_count $dir/dir1/file$j $expected
6632         done
6633
6634         # lfs_migrate works with lfs find
6635         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6636              $LFS_MIGRATE -y -c $expected"
6637         echo "$cmd"
6638         eval $cmd || error "$cmd failed"
6639
6640         for i in $(seq 2 $NUMFILES); do
6641                 check_stripe_count $dir/file$i $expected
6642         done
6643         for i in $(seq 2 $NUMDIRS); do
6644                 for j in $(seq $NUMFILES); do
6645                 check_stripe_count $dir/dir$i/file$j $expected
6646                 done
6647         done
6648 }
6649 run_test 56w "check lfs_migrate -c stripe_count works"
6650
6651 test_56wb() {
6652         local file1=$DIR/$tdir/file1
6653         local create_pool=false
6654         local initial_pool=$($LFS getstripe -p $DIR)
6655         local pool_list=()
6656         local pool=""
6657
6658         echo -n "Creating test dir..."
6659         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6660         echo "done."
6661
6662         echo -n "Creating test file..."
6663         touch $file1 || error "cannot create file"
6664         echo "done."
6665
6666         echo -n "Detecting existing pools..."
6667         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6668
6669         if [ ${#pool_list[@]} -gt 0 ]; then
6670                 echo "${pool_list[@]}"
6671                 for thispool in "${pool_list[@]}"; do
6672                         if [[ -z "$initial_pool" ||
6673                               "$initial_pool" != "$thispool" ]]; then
6674                                 pool="$thispool"
6675                                 echo "Using existing pool '$pool'"
6676                                 break
6677                         fi
6678                 done
6679         else
6680                 echo "none detected."
6681         fi
6682         if [ -z "$pool" ]; then
6683                 pool=${POOL:-testpool}
6684                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6685                 echo -n "Creating pool '$pool'..."
6686                 create_pool=true
6687                 pool_add $pool &> /dev/null ||
6688                         error "pool_add failed"
6689                 echo "done."
6690
6691                 echo -n "Adding target to pool..."
6692                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6693                         error "pool_add_targets failed"
6694                 echo "done."
6695         fi
6696
6697         echo -n "Setting pool using -p option..."
6698         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6699                 error "migrate failed rc = $?"
6700         echo "done."
6701
6702         echo -n "Verifying test file is in pool after migrating..."
6703         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6704                 error "file was not migrated to pool $pool"
6705         echo "done."
6706
6707         echo -n "Removing test file from pool '$pool'..."
6708         # "lfs migrate $file" won't remove the file from the pool
6709         # until some striping information is changed.
6710         $LFS migrate -c 1 $file1 &> /dev/null ||
6711                 error "cannot remove from pool"
6712         [ "$($LFS getstripe -p $file1)" ] &&
6713                 error "pool still set"
6714         echo "done."
6715
6716         echo -n "Setting pool using --pool option..."
6717         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6718                 error "migrate failed rc = $?"
6719         echo "done."
6720
6721         # Clean up
6722         rm -f $file1
6723         if $create_pool; then
6724                 destroy_test_pools 2> /dev/null ||
6725                         error "destroy test pools failed"
6726         fi
6727 }
6728 run_test 56wb "check lfs_migrate pool support"
6729
6730 test_56wc() {
6731         local file1="$DIR/$tdir/file1"
6732         local parent_ssize
6733         local parent_scount
6734         local cur_ssize
6735         local cur_scount
6736         local orig_ssize
6737
6738         echo -n "Creating test dir..."
6739         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6740         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6741                 error "cannot set stripe by '-S 1M -c 1'"
6742         echo "done"
6743
6744         echo -n "Setting initial stripe for test file..."
6745         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6746                 error "cannot set stripe"
6747         cur_ssize=$($LFS getstripe -S "$file1")
6748         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6749         echo "done."
6750
6751         # File currently set to -S 512K -c 1
6752
6753         # Ensure -c and -S options are rejected when -R is set
6754         echo -n "Verifying incompatible options are detected..."
6755         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6756                 error "incompatible -c and -R options not detected"
6757         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6758                 error "incompatible -S and -R options not detected"
6759         echo "done."
6760
6761         # Ensure unrecognized options are passed through to 'lfs migrate'
6762         echo -n "Verifying -S option is passed through to lfs migrate..."
6763         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6764                 error "migration failed"
6765         cur_ssize=$($LFS getstripe -S "$file1")
6766         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6767         echo "done."
6768
6769         # File currently set to -S 1M -c 1
6770
6771         # Ensure long options are supported
6772         echo -n "Verifying long options supported..."
6773         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6774                 error "long option without argument not supported"
6775         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6776                 error "long option with argument not supported"
6777         cur_ssize=$($LFS getstripe -S "$file1")
6778         [ $cur_ssize -eq 524288 ] ||
6779                 error "migrate --stripe-size $cur_ssize != 524288"
6780         echo "done."
6781
6782         # File currently set to -S 512K -c 1
6783
6784         if [ "$OSTCOUNT" -gt 1 ]; then
6785                 echo -n "Verifying explicit stripe count can be set..."
6786                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6787                         error "migrate failed"
6788                 cur_scount=$($LFS getstripe -c "$file1")
6789                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6790                 echo "done."
6791         fi
6792
6793         # File currently set to -S 512K -c 1 or -S 512K -c 2
6794
6795         # Ensure parent striping is used if -R is set, and no stripe
6796         # count or size is specified
6797         echo -n "Setting stripe for parent directory..."
6798         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6799                 error "cannot set stripe '-S 2M -c 1'"
6800         echo "done."
6801
6802         echo -n "Verifying restripe option uses parent stripe settings..."
6803         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6804         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6805         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6806                 error "migrate failed"
6807         cur_ssize=$($LFS getstripe -S "$file1")
6808         [ $cur_ssize -eq $parent_ssize ] ||
6809                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6810         cur_scount=$($LFS getstripe -c "$file1")
6811         [ $cur_scount -eq $parent_scount ] ||
6812                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6813         echo "done."
6814
6815         # File currently set to -S 1M -c 1
6816
6817         # Ensure striping is preserved if -R is not set, and no stripe
6818         # count or size is specified
6819         echo -n "Verifying striping size preserved when not specified..."
6820         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6821         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6822                 error "cannot set stripe on parent directory"
6823         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6824                 error "migrate failed"
6825         cur_ssize=$($LFS getstripe -S "$file1")
6826         [ $cur_ssize -eq $orig_ssize ] ||
6827                 error "migrate by default $cur_ssize != $orig_ssize"
6828         echo "done."
6829
6830         # Ensure file name properly detected when final option has no argument
6831         echo -n "Verifying file name properly detected..."
6832         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6833                 error "file name interpreted as option argument"
6834         echo "done."
6835
6836         # Clean up
6837         rm -f "$file1"
6838 }
6839 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6840
6841 test_56wd() {
6842         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6843
6844         local file1=$DIR/$tdir/file1
6845
6846         echo -n "Creating test dir..."
6847         test_mkdir $DIR/$tdir || error "cannot create dir"
6848         echo "done."
6849
6850         echo -n "Creating test file..."
6851         touch $file1
6852         echo "done."
6853
6854         # Ensure 'lfs migrate' will fail by using a non-existent option,
6855         # and make sure rsync is not called to recover
6856         echo -n "Make sure --no-rsync option works..."
6857         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6858                 grep -q 'refusing to fall back to rsync' ||
6859                 error "rsync was called with --no-rsync set"
6860         echo "done."
6861
6862         # Ensure rsync is called without trying 'lfs migrate' first
6863         echo -n "Make sure --rsync option works..."
6864         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6865                 grep -q 'falling back to rsync' &&
6866                 error "lfs migrate was called with --rsync set"
6867         echo "done."
6868
6869         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6870         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6871                 grep -q 'at the same time' ||
6872                 error "--rsync and --no-rsync accepted concurrently"
6873         echo "done."
6874
6875         # Clean up
6876         rm -f $file1
6877 }
6878 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6879
6880 test_56we() {
6881         local td=$DIR/$tdir
6882         local tf=$td/$tfile
6883
6884         test_mkdir $td || error "cannot create $td"
6885         touch $tf || error "cannot touch $tf"
6886
6887         echo -n "Make sure --non-direct|-D works..."
6888         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6889                 grep -q "lfs migrate --non-direct" ||
6890                 error "--non-direct option cannot work correctly"
6891         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6892                 grep -q "lfs migrate -D" ||
6893                 error "-D option cannot work correctly"
6894         echo "done."
6895 }
6896 run_test 56we "check lfs_migrate --non-direct|-D support"
6897
6898 test_56x() {
6899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6900         check_swap_layouts_support
6901
6902         local dir=$DIR/$tdir
6903         local ref1=/etc/passwd
6904         local file1=$dir/file1
6905
6906         test_mkdir $dir || error "creating dir $dir"
6907         $LFS setstripe -c 2 $file1
6908         cp $ref1 $file1
6909         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6910         stripe=$($LFS getstripe -c $file1)
6911         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6912         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6913
6914         # clean up
6915         rm -f $file1
6916 }
6917 run_test 56x "lfs migration support"
6918
6919 test_56xa() {
6920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6921         check_swap_layouts_support
6922
6923         local dir=$DIR/$tdir/$testnum
6924
6925         test_mkdir -p $dir
6926
6927         local ref1=/etc/passwd
6928         local file1=$dir/file1
6929
6930         $LFS setstripe -c 2 $file1
6931         cp $ref1 $file1
6932         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6933
6934         local stripe=$($LFS getstripe -c $file1)
6935
6936         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6937         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6938
6939         # clean up
6940         rm -f $file1
6941 }
6942 run_test 56xa "lfs migration --block support"
6943
6944 check_migrate_links() {
6945         local dir="$1"
6946         local file1="$dir/file1"
6947         local begin="$2"
6948         local count="$3"
6949         local runas="$4"
6950         local total_count=$(($begin + $count - 1))
6951         local symlink_count=10
6952         local uniq_count=10
6953
6954         if [ ! -f "$file1" ]; then
6955                 echo -n "creating initial file..."
6956                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6957                         error "cannot setstripe initial file"
6958                 echo "done"
6959
6960                 echo -n "creating symlinks..."
6961                 for s in $(seq 1 $symlink_count); do
6962                         ln -s "$file1" "$dir/slink$s" ||
6963                                 error "cannot create symlinks"
6964                 done
6965                 echo "done"
6966
6967                 echo -n "creating nonlinked files..."
6968                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6969                         error "cannot create nonlinked files"
6970                 echo "done"
6971         fi
6972
6973         # create hard links
6974         if [ ! -f "$dir/file$total_count" ]; then
6975                 echo -n "creating hard links $begin:$total_count..."
6976                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6977                         /dev/null || error "cannot create hard links"
6978                 echo "done"
6979         fi
6980
6981         echo -n "checking number of hard links listed in xattrs..."
6982         local fid=$($LFS getstripe -F "$file1")
6983         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6984
6985         echo "${#paths[*]}"
6986         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6987                         skip "hard link list has unexpected size, skipping test"
6988         fi
6989         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6990                         error "link names should exceed xattrs size"
6991         fi
6992
6993         echo -n "migrating files..."
6994         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6995         local rc=$?
6996         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6997         echo "done"
6998
6999         # make sure all links have been properly migrated
7000         echo -n "verifying files..."
7001         fid=$($LFS getstripe -F "$file1") ||
7002                 error "cannot get fid for file $file1"
7003         for i in $(seq 2 $total_count); do
7004                 local fid2=$($LFS getstripe -F $dir/file$i)
7005
7006                 [ "$fid2" == "$fid" ] ||
7007                         error "migrated hard link has mismatched FID"
7008         done
7009
7010         # make sure hard links were properly detected, and migration was
7011         # performed only once for the entire link set; nonlinked files should
7012         # also be migrated
7013         local actual=$(grep -c 'done' <<< "$migrate_out")
7014         local expected=$(($uniq_count + 1))
7015
7016         [ "$actual" -eq  "$expected" ] ||
7017                 error "hard links individually migrated ($actual != $expected)"
7018
7019         # make sure the correct number of hard links are present
7020         local hardlinks=$(stat -c '%h' "$file1")
7021
7022         [ $hardlinks -eq $total_count ] ||
7023                 error "num hard links $hardlinks != $total_count"
7024         echo "done"
7025
7026         return 0
7027 }
7028
7029 test_56xb() {
7030         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7031                 skip "Need MDS version at least 2.10.55"
7032
7033         local dir="$DIR/$tdir"
7034
7035         test_mkdir "$dir" || error "cannot create dir $dir"
7036
7037         echo "testing lfs migrate mode when all links fit within xattrs"
7038         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7039
7040         echo "testing rsync mode when all links fit within xattrs"
7041         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7042
7043         echo "testing lfs migrate mode when all links do not fit within xattrs"
7044         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7045
7046         echo "testing rsync mode when all links do not fit within xattrs"
7047         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7048
7049         chown -R $RUNAS_ID $dir
7050         echo "testing non-root lfs migrate mode when not all links are in xattr"
7051         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7052
7053         # clean up
7054         rm -rf $dir
7055 }
7056 run_test 56xb "lfs migration hard link support"
7057
7058 test_56xc() {
7059         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7060
7061         local dir="$DIR/$tdir"
7062
7063         test_mkdir "$dir" || error "cannot create dir $dir"
7064
7065         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7066         echo -n "Setting initial stripe for 20MB test file..."
7067         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7068                 error "cannot setstripe 20MB file"
7069         echo "done"
7070         echo -n "Sizing 20MB test file..."
7071         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7072         echo "done"
7073         echo -n "Verifying small file autostripe count is 1..."
7074         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7075                 error "cannot migrate 20MB file"
7076         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7077                 error "cannot get stripe for $dir/20mb"
7078         [ $stripe_count -eq 1 ] ||
7079                 error "unexpected stripe count $stripe_count for 20MB file"
7080         rm -f "$dir/20mb"
7081         echo "done"
7082
7083         # Test 2: File is small enough to fit within the available space on
7084         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7085         # have at least an additional 1KB for each desired stripe for test 3
7086         echo -n "Setting stripe for 1GB test file..."
7087         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7088         echo "done"
7089         echo -n "Sizing 1GB test file..."
7090         # File size is 1GB + 3KB
7091         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7092         echo "done"
7093
7094         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7095         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7096         if (( avail > 524288 * OSTCOUNT )); then
7097                 echo -n "Migrating 1GB file..."
7098                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7099                         error "cannot migrate 1GB file"
7100                 echo "done"
7101                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7102                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7103                         error "cannot getstripe for 1GB file"
7104                 [ $stripe_count -eq 2 ] ||
7105                         error "unexpected stripe count $stripe_count != 2"
7106                 echo "done"
7107         fi
7108
7109         # Test 3: File is too large to fit within the available space on
7110         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7111         if [ $OSTCOUNT -ge 3 ]; then
7112                 # The required available space is calculated as
7113                 # file size (1GB + 3KB) / OST count (3).
7114                 local kb_per_ost=349526
7115
7116                 echo -n "Migrating 1GB file with limit..."
7117                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7118                         error "cannot migrate 1GB file with limit"
7119                 echo "done"
7120
7121                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7122                 echo -n "Verifying 1GB autostripe count with limited space..."
7123                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7124                         error "unexpected stripe count $stripe_count (min 3)"
7125                 echo "done"
7126         fi
7127
7128         # clean up
7129         rm -rf $dir
7130 }
7131 run_test 56xc "lfs migration autostripe"
7132
7133 test_56xd() {
7134         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7135
7136         local dir=$DIR/$tdir
7137         local f_mgrt=$dir/$tfile.mgrt
7138         local f_yaml=$dir/$tfile.yaml
7139         local f_copy=$dir/$tfile.copy
7140         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7141         local layout_copy="-c 2 -S 2M -i 1"
7142         local yamlfile=$dir/yamlfile
7143         local layout_before;
7144         local layout_after;
7145
7146         test_mkdir "$dir" || error "cannot create dir $dir"
7147         $LFS setstripe $layout_yaml $f_yaml ||
7148                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7149         $LFS getstripe --yaml $f_yaml > $yamlfile
7150         $LFS setstripe $layout_copy $f_copy ||
7151                 error "cannot setstripe $f_copy with layout $layout_copy"
7152         touch $f_mgrt
7153         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7154
7155         # 1. test option --yaml
7156         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7157                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7158         layout_before=$(get_layout_param $f_yaml)
7159         layout_after=$(get_layout_param $f_mgrt)
7160         [ "$layout_after" == "$layout_before" ] ||
7161                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7162
7163         # 2. test option --copy
7164         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7165                 error "cannot migrate $f_mgrt with --copy $f_copy"
7166         layout_before=$(get_layout_param $f_copy)
7167         layout_after=$(get_layout_param $f_mgrt)
7168         [ "$layout_after" == "$layout_before" ] ||
7169                 error "lfs_migrate --copy: $layout_after != $layout_before"
7170 }
7171 run_test 56xd "check lfs_migrate --yaml and --copy support"
7172
7173 test_56xe() {
7174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7175
7176         local dir=$DIR/$tdir
7177         local f_comp=$dir/$tfile
7178         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7179         local layout_before=""
7180         local layout_after=""
7181
7182         test_mkdir "$dir" || error "cannot create dir $dir"
7183         $LFS setstripe $layout $f_comp ||
7184                 error "cannot setstripe $f_comp with layout $layout"
7185         layout_before=$(get_layout_param $f_comp)
7186         dd if=/dev/zero of=$f_comp bs=1M count=4
7187
7188         # 1. migrate a comp layout file by lfs_migrate
7189         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7190         layout_after=$(get_layout_param $f_comp)
7191         [ "$layout_before" == "$layout_after" ] ||
7192                 error "lfs_migrate: $layout_before != $layout_after"
7193
7194         # 2. migrate a comp layout file by lfs migrate
7195         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7196         layout_after=$(get_layout_param $f_comp)
7197         [ "$layout_before" == "$layout_after" ] ||
7198                 error "lfs migrate: $layout_before != $layout_after"
7199 }
7200 run_test 56xe "migrate a composite layout file"
7201
7202 test_56xf() {
7203         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7204
7205         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7206                 skip "Need server version at least 2.13.53"
7207
7208         local dir=$DIR/$tdir
7209         local f_comp=$dir/$tfile
7210         local layout="-E 1M -c1 -E -1 -c2"
7211         local fid_before=""
7212         local fid_after=""
7213
7214         test_mkdir "$dir" || error "cannot create dir $dir"
7215         $LFS setstripe $layout $f_comp ||
7216                 error "cannot setstripe $f_comp with layout $layout"
7217         fid_before=$($LFS getstripe --fid $f_comp)
7218         dd if=/dev/zero of=$f_comp bs=1M count=4
7219
7220         # 1. migrate a comp layout file to a comp layout
7221         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7222         fid_after=$($LFS getstripe --fid $f_comp)
7223         [ "$fid_before" == "$fid_after" ] ||
7224                 error "comp-to-comp migrate: $fid_before != $fid_after"
7225
7226         # 2. migrate a comp layout file to a plain layout
7227         $LFS migrate -c2 $f_comp ||
7228                 error "cannot migrate $f_comp by lfs migrate"
7229         fid_after=$($LFS getstripe --fid $f_comp)
7230         [ "$fid_before" == "$fid_after" ] ||
7231                 error "comp-to-plain migrate: $fid_before != $fid_after"
7232
7233         # 3. migrate a plain layout file to a comp layout
7234         $LFS migrate $layout $f_comp ||
7235                 error "cannot migrate $f_comp by lfs migrate"
7236         fid_after=$($LFS getstripe --fid $f_comp)
7237         [ "$fid_before" == "$fid_after" ] ||
7238                 error "plain-to-comp migrate: $fid_before != $fid_after"
7239 }
7240 run_test 56xf "FID is not lost during migration of a composite layout file"
7241
7242 test_56y() {
7243         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7244                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7245
7246         local res=""
7247         local dir=$DIR/$tdir
7248         local f1=$dir/file1
7249         local f2=$dir/file2
7250
7251         test_mkdir -p $dir || error "creating dir $dir"
7252         touch $f1 || error "creating std file $f1"
7253         $MULTIOP $f2 H2c || error "creating released file $f2"
7254
7255         # a directory can be raid0, so ask only for files
7256         res=$($LFS find $dir -L raid0 -type f | wc -l)
7257         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7258
7259         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7260         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7261
7262         # only files can be released, so no need to force file search
7263         res=$($LFS find $dir -L released)
7264         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7265
7266         res=$($LFS find $dir -type f \! -L released)
7267         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7268 }
7269 run_test 56y "lfs find -L raid0|released"
7270
7271 test_56z() { # LU-4824
7272         # This checks to make sure 'lfs find' continues after errors
7273         # There are two classes of errors that should be caught:
7274         # - If multiple paths are provided, all should be searched even if one
7275         #   errors out
7276         # - If errors are encountered during the search, it should not terminate
7277         #   early
7278         local dir=$DIR/$tdir
7279         local i
7280
7281         test_mkdir $dir
7282         for i in d{0..9}; do
7283                 test_mkdir $dir/$i
7284                 touch $dir/$i/$tfile
7285         done
7286         $LFS find $DIR/non_existent_dir $dir &&
7287                 error "$LFS find did not return an error"
7288         # Make a directory unsearchable. This should NOT be the last entry in
7289         # directory order.  Arbitrarily pick the 6th entry
7290         chmod 700 $($LFS find $dir -type d | sed '6!d')
7291
7292         $RUNAS $LFS find $DIR/non_existent $dir
7293         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7294
7295         # The user should be able to see 10 directories and 9 files
7296         (( count == 19 )) ||
7297                 error "$LFS find found $count != 19 entries after error"
7298 }
7299 run_test 56z "lfs find should continue after an error"
7300
7301 test_56aa() { # LU-5937
7302         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7303
7304         local dir=$DIR/$tdir
7305
7306         mkdir $dir
7307         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7308
7309         createmany -o $dir/striped_dir/${tfile}- 1024
7310         local dirs=$($LFS find --size +8k $dir/)
7311
7312         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7313 }
7314 run_test 56aa "lfs find --size under striped dir"
7315
7316 test_56ab() { # LU-10705
7317         test_mkdir $DIR/$tdir
7318         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7319         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7320         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7321         # Flush writes to ensure valid blocks.  Need to be more thorough for
7322         # ZFS, since blocks are not allocated/returned to client immediately.
7323         sync_all_data
7324         wait_zfs_commit ost1 2
7325         cancel_lru_locks osc
7326         ls -ls $DIR/$tdir
7327
7328         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7329
7330         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7331
7332         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7333         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7334
7335         rm -f $DIR/$tdir/$tfile.[123]
7336 }
7337 run_test 56ab "lfs find --blocks"
7338
7339 test_56ba() {
7340         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7341                 skip "Need MDS version at least 2.10.50"
7342
7343         # Create composite files with one component
7344         local dir=$DIR/$tdir
7345
7346         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7347         # Create composite files with three components
7348         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7349         # Create non-composite files
7350         createmany -o $dir/${tfile}- 10
7351
7352         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7353
7354         [[ $nfiles == 10 ]] ||
7355                 error "lfs find -E 1M found $nfiles != 10 files"
7356
7357         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7358         [[ $nfiles == 25 ]] ||
7359                 error "lfs find ! -E 1M found $nfiles != 25 files"
7360
7361         # All files have a component that starts at 0
7362         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7363         [[ $nfiles == 35 ]] ||
7364                 error "lfs find --component-start 0 - $nfiles != 35 files"
7365
7366         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7367         [[ $nfiles == 15 ]] ||
7368                 error "lfs find --component-start 2M - $nfiles != 15 files"
7369
7370         # All files created here have a componenet that does not starts at 2M
7371         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7372         [[ $nfiles == 35 ]] ||
7373                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7374
7375         # Find files with a specified number of components
7376         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7377         [[ $nfiles == 15 ]] ||
7378                 error "lfs find --component-count 3 - $nfiles != 15 files"
7379
7380         # Remember non-composite files have a component count of zero
7381         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7382         [[ $nfiles == 10 ]] ||
7383                 error "lfs find --component-count 0 - $nfiles != 10 files"
7384
7385         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7386         [[ $nfiles == 20 ]] ||
7387                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7388
7389         # All files have a flag called "init"
7390         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7391         [[ $nfiles == 35 ]] ||
7392                 error "lfs find --component-flags init - $nfiles != 35 files"
7393
7394         # Multi-component files will have a component not initialized
7395         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7396         [[ $nfiles == 15 ]] ||
7397                 error "lfs find !--component-flags init - $nfiles != 15 files"
7398
7399         rm -rf $dir
7400
7401 }
7402 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7403
7404 test_56ca() {
7405         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7406                 skip "Need MDS version at least 2.10.57"
7407
7408         local td=$DIR/$tdir
7409         local tf=$td/$tfile
7410         local dir
7411         local nfiles
7412         local cmd
7413         local i
7414         local j
7415
7416         # create mirrored directories and mirrored files
7417         mkdir $td || error "mkdir $td failed"
7418         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7419         createmany -o $tf- 10 || error "create $tf- failed"
7420
7421         for i in $(seq 2); do
7422                 dir=$td/dir$i
7423                 mkdir $dir || error "mkdir $dir failed"
7424                 $LFS mirror create -N$((3 + i)) $dir ||
7425                         error "create mirrored dir $dir failed"
7426                 createmany -o $dir/$tfile- 10 ||
7427                         error "create $dir/$tfile- failed"
7428         done
7429
7430         # change the states of some mirrored files
7431         echo foo > $tf-6
7432         for i in $(seq 2); do
7433                 dir=$td/dir$i
7434                 for j in $(seq 4 9); do
7435                         echo foo > $dir/$tfile-$j
7436                 done
7437         done
7438
7439         # find mirrored files with specific mirror count
7440         cmd="$LFS find --mirror-count 3 --type f $td"
7441         nfiles=$($cmd | wc -l)
7442         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7443
7444         cmd="$LFS find ! --mirror-count 3 --type f $td"
7445         nfiles=$($cmd | wc -l)
7446         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7447
7448         cmd="$LFS find --mirror-count +2 --type f $td"
7449         nfiles=$($cmd | wc -l)
7450         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7451
7452         cmd="$LFS find --mirror-count -6 --type f $td"
7453         nfiles=$($cmd | wc -l)
7454         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7455
7456         # find mirrored files with specific file state
7457         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7458         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7459
7460         cmd="$LFS find --mirror-state=ro --type f $td"
7461         nfiles=$($cmd | wc -l)
7462         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7463
7464         cmd="$LFS find ! --mirror-state=ro --type f $td"
7465         nfiles=$($cmd | wc -l)
7466         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7467
7468         cmd="$LFS find --mirror-state=wp --type f $td"
7469         nfiles=$($cmd | wc -l)
7470         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7471
7472         cmd="$LFS find ! --mirror-state=sp --type f $td"
7473         nfiles=$($cmd | wc -l)
7474         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7475 }
7476 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7477
7478 test_57a() {
7479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7480         # note test will not do anything if MDS is not local
7481         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7482                 skip_env "ldiskfs only test"
7483         fi
7484         remote_mds_nodsh && skip "remote MDS with nodsh"
7485
7486         local MNTDEV="osd*.*MDT*.mntdev"
7487         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7488         [ -z "$DEV" ] && error "can't access $MNTDEV"
7489         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7490                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7491                         error "can't access $DEV"
7492                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7493                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7494                 rm $TMP/t57a.dump
7495         done
7496 }
7497 run_test 57a "verify MDS filesystem created with large inodes =="
7498
7499 test_57b() {
7500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7501         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7502                 skip_env "ldiskfs only test"
7503         fi
7504         remote_mds_nodsh && skip "remote MDS with nodsh"
7505
7506         local dir=$DIR/$tdir
7507         local filecount=100
7508         local file1=$dir/f1
7509         local fileN=$dir/f$filecount
7510
7511         rm -rf $dir || error "removing $dir"
7512         test_mkdir -c1 $dir
7513         local mdtidx=$($LFS getstripe -m $dir)
7514         local mdtname=MDT$(printf %04x $mdtidx)
7515         local facet=mds$((mdtidx + 1))
7516
7517         echo "mcreating $filecount files"
7518         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7519
7520         # verify that files do not have EAs yet
7521         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7522                 error "$file1 has an EA"
7523         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7524                 error "$fileN has an EA"
7525
7526         sync
7527         sleep 1
7528         df $dir  #make sure we get new statfs data
7529         local mdsfree=$(do_facet $facet \
7530                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7531         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7532         local file
7533
7534         echo "opening files to create objects/EAs"
7535         for file in $(seq -f $dir/f%g 1 $filecount); do
7536                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7537                         error "opening $file"
7538         done
7539
7540         # verify that files have EAs now
7541         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7542         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7543
7544         sleep 1  #make sure we get new statfs data
7545         df $dir
7546         local mdsfree2=$(do_facet $facet \
7547                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7548         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7549
7550         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7551                 if [ "$mdsfree" != "$mdsfree2" ]; then
7552                         error "MDC before $mdcfree != after $mdcfree2"
7553                 else
7554                         echo "MDC before $mdcfree != after $mdcfree2"
7555                         echo "unable to confirm if MDS has large inodes"
7556                 fi
7557         fi
7558         rm -rf $dir
7559 }
7560 run_test 57b "default LOV EAs are stored inside large inodes ==="
7561
7562 test_58() {
7563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7564         [ -z "$(which wiretest 2>/dev/null)" ] &&
7565                         skip_env "could not find wiretest"
7566
7567         wiretest
7568 }
7569 run_test 58 "verify cross-platform wire constants =============="
7570
7571 test_59() {
7572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7573
7574         echo "touch 130 files"
7575         createmany -o $DIR/f59- 130
7576         echo "rm 130 files"
7577         unlinkmany $DIR/f59- 130
7578         sync
7579         # wait for commitment of removal
7580         wait_delete_completed
7581 }
7582 run_test 59 "verify cancellation of llog records async ========="
7583
7584 TEST60_HEAD="test_60 run $RANDOM"
7585 test_60a() {
7586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7587         remote_mgs_nodsh && skip "remote MGS with nodsh"
7588         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7589                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7590                         skip_env "missing subtest run-llog.sh"
7591
7592         log "$TEST60_HEAD - from kernel mode"
7593         do_facet mgs "$LCTL dk > /dev/null"
7594         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7595         do_facet mgs $LCTL dk > $TMP/$tfile
7596
7597         # LU-6388: test llog_reader
7598         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7599         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7600         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7601                         skip_env "missing llog_reader"
7602         local fstype=$(facet_fstype mgs)
7603         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7604                 skip_env "Only for ldiskfs or zfs type mgs"
7605
7606         local mntpt=$(facet_mntpt mgs)
7607         local mgsdev=$(mgsdevname 1)
7608         local fid_list
7609         local fid
7610         local rec_list
7611         local rec
7612         local rec_type
7613         local obj_file
7614         local path
7615         local seq
7616         local oid
7617         local pass=true
7618
7619         #get fid and record list
7620         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7621                 tail -n 4))
7622         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7623                 tail -n 4))
7624         #remount mgs as ldiskfs or zfs type
7625         stop mgs || error "stop mgs failed"
7626         mount_fstype mgs || error "remount mgs failed"
7627         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7628                 fid=${fid_list[i]}
7629                 rec=${rec_list[i]}
7630                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7631                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7632                 oid=$((16#$oid))
7633
7634                 case $fstype in
7635                         ldiskfs )
7636                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7637                         zfs )
7638                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7639                 esac
7640                 echo "obj_file is $obj_file"
7641                 do_facet mgs $llog_reader $obj_file
7642
7643                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7644                         awk '{ print $3 }' | sed -e "s/^type=//g")
7645                 if [ $rec_type != $rec ]; then
7646                         echo "FAILED test_60a wrong record type $rec_type," \
7647                               "should be $rec"
7648                         pass=false
7649                         break
7650                 fi
7651
7652                 #check obj path if record type is LLOG_LOGID_MAGIC
7653                 if [ "$rec" == "1064553b" ]; then
7654                         path=$(do_facet mgs $llog_reader $obj_file |
7655                                 grep "path=" | awk '{ print $NF }' |
7656                                 sed -e "s/^path=//g")
7657                         if [ $obj_file != $mntpt/$path ]; then
7658                                 echo "FAILED test_60a wrong obj path" \
7659                                       "$montpt/$path, should be $obj_file"
7660                                 pass=false
7661                                 break
7662                         fi
7663                 fi
7664         done
7665         rm -f $TMP/$tfile
7666         #restart mgs before "error", otherwise it will block the next test
7667         stop mgs || error "stop mgs failed"
7668         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7669         $pass || error "test failed, see FAILED test_60a messages for specifics"
7670 }
7671 run_test 60a "llog_test run from kernel module and test llog_reader"
7672
7673 test_60b() { # bug 6411
7674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7675
7676         dmesg > $DIR/$tfile
7677         LLOG_COUNT=$(do_facet mgs dmesg |
7678                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7679                           /llog_[a-z]*.c:[0-9]/ {
7680                                 if (marker)
7681                                         from_marker++
7682                                 from_begin++
7683                           }
7684                           END {
7685                                 if (marker)
7686                                         print from_marker
7687                                 else
7688                                         print from_begin
7689                           }")
7690
7691         [[ $LLOG_COUNT -gt 120 ]] &&
7692                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7693 }
7694 run_test 60b "limit repeated messages from CERROR/CWARN"
7695
7696 test_60c() {
7697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7698
7699         echo "create 5000 files"
7700         createmany -o $DIR/f60c- 5000
7701 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7702         lctl set_param fail_loc=0x80000137
7703         unlinkmany $DIR/f60c- 5000
7704         lctl set_param fail_loc=0
7705 }
7706 run_test 60c "unlink file when mds full"
7707
7708 test_60d() {
7709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7710
7711         SAVEPRINTK=$(lctl get_param -n printk)
7712         # verify "lctl mark" is even working"
7713         MESSAGE="test message ID $RANDOM $$"
7714         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7715         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7716
7717         lctl set_param printk=0 || error "set lnet.printk failed"
7718         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7719         MESSAGE="new test message ID $RANDOM $$"
7720         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7721         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7722         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7723
7724         lctl set_param -n printk="$SAVEPRINTK"
7725 }
7726 run_test 60d "test printk console message masking"
7727
7728 test_60e() {
7729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7730         remote_mds_nodsh && skip "remote MDS with nodsh"
7731
7732         touch $DIR/$tfile
7733 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7734         do_facet mds1 lctl set_param fail_loc=0x15b
7735         rm $DIR/$tfile
7736 }
7737 run_test 60e "no space while new llog is being created"
7738
7739 test_60g() {
7740         local pid
7741         local i
7742
7743         test_mkdir -c $MDSCOUNT $DIR/$tdir
7744
7745         (
7746                 local index=0
7747                 while true; do
7748                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7749                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7750                                 2>/dev/null
7751                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7752                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7753                         index=$((index + 1))
7754                 done
7755         ) &
7756
7757         pid=$!
7758
7759         for i in {0..100}; do
7760                 # define OBD_FAIL_OSD_TXN_START    0x19a
7761                 local index=$((i % MDSCOUNT + 1))
7762
7763                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7764                         > /dev/null
7765                 sleep 0.01
7766         done
7767
7768         kill -9 $pid
7769
7770         for i in $(seq $MDSCOUNT); do
7771                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7772         done
7773
7774         mkdir $DIR/$tdir/new || error "mkdir failed"
7775         rmdir $DIR/$tdir/new || error "rmdir failed"
7776
7777         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7778                 -t namespace
7779         for i in $(seq $MDSCOUNT); do
7780                 wait_update_facet mds$i "$LCTL get_param -n \
7781                         mdd.$(facet_svc mds$i).lfsck_namespace |
7782                         awk '/^status/ { print \\\$2 }'" "completed"
7783         done
7784
7785         ls -R $DIR/$tdir || error "ls failed"
7786         rm -rf $DIR/$tdir || error "rmdir failed"
7787 }
7788 run_test 60g "transaction abort won't cause MDT hung"
7789
7790 test_60h() {
7791         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7792                 skip "Need MDS version at least 2.12.52"
7793         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7794
7795         local f
7796
7797         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7798         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7799         for fail_loc in 0x80000188 0x80000189; do
7800                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7801                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7802                         error "mkdir $dir-$fail_loc failed"
7803                 for i in {0..10}; do
7804                         # create may fail on missing stripe
7805                         echo $i > $DIR/$tdir-$fail_loc/$i
7806                 done
7807                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7808                         error "getdirstripe $tdir-$fail_loc failed"
7809                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7810                         error "migrate $tdir-$fail_loc failed"
7811                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7812                         error "getdirstripe $tdir-$fail_loc failed"
7813                 pushd $DIR/$tdir-$fail_loc
7814                 for f in *; do
7815                         echo $f | cmp $f - || error "$f data mismatch"
7816                 done
7817                 popd
7818                 rm -rf $DIR/$tdir-$fail_loc
7819         done
7820 }
7821 run_test 60h "striped directory with missing stripes can be accessed"
7822
7823 test_61a() {
7824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7825
7826         f="$DIR/f61"
7827         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7828         cancel_lru_locks osc
7829         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7830         sync
7831 }
7832 run_test 61a "mmap() writes don't make sync hang ================"
7833
7834 test_61b() {
7835         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7836 }
7837 run_test 61b "mmap() of unstriped file is successful"
7838
7839 # bug 2330 - insufficient obd_match error checking causes LBUG
7840 test_62() {
7841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7842
7843         f="$DIR/f62"
7844         echo foo > $f
7845         cancel_lru_locks osc
7846         lctl set_param fail_loc=0x405
7847         cat $f && error "cat succeeded, expect -EIO"
7848         lctl set_param fail_loc=0
7849 }
7850 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7851 # match every page all of the time.
7852 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7853
7854 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7855 # Though this test is irrelevant anymore, it helped to reveal some
7856 # other grant bugs (LU-4482), let's keep it.
7857 test_63a() {   # was test_63
7858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7859
7860         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7861
7862         for i in `seq 10` ; do
7863                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7864                 sleep 5
7865                 kill $!
7866                 sleep 1
7867         done
7868
7869         rm -f $DIR/f63 || true
7870 }
7871 run_test 63a "Verify oig_wait interruption does not crash ======="
7872
7873 # bug 2248 - async write errors didn't return to application on sync
7874 # bug 3677 - async write errors left page locked
7875 test_63b() {
7876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7877
7878         debugsave
7879         lctl set_param debug=-1
7880
7881         # ensure we have a grant to do async writes
7882         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7883         rm $DIR/$tfile
7884
7885         sync    # sync lest earlier test intercept the fail_loc
7886
7887         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7888         lctl set_param fail_loc=0x80000406
7889         $MULTIOP $DIR/$tfile Owy && \
7890                 error "sync didn't return ENOMEM"
7891         sync; sleep 2; sync     # do a real sync this time to flush page
7892         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7893                 error "locked page left in cache after async error" || true
7894         debugrestore
7895 }
7896 run_test 63b "async write errors should be returned to fsync ==="
7897
7898 test_64a () {
7899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7900
7901         lfs df $DIR
7902         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7903 }
7904 run_test 64a "verify filter grant calculations (in kernel) ====="
7905
7906 test_64b () {
7907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7908
7909         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7910 }
7911 run_test 64b "check out-of-space detection on client"
7912
7913 test_64c() {
7914         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7915 }
7916 run_test 64c "verify grant shrink"
7917
7918 import_param() {
7919         local tgt=$1
7920         local param=$2
7921
7922         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7923 }
7924
7925 # this does exactly what osc_request.c:osc_announce_cached() does in
7926 # order to calculate max amount of grants to ask from server
7927 want_grant() {
7928         local tgt=$1
7929
7930         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7931         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7932
7933         ((rpc_in_flight++));
7934         nrpages=$((nrpages * rpc_in_flight))
7935
7936         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7937
7938         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7939
7940         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7941         local undirty=$((nrpages * PAGE_SIZE))
7942
7943         local max_extent_pages
7944         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7945         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7946         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7947         local grant_extent_tax
7948         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7949
7950         undirty=$((undirty + nrextents * grant_extent_tax))
7951
7952         echo $undirty
7953 }
7954
7955 # this is size of unit for grant allocation. It should be equal to
7956 # what tgt_grant.c:tgt_grant_chunk() calculates
7957 grant_chunk() {
7958         local tgt=$1
7959         local max_brw_size
7960         local grant_extent_tax
7961
7962         max_brw_size=$(import_param $tgt max_brw_size)
7963
7964         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7965
7966         echo $(((max_brw_size + grant_extent_tax) * 2))
7967 }
7968
7969 test_64d() {
7970         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7971                 skip "OST < 2.10.55 doesn't limit grants enough"
7972
7973         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7974
7975         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7976                 skip "no grant_param connect flag"
7977
7978         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7979
7980         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7981         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7982
7983
7984         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7985         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7986
7987         $LFS setstripe $DIR/$tfile -i 0 -c 1
7988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7989         ddpid=$!
7990
7991         while kill -0 $ddpid; do
7992                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7993
7994                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7995                         kill $ddpid
7996                         error "cur_grant $cur_grant > $max_cur_granted"
7997                 fi
7998
7999                 sleep 1
8000         done
8001 }
8002 run_test 64d "check grant limit exceed"
8003
8004 check_grants() {
8005         local tgt=$1
8006         local expected=$2
8007         local msg=$3
8008         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8009
8010         ((cur_grants == expected)) ||
8011                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8012 }
8013
8014 round_up_p2() {
8015         echo $((($1 + $2 - 1) & ~($2 - 1)))
8016 }
8017
8018 test_64e() {
8019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8020         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8021                 skip "Need OSS version at least 2.11.56"
8022
8023         # Remount client to reset grant
8024         remount_client $MOUNT || error "failed to remount client"
8025         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8026
8027         local init_grants=$(import_param $osc_tgt initial_grant)
8028
8029         check_grants $osc_tgt $init_grants "init grants"
8030
8031         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8032         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8033         local gbs=$(import_param $osc_tgt grant_block_size)
8034
8035         # write random number of bytes from max_brw_size / 4 to max_brw_size
8036         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8037         # align for direct io
8038         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8039         # round to grant consumption unit
8040         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8041
8042         local grants=$((wb_round_up + extent_tax))
8043
8044         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8045
8046         # define OBD_FAIL_TGT_NO_GRANT 0x725
8047         # make the server not grant more back
8048         do_facet ost1 $LCTL set_param fail_loc=0x725
8049         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8050
8051         do_facet ost1 $LCTL set_param fail_loc=0
8052
8053         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8054
8055         rm -f $DIR/$tfile || error "rm failed"
8056
8057         # Remount client to reset grant
8058         remount_client $MOUNT || error "failed to remount client"
8059         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8060
8061         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8062
8063         # define OBD_FAIL_TGT_NO_GRANT 0x725
8064         # make the server not grant more back
8065         do_facet ost1 $LCTL set_param fail_loc=0x725
8066         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8067         do_facet ost1 $LCTL set_param fail_loc=0
8068
8069         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8070 }
8071 run_test 64e "check grant consumption (no grant allocation)"
8072
8073 test_64f() {
8074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8075
8076         # Remount client to reset grant
8077         remount_client $MOUNT || error "failed to remount client"
8078         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8079
8080         local init_grants=$(import_param $osc_tgt initial_grant)
8081         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8082         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8083         local gbs=$(import_param $osc_tgt grant_block_size)
8084         local chunk=$(grant_chunk $osc_tgt)
8085
8086         # write random number of bytes from max_brw_size / 4 to max_brw_size
8087         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8088         # align for direct io
8089         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8090         # round to grant consumption unit
8091         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8092
8093         local grants=$((wb_round_up + extent_tax))
8094
8095         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8096         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8097                 error "error writing to $DIR/$tfile"
8098
8099         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8100                 "direct io with grant allocation"
8101
8102         rm -f $DIR/$tfile || error "rm failed"
8103
8104         # Remount client to reset grant
8105         remount_client $MOUNT || error "failed to remount client"
8106         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8107
8108         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8109
8110         local cmd="oO_WRONLY:w${write_bytes}_yc"
8111
8112         $MULTIOP $DIR/$tfile $cmd &
8113         MULTIPID=$!
8114         sleep 1
8115
8116         check_grants $osc_tgt $((init_grants - grants)) \
8117                 "buffered io, not write rpc"
8118
8119         kill -USR1 $MULTIPID
8120         wait
8121
8122         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8123                 "buffered io, one RPC"
8124 }
8125 run_test 64f "check grant consumption (with grant allocation)"
8126
8127 # bug 1414 - set/get directories' stripe info
8128 test_65a() {
8129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8130
8131         test_mkdir $DIR/$tdir
8132         touch $DIR/$tdir/f1
8133         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8134 }
8135 run_test 65a "directory with no stripe info"
8136
8137 test_65b() {
8138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8139
8140         test_mkdir $DIR/$tdir
8141         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8142
8143         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8144                                                 error "setstripe"
8145         touch $DIR/$tdir/f2
8146         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8147 }
8148 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8149
8150 test_65c() {
8151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8152         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8153
8154         test_mkdir $DIR/$tdir
8155         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8156
8157         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8158                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8159         touch $DIR/$tdir/f3
8160         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8161 }
8162 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8163
8164 test_65d() {
8165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8166
8167         test_mkdir $DIR/$tdir
8168         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8169         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8170
8171         if [[ $STRIPECOUNT -le 0 ]]; then
8172                 sc=1
8173         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8174                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8175                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8176         else
8177                 sc=$(($STRIPECOUNT - 1))
8178         fi
8179         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8180         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8181         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8182                 error "lverify failed"
8183 }
8184 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8185
8186 test_65e() {
8187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8188
8189         test_mkdir $DIR/$tdir
8190
8191         $LFS setstripe $DIR/$tdir || error "setstripe"
8192         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8193                                         error "no stripe info failed"
8194         touch $DIR/$tdir/f6
8195         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8196 }
8197 run_test 65e "directory setstripe defaults"
8198
8199 test_65f() {
8200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8201
8202         test_mkdir $DIR/${tdir}f
8203         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8204                 error "setstripe succeeded" || true
8205 }
8206 run_test 65f "dir setstripe permission (should return error) ==="
8207
8208 test_65g() {
8209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8210
8211         test_mkdir $DIR/$tdir
8212         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8213
8214         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8215                 error "setstripe -S failed"
8216         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8217         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8218                 error "delete default stripe failed"
8219 }
8220 run_test 65g "directory setstripe -d"
8221
8222 test_65h() {
8223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8224
8225         test_mkdir $DIR/$tdir
8226         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8227
8228         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8229                 error "setstripe -S failed"
8230         test_mkdir $DIR/$tdir/dd1
8231         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8232                 error "stripe info inherit failed"
8233 }
8234 run_test 65h "directory stripe info inherit ===================="
8235
8236 test_65i() {
8237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8238
8239         save_layout_restore_at_exit $MOUNT
8240
8241         # bug6367: set non-default striping on root directory
8242         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8243
8244         # bug12836: getstripe on -1 default directory striping
8245         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8246
8247         # bug12836: getstripe -v on -1 default directory striping
8248         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8249
8250         # bug12836: new find on -1 default directory striping
8251         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8252 }
8253 run_test 65i "various tests to set root directory striping"
8254
8255 test_65j() { # bug6367
8256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8257
8258         sync; sleep 1
8259
8260         # if we aren't already remounting for each test, do so for this test
8261         if [ "$I_MOUNTED" = "yes" ]; then
8262                 cleanup || error "failed to unmount"
8263                 setup
8264         fi
8265
8266         save_layout_restore_at_exit $MOUNT
8267
8268         $LFS setstripe -d $MOUNT || error "setstripe failed"
8269 }
8270 run_test 65j "set default striping on root directory (bug 6367)="
8271
8272 cleanup_65k() {
8273         rm -rf $DIR/$tdir
8274         wait_delete_completed
8275         do_facet $SINGLEMDS "lctl set_param -n \
8276                 osp.$ost*MDT0000.max_create_count=$max_count"
8277         do_facet $SINGLEMDS "lctl set_param -n \
8278                 osp.$ost*MDT0000.create_count=$count"
8279         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8280         echo $INACTIVE_OSC "is Activate"
8281
8282         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8283 }
8284
8285 test_65k() { # bug11679
8286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8287         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8288         remote_mds_nodsh && skip "remote MDS with nodsh"
8289
8290         local disable_precreate=true
8291         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8292                 disable_precreate=false
8293
8294         echo "Check OST status: "
8295         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8296                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8297
8298         for OSC in $MDS_OSCS; do
8299                 echo $OSC "is active"
8300                 do_facet $SINGLEMDS lctl --device %$OSC activate
8301         done
8302
8303         for INACTIVE_OSC in $MDS_OSCS; do
8304                 local ost=$(osc_to_ost $INACTIVE_OSC)
8305                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8306                                lov.*md*.target_obd |
8307                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8308
8309                 mkdir -p $DIR/$tdir
8310                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8311                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8312
8313                 echo "Deactivate: " $INACTIVE_OSC
8314                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8315
8316                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8317                               osp.$ost*MDT0000.create_count")
8318                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8319                                   osp.$ost*MDT0000.max_create_count")
8320                 $disable_precreate &&
8321                         do_facet $SINGLEMDS "lctl set_param -n \
8322                                 osp.$ost*MDT0000.max_create_count=0"
8323
8324                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8325                         [ -f $DIR/$tdir/$idx ] && continue
8326                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8327                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8328                                 { cleanup_65k;
8329                                   error "setstripe $idx should succeed"; }
8330                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8331                 done
8332                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8333                 rmdir $DIR/$tdir
8334
8335                 do_facet $SINGLEMDS "lctl set_param -n \
8336                         osp.$ost*MDT0000.max_create_count=$max_count"
8337                 do_facet $SINGLEMDS "lctl set_param -n \
8338                         osp.$ost*MDT0000.create_count=$count"
8339                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8340                 echo $INACTIVE_OSC "is Activate"
8341
8342                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8343         done
8344 }
8345 run_test 65k "validate manual striping works properly with deactivated OSCs"
8346
8347 test_65l() { # bug 12836
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         test_mkdir -p $DIR/$tdir/test_dir
8351         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8352         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8353 }
8354 run_test 65l "lfs find on -1 stripe dir ========================"
8355
8356 test_65m() {
8357         local layout=$(save_layout $MOUNT)
8358         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8359                 restore_layout $MOUNT $layout
8360                 error "setstripe should fail by non-root users"
8361         }
8362         true
8363 }
8364 run_test 65m "normal user can't set filesystem default stripe"
8365
8366 test_65n() {
8367         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8368         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8369                 skip "Need MDS version at least 2.12.50"
8370         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8371
8372         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8373         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8374         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8375
8376         local root_layout=$(save_layout $MOUNT)
8377         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8378
8379         # new subdirectory under root directory should not inherit
8380         # the default layout from root
8381         local dir1=$MOUNT/$tdir-1
8382         mkdir $dir1 || error "mkdir $dir1 failed"
8383         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8384                 error "$dir1 shouldn't have LOV EA"
8385
8386         # delete the default layout on root directory
8387         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8388
8389         local dir2=$MOUNT/$tdir-2
8390         mkdir $dir2 || error "mkdir $dir2 failed"
8391         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8392                 error "$dir2 shouldn't have LOV EA"
8393
8394         # set a new striping pattern on root directory
8395         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8396         local new_def_stripe_size=$((def_stripe_size * 2))
8397         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8398                 error "set stripe size on $MOUNT failed"
8399
8400         # new file created in $dir2 should inherit the new stripe size from
8401         # the filesystem default
8402         local file2=$dir2/$tfile-2
8403         touch $file2 || error "touch $file2 failed"
8404
8405         local file2_stripe_size=$($LFS getstripe -S $file2)
8406         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8407         {
8408                 echo "file2_stripe_size: '$file2_stripe_size'"
8409                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8410                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8411         }
8412
8413         local dir3=$MOUNT/$tdir-3
8414         mkdir $dir3 || error "mkdir $dir3 failed"
8415         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8416         # the root layout, which is the actual default layout that will be used
8417         # when new files are created in $dir3.
8418         local dir3_layout=$(get_layout_param $dir3)
8419         local root_dir_layout=$(get_layout_param $MOUNT)
8420         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8421         {
8422                 echo "dir3_layout: '$dir3_layout'"
8423                 echo "root_dir_layout: '$root_dir_layout'"
8424                 error "$dir3 should show the default layout from $MOUNT"
8425         }
8426
8427         # set OST pool on root directory
8428         local pool=$TESTNAME
8429         pool_add $pool || error "add $pool failed"
8430         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8431                 error "add targets to $pool failed"
8432
8433         $LFS setstripe -p $pool $MOUNT ||
8434                 error "set OST pool on $MOUNT failed"
8435
8436         # new file created in $dir3 should inherit the pool from
8437         # the filesystem default
8438         local file3=$dir3/$tfile-3
8439         touch $file3 || error "touch $file3 failed"
8440
8441         local file3_pool=$($LFS getstripe -p $file3)
8442         [[ "$file3_pool" = "$pool" ]] ||
8443                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8444
8445         local dir4=$MOUNT/$tdir-4
8446         mkdir $dir4 || error "mkdir $dir4 failed"
8447         local dir4_layout=$(get_layout_param $dir4)
8448         root_dir_layout=$(get_layout_param $MOUNT)
8449         echo "$LFS getstripe -d $dir4"
8450         $LFS getstripe -d $dir4
8451         echo "$LFS getstripe -d $MOUNT"
8452         $LFS getstripe -d $MOUNT
8453         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8454         {
8455                 echo "dir4_layout: '$dir4_layout'"
8456                 echo "root_dir_layout: '$root_dir_layout'"
8457                 error "$dir4 should show the default layout from $MOUNT"
8458         }
8459
8460         # new file created in $dir4 should inherit the pool from
8461         # the filesystem default
8462         local file4=$dir4/$tfile-4
8463         touch $file4 || error "touch $file4 failed"
8464
8465         local file4_pool=$($LFS getstripe -p $file4)
8466         [[ "$file4_pool" = "$pool" ]] ||
8467                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8468
8469         # new subdirectory under non-root directory should inherit
8470         # the default layout from its parent directory
8471         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8472                 error "set directory layout on $dir4 failed"
8473
8474         local dir5=$dir4/$tdir-5
8475         mkdir $dir5 || error "mkdir $dir5 failed"
8476
8477         dir4_layout=$(get_layout_param $dir4)
8478         local dir5_layout=$(get_layout_param $dir5)
8479         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8480         {
8481                 echo "dir4_layout: '$dir4_layout'"
8482                 echo "dir5_layout: '$dir5_layout'"
8483                 error "$dir5 should inherit the default layout from $dir4"
8484         }
8485
8486         # though subdir under ROOT doesn't inherit default layout, but
8487         # its sub dir/file should be created with default layout.
8488         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8489         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8490                 skip "Need MDS version at least 2.12.59"
8491
8492         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8493         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8494         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8495
8496         if [ $default_lmv_hash == "none" ]; then
8497                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8498         else
8499                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8500                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8501         fi
8502
8503         $LFS setdirstripe -D -c 2 $MOUNT ||
8504                 error "setdirstripe -D -c 2 failed"
8505         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8506         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8507         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8508 }
8509 run_test 65n "don't inherit default layout from root for new subdirectories"
8510
8511 # bug 2543 - update blocks count on client
8512 test_66() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         COUNT=${COUNT:-8}
8516         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8517         sync; sync_all_data; sync; sync_all_data
8518         cancel_lru_locks osc
8519         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8520         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8521 }
8522 run_test 66 "update inode blocks count on client ==============="
8523
8524 meminfo() {
8525         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8526 }
8527
8528 swap_used() {
8529         swapon -s | awk '($1 == "'$1'") { print $4 }'
8530 }
8531
8532 # bug5265, obdfilter oa2dentry return -ENOENT
8533 # #define OBD_FAIL_SRV_ENOENT 0x217
8534 test_69() {
8535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8536         remote_ost_nodsh && skip "remote OST with nodsh"
8537
8538         f="$DIR/$tfile"
8539         $LFS setstripe -c 1 -i 0 $f
8540
8541         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8542
8543         do_facet ost1 lctl set_param fail_loc=0x217
8544         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8545         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8546
8547         do_facet ost1 lctl set_param fail_loc=0
8548         $DIRECTIO write $f 0 2 || error "write error"
8549
8550         cancel_lru_locks osc
8551         $DIRECTIO read $f 0 1 || error "read error"
8552
8553         do_facet ost1 lctl set_param fail_loc=0x217
8554         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8555
8556         do_facet ost1 lctl set_param fail_loc=0
8557         rm -f $f
8558 }
8559 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8560
8561 test_71() {
8562         test_mkdir $DIR/$tdir
8563         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8564         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8565 }
8566 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8567
8568 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8570         [ "$RUNAS_ID" = "$UID" ] &&
8571                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8572         # Check that testing environment is properly set up. Skip if not
8573         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8574                 skip_env "User $RUNAS_ID does not exist - skipping"
8575
8576         touch $DIR/$tfile
8577         chmod 777 $DIR/$tfile
8578         chmod ug+s $DIR/$tfile
8579         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8580                 error "$RUNAS dd $DIR/$tfile failed"
8581         # See if we are still setuid/sgid
8582         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8583                 error "S/gid is not dropped on write"
8584         # Now test that MDS is updated too
8585         cancel_lru_locks mdc
8586         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8587                 error "S/gid is not dropped on MDS"
8588         rm -f $DIR/$tfile
8589 }
8590 run_test 72a "Test that remove suid works properly (bug5695) ===="
8591
8592 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8593         local perm
8594
8595         [ "$RUNAS_ID" = "$UID" ] &&
8596                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8597         [ "$RUNAS_ID" -eq 0 ] &&
8598                 skip_env "RUNAS_ID = 0 -- skipping"
8599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8600         # Check that testing environment is properly set up. Skip if not
8601         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8602                 skip_env "User $RUNAS_ID does not exist - skipping"
8603
8604         touch $DIR/${tfile}-f{g,u}
8605         test_mkdir $DIR/${tfile}-dg
8606         test_mkdir $DIR/${tfile}-du
8607         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8608         chmod g+s $DIR/${tfile}-{f,d}g
8609         chmod u+s $DIR/${tfile}-{f,d}u
8610         for perm in 777 2777 4777; do
8611                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8612                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8613                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8614                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8615         done
8616         true
8617 }
8618 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8619
8620 # bug 3462 - multiple simultaneous MDC requests
8621 test_73() {
8622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8623
8624         test_mkdir $DIR/d73-1
8625         test_mkdir $DIR/d73-2
8626         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8627         pid1=$!
8628
8629         lctl set_param fail_loc=0x80000129
8630         $MULTIOP $DIR/d73-1/f73-2 Oc &
8631         sleep 1
8632         lctl set_param fail_loc=0
8633
8634         $MULTIOP $DIR/d73-2/f73-3 Oc &
8635         pid3=$!
8636
8637         kill -USR1 $pid1
8638         wait $pid1 || return 1
8639
8640         sleep 25
8641
8642         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8643         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8644         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8645
8646         rm -rf $DIR/d73-*
8647 }
8648 run_test 73 "multiple MDC requests (should not deadlock)"
8649
8650 test_74a() { # bug 6149, 6184
8651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8652
8653         touch $DIR/f74a
8654         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8655         #
8656         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8657         # will spin in a tight reconnection loop
8658         $LCTL set_param fail_loc=0x8000030e
8659         # get any lock that won't be difficult - lookup works.
8660         ls $DIR/f74a
8661         $LCTL set_param fail_loc=0
8662         rm -f $DIR/f74a
8663         true
8664 }
8665 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8666
8667 test_74b() { # bug 13310
8668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8669
8670         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8671         #
8672         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8673         # will spin in a tight reconnection loop
8674         $LCTL set_param fail_loc=0x8000030e
8675         # get a "difficult" lock
8676         touch $DIR/f74b
8677         $LCTL set_param fail_loc=0
8678         rm -f $DIR/f74b
8679         true
8680 }
8681 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8682
8683 test_74c() {
8684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8685
8686         #define OBD_FAIL_LDLM_NEW_LOCK
8687         $LCTL set_param fail_loc=0x319
8688         touch $DIR/$tfile && error "touch successful"
8689         $LCTL set_param fail_loc=0
8690         true
8691 }
8692 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8693
8694 slab_lic=/sys/kernel/slab/lustre_inode_cache
8695 num_objects() {
8696         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8697         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8698                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8699 }
8700
8701 test_76a() { # Now for b=20433, added originally in b=1443
8702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8703
8704         cancel_lru_locks osc
8705         # there may be some slab objects cached per core
8706         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8707         local before=$(num_objects)
8708         local count=$((512 * cpus))
8709         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8710         local margin=$((count / 10))
8711         if [[ -f $slab_lic/aliases ]]; then
8712                 local aliases=$(cat $slab_lic/aliases)
8713                 (( aliases > 0 )) && margin=$((margin * aliases))
8714         fi
8715
8716         echo "before slab objects: $before"
8717         for i in $(seq $count); do
8718                 touch $DIR/$tfile
8719                 rm -f $DIR/$tfile
8720         done
8721         cancel_lru_locks osc
8722         local after=$(num_objects)
8723         echo "created: $count, after slab objects: $after"
8724         # shared slab counts are not very accurate, allow significant margin
8725         # the main goal is that the cache growth is not permanently > $count
8726         while (( after > before + margin )); do
8727                 sleep 1
8728                 after=$(num_objects)
8729                 wait=$((wait + 1))
8730                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8731                 if (( wait > 60 )); then
8732                         error "inode slab grew from $before+$margin to $after"
8733                 fi
8734         done
8735 }
8736 run_test 76a "confirm clients recycle inodes properly ===="
8737
8738 test_76b() {
8739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8740         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8741
8742         local count=512
8743         local before=$(num_objects)
8744
8745         for i in $(seq $count); do
8746                 mkdir $DIR/$tdir
8747                 rmdir $DIR/$tdir
8748         done
8749
8750         local after=$(num_objects)
8751         local wait=0
8752
8753         while (( after > before )); do
8754                 sleep 1
8755                 after=$(num_objects)
8756                 wait=$((wait + 1))
8757                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8758                 if (( wait > 60 )); then
8759                         error "inode slab grew from $before to $after"
8760                 fi
8761         done
8762
8763         echo "slab objects before: $before, after: $after"
8764 }
8765 run_test 76b "confirm clients recycle directory inodes properly ===="
8766
8767 export ORIG_CSUM=""
8768 set_checksums()
8769 {
8770         # Note: in sptlrpc modes which enable its own bulk checksum, the
8771         # original crc32_le bulk checksum will be automatically disabled,
8772         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8773         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8774         # In this case set_checksums() will not be no-op, because sptlrpc
8775         # bulk checksum will be enabled all through the test.
8776
8777         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8778         lctl set_param -n osc.*.checksums $1
8779         return 0
8780 }
8781
8782 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8783                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8784 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8785                              tr -d [] | head -n1)}
8786 set_checksum_type()
8787 {
8788         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8789         rc=$?
8790         log "set checksum type to $1, rc = $rc"
8791         return $rc
8792 }
8793
8794 get_osc_checksum_type()
8795 {
8796         # arugment 1: OST name, like OST0000
8797         ost=$1
8798         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8799                         sed 's/.*\[\(.*\)\].*/\1/g')
8800         rc=$?
8801         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8802         echo $checksum_type
8803 }
8804
8805 F77_TMP=$TMP/f77-temp
8806 F77SZ=8
8807 setup_f77() {
8808         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8809                 error "error writing to $F77_TMP"
8810 }
8811
8812 test_77a() { # bug 10889
8813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8814         $GSS && skip_env "could not run with gss"
8815
8816         [ ! -f $F77_TMP ] && setup_f77
8817         set_checksums 1
8818         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8819         set_checksums 0
8820         rm -f $DIR/$tfile
8821 }
8822 run_test 77a "normal checksum read/write operation"
8823
8824 test_77b() { # bug 10889
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826         $GSS && skip_env "could not run with gss"
8827
8828         [ ! -f $F77_TMP ] && setup_f77
8829         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8830         $LCTL set_param fail_loc=0x80000409
8831         set_checksums 1
8832
8833         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8834                 error "dd error: $?"
8835         $LCTL set_param fail_loc=0
8836
8837         for algo in $CKSUM_TYPES; do
8838                 cancel_lru_locks osc
8839                 set_checksum_type $algo
8840                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8841                 $LCTL set_param fail_loc=0x80000408
8842                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8843                 $LCTL set_param fail_loc=0
8844         done
8845         set_checksums 0
8846         set_checksum_type $ORIG_CSUM_TYPE
8847         rm -f $DIR/$tfile
8848 }
8849 run_test 77b "checksum error on client write, read"
8850
8851 cleanup_77c() {
8852         trap 0
8853         set_checksums 0
8854         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8855         $check_ost &&
8856                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8857         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8858         $check_ost && [ -n "$ost_file_prefix" ] &&
8859                 do_facet ost1 rm -f ${ost_file_prefix}\*
8860 }
8861
8862 test_77c() {
8863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8864         $GSS && skip_env "could not run with gss"
8865         remote_ost_nodsh && skip "remote OST with nodsh"
8866
8867         local bad1
8868         local osc_file_prefix
8869         local osc_file
8870         local check_ost=false
8871         local ost_file_prefix
8872         local ost_file
8873         local orig_cksum
8874         local dump_cksum
8875         local fid
8876
8877         # ensure corruption will occur on first OSS/OST
8878         $LFS setstripe -i 0 $DIR/$tfile
8879
8880         [ ! -f $F77_TMP ] && setup_f77
8881         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8882                 error "dd write error: $?"
8883         fid=$($LFS path2fid $DIR/$tfile)
8884
8885         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8886         then
8887                 check_ost=true
8888                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8889                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8890         else
8891                 echo "OSS do not support bulk pages dump upon error"
8892         fi
8893
8894         osc_file_prefix=$($LCTL get_param -n debug_path)
8895         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8896
8897         trap cleanup_77c EXIT
8898
8899         set_checksums 1
8900         # enable bulk pages dump upon error on Client
8901         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8902         # enable bulk pages dump upon error on OSS
8903         $check_ost &&
8904                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8905
8906         # flush Client cache to allow next read to reach OSS
8907         cancel_lru_locks osc
8908
8909         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8910         $LCTL set_param fail_loc=0x80000408
8911         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8912         $LCTL set_param fail_loc=0
8913
8914         rm -f $DIR/$tfile
8915
8916         # check cksum dump on Client
8917         osc_file=$(ls ${osc_file_prefix}*)
8918         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8919         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8920         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8921         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8922         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8923                      cksum)
8924         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8925         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8926                 error "dump content does not match on Client"
8927
8928         $check_ost || skip "No need to check cksum dump on OSS"
8929
8930         # check cksum dump on OSS
8931         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8932         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8933         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8934         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8935         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8936                 error "dump content does not match on OSS"
8937
8938         cleanup_77c
8939 }
8940 run_test 77c "checksum error on client read with debug"
8941
8942 test_77d() { # bug 10889
8943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8944         $GSS && skip_env "could not run with gss"
8945
8946         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8947         $LCTL set_param fail_loc=0x80000409
8948         set_checksums 1
8949         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8950                 error "direct write: rc=$?"
8951         $LCTL set_param fail_loc=0
8952         set_checksums 0
8953
8954         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8955         $LCTL set_param fail_loc=0x80000408
8956         set_checksums 1
8957         cancel_lru_locks osc
8958         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8959                 error "direct read: rc=$?"
8960         $LCTL set_param fail_loc=0
8961         set_checksums 0
8962 }
8963 run_test 77d "checksum error on OST direct write, read"
8964
8965 test_77f() { # bug 10889
8966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8967         $GSS && skip_env "could not run with gss"
8968
8969         set_checksums 1
8970         for algo in $CKSUM_TYPES; do
8971                 cancel_lru_locks osc
8972                 set_checksum_type $algo
8973                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8974                 $LCTL set_param fail_loc=0x409
8975                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8976                         error "direct write succeeded"
8977                 $LCTL set_param fail_loc=0
8978         done
8979         set_checksum_type $ORIG_CSUM_TYPE
8980         set_checksums 0
8981 }
8982 run_test 77f "repeat checksum error on write (expect error)"
8983
8984 test_77g() { # bug 10889
8985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8986         $GSS && skip_env "could not run with gss"
8987         remote_ost_nodsh && skip "remote OST with nodsh"
8988
8989         [ ! -f $F77_TMP ] && setup_f77
8990
8991         local file=$DIR/$tfile
8992         stack_trap "rm -f $file" EXIT
8993
8994         $LFS setstripe -c 1 -i 0 $file
8995         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8996         do_facet ost1 lctl set_param fail_loc=0x8000021a
8997         set_checksums 1
8998         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8999                 error "write error: rc=$?"
9000         do_facet ost1 lctl set_param fail_loc=0
9001         set_checksums 0
9002
9003         cancel_lru_locks osc
9004         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9005         do_facet ost1 lctl set_param fail_loc=0x8000021b
9006         set_checksums 1
9007         cmp $F77_TMP $file || error "file compare failed"
9008         do_facet ost1 lctl set_param fail_loc=0
9009         set_checksums 0
9010 }
9011 run_test 77g "checksum error on OST write, read"
9012
9013 test_77k() { # LU-10906
9014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9015         $GSS && skip_env "could not run with gss"
9016
9017         local cksum_param="osc.$FSNAME*.checksums"
9018         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9019         local checksum
9020         local i
9021
9022         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9023         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9024         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9025
9026         for i in 0 1; do
9027                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9028                         error "failed to set checksum=$i on MGS"
9029                 wait_update $HOSTNAME "$get_checksum" $i
9030                 #remount
9031                 echo "remount client, checksum should be $i"
9032                 remount_client $MOUNT || error "failed to remount client"
9033                 checksum=$(eval $get_checksum)
9034                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9035         done
9036         # remove persistent param to avoid races with checksum mountopt below
9037         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9038                 error "failed to delete checksum on MGS"
9039
9040         for opt in "checksum" "nochecksum"; do
9041                 #remount with mount option
9042                 echo "remount client with option $opt, checksum should be $i"
9043                 umount_client $MOUNT || error "failed to umount client"
9044                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9045                         error "failed to mount client with option '$opt'"
9046                 checksum=$(eval $get_checksum)
9047                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9048                 i=$((i - 1))
9049         done
9050
9051         remount_client $MOUNT || error "failed to remount client"
9052 }
9053 run_test 77k "enable/disable checksum correctly"
9054
9055 test_77l() {
9056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9057         $GSS && skip_env "could not run with gss"
9058
9059         set_checksums 1
9060         stack_trap "set_checksums $ORIG_CSUM" EXIT
9061         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9062
9063         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9064
9065         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9066         for algo in $CKSUM_TYPES; do
9067                 set_checksum_type $algo || error "fail to set checksum type $algo"
9068                 osc_algo=$(get_osc_checksum_type OST0000)
9069                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9070
9071                 # no locks, no reqs to let the connection idle
9072                 cancel_lru_locks osc
9073                 lru_resize_disable osc
9074                 wait_osc_import_state client ost1 IDLE
9075
9076                 # ensure ost1 is connected
9077                 stat $DIR/$tfile >/dev/null || error "can't stat"
9078                 wait_osc_import_state client ost1 FULL
9079
9080                 osc_algo=$(get_osc_checksum_type OST0000)
9081                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9082         done
9083         return 0
9084 }
9085 run_test 77l "preferred checksum type is remembered after reconnected"
9086
9087 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9088 rm -f $F77_TMP
9089 unset F77_TMP
9090
9091 cleanup_test_78() {
9092         trap 0
9093         rm -f $DIR/$tfile
9094 }
9095
9096 test_78() { # bug 10901
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098         remote_ost || skip_env "local OST"
9099
9100         NSEQ=5
9101         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9102         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9103         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9104         echo "MemTotal: $MEMTOTAL"
9105
9106         # reserve 256MB of memory for the kernel and other running processes,
9107         # and then take 1/2 of the remaining memory for the read/write buffers.
9108         if [ $MEMTOTAL -gt 512 ] ;then
9109                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9110         else
9111                 # for those poor memory-starved high-end clusters...
9112                 MEMTOTAL=$((MEMTOTAL / 2))
9113         fi
9114         echo "Mem to use for directio: $MEMTOTAL"
9115
9116         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9117         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9118         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9119         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9120                 head -n1)
9121         echo "Smallest OST: $SMALLESTOST"
9122         [[ $SMALLESTOST -lt 10240 ]] &&
9123                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9124
9125         trap cleanup_test_78 EXIT
9126
9127         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9128                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9129
9130         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9131         echo "File size: $F78SIZE"
9132         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9133         for i in $(seq 1 $NSEQ); do
9134                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9135                 echo directIO rdwr round $i of $NSEQ
9136                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9137         done
9138
9139         cleanup_test_78
9140 }
9141 run_test 78 "handle large O_DIRECT writes correctly ============"
9142
9143 test_79() { # bug 12743
9144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9145
9146         wait_delete_completed
9147
9148         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9149         BKFREE=$(calc_osc_kbytes kbytesfree)
9150         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9151
9152         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9153         DFTOTAL=`echo $STRING | cut -d, -f1`
9154         DFUSED=`echo $STRING  | cut -d, -f2`
9155         DFAVAIL=`echo $STRING | cut -d, -f3`
9156         DFFREE=$(($DFTOTAL - $DFUSED))
9157
9158         ALLOWANCE=$((64 * $OSTCOUNT))
9159
9160         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9161            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9162                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9163         fi
9164         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9165            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9166                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9167         fi
9168         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9169            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9170                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9171         fi
9172 }
9173 run_test 79 "df report consistency check ======================="
9174
9175 test_80() { # bug 10718
9176         remote_ost_nodsh && skip "remote OST with nodsh"
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178
9179         # relax strong synchronous semantics for slow backends like ZFS
9180         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9181                 local soc="obdfilter.*.sync_lock_cancel"
9182                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9183
9184                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9185                 if [ -z "$save" ]; then
9186                         soc="obdfilter.*.sync_on_lock_cancel"
9187                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9188                 fi
9189
9190                 if [ "$save" != "never" ]; then
9191                         local hosts=$(comma_list $(osts_nodes))
9192
9193                         do_nodes $hosts $LCTL set_param $soc=never
9194                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9195                 fi
9196         fi
9197
9198         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9199         sync; sleep 1; sync
9200         local before=$(date +%s)
9201         cancel_lru_locks osc
9202         local after=$(date +%s)
9203         local diff=$((after - before))
9204         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9205
9206         rm -f $DIR/$tfile
9207 }
9208 run_test 80 "Page eviction is equally fast at high offsets too"
9209
9210 test_81a() { # LU-456
9211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9212         remote_ost_nodsh && skip "remote OST with nodsh"
9213
9214         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9215         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9216         do_facet ost1 lctl set_param fail_loc=0x80000228
9217
9218         # write should trigger a retry and success
9219         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9220         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9221         RC=$?
9222         if [ $RC -ne 0 ] ; then
9223                 error "write should success, but failed for $RC"
9224         fi
9225 }
9226 run_test 81a "OST should retry write when get -ENOSPC ==============="
9227
9228 test_81b() { # LU-456
9229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9230         remote_ost_nodsh && skip "remote OST with nodsh"
9231
9232         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9233         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9234         do_facet ost1 lctl set_param fail_loc=0x228
9235
9236         # write should retry several times and return -ENOSPC finally
9237         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9238         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9239         RC=$?
9240         ENOSPC=28
9241         if [ $RC -ne $ENOSPC ] ; then
9242                 error "dd should fail for -ENOSPC, but succeed."
9243         fi
9244 }
9245 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9246
9247 test_99() {
9248         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9249
9250         test_mkdir $DIR/$tdir.cvsroot
9251         chown $RUNAS_ID $DIR/$tdir.cvsroot
9252
9253         cd $TMP
9254         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9255
9256         cd /etc/init.d
9257         # some versions of cvs import exit(1) when asked to import links or
9258         # files they can't read.  ignore those files.
9259         local toignore=$(find . -type l -printf '-I %f\n' -o \
9260                          ! -perm /4 -printf '-I %f\n')
9261         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9262                 $tdir.reposname vtag rtag
9263
9264         cd $DIR
9265         test_mkdir $DIR/$tdir.reposname
9266         chown $RUNAS_ID $DIR/$tdir.reposname
9267         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9268
9269         cd $DIR/$tdir.reposname
9270         $RUNAS touch foo99
9271         $RUNAS cvs add -m 'addmsg' foo99
9272         $RUNAS cvs update
9273         $RUNAS cvs commit -m 'nomsg' foo99
9274         rm -fr $DIR/$tdir.cvsroot
9275 }
9276 run_test 99 "cvs strange file/directory operations"
9277
9278 test_100() {
9279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9280         [[ "$NETTYPE" =~ tcp ]] ||
9281                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9282         remote_ost_nodsh && skip "remote OST with nodsh"
9283         remote_mds_nodsh && skip "remote MDS with nodsh"
9284         remote_servers ||
9285                 skip "useless for local single node setup"
9286
9287         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9288                 [ "$PROT" != "tcp" ] && continue
9289                 RPORT=$(echo $REMOTE | cut -d: -f2)
9290                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9291
9292                 rc=0
9293                 LPORT=`echo $LOCAL | cut -d: -f2`
9294                 if [ $LPORT -ge 1024 ]; then
9295                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9296                         netstat -tna
9297                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9298                 fi
9299         done
9300         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9301 }
9302 run_test 100 "check local port using privileged port ==========="
9303
9304 function get_named_value()
9305 {
9306     local tag
9307
9308     tag=$1
9309     while read ;do
9310         line=$REPLY
9311         case $line in
9312         $tag*)
9313             echo $line | sed "s/^$tag[ ]*//"
9314             break
9315             ;;
9316         esac
9317     done
9318 }
9319
9320 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9321                    awk '/^max_cached_mb/ { print $2 }')
9322
9323 cleanup_101a() {
9324         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9325         trap 0
9326 }
9327
9328 test_101a() {
9329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9330
9331         local s
9332         local discard
9333         local nreads=10000
9334         local cache_limit=32
9335
9336         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9337         trap cleanup_101a EXIT
9338         $LCTL set_param -n llite.*.read_ahead_stats 0
9339         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9340
9341         #
9342         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9343         #
9344         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9345         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9346
9347         discard=0
9348         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9349                 get_named_value 'read but discarded' | cut -d" " -f1); do
9350                         discard=$(($discard + $s))
9351         done
9352         cleanup_101a
9353
9354         $LCTL get_param osc.*-osc*.rpc_stats
9355         $LCTL get_param llite.*.read_ahead_stats
9356
9357         # Discard is generally zero, but sometimes a few random reads line up
9358         # and trigger larger readahead, which is wasted & leads to discards.
9359         if [[ $(($discard)) -gt $nreads ]]; then
9360                 error "too many ($discard) discarded pages"
9361         fi
9362         rm -f $DIR/$tfile || true
9363 }
9364 run_test 101a "check read-ahead for random reads"
9365
9366 setup_test101bc() {
9367         test_mkdir $DIR/$tdir
9368         local ssize=$1
9369         local FILE_LENGTH=$2
9370         STRIPE_OFFSET=0
9371
9372         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9373
9374         local list=$(comma_list $(osts_nodes))
9375         set_osd_param $list '' read_cache_enable 0
9376         set_osd_param $list '' writethrough_cache_enable 0
9377
9378         trap cleanup_test101bc EXIT
9379         # prepare the read-ahead file
9380         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9381
9382         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9383                                 count=$FILE_SIZE_MB 2> /dev/null
9384
9385 }
9386
9387 cleanup_test101bc() {
9388         trap 0
9389         rm -rf $DIR/$tdir
9390         rm -f $DIR/$tfile
9391
9392         local list=$(comma_list $(osts_nodes))
9393         set_osd_param $list '' read_cache_enable 1
9394         set_osd_param $list '' writethrough_cache_enable 1
9395 }
9396
9397 calc_total() {
9398         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9399 }
9400
9401 ra_check_101() {
9402         local READ_SIZE=$1
9403         local STRIPE_SIZE=$2
9404         local FILE_LENGTH=$3
9405         local RA_INC=1048576
9406         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9407         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9408                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9409         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9410                         get_named_value 'read but discarded' |
9411                         cut -d" " -f1 | calc_total)
9412         if [[ $DISCARD -gt $discard_limit ]]; then
9413                 $LCTL get_param llite.*.read_ahead_stats
9414                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9415         else
9416                 echo "Read-ahead success for size ${READ_SIZE}"
9417         fi
9418 }
9419
9420 test_101b() {
9421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9422         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9423
9424         local STRIPE_SIZE=1048576
9425         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9426
9427         if [ $SLOW == "yes" ]; then
9428                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9429         else
9430                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9431         fi
9432
9433         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9434
9435         # prepare the read-ahead file
9436         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9437         cancel_lru_locks osc
9438         for BIDX in 2 4 8 16 32 64 128 256
9439         do
9440                 local BSIZE=$((BIDX*4096))
9441                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9442                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9443                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9444                 $LCTL set_param -n llite.*.read_ahead_stats 0
9445                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9446                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9447                 cancel_lru_locks osc
9448                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9449         done
9450         cleanup_test101bc
9451         true
9452 }
9453 run_test 101b "check stride-io mode read-ahead ================="
9454
9455 test_101c() {
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457
9458         local STRIPE_SIZE=1048576
9459         local FILE_LENGTH=$((STRIPE_SIZE*100))
9460         local nreads=10000
9461         local rsize=65536
9462         local osc_rpc_stats
9463
9464         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9465
9466         cancel_lru_locks osc
9467         $LCTL set_param osc.*.rpc_stats 0
9468         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9469         $LCTL get_param osc.*.rpc_stats
9470         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9471                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9472                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9473                 local size
9474
9475                 if [ $lines -le 20 ]; then
9476                         echo "continue debug"
9477                         continue
9478                 fi
9479                 for size in 1 2 4 8; do
9480                         local rpc=$(echo "$stats" |
9481                                     awk '($1 == "'$size':") {print $2; exit; }')
9482                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9483                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9484                 done
9485                 echo "$osc_rpc_stats check passed!"
9486         done
9487         cleanup_test101bc
9488         true
9489 }
9490 run_test 101c "check stripe_size aligned read-ahead ================="
9491
9492 test_101d() {
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494
9495         local file=$DIR/$tfile
9496         local sz_MB=${FILESIZE_101d:-80}
9497         local ra_MB=${READAHEAD_MB:-40}
9498
9499         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9500         [ $free_MB -lt $sz_MB ] &&
9501                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9502
9503         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9504         $LFS setstripe -c -1 $file || error "setstripe failed"
9505
9506         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9507         echo Cancel LRU locks on lustre client to flush the client cache
9508         cancel_lru_locks osc
9509
9510         echo Disable read-ahead
9511         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9512         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9513         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9514         $LCTL get_param -n llite.*.max_read_ahead_mb
9515
9516         echo "Reading the test file $file with read-ahead disabled"
9517         local sz_KB=$((sz_MB * 1024 / 4))
9518         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9519         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9520         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9521                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9522
9523         echo "Cancel LRU locks on lustre client to flush the client cache"
9524         cancel_lru_locks osc
9525         echo Enable read-ahead with ${ra_MB}MB
9526         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9527
9528         echo "Reading the test file $file with read-ahead enabled"
9529         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9530                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9531
9532         echo "read-ahead disabled time read $raOFF"
9533         echo "read-ahead enabled time read $raON"
9534
9535         rm -f $file
9536         wait_delete_completed
9537
9538         # use awk for this check instead of bash because it handles decimals
9539         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9540                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9541 }
9542 run_test 101d "file read with and without read-ahead enabled"
9543
9544 test_101e() {
9545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9546
9547         local file=$DIR/$tfile
9548         local size_KB=500  #KB
9549         local count=100
9550         local bsize=1024
9551
9552         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9553         local need_KB=$((count * size_KB))
9554         [[ $free_KB -le $need_KB ]] &&
9555                 skip_env "Need free space $need_KB, have $free_KB"
9556
9557         echo "Creating $count ${size_KB}K test files"
9558         for ((i = 0; i < $count; i++)); do
9559                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9560         done
9561
9562         echo "Cancel LRU locks on lustre client to flush the client cache"
9563         cancel_lru_locks $OSC
9564
9565         echo "Reset readahead stats"
9566         $LCTL set_param -n llite.*.read_ahead_stats 0
9567
9568         for ((i = 0; i < $count; i++)); do
9569                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9570         done
9571
9572         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9573                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9574
9575         for ((i = 0; i < $count; i++)); do
9576                 rm -rf $file.$i 2>/dev/null
9577         done
9578
9579         #10000 means 20% reads are missing in readahead
9580         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9581 }
9582 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9583
9584 test_101f() {
9585         which iozone || skip_env "no iozone installed"
9586
9587         local old_debug=$($LCTL get_param debug)
9588         old_debug=${old_debug#*=}
9589         $LCTL set_param debug="reada mmap"
9590
9591         # create a test file
9592         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9593
9594         echo Cancel LRU locks on lustre client to flush the client cache
9595         cancel_lru_locks osc
9596
9597         echo Reset readahead stats
9598         $LCTL set_param -n llite.*.read_ahead_stats 0
9599
9600         echo mmap read the file with small block size
9601         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9602                 > /dev/null 2>&1
9603
9604         echo checking missing pages
9605         $LCTL get_param llite.*.read_ahead_stats
9606         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9607                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9608
9609         $LCTL set_param debug="$old_debug"
9610         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9611         rm -f $DIR/$tfile
9612 }
9613 run_test 101f "check mmap read performance"
9614
9615 test_101g_brw_size_test() {
9616         local mb=$1
9617         local pages=$((mb * 1048576 / PAGE_SIZE))
9618         local file=$DIR/$tfile
9619
9620         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9621                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9622         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9623                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9624                         return 2
9625         done
9626
9627         stack_trap "rm -f $file" EXIT
9628         $LCTL set_param -n osc.*.rpc_stats=0
9629
9630         # 10 RPCs should be enough for the test
9631         local count=10
9632         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9633                 { error "dd write ${mb} MB blocks failed"; return 3; }
9634         cancel_lru_locks osc
9635         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9636                 { error "dd write ${mb} MB blocks failed"; return 4; }
9637
9638         # calculate number of full-sized read and write RPCs
9639         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9640                 sed -n '/pages per rpc/,/^$/p' |
9641                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9642                 END { print reads,writes }'))
9643         # allow one extra full-sized read RPC for async readahead
9644         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9645                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9646         [[ ${rpcs[1]} == $count ]] ||
9647                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9648 }
9649
9650 test_101g() {
9651         remote_ost_nodsh && skip "remote OST with nodsh"
9652
9653         local rpcs
9654         local osts=$(get_facets OST)
9655         local list=$(comma_list $(osts_nodes))
9656         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9657         local brw_size="obdfilter.*.brw_size"
9658
9659         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9660
9661         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9662
9663         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9664                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9665                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9666            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9667                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9668                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9669
9670                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9671                         suffix="M"
9672
9673                 if [[ $orig_mb -lt 16 ]]; then
9674                         save_lustre_params $osts "$brw_size" > $p
9675                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9676                                 error "set 16MB RPC size failed"
9677
9678                         echo "remount client to enable new RPC size"
9679                         remount_client $MOUNT || error "remount_client failed"
9680                 fi
9681
9682                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9683                 # should be able to set brw_size=12, but no rpc_stats for that
9684                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9685         fi
9686
9687         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9688
9689         if [[ $orig_mb -lt 16 ]]; then
9690                 restore_lustre_params < $p
9691                 remount_client $MOUNT || error "remount_client restore failed"
9692         fi
9693
9694         rm -f $p $DIR/$tfile
9695 }
9696 run_test 101g "Big bulk(4/16 MiB) readahead"
9697
9698 test_101h() {
9699         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9700
9701         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9702                 error "dd 70M file failed"
9703         echo Cancel LRU locks on lustre client to flush the client cache
9704         cancel_lru_locks osc
9705
9706         echo "Reset readahead stats"
9707         $LCTL set_param -n llite.*.read_ahead_stats 0
9708
9709         echo "Read 10M of data but cross 64M bundary"
9710         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9711         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9712                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9713         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9714         rm -f $p $DIR/$tfile
9715 }
9716 run_test 101h "Readahead should cover current read window"
9717
9718 test_101i() {
9719         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9720                 error "dd 10M file failed"
9721
9722         local max_per_file_mb=$($LCTL get_param -n \
9723                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9724         cancel_lru_locks osc
9725         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9726         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9727                 error "set max_read_ahead_per_file_mb to 1 failed"
9728
9729         echo "Reset readahead stats"
9730         $LCTL set_param llite.*.read_ahead_stats=0
9731
9732         dd if=$DIR/$tfile of=/dev/null bs=2M
9733
9734         $LCTL get_param llite.*.read_ahead_stats
9735         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9736                      awk '/misses/ { print $2 }')
9737         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9738         rm -f $DIR/$tfile
9739 }
9740 run_test 101i "allow current readahead to exceed reservation"
9741
9742 test_101j() {
9743         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9744                 error "setstripe $DIR/$tfile failed"
9745         local file_size=$((1048576 * 16))
9746         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9747         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9748
9749         echo Disable read-ahead
9750         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9751
9752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9753         for blk in $PAGE_SIZE 1048576 $file_size; do
9754                 cancel_lru_locks osc
9755                 echo "Reset readahead stats"
9756                 $LCTL set_param -n llite.*.read_ahead_stats=0
9757                 local count=$(($file_size / $blk))
9758                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9759                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9760                              get_named_value 'failed to fast read' |
9761                              cut -d" " -f1 | calc_total)
9762                 $LCTL get_param -n llite.*.read_ahead_stats
9763                 [ $miss -eq $count ] || error "expected $count got $miss"
9764         done
9765
9766         rm -f $p $DIR/$tfile
9767 }
9768 run_test 101j "A complete read block should be submitted when no RA"
9769
9770 setup_test102() {
9771         test_mkdir $DIR/$tdir
9772         chown $RUNAS_ID $DIR/$tdir
9773         STRIPE_SIZE=65536
9774         STRIPE_OFFSET=1
9775         STRIPE_COUNT=$OSTCOUNT
9776         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9777
9778         trap cleanup_test102 EXIT
9779         cd $DIR
9780         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9781         cd $DIR/$tdir
9782         for num in 1 2 3 4; do
9783                 for count in $(seq 1 $STRIPE_COUNT); do
9784                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9785                                 local size=`expr $STRIPE_SIZE \* $num`
9786                                 local file=file"$num-$idx-$count"
9787                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9788                         done
9789                 done
9790         done
9791
9792         cd $DIR
9793         $1 tar cf $TMP/f102.tar $tdir --xattrs
9794 }
9795
9796 cleanup_test102() {
9797         trap 0
9798         rm -f $TMP/f102.tar
9799         rm -rf $DIR/d0.sanity/d102
9800 }
9801
9802 test_102a() {
9803         [ "$UID" != 0 ] && skip "must run as root"
9804         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9805                 skip_env "must have user_xattr"
9806
9807         [ -z "$(which setfattr 2>/dev/null)" ] &&
9808                 skip_env "could not find setfattr"
9809
9810         local testfile=$DIR/$tfile
9811
9812         touch $testfile
9813         echo "set/get xattr..."
9814         setfattr -n trusted.name1 -v value1 $testfile ||
9815                 error "setfattr -n trusted.name1=value1 $testfile failed"
9816         getfattr -n trusted.name1 $testfile 2> /dev/null |
9817           grep "trusted.name1=.value1" ||
9818                 error "$testfile missing trusted.name1=value1"
9819
9820         setfattr -n user.author1 -v author1 $testfile ||
9821                 error "setfattr -n user.author1=author1 $testfile failed"
9822         getfattr -n user.author1 $testfile 2> /dev/null |
9823           grep "user.author1=.author1" ||
9824                 error "$testfile missing trusted.author1=author1"
9825
9826         echo "listxattr..."
9827         setfattr -n trusted.name2 -v value2 $testfile ||
9828                 error "$testfile unable to set trusted.name2"
9829         setfattr -n trusted.name3 -v value3 $testfile ||
9830                 error "$testfile unable to set trusted.name3"
9831         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9832             grep "trusted.name" | wc -l) -eq 3 ] ||
9833                 error "$testfile missing 3 trusted.name xattrs"
9834
9835         setfattr -n user.author2 -v author2 $testfile ||
9836                 error "$testfile unable to set user.author2"
9837         setfattr -n user.author3 -v author3 $testfile ||
9838                 error "$testfile unable to set user.author3"
9839         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9840             grep "user.author" | wc -l) -eq 3 ] ||
9841                 error "$testfile missing 3 user.author xattrs"
9842
9843         echo "remove xattr..."
9844         setfattr -x trusted.name1 $testfile ||
9845                 error "$testfile error deleting trusted.name1"
9846         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9847                 error "$testfile did not delete trusted.name1 xattr"
9848
9849         setfattr -x user.author1 $testfile ||
9850                 error "$testfile error deleting user.author1"
9851         echo "set lustre special xattr ..."
9852         $LFS setstripe -c1 $testfile
9853         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9854                 awk -F "=" '/trusted.lov/ { print $2 }' )
9855         setfattr -n "trusted.lov" -v $lovea $testfile ||
9856                 error "$testfile doesn't ignore setting trusted.lov again"
9857         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9858                 error "$testfile allow setting invalid trusted.lov"
9859         rm -f $testfile
9860 }
9861 run_test 102a "user xattr test =================================="
9862
9863 check_102b_layout() {
9864         local layout="$*"
9865         local testfile=$DIR/$tfile
9866
9867         echo "test layout '$layout'"
9868         $LFS setstripe $layout $testfile || error "setstripe failed"
9869         $LFS getstripe -y $testfile
9870
9871         echo "get/set/list trusted.lov xattr ..." # b=10930
9872         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9873         [[ "$value" =~ "trusted.lov" ]] ||
9874                 error "can't get trusted.lov from $testfile"
9875         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9876                 error "getstripe failed"
9877
9878         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9879
9880         value=$(cut -d= -f2 <<<$value)
9881         # LU-13168: truncated xattr should fail if short lov_user_md header
9882         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9883                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9884         for len in $lens; do
9885                 echo "setfattr $len $testfile.2"
9886                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9887                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9888         done
9889         local stripe_size=$($LFS getstripe -S $testfile.2)
9890         local stripe_count=$($LFS getstripe -c $testfile.2)
9891         [[ $stripe_size -eq 65536 ]] ||
9892                 error "stripe size $stripe_size != 65536"
9893         [[ $stripe_count -eq $stripe_count_orig ]] ||
9894                 error "stripe count $stripe_count != $stripe_count_orig"
9895         rm $testfile $testfile.2
9896 }
9897
9898 test_102b() {
9899         [ -z "$(which setfattr 2>/dev/null)" ] &&
9900                 skip_env "could not find setfattr"
9901         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9902
9903         # check plain layout
9904         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9905
9906         # and also check composite layout
9907         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9908
9909 }
9910 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9911
9912 test_102c() {
9913         [ -z "$(which setfattr 2>/dev/null)" ] &&
9914                 skip_env "could not find setfattr"
9915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9916
9917         # b10930: get/set/list lustre.lov xattr
9918         echo "get/set/list lustre.lov xattr ..."
9919         test_mkdir $DIR/$tdir
9920         chown $RUNAS_ID $DIR/$tdir
9921         local testfile=$DIR/$tdir/$tfile
9922         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9923                 error "setstripe failed"
9924         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9925                 error "getstripe failed"
9926         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9927         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9928
9929         local testfile2=${testfile}2
9930         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9931                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9932
9933         $RUNAS $MCREATE $testfile2
9934         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9935         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9936         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9937         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9938         [ $stripe_count -eq $STRIPECOUNT ] ||
9939                 error "stripe count $stripe_count != $STRIPECOUNT"
9940 }
9941 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9942
9943 compare_stripe_info1() {
9944         local stripe_index_all_zero=true
9945
9946         for num in 1 2 3 4; do
9947                 for count in $(seq 1 $STRIPE_COUNT); do
9948                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9949                                 local size=$((STRIPE_SIZE * num))
9950                                 local file=file"$num-$offset-$count"
9951                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9952                                 [[ $stripe_size -ne $size ]] &&
9953                                     error "$file: size $stripe_size != $size"
9954                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9955                                 # allow fewer stripes to be created, ORI-601
9956                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9957                                     error "$file: count $stripe_count != $count"
9958                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9959                                 [[ $stripe_index -ne 0 ]] &&
9960                                         stripe_index_all_zero=false
9961                         done
9962                 done
9963         done
9964         $stripe_index_all_zero &&
9965                 error "all files are being extracted starting from OST index 0"
9966         return 0
9967 }
9968
9969 have_xattrs_include() {
9970         tar --help | grep -q xattrs-include &&
9971                 echo --xattrs-include="lustre.*"
9972 }
9973
9974 test_102d() {
9975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9976         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9977
9978         XINC=$(have_xattrs_include)
9979         setup_test102
9980         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9981         cd $DIR/$tdir/$tdir
9982         compare_stripe_info1
9983 }
9984 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9985
9986 test_102f() {
9987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9989
9990         XINC=$(have_xattrs_include)
9991         setup_test102
9992         test_mkdir $DIR/$tdir.restore
9993         cd $DIR
9994         tar cf - --xattrs $tdir | tar xf - \
9995                 -C $DIR/$tdir.restore --xattrs $XINC
9996         cd $DIR/$tdir.restore/$tdir
9997         compare_stripe_info1
9998 }
9999 run_test 102f "tar copy files, not keep osts"
10000
10001 grow_xattr() {
10002         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10003                 skip "must have user_xattr"
10004         [ -z "$(which setfattr 2>/dev/null)" ] &&
10005                 skip_env "could not find setfattr"
10006         [ -z "$(which getfattr 2>/dev/null)" ] &&
10007                 skip_env "could not find getfattr"
10008
10009         local xsize=${1:-1024}  # in bytes
10010         local file=$DIR/$tfile
10011         local value="$(generate_string $xsize)"
10012         local xbig=trusted.big
10013         local toobig=$2
10014
10015         touch $file
10016         log "save $xbig on $file"
10017         if [ -z "$toobig" ]
10018         then
10019                 setfattr -n $xbig -v $value $file ||
10020                         error "saving $xbig on $file failed"
10021         else
10022                 setfattr -n $xbig -v $value $file &&
10023                         error "saving $xbig on $file succeeded"
10024                 return 0
10025         fi
10026
10027         local orig=$(get_xattr_value $xbig $file)
10028         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10029
10030         local xsml=trusted.sml
10031         log "save $xsml on $file"
10032         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10033
10034         local new=$(get_xattr_value $xbig $file)
10035         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10036
10037         log "grow $xsml on $file"
10038         setfattr -n $xsml -v "$value" $file ||
10039                 error "growing $xsml on $file failed"
10040
10041         new=$(get_xattr_value $xbig $file)
10042         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10043         log "$xbig still valid after growing $xsml"
10044
10045         rm -f $file
10046 }
10047
10048 test_102h() { # bug 15777
10049         grow_xattr 1024
10050 }
10051 run_test 102h "grow xattr from inside inode to external block"
10052
10053 test_102ha() {
10054         large_xattr_enabled || skip_env "ea_inode feature disabled"
10055
10056         echo "setting xattr of max xattr size: $(max_xattr_size)"
10057         grow_xattr $(max_xattr_size)
10058
10059         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10060         echo "This should fail:"
10061         grow_xattr $(($(max_xattr_size) + 10)) 1
10062 }
10063 run_test 102ha "grow xattr from inside inode to external inode"
10064
10065 test_102i() { # bug 17038
10066         [ -z "$(which getfattr 2>/dev/null)" ] &&
10067                 skip "could not find getfattr"
10068
10069         touch $DIR/$tfile
10070         ln -s $DIR/$tfile $DIR/${tfile}link
10071         getfattr -n trusted.lov $DIR/$tfile ||
10072                 error "lgetxattr on $DIR/$tfile failed"
10073         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10074                 grep -i "no such attr" ||
10075                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10076         rm -f $DIR/$tfile $DIR/${tfile}link
10077 }
10078 run_test 102i "lgetxattr test on symbolic link ============"
10079
10080 test_102j() {
10081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10083
10084         XINC=$(have_xattrs_include)
10085         setup_test102 "$RUNAS"
10086         chown $RUNAS_ID $DIR/$tdir
10087         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10088         cd $DIR/$tdir/$tdir
10089         compare_stripe_info1 "$RUNAS"
10090 }
10091 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10092
10093 test_102k() {
10094         [ -z "$(which setfattr 2>/dev/null)" ] &&
10095                 skip "could not find setfattr"
10096
10097         touch $DIR/$tfile
10098         # b22187 just check that does not crash for regular file.
10099         setfattr -n trusted.lov $DIR/$tfile
10100         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10101         local test_kdir=$DIR/$tdir
10102         test_mkdir $test_kdir
10103         local default_size=$($LFS getstripe -S $test_kdir)
10104         local default_count=$($LFS getstripe -c $test_kdir)
10105         local default_offset=$($LFS getstripe -i $test_kdir)
10106         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10107                 error 'dir setstripe failed'
10108         setfattr -n trusted.lov $test_kdir
10109         local stripe_size=$($LFS getstripe -S $test_kdir)
10110         local stripe_count=$($LFS getstripe -c $test_kdir)
10111         local stripe_offset=$($LFS getstripe -i $test_kdir)
10112         [ $stripe_size -eq $default_size ] ||
10113                 error "stripe size $stripe_size != $default_size"
10114         [ $stripe_count -eq $default_count ] ||
10115                 error "stripe count $stripe_count != $default_count"
10116         [ $stripe_offset -eq $default_offset ] ||
10117                 error "stripe offset $stripe_offset != $default_offset"
10118         rm -rf $DIR/$tfile $test_kdir
10119 }
10120 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10121
10122 test_102l() {
10123         [ -z "$(which getfattr 2>/dev/null)" ] &&
10124                 skip "could not find getfattr"
10125
10126         # LU-532 trusted. xattr is invisible to non-root
10127         local testfile=$DIR/$tfile
10128
10129         touch $testfile
10130
10131         echo "listxattr as user..."
10132         chown $RUNAS_ID $testfile
10133         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10134             grep -q "trusted" &&
10135                 error "$testfile trusted xattrs are user visible"
10136
10137         return 0;
10138 }
10139 run_test 102l "listxattr size test =================================="
10140
10141 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10142         local path=$DIR/$tfile
10143         touch $path
10144
10145         listxattr_size_check $path || error "listattr_size_check $path failed"
10146 }
10147 run_test 102m "Ensure listxattr fails on small bufffer ========"
10148
10149 cleanup_test102
10150
10151 getxattr() { # getxattr path name
10152         # Return the base64 encoding of the value of xattr name on path.
10153         local path=$1
10154         local name=$2
10155
10156         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10157         # file: $path
10158         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10159         #
10160         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10161
10162         getfattr --absolute-names --encoding=base64 --name=$name $path |
10163                 awk -F= -v name=$name '$1 == name {
10164                         print substr($0, index($0, "=") + 1);
10165         }'
10166 }
10167
10168 test_102n() { # LU-4101 mdt: protect internal xattrs
10169         [ -z "$(which setfattr 2>/dev/null)" ] &&
10170                 skip "could not find setfattr"
10171         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10172         then
10173                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10174         fi
10175
10176         local file0=$DIR/$tfile.0
10177         local file1=$DIR/$tfile.1
10178         local xattr0=$TMP/$tfile.0
10179         local xattr1=$TMP/$tfile.1
10180         local namelist="lov lma lmv link fid version som hsm"
10181         local name
10182         local value
10183
10184         rm -rf $file0 $file1 $xattr0 $xattr1
10185         touch $file0 $file1
10186
10187         # Get 'before' xattrs of $file1.
10188         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10189
10190         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10191                 namelist+=" lfsck_namespace"
10192         for name in $namelist; do
10193                 # Try to copy xattr from $file0 to $file1.
10194                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10195
10196                 setfattr --name=trusted.$name --value="$value" $file1 ||
10197                         error "setxattr 'trusted.$name' failed"
10198
10199                 # Try to set a garbage xattr.
10200                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10201
10202                 if [[ x$name == "xlov" ]]; then
10203                         setfattr --name=trusted.lov --value="$value" $file1 &&
10204                         error "setxattr invalid 'trusted.lov' success"
10205                 else
10206                         setfattr --name=trusted.$name --value="$value" $file1 ||
10207                                 error "setxattr invalid 'trusted.$name' failed"
10208                 fi
10209
10210                 # Try to remove the xattr from $file1. We don't care if this
10211                 # appears to succeed or fail, we just don't want there to be
10212                 # any changes or crashes.
10213                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10214         done
10215
10216         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10217         then
10218                 name="lfsck_ns"
10219                 # Try to copy xattr from $file0 to $file1.
10220                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10221
10222                 setfattr --name=trusted.$name --value="$value" $file1 ||
10223                         error "setxattr 'trusted.$name' failed"
10224
10225                 # Try to set a garbage xattr.
10226                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10227
10228                 setfattr --name=trusted.$name --value="$value" $file1 ||
10229                         error "setxattr 'trusted.$name' failed"
10230
10231                 # Try to remove the xattr from $file1. We don't care if this
10232                 # appears to succeed or fail, we just don't want there to be
10233                 # any changes or crashes.
10234                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10235         fi
10236
10237         # Get 'after' xattrs of file1.
10238         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10239
10240         if ! diff $xattr0 $xattr1; then
10241                 error "before and after xattrs of '$file1' differ"
10242         fi
10243
10244         rm -rf $file0 $file1 $xattr0 $xattr1
10245
10246         return 0
10247 }
10248 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10249
10250 test_102p() { # LU-4703 setxattr did not check ownership
10251         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10252                 skip "MDS needs to be at least 2.5.56"
10253
10254         local testfile=$DIR/$tfile
10255
10256         touch $testfile
10257
10258         echo "setfacl as user..."
10259         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10260         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10261
10262         echo "setfattr as user..."
10263         setfacl -m "u:$RUNAS_ID:---" $testfile
10264         $RUNAS setfattr -x system.posix_acl_access $testfile
10265         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10266 }
10267 run_test 102p "check setxattr(2) correctly fails without permission"
10268
10269 test_102q() {
10270         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10271                 skip "MDS needs to be at least 2.6.92"
10272
10273         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10274 }
10275 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10276
10277 test_102r() {
10278         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10279                 skip "MDS needs to be at least 2.6.93"
10280
10281         touch $DIR/$tfile || error "touch"
10282         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10283         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10284         rm $DIR/$tfile || error "rm"
10285
10286         #normal directory
10287         mkdir -p $DIR/$tdir || error "mkdir"
10288         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10289         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10290         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10291                 error "$testfile error deleting user.author1"
10292         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10293                 grep "user.$(basename $tdir)" &&
10294                 error "$tdir did not delete user.$(basename $tdir)"
10295         rmdir $DIR/$tdir || error "rmdir"
10296
10297         #striped directory
10298         test_mkdir $DIR/$tdir
10299         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10300         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10301         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10302                 error "$testfile error deleting user.author1"
10303         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10304                 grep "user.$(basename $tdir)" &&
10305                 error "$tdir did not delete user.$(basename $tdir)"
10306         rmdir $DIR/$tdir || error "rm striped dir"
10307 }
10308 run_test 102r "set EAs with empty values"
10309
10310 test_102s() {
10311         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10312                 skip "MDS needs to be at least 2.11.52"
10313
10314         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10315
10316         save_lustre_params client "llite.*.xattr_cache" > $save
10317
10318         for cache in 0 1; do
10319                 lctl set_param llite.*.xattr_cache=$cache
10320
10321                 rm -f $DIR/$tfile
10322                 touch $DIR/$tfile || error "touch"
10323                 for prefix in lustre security system trusted user; do
10324                         # Note getxattr() may fail with 'Operation not
10325                         # supported' or 'No such attribute' depending
10326                         # on prefix and cache.
10327                         getfattr -n $prefix.n102s $DIR/$tfile &&
10328                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10329                 done
10330         done
10331
10332         restore_lustre_params < $save
10333 }
10334 run_test 102s "getting nonexistent xattrs should fail"
10335
10336 test_102t() {
10337         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10338                 skip "MDS needs to be at least 2.11.52"
10339
10340         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10341
10342         save_lustre_params client "llite.*.xattr_cache" > $save
10343
10344         for cache in 0 1; do
10345                 lctl set_param llite.*.xattr_cache=$cache
10346
10347                 for buf_size in 0 256; do
10348                         rm -f $DIR/$tfile
10349                         touch $DIR/$tfile || error "touch"
10350                         setfattr -n user.multiop $DIR/$tfile
10351                         $MULTIOP $DIR/$tfile oa$buf_size ||
10352                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10353                 done
10354         done
10355
10356         restore_lustre_params < $save
10357 }
10358 run_test 102t "zero length xattr values handled correctly"
10359
10360 run_acl_subtest()
10361 {
10362     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10363     return $?
10364 }
10365
10366 test_103a() {
10367         [ "$UID" != 0 ] && skip "must run as root"
10368         $GSS && skip_env "could not run under gss"
10369         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10370                 skip_env "must have acl enabled"
10371         [ -z "$(which setfacl 2>/dev/null)" ] &&
10372                 skip_env "could not find setfacl"
10373         remote_mds_nodsh && skip "remote MDS with nodsh"
10374
10375         gpasswd -a daemon bin                           # LU-5641
10376         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10377
10378         declare -a identity_old
10379
10380         for num in $(seq $MDSCOUNT); do
10381                 switch_identity $num true || identity_old[$num]=$?
10382         done
10383
10384         SAVE_UMASK=$(umask)
10385         umask 0022
10386         mkdir -p $DIR/$tdir
10387         cd $DIR/$tdir
10388
10389         echo "performing cp ..."
10390         run_acl_subtest cp || error "run_acl_subtest cp failed"
10391         echo "performing getfacl-noacl..."
10392         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10393         echo "performing misc..."
10394         run_acl_subtest misc || error  "misc test failed"
10395         echo "performing permissions..."
10396         run_acl_subtest permissions || error "permissions failed"
10397         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10398         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10399                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10400                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10401         then
10402                 echo "performing permissions xattr..."
10403                 run_acl_subtest permissions_xattr ||
10404                         error "permissions_xattr failed"
10405         fi
10406         echo "performing setfacl..."
10407         run_acl_subtest setfacl || error  "setfacl test failed"
10408
10409         # inheritance test got from HP
10410         echo "performing inheritance..."
10411         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10412         chmod +x make-tree || error "chmod +x failed"
10413         run_acl_subtest inheritance || error "inheritance test failed"
10414         rm -f make-tree
10415
10416         echo "LU-974 ignore umask when acl is enabled..."
10417         run_acl_subtest 974 || error "LU-974 umask test failed"
10418         if [ $MDSCOUNT -ge 2 ]; then
10419                 run_acl_subtest 974_remote ||
10420                         error "LU-974 umask test failed under remote dir"
10421         fi
10422
10423         echo "LU-2561 newly created file is same size as directory..."
10424         if [ "$mds1_FSTYPE" != "zfs" ]; then
10425                 run_acl_subtest 2561 || error "LU-2561 test failed"
10426         else
10427                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10428         fi
10429
10430         run_acl_subtest 4924 || error "LU-4924 test failed"
10431
10432         cd $SAVE_PWD
10433         umask $SAVE_UMASK
10434
10435         for num in $(seq $MDSCOUNT); do
10436                 if [ "${identity_old[$num]}" = 1 ]; then
10437                         switch_identity $num false || identity_old[$num]=$?
10438                 fi
10439         done
10440 }
10441 run_test 103a "acl test"
10442
10443 test_103b() {
10444         declare -a pids
10445         local U
10446
10447         for U in {0..511}; do
10448                 {
10449                 local O=$(printf "%04o" $U)
10450
10451                 umask $(printf "%04o" $((511 ^ $O)))
10452                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10453                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10454
10455                 (( $S == ($O & 0666) )) ||
10456                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10457
10458                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10459                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10460                 (( $S == ($O & 0666) )) ||
10461                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10462
10463                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10464                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10465                 (( $S == ($O & 0666) )) ||
10466                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10467                 rm -f $DIR/$tfile.[smp]$0
10468                 } &
10469                 local pid=$!
10470
10471                 # limit the concurrently running threads to 64. LU-11878
10472                 local idx=$((U % 64))
10473                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10474                 pids[idx]=$pid
10475         done
10476         wait
10477 }
10478 run_test 103b "umask lfs setstripe"
10479
10480 test_103c() {
10481         mkdir -p $DIR/$tdir
10482         cp -rp $DIR/$tdir $DIR/$tdir.bak
10483
10484         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10485                 error "$DIR/$tdir shouldn't contain default ACL"
10486         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10487                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10488         true
10489 }
10490 run_test 103c "'cp -rp' won't set empty acl"
10491
10492 test_104a() {
10493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10494
10495         touch $DIR/$tfile
10496         lfs df || error "lfs df failed"
10497         lfs df -ih || error "lfs df -ih failed"
10498         lfs df -h $DIR || error "lfs df -h $DIR failed"
10499         lfs df -i $DIR || error "lfs df -i $DIR failed"
10500         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10501         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10502
10503         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10504         lctl --device %$OSC deactivate
10505         lfs df || error "lfs df with deactivated OSC failed"
10506         lctl --device %$OSC activate
10507         # wait the osc back to normal
10508         wait_osc_import_ready client ost
10509
10510         lfs df || error "lfs df with reactivated OSC failed"
10511         rm -f $DIR/$tfile
10512 }
10513 run_test 104a "lfs df [-ih] [path] test ========================="
10514
10515 test_104b() {
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517         [ $RUNAS_ID -eq $UID ] &&
10518                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10519
10520         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10521                         grep "Permission denied" | wc -l)))
10522         if [ $denied_cnt -ne 0 ]; then
10523                 error "lfs check servers test failed"
10524         fi
10525 }
10526 run_test 104b "$RUNAS lfs check servers test ===================="
10527
10528 test_105a() {
10529         # doesn't work on 2.4 kernels
10530         touch $DIR/$tfile
10531         if $(flock_is_enabled); then
10532                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10533         else
10534                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10535         fi
10536         rm -f $DIR/$tfile
10537 }
10538 run_test 105a "flock when mounted without -o flock test ========"
10539
10540 test_105b() {
10541         touch $DIR/$tfile
10542         if $(flock_is_enabled); then
10543                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10544         else
10545                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10546         fi
10547         rm -f $DIR/$tfile
10548 }
10549 run_test 105b "fcntl when mounted without -o flock test ========"
10550
10551 test_105c() {
10552         touch $DIR/$tfile
10553         if $(flock_is_enabled); then
10554                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10555         else
10556                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10557         fi
10558         rm -f $DIR/$tfile
10559 }
10560 run_test 105c "lockf when mounted without -o flock test"
10561
10562 test_105d() { # bug 15924
10563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10564
10565         test_mkdir $DIR/$tdir
10566         flock_is_enabled || skip_env "mount w/o flock enabled"
10567         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10568         $LCTL set_param fail_loc=0x80000315
10569         flocks_test 2 $DIR/$tdir
10570 }
10571 run_test 105d "flock race (should not freeze) ========"
10572
10573 test_105e() { # bug 22660 && 22040
10574         flock_is_enabled || skip_env "mount w/o flock enabled"
10575
10576         touch $DIR/$tfile
10577         flocks_test 3 $DIR/$tfile
10578 }
10579 run_test 105e "Two conflicting flocks from same process"
10580
10581 test_106() { #bug 10921
10582         test_mkdir $DIR/$tdir
10583         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10584         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10585 }
10586 run_test 106 "attempt exec of dir followed by chown of that dir"
10587
10588 test_107() {
10589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10590
10591         CDIR=`pwd`
10592         local file=core
10593
10594         cd $DIR
10595         rm -f $file
10596
10597         local save_pattern=$(sysctl -n kernel.core_pattern)
10598         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10599         sysctl -w kernel.core_pattern=$file
10600         sysctl -w kernel.core_uses_pid=0
10601
10602         ulimit -c unlimited
10603         sleep 60 &
10604         SLEEPPID=$!
10605
10606         sleep 1
10607
10608         kill -s 11 $SLEEPPID
10609         wait $SLEEPPID
10610         if [ -e $file ]; then
10611                 size=`stat -c%s $file`
10612                 [ $size -eq 0 ] && error "Fail to create core file $file"
10613         else
10614                 error "Fail to create core file $file"
10615         fi
10616         rm -f $file
10617         sysctl -w kernel.core_pattern=$save_pattern
10618         sysctl -w kernel.core_uses_pid=$save_uses_pid
10619         cd $CDIR
10620 }
10621 run_test 107 "Coredump on SIG"
10622
10623 test_110() {
10624         test_mkdir $DIR/$tdir
10625         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10626         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10627                 error "mkdir with 256 char should fail, but did not"
10628         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10629                 error "create with 255 char failed"
10630         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10631                 error "create with 256 char should fail, but did not"
10632
10633         ls -l $DIR/$tdir
10634         rm -rf $DIR/$tdir
10635 }
10636 run_test 110 "filename length checking"
10637
10638 #
10639 # Purpose: To verify dynamic thread (OSS) creation.
10640 #
10641 test_115() {
10642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10643         remote_ost_nodsh && skip "remote OST with nodsh"
10644
10645         # Lustre does not stop service threads once they are started.
10646         # Reset number of running threads to default.
10647         stopall
10648         setupall
10649
10650         local OSTIO_pre
10651         local save_params="$TMP/sanity-$TESTNAME.parameters"
10652
10653         # Get ll_ost_io count before I/O
10654         OSTIO_pre=$(do_facet ost1 \
10655                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10656         # Exit if lustre is not running (ll_ost_io not running).
10657         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10658
10659         echo "Starting with $OSTIO_pre threads"
10660         local thread_max=$((OSTIO_pre * 2))
10661         local rpc_in_flight=$((thread_max * 2))
10662         # Number of I/O Process proposed to be started.
10663         local nfiles
10664         local facets=$(get_facets OST)
10665
10666         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10667         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10668
10669         # Set in_flight to $rpc_in_flight
10670         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10671                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10672         nfiles=${rpc_in_flight}
10673         # Set ost thread_max to $thread_max
10674         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10675
10676         # 5 Minutes should be sufficient for max number of OSS
10677         # threads(thread_max) to be created.
10678         local timeout=300
10679
10680         # Start I/O.
10681         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10682         test_mkdir $DIR/$tdir
10683         for i in $(seq $nfiles); do
10684                 local file=$DIR/$tdir/${tfile}-$i
10685                 $LFS setstripe -c -1 -i 0 $file
10686                 ($WTL $file $timeout)&
10687         done
10688
10689         # I/O Started - Wait for thread_started to reach thread_max or report
10690         # error if thread_started is more than thread_max.
10691         echo "Waiting for thread_started to reach thread_max"
10692         local thread_started=0
10693         local end_time=$((SECONDS + timeout))
10694
10695         while [ $SECONDS -le $end_time ] ; do
10696                 echo -n "."
10697                 # Get ost i/o thread_started count.
10698                 thread_started=$(do_facet ost1 \
10699                         "$LCTL get_param \
10700                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10701                 # Break out if thread_started is equal/greater than thread_max
10702                 if [[ $thread_started -ge $thread_max ]]; then
10703                         echo ll_ost_io thread_started $thread_started, \
10704                                 equal/greater than thread_max $thread_max
10705                         break
10706                 fi
10707                 sleep 1
10708         done
10709
10710         # Cleanup - We have the numbers, Kill i/o jobs if running.
10711         jobcount=($(jobs -p))
10712         for i in $(seq 0 $((${#jobcount[@]}-1)))
10713         do
10714                 kill -9 ${jobcount[$i]}
10715                 if [ $? -ne 0 ] ; then
10716                         echo Warning: \
10717                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10718                 fi
10719         done
10720
10721         # Cleanup files left by WTL binary.
10722         for i in $(seq $nfiles); do
10723                 local file=$DIR/$tdir/${tfile}-$i
10724                 rm -rf $file
10725                 if [ $? -ne 0 ] ; then
10726                         echo "Warning: Failed to delete file $file"
10727                 fi
10728         done
10729
10730         restore_lustre_params <$save_params
10731         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10732
10733         # Error out if no new thread has started or Thread started is greater
10734         # than thread max.
10735         if [[ $thread_started -le $OSTIO_pre ||
10736                         $thread_started -gt $thread_max ]]; then
10737                 error "ll_ost_io: thread_started $thread_started" \
10738                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10739                       "No new thread started or thread started greater " \
10740                       "than thread_max."
10741         fi
10742 }
10743 run_test 115 "verify dynamic thread creation===================="
10744
10745 free_min_max () {
10746         wait_delete_completed
10747         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10748         echo "OST kbytes available: ${AVAIL[@]}"
10749         MAXV=${AVAIL[0]}
10750         MAXI=0
10751         MINV=${AVAIL[0]}
10752         MINI=0
10753         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10754                 #echo OST $i: ${AVAIL[i]}kb
10755                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10756                         MAXV=${AVAIL[i]}
10757                         MAXI=$i
10758                 fi
10759                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10760                         MINV=${AVAIL[i]}
10761                         MINI=$i
10762                 fi
10763         done
10764         echo "Min free space: OST $MINI: $MINV"
10765         echo "Max free space: OST $MAXI: $MAXV"
10766 }
10767
10768 test_116a() { # was previously test_116()
10769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10771         remote_mds_nodsh && skip "remote MDS with nodsh"
10772
10773         echo -n "Free space priority "
10774         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10775                 head -n1
10776         declare -a AVAIL
10777         free_min_max
10778
10779         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10780         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10781         trap simple_cleanup_common EXIT
10782
10783         # Check if we need to generate uneven OSTs
10784         test_mkdir -p $DIR/$tdir/OST${MINI}
10785         local FILL=$((MINV / 4))
10786         local DIFF=$((MAXV - MINV))
10787         local DIFF2=$((DIFF * 100 / MINV))
10788
10789         local threshold=$(do_facet $SINGLEMDS \
10790                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10791         threshold=${threshold%%%}
10792         echo -n "Check for uneven OSTs: "
10793         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10794
10795         if [[ $DIFF2 -gt $threshold ]]; then
10796                 echo "ok"
10797                 echo "Don't need to fill OST$MINI"
10798         else
10799                 # generate uneven OSTs. Write 2% over the QOS threshold value
10800                 echo "no"
10801                 DIFF=$((threshold - DIFF2 + 2))
10802                 DIFF2=$((MINV * DIFF / 100))
10803                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10804                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10805                         error "setstripe failed"
10806                 DIFF=$((DIFF2 / 2048))
10807                 i=0
10808                 while [ $i -lt $DIFF ]; do
10809                         i=$((i + 1))
10810                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10811                                 bs=2M count=1 2>/dev/null
10812                         echo -n .
10813                 done
10814                 echo .
10815                 sync
10816                 sleep_maxage
10817                 free_min_max
10818         fi
10819
10820         DIFF=$((MAXV - MINV))
10821         DIFF2=$((DIFF * 100 / MINV))
10822         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10823         if [ $DIFF2 -gt $threshold ]; then
10824                 echo "ok"
10825         else
10826                 echo "failed - QOS mode won't be used"
10827                 simple_cleanup_common
10828                 skip "QOS imbalance criteria not met"
10829         fi
10830
10831         MINI1=$MINI
10832         MINV1=$MINV
10833         MAXI1=$MAXI
10834         MAXV1=$MAXV
10835
10836         # now fill using QOS
10837         $LFS setstripe -c 1 $DIR/$tdir
10838         FILL=$((FILL / 200))
10839         if [ $FILL -gt 600 ]; then
10840                 FILL=600
10841         fi
10842         echo "writing $FILL files to QOS-assigned OSTs"
10843         i=0
10844         while [ $i -lt $FILL ]; do
10845                 i=$((i + 1))
10846                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10847                         count=1 2>/dev/null
10848                 echo -n .
10849         done
10850         echo "wrote $i 200k files"
10851         sync
10852         sleep_maxage
10853
10854         echo "Note: free space may not be updated, so measurements might be off"
10855         free_min_max
10856         DIFF2=$((MAXV - MINV))
10857         echo "free space delta: orig $DIFF final $DIFF2"
10858         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10859         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10860         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10861         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10862         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10863         if [[ $DIFF -gt 0 ]]; then
10864                 FILL=$((DIFF2 * 100 / DIFF - 100))
10865                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10866         fi
10867
10868         # Figure out which files were written where
10869         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10870                awk '/'$MINI1': / {print $2; exit}')
10871         echo $UUID
10872         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10873         echo "$MINC files created on smaller OST $MINI1"
10874         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10875                awk '/'$MAXI1': / {print $2; exit}')
10876         echo $UUID
10877         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10878         echo "$MAXC files created on larger OST $MAXI1"
10879         if [[ $MINC -gt 0 ]]; then
10880                 FILL=$((MAXC * 100 / MINC - 100))
10881                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10882         fi
10883         [[ $MAXC -gt $MINC ]] ||
10884                 error_ignore LU-9 "stripe QOS didn't balance free space"
10885         simple_cleanup_common
10886 }
10887 run_test 116a "stripe QOS: free space balance ==================="
10888
10889 test_116b() { # LU-2093
10890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10891         remote_mds_nodsh && skip "remote MDS with nodsh"
10892
10893 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10894         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10895                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10896         [ -z "$old_rr" ] && skip "no QOS"
10897         do_facet $SINGLEMDS lctl set_param \
10898                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10899         mkdir -p $DIR/$tdir
10900         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10901         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10902         do_facet $SINGLEMDS lctl set_param fail_loc=0
10903         rm -rf $DIR/$tdir
10904         do_facet $SINGLEMDS lctl set_param \
10905                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10906 }
10907 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10908
10909 test_117() # bug 10891
10910 {
10911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10912
10913         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10914         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10915         lctl set_param fail_loc=0x21e
10916         > $DIR/$tfile || error "truncate failed"
10917         lctl set_param fail_loc=0
10918         echo "Truncate succeeded."
10919         rm -f $DIR/$tfile
10920 }
10921 run_test 117 "verify osd extend =========="
10922
10923 NO_SLOW_RESENDCOUNT=4
10924 export OLD_RESENDCOUNT=""
10925 set_resend_count () {
10926         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10927         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10928         lctl set_param -n $PROC_RESENDCOUNT $1
10929         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10930 }
10931
10932 # for reduce test_118* time (b=14842)
10933 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10934
10935 # Reset async IO behavior after error case
10936 reset_async() {
10937         FILE=$DIR/reset_async
10938
10939         # Ensure all OSCs are cleared
10940         $LFS setstripe -c -1 $FILE
10941         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10942         sync
10943         rm $FILE
10944 }
10945
10946 test_118a() #bug 11710
10947 {
10948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10949
10950         reset_async
10951
10952         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10953         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10954         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10955
10956         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10957                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10958                 return 1;
10959         fi
10960         rm -f $DIR/$tfile
10961 }
10962 run_test 118a "verify O_SYNC works =========="
10963
10964 test_118b()
10965 {
10966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10967         remote_ost_nodsh && skip "remote OST with nodsh"
10968
10969         reset_async
10970
10971         #define OBD_FAIL_SRV_ENOENT 0x217
10972         set_nodes_failloc "$(osts_nodes)" 0x217
10973         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10974         RC=$?
10975         set_nodes_failloc "$(osts_nodes)" 0
10976         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10977         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10978                     grep -c writeback)
10979
10980         if [[ $RC -eq 0 ]]; then
10981                 error "Must return error due to dropped pages, rc=$RC"
10982                 return 1;
10983         fi
10984
10985         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10986                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10987                 return 1;
10988         fi
10989
10990         echo "Dirty pages not leaked on ENOENT"
10991
10992         # Due to the above error the OSC will issue all RPCs syncronously
10993         # until a subsequent RPC completes successfully without error.
10994         $MULTIOP $DIR/$tfile Ow4096yc
10995         rm -f $DIR/$tfile
10996
10997         return 0
10998 }
10999 run_test 118b "Reclaim dirty pages on fatal error =========="
11000
11001 test_118c()
11002 {
11003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11004
11005         # for 118c, restore the original resend count, LU-1940
11006         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11007                                 set_resend_count $OLD_RESENDCOUNT
11008         remote_ost_nodsh && skip "remote OST with nodsh"
11009
11010         reset_async
11011
11012         #define OBD_FAIL_OST_EROFS               0x216
11013         set_nodes_failloc "$(osts_nodes)" 0x216
11014
11015         # multiop should block due to fsync until pages are written
11016         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11017         MULTIPID=$!
11018         sleep 1
11019
11020         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11021                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11022         fi
11023
11024         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11025                     grep -c writeback)
11026         if [[ $WRITEBACK -eq 0 ]]; then
11027                 error "No page in writeback, writeback=$WRITEBACK"
11028         fi
11029
11030         set_nodes_failloc "$(osts_nodes)" 0
11031         wait $MULTIPID
11032         RC=$?
11033         if [[ $RC -ne 0 ]]; then
11034                 error "Multiop fsync failed, rc=$RC"
11035         fi
11036
11037         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11038         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11039                     grep -c writeback)
11040         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11041                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11042         fi
11043
11044         rm -f $DIR/$tfile
11045         echo "Dirty pages flushed via fsync on EROFS"
11046         return 0
11047 }
11048 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11049
11050 # continue to use small resend count to reduce test_118* time (b=14842)
11051 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11052
11053 test_118d()
11054 {
11055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11056         remote_ost_nodsh && skip "remote OST with nodsh"
11057
11058         reset_async
11059
11060         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11061         set_nodes_failloc "$(osts_nodes)" 0x214
11062         # multiop should block due to fsync until pages are written
11063         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11064         MULTIPID=$!
11065         sleep 1
11066
11067         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11068                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11069         fi
11070
11071         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11072                     grep -c writeback)
11073         if [[ $WRITEBACK -eq 0 ]]; then
11074                 error "No page in writeback, writeback=$WRITEBACK"
11075         fi
11076
11077         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11078         set_nodes_failloc "$(osts_nodes)" 0
11079
11080         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11081         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11082                     grep -c writeback)
11083         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11084                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11085         fi
11086
11087         rm -f $DIR/$tfile
11088         echo "Dirty pages gaurenteed flushed via fsync"
11089         return 0
11090 }
11091 run_test 118d "Fsync validation inject a delay of the bulk =========="
11092
11093 test_118f() {
11094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11095
11096         reset_async
11097
11098         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11099         lctl set_param fail_loc=0x8000040a
11100
11101         # Should simulate EINVAL error which is fatal
11102         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11103         RC=$?
11104         if [[ $RC -eq 0 ]]; then
11105                 error "Must return error due to dropped pages, rc=$RC"
11106         fi
11107
11108         lctl set_param fail_loc=0x0
11109
11110         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11111         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11112         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11113                     grep -c writeback)
11114         if [[ $LOCKED -ne 0 ]]; then
11115                 error "Locked pages remain in cache, locked=$LOCKED"
11116         fi
11117
11118         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11119                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11120         fi
11121
11122         rm -f $DIR/$tfile
11123         echo "No pages locked after fsync"
11124
11125         reset_async
11126         return 0
11127 }
11128 run_test 118f "Simulate unrecoverable OSC side error =========="
11129
11130 test_118g() {
11131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11132
11133         reset_async
11134
11135         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11136         lctl set_param fail_loc=0x406
11137
11138         # simulate local -ENOMEM
11139         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11140         RC=$?
11141
11142         lctl set_param fail_loc=0
11143         if [[ $RC -eq 0 ]]; then
11144                 error "Must return error due to dropped pages, rc=$RC"
11145         fi
11146
11147         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11148         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11149         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11150                         grep -c writeback)
11151         if [[ $LOCKED -ne 0 ]]; then
11152                 error "Locked pages remain in cache, locked=$LOCKED"
11153         fi
11154
11155         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11156                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11157         fi
11158
11159         rm -f $DIR/$tfile
11160         echo "No pages locked after fsync"
11161
11162         reset_async
11163         return 0
11164 }
11165 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11166
11167 test_118h() {
11168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11169         remote_ost_nodsh && skip "remote OST with nodsh"
11170
11171         reset_async
11172
11173         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11174         set_nodes_failloc "$(osts_nodes)" 0x20e
11175         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11176         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11177         RC=$?
11178
11179         set_nodes_failloc "$(osts_nodes)" 0
11180         if [[ $RC -eq 0 ]]; then
11181                 error "Must return error due to dropped pages, rc=$RC"
11182         fi
11183
11184         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11185         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11186         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11187                     grep -c writeback)
11188         if [[ $LOCKED -ne 0 ]]; then
11189                 error "Locked pages remain in cache, locked=$LOCKED"
11190         fi
11191
11192         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11193                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11194         fi
11195
11196         rm -f $DIR/$tfile
11197         echo "No pages locked after fsync"
11198
11199         return 0
11200 }
11201 run_test 118h "Verify timeout in handling recoverables errors  =========="
11202
11203 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11204
11205 test_118i() {
11206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11207         remote_ost_nodsh && skip "remote OST with nodsh"
11208
11209         reset_async
11210
11211         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11212         set_nodes_failloc "$(osts_nodes)" 0x20e
11213
11214         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11215         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11216         PID=$!
11217         sleep 5
11218         set_nodes_failloc "$(osts_nodes)" 0
11219
11220         wait $PID
11221         RC=$?
11222         if [[ $RC -ne 0 ]]; then
11223                 error "got error, but should be not, rc=$RC"
11224         fi
11225
11226         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11227         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11228         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11229         if [[ $LOCKED -ne 0 ]]; then
11230                 error "Locked pages remain in cache, locked=$LOCKED"
11231         fi
11232
11233         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11234                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11235         fi
11236
11237         rm -f $DIR/$tfile
11238         echo "No pages locked after fsync"
11239
11240         return 0
11241 }
11242 run_test 118i "Fix error before timeout in recoverable error  =========="
11243
11244 [ "$SLOW" = "no" ] && set_resend_count 4
11245
11246 test_118j() {
11247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11248         remote_ost_nodsh && skip "remote OST with nodsh"
11249
11250         reset_async
11251
11252         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11253         set_nodes_failloc "$(osts_nodes)" 0x220
11254
11255         # return -EIO from OST
11256         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11257         RC=$?
11258         set_nodes_failloc "$(osts_nodes)" 0x0
11259         if [[ $RC -eq 0 ]]; then
11260                 error "Must return error due to dropped pages, rc=$RC"
11261         fi
11262
11263         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11264         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11265         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11266         if [[ $LOCKED -ne 0 ]]; then
11267                 error "Locked pages remain in cache, locked=$LOCKED"
11268         fi
11269
11270         # in recoverable error on OST we want resend and stay until it finished
11271         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11272                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11273         fi
11274
11275         rm -f $DIR/$tfile
11276         echo "No pages locked after fsync"
11277
11278         return 0
11279 }
11280 run_test 118j "Simulate unrecoverable OST side error =========="
11281
11282 test_118k()
11283 {
11284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11285         remote_ost_nodsh && skip "remote OSTs with nodsh"
11286
11287         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11288         set_nodes_failloc "$(osts_nodes)" 0x20e
11289         test_mkdir $DIR/$tdir
11290
11291         for ((i=0;i<10;i++)); do
11292                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11293                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11294                 SLEEPPID=$!
11295                 sleep 0.500s
11296                 kill $SLEEPPID
11297                 wait $SLEEPPID
11298         done
11299
11300         set_nodes_failloc "$(osts_nodes)" 0
11301         rm -rf $DIR/$tdir
11302 }
11303 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11304
11305 test_118l() # LU-646
11306 {
11307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11308
11309         test_mkdir $DIR/$tdir
11310         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11311         rm -rf $DIR/$tdir
11312 }
11313 run_test 118l "fsync dir"
11314
11315 test_118m() # LU-3066
11316 {
11317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11318
11319         test_mkdir $DIR/$tdir
11320         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11321         rm -rf $DIR/$tdir
11322 }
11323 run_test 118m "fdatasync dir ========="
11324
11325 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11326
11327 test_118n()
11328 {
11329         local begin
11330         local end
11331
11332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11333         remote_ost_nodsh && skip "remote OSTs with nodsh"
11334
11335         # Sleep to avoid a cached response.
11336         #define OBD_STATFS_CACHE_SECONDS 1
11337         sleep 2
11338
11339         # Inject a 10 second delay in the OST_STATFS handler.
11340         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11341         set_nodes_failloc "$(osts_nodes)" 0x242
11342
11343         begin=$SECONDS
11344         stat --file-system $MOUNT > /dev/null
11345         end=$SECONDS
11346
11347         set_nodes_failloc "$(osts_nodes)" 0
11348
11349         if ((end - begin > 20)); then
11350             error "statfs took $((end - begin)) seconds, expected 10"
11351         fi
11352 }
11353 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11354
11355 test_119a() # bug 11737
11356 {
11357         BSIZE=$((512 * 1024))
11358         directio write $DIR/$tfile 0 1 $BSIZE
11359         # We ask to read two blocks, which is more than a file size.
11360         # directio will indicate an error when requested and actual
11361         # sizes aren't equeal (a normal situation in this case) and
11362         # print actual read amount.
11363         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11364         if [ "$NOB" != "$BSIZE" ]; then
11365                 error "read $NOB bytes instead of $BSIZE"
11366         fi
11367         rm -f $DIR/$tfile
11368 }
11369 run_test 119a "Short directIO read must return actual read amount"
11370
11371 test_119b() # bug 11737
11372 {
11373         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11374
11375         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11376         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11377         sync
11378         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11379                 error "direct read failed"
11380         rm -f $DIR/$tfile
11381 }
11382 run_test 119b "Sparse directIO read must return actual read amount"
11383
11384 test_119c() # bug 13099
11385 {
11386         BSIZE=1048576
11387         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11388         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11389         rm -f $DIR/$tfile
11390 }
11391 run_test 119c "Testing for direct read hitting hole"
11392
11393 test_119d() # bug 15950
11394 {
11395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11396
11397         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11398         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11399         BSIZE=1048576
11400         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11401         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11402         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11403         lctl set_param fail_loc=0x40d
11404         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11405         pid_dio=$!
11406         sleep 1
11407         cat $DIR/$tfile > /dev/null &
11408         lctl set_param fail_loc=0
11409         pid_reads=$!
11410         wait $pid_dio
11411         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11412         sleep 2
11413         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11414         error "the read rpcs have not completed in 2s"
11415         rm -f $DIR/$tfile
11416         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11417 }
11418 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11419
11420 test_120a() {
11421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11422         remote_mds_nodsh && skip "remote MDS with nodsh"
11423         test_mkdir -i0 -c1 $DIR/$tdir
11424         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11425                 skip_env "no early lock cancel on server"
11426
11427         lru_resize_disable mdc
11428         lru_resize_disable osc
11429         cancel_lru_locks mdc
11430         # asynchronous object destroy at MDT could cause bl ast to client
11431         cancel_lru_locks osc
11432
11433         stat $DIR/$tdir > /dev/null
11434         can1=$(do_facet mds1 \
11435                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11436                awk '/ldlm_cancel/ {print $2}')
11437         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11438                awk '/ldlm_bl_callback/ {print $2}')
11439         test_mkdir -i0 -c1 $DIR/$tdir/d1
11440         can2=$(do_facet mds1 \
11441                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11442                awk '/ldlm_cancel/ {print $2}')
11443         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11444                awk '/ldlm_bl_callback/ {print $2}')
11445         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11446         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11447         lru_resize_enable mdc
11448         lru_resize_enable osc
11449 }
11450 run_test 120a "Early Lock Cancel: mkdir test"
11451
11452 test_120b() {
11453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11454         remote_mds_nodsh && skip "remote MDS with nodsh"
11455         test_mkdir $DIR/$tdir
11456         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11457                 skip_env "no early lock cancel on server"
11458
11459         lru_resize_disable mdc
11460         lru_resize_disable osc
11461         cancel_lru_locks mdc
11462         stat $DIR/$tdir > /dev/null
11463         can1=$(do_facet $SINGLEMDS \
11464                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11465                awk '/ldlm_cancel/ {print $2}')
11466         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11467                awk '/ldlm_bl_callback/ {print $2}')
11468         touch $DIR/$tdir/f1
11469         can2=$(do_facet $SINGLEMDS \
11470                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11471                awk '/ldlm_cancel/ {print $2}')
11472         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11473                awk '/ldlm_bl_callback/ {print $2}')
11474         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11475         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11476         lru_resize_enable mdc
11477         lru_resize_enable osc
11478 }
11479 run_test 120b "Early Lock Cancel: create test"
11480
11481 test_120c() {
11482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11483         remote_mds_nodsh && skip "remote MDS with nodsh"
11484         test_mkdir -i0 -c1 $DIR/$tdir
11485         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11486                 skip "no early lock cancel on server"
11487
11488         lru_resize_disable mdc
11489         lru_resize_disable osc
11490         test_mkdir -i0 -c1 $DIR/$tdir/d1
11491         test_mkdir -i0 -c1 $DIR/$tdir/d2
11492         touch $DIR/$tdir/d1/f1
11493         cancel_lru_locks mdc
11494         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11495         can1=$(do_facet mds1 \
11496                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11497                awk '/ldlm_cancel/ {print $2}')
11498         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11499                awk '/ldlm_bl_callback/ {print $2}')
11500         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11501         can2=$(do_facet mds1 \
11502                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11503                awk '/ldlm_cancel/ {print $2}')
11504         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11505                awk '/ldlm_bl_callback/ {print $2}')
11506         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11507         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11508         lru_resize_enable mdc
11509         lru_resize_enable osc
11510 }
11511 run_test 120c "Early Lock Cancel: link test"
11512
11513 test_120d() {
11514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11515         remote_mds_nodsh && skip "remote MDS with nodsh"
11516         test_mkdir -i0 -c1 $DIR/$tdir
11517         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11518                 skip_env "no early lock cancel on server"
11519
11520         lru_resize_disable mdc
11521         lru_resize_disable osc
11522         touch $DIR/$tdir
11523         cancel_lru_locks mdc
11524         stat $DIR/$tdir > /dev/null
11525         can1=$(do_facet mds1 \
11526                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11527                awk '/ldlm_cancel/ {print $2}')
11528         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11529                awk '/ldlm_bl_callback/ {print $2}')
11530         chmod a+x $DIR/$tdir
11531         can2=$(do_facet mds1 \
11532                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11533                awk '/ldlm_cancel/ {print $2}')
11534         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11535                awk '/ldlm_bl_callback/ {print $2}')
11536         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11537         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11538         lru_resize_enable mdc
11539         lru_resize_enable osc
11540 }
11541 run_test 120d "Early Lock Cancel: setattr test"
11542
11543 test_120e() {
11544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11545         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11546                 skip_env "no early lock cancel on server"
11547         remote_mds_nodsh && skip "remote MDS with nodsh"
11548
11549         local dlmtrace_set=false
11550
11551         test_mkdir -i0 -c1 $DIR/$tdir
11552         lru_resize_disable mdc
11553         lru_resize_disable osc
11554         ! $LCTL get_param debug | grep -q dlmtrace &&
11555                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11556         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11557         cancel_lru_locks mdc
11558         cancel_lru_locks osc
11559         dd if=$DIR/$tdir/f1 of=/dev/null
11560         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11561         # XXX client can not do early lock cancel of OST lock
11562         # during unlink (LU-4206), so cancel osc lock now.
11563         sleep 2
11564         cancel_lru_locks osc
11565         can1=$(do_facet mds1 \
11566                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11567                awk '/ldlm_cancel/ {print $2}')
11568         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11569                awk '/ldlm_bl_callback/ {print $2}')
11570         unlink $DIR/$tdir/f1
11571         sleep 5
11572         can2=$(do_facet mds1 \
11573                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11574                awk '/ldlm_cancel/ {print $2}')
11575         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11576                awk '/ldlm_bl_callback/ {print $2}')
11577         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11578                 $LCTL dk $TMP/cancel.debug.txt
11579         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11580                 $LCTL dk $TMP/blocking.debug.txt
11581         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11582         lru_resize_enable mdc
11583         lru_resize_enable osc
11584 }
11585 run_test 120e "Early Lock Cancel: unlink test"
11586
11587 test_120f() {
11588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11589         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11590                 skip_env "no early lock cancel on server"
11591         remote_mds_nodsh && skip "remote MDS with nodsh"
11592
11593         test_mkdir -i0 -c1 $DIR/$tdir
11594         lru_resize_disable mdc
11595         lru_resize_disable osc
11596         test_mkdir -i0 -c1 $DIR/$tdir/d1
11597         test_mkdir -i0 -c1 $DIR/$tdir/d2
11598         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11599         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11600         cancel_lru_locks mdc
11601         cancel_lru_locks osc
11602         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11603         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11604         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11605         # XXX client can not do early lock cancel of OST lock
11606         # during rename (LU-4206), so cancel osc lock now.
11607         sleep 2
11608         cancel_lru_locks osc
11609         can1=$(do_facet mds1 \
11610                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11611                awk '/ldlm_cancel/ {print $2}')
11612         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11613                awk '/ldlm_bl_callback/ {print $2}')
11614         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11615         sleep 5
11616         can2=$(do_facet mds1 \
11617                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11618                awk '/ldlm_cancel/ {print $2}')
11619         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11620                awk '/ldlm_bl_callback/ {print $2}')
11621         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11622         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11623         lru_resize_enable mdc
11624         lru_resize_enable osc
11625 }
11626 run_test 120f "Early Lock Cancel: rename test"
11627
11628 test_120g() {
11629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11630         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11631                 skip_env "no early lock cancel on server"
11632         remote_mds_nodsh && skip "remote MDS with nodsh"
11633
11634         lru_resize_disable mdc
11635         lru_resize_disable osc
11636         count=10000
11637         echo create $count files
11638         test_mkdir $DIR/$tdir
11639         cancel_lru_locks mdc
11640         cancel_lru_locks osc
11641         t0=$(date +%s)
11642
11643         can0=$(do_facet $SINGLEMDS \
11644                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11645                awk '/ldlm_cancel/ {print $2}')
11646         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11647                awk '/ldlm_bl_callback/ {print $2}')
11648         createmany -o $DIR/$tdir/f $count
11649         sync
11650         can1=$(do_facet $SINGLEMDS \
11651                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11652                awk '/ldlm_cancel/ {print $2}')
11653         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11654                awk '/ldlm_bl_callback/ {print $2}')
11655         t1=$(date +%s)
11656         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11657         echo rm $count files
11658         rm -r $DIR/$tdir
11659         sync
11660         can2=$(do_facet $SINGLEMDS \
11661                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11662                awk '/ldlm_cancel/ {print $2}')
11663         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11664                awk '/ldlm_bl_callback/ {print $2}')
11665         t2=$(date +%s)
11666         echo total: $count removes in $((t2-t1))
11667         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11668         sleep 2
11669         # wait for commitment of removal
11670         lru_resize_enable mdc
11671         lru_resize_enable osc
11672 }
11673 run_test 120g "Early Lock Cancel: performance test"
11674
11675 test_121() { #bug #10589
11676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11677
11678         rm -rf $DIR/$tfile
11679         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11680 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11681         lctl set_param fail_loc=0x310
11682         cancel_lru_locks osc > /dev/null
11683         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11684         lctl set_param fail_loc=0
11685         [[ $reads -eq $writes ]] ||
11686                 error "read $reads blocks, must be $writes blocks"
11687 }
11688 run_test 121 "read cancel race ========="
11689
11690 test_123a_base() { # was test 123, statahead(bug 11401)
11691         local lsx="$1"
11692
11693         SLOWOK=0
11694         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11695                 log "testing UP system. Performance may be lower than expected."
11696                 SLOWOK=1
11697         fi
11698
11699         rm -rf $DIR/$tdir
11700         test_mkdir $DIR/$tdir
11701         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11702         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11703         MULT=10
11704         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11705                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11706
11707                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11708                 lctl set_param -n llite.*.statahead_max 0
11709                 lctl get_param llite.*.statahead_max
11710                 cancel_lru_locks mdc
11711                 cancel_lru_locks osc
11712                 stime=$(date +%s)
11713                 time $lsx $DIR/$tdir | wc -l
11714                 etime=$(date +%s)
11715                 delta=$((etime - stime))
11716                 log "$lsx $i files without statahead: $delta sec"
11717                 lctl set_param llite.*.statahead_max=$max
11718
11719                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11720                         grep "statahead wrong:" | awk '{print $3}')
11721                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11722                 cancel_lru_locks mdc
11723                 cancel_lru_locks osc
11724                 stime=$(date +%s)
11725                 time $lsx $DIR/$tdir | wc -l
11726                 etime=$(date +%s)
11727                 delta_sa=$((etime - stime))
11728                 log "$lsx $i files with statahead: $delta_sa sec"
11729                 lctl get_param -n llite.*.statahead_stats
11730                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11731                         grep "statahead wrong:" | awk '{print $3}')
11732
11733                 [[ $swrong -lt $ewrong ]] &&
11734                         log "statahead was stopped, maybe too many locks held!"
11735                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11736
11737                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11738                         max=$(lctl get_param -n llite.*.statahead_max |
11739                                 head -n 1)
11740                         lctl set_param -n llite.*.statahead_max 0
11741                         lctl get_param llite.*.statahead_max
11742                         cancel_lru_locks mdc
11743                         cancel_lru_locks osc
11744                         stime=$(date +%s)
11745                         time $lsx $DIR/$tdir | wc -l
11746                         etime=$(date +%s)
11747                         delta=$((etime - stime))
11748                         log "$lsx $i files again without statahead: $delta sec"
11749                         lctl set_param llite.*.statahead_max=$max
11750                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11751                                 if [  $SLOWOK -eq 0 ]; then
11752                                         error "$lsx $i files is slower with statahead!"
11753                                 else
11754                                         log "$lsx $i files is slower with statahead!"
11755                                 fi
11756                                 break
11757                         fi
11758                 fi
11759
11760                 [ $delta -gt 20 ] && break
11761                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11762                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11763         done
11764         log "$lsx done"
11765
11766         stime=$(date +%s)
11767         rm -r $DIR/$tdir
11768         sync
11769         etime=$(date +%s)
11770         delta=$((etime - stime))
11771         log "rm -r $DIR/$tdir/: $delta seconds"
11772         log "rm done"
11773         lctl get_param -n llite.*.statahead_stats
11774 }
11775
11776 test_123aa() {
11777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11778
11779         test_123a_base "ls -l"
11780 }
11781 run_test 123aa "verify statahead work"
11782
11783 test_123ab() {
11784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11785
11786         statx_supported || skip_env "Test must be statx() syscall supported"
11787
11788         test_123a_base "$STATX -l"
11789 }
11790 run_test 123ab "verify statahead work by using statx"
11791
11792 test_123ac() {
11793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11794
11795         statx_supported || skip_env "Test must be statx() syscall supported"
11796
11797         local rpcs_before
11798         local rpcs_after
11799         local agl_before
11800         local agl_after
11801
11802         cancel_lru_locks $OSC
11803         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11804         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11805                 awk '/agl.total:/ {print $3}')
11806         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11807         test_123a_base "$STATX --cached=always -D"
11808         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11809                 awk '/agl.total:/ {print $3}')
11810         [ $agl_before -eq $agl_after ] ||
11811                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11812         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11813         [ $rpcs_after -eq $rpcs_before ] ||
11814                 error "$STATX should not send glimpse RPCs to $OSC"
11815 }
11816 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11817
11818 test_123b () { # statahead(bug 15027)
11819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11820
11821         test_mkdir $DIR/$tdir
11822         createmany -o $DIR/$tdir/$tfile-%d 1000
11823
11824         cancel_lru_locks mdc
11825         cancel_lru_locks osc
11826
11827 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11828         lctl set_param fail_loc=0x80000803
11829         ls -lR $DIR/$tdir > /dev/null
11830         log "ls done"
11831         lctl set_param fail_loc=0x0
11832         lctl get_param -n llite.*.statahead_stats
11833         rm -r $DIR/$tdir
11834         sync
11835
11836 }
11837 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11838
11839 test_123c() {
11840         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11841
11842         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11843         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11844         touch $DIR/$tdir.1/{1..3}
11845         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11846
11847         remount_client $MOUNT
11848
11849         $MULTIOP $DIR/$tdir.0 Q
11850
11851         # let statahead to complete
11852         ls -l $DIR/$tdir.0 > /dev/null
11853
11854         testid=$(echo $TESTNAME | tr '_' ' ')
11855         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11856                 error "statahead warning" || true
11857 }
11858 run_test 123c "Can not initialize inode warning on DNE statahead"
11859
11860 test_124a() {
11861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11862         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11863                 skip_env "no lru resize on server"
11864
11865         local NR=2000
11866
11867         test_mkdir $DIR/$tdir
11868
11869         log "create $NR files at $DIR/$tdir"
11870         createmany -o $DIR/$tdir/f $NR ||
11871                 error "failed to create $NR files in $DIR/$tdir"
11872
11873         cancel_lru_locks mdc
11874         ls -l $DIR/$tdir > /dev/null
11875
11876         local NSDIR=""
11877         local LRU_SIZE=0
11878         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11879                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11880                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11881                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11882                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11883                         log "NSDIR=$NSDIR"
11884                         log "NS=$(basename $NSDIR)"
11885                         break
11886                 fi
11887         done
11888
11889         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11890                 skip "Not enough cached locks created!"
11891         fi
11892         log "LRU=$LRU_SIZE"
11893
11894         local SLEEP=30
11895
11896         # We know that lru resize allows one client to hold $LIMIT locks
11897         # for 10h. After that locks begin to be killed by client.
11898         local MAX_HRS=10
11899         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11900         log "LIMIT=$LIMIT"
11901         if [ $LIMIT -lt $LRU_SIZE ]; then
11902                 skip "Limit is too small $LIMIT"
11903         fi
11904
11905         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11906         # killing locks. Some time was spent for creating locks. This means
11907         # that up to the moment of sleep finish we must have killed some of
11908         # them (10-100 locks). This depends on how fast ther were created.
11909         # Many of them were touched in almost the same moment and thus will
11910         # be killed in groups.
11911         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11912
11913         # Use $LRU_SIZE_B here to take into account real number of locks
11914         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11915         local LRU_SIZE_B=$LRU_SIZE
11916         log "LVF=$LVF"
11917         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11918         log "OLD_LVF=$OLD_LVF"
11919         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11920
11921         # Let's make sure that we really have some margin. Client checks
11922         # cached locks every 10 sec.
11923         SLEEP=$((SLEEP+20))
11924         log "Sleep ${SLEEP} sec"
11925         local SEC=0
11926         while ((SEC<$SLEEP)); do
11927                 echo -n "..."
11928                 sleep 5
11929                 SEC=$((SEC+5))
11930                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11931                 echo -n "$LRU_SIZE"
11932         done
11933         echo ""
11934         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11935         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11936
11937         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11938                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11939                 unlinkmany $DIR/$tdir/f $NR
11940                 return
11941         }
11942
11943         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11944         log "unlink $NR files at $DIR/$tdir"
11945         unlinkmany $DIR/$tdir/f $NR
11946 }
11947 run_test 124a "lru resize ======================================="
11948
11949 get_max_pool_limit()
11950 {
11951         local limit=$($LCTL get_param \
11952                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11953         local max=0
11954         for l in $limit; do
11955                 if [[ $l -gt $max ]]; then
11956                         max=$l
11957                 fi
11958         done
11959         echo $max
11960 }
11961
11962 test_124b() {
11963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11964         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11965                 skip_env "no lru resize on server"
11966
11967         LIMIT=$(get_max_pool_limit)
11968
11969         NR=$(($(default_lru_size)*20))
11970         if [[ $NR -gt $LIMIT ]]; then
11971                 log "Limit lock number by $LIMIT locks"
11972                 NR=$LIMIT
11973         fi
11974
11975         IFree=$(mdsrate_inodes_available)
11976         if [ $IFree -lt $NR ]; then
11977                 log "Limit lock number by $IFree inodes"
11978                 NR=$IFree
11979         fi
11980
11981         lru_resize_disable mdc
11982         test_mkdir -p $DIR/$tdir/disable_lru_resize
11983
11984         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11985         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11986         cancel_lru_locks mdc
11987         stime=`date +%s`
11988         PID=""
11989         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11990         PID="$PID $!"
11991         sleep 2
11992         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11993         PID="$PID $!"
11994         sleep 2
11995         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11996         PID="$PID $!"
11997         wait $PID
11998         etime=`date +%s`
11999         nolruresize_delta=$((etime-stime))
12000         log "ls -la time: $nolruresize_delta seconds"
12001         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12002         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12003
12004         lru_resize_enable mdc
12005         test_mkdir -p $DIR/$tdir/enable_lru_resize
12006
12007         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12008         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12009         cancel_lru_locks mdc
12010         stime=`date +%s`
12011         PID=""
12012         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12013         PID="$PID $!"
12014         sleep 2
12015         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12016         PID="$PID $!"
12017         sleep 2
12018         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12019         PID="$PID $!"
12020         wait $PID
12021         etime=`date +%s`
12022         lruresize_delta=$((etime-stime))
12023         log "ls -la time: $lruresize_delta seconds"
12024         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12025
12026         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12027                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12028         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12029                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12030         else
12031                 log "lru resize performs the same with no lru resize"
12032         fi
12033         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12034 }
12035 run_test 124b "lru resize (performance test) ======================="
12036
12037 test_124c() {
12038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12039         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12040                 skip_env "no lru resize on server"
12041
12042         # cache ununsed locks on client
12043         local nr=100
12044         cancel_lru_locks mdc
12045         test_mkdir $DIR/$tdir
12046         createmany -o $DIR/$tdir/f $nr ||
12047                 error "failed to create $nr files in $DIR/$tdir"
12048         ls -l $DIR/$tdir > /dev/null
12049
12050         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12051         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12052         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12053         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12054         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12055
12056         # set lru_max_age to 1 sec
12057         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12058         echo "sleep $((recalc_p * 2)) seconds..."
12059         sleep $((recalc_p * 2))
12060
12061         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12062         # restore lru_max_age
12063         $LCTL set_param -n $nsdir.lru_max_age $max_age
12064         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12065         unlinkmany $DIR/$tdir/f $nr
12066 }
12067 run_test 124c "LRUR cancel very aged locks"
12068
12069 test_124d() {
12070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12071         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12072                 skip_env "no lru resize on server"
12073
12074         # cache ununsed locks on client
12075         local nr=100
12076
12077         lru_resize_disable mdc
12078         stack_trap "lru_resize_enable mdc" EXIT
12079
12080         cancel_lru_locks mdc
12081
12082         # asynchronous object destroy at MDT could cause bl ast to client
12083         test_mkdir $DIR/$tdir
12084         createmany -o $DIR/$tdir/f $nr ||
12085                 error "failed to create $nr files in $DIR/$tdir"
12086         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12087
12088         ls -l $DIR/$tdir > /dev/null
12089
12090         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12091         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12092         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12093         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12094
12095         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12096
12097         # set lru_max_age to 1 sec
12098         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12099         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12100
12101         echo "sleep $((recalc_p * 2)) seconds..."
12102         sleep $((recalc_p * 2))
12103
12104         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12105
12106         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12107 }
12108 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12109
12110 test_125() { # 13358
12111         $LCTL get_param -n llite.*.client_type | grep -q local ||
12112                 skip "must run as local client"
12113         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12114                 skip_env "must have acl enabled"
12115         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12116
12117         test_mkdir $DIR/$tdir
12118         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12119         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12120         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12121 }
12122 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12123
12124 test_126() { # bug 12829/13455
12125         $GSS && skip_env "must run as gss disabled"
12126         $LCTL get_param -n llite.*.client_type | grep -q local ||
12127                 skip "must run as local client"
12128         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12129
12130         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12131         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12132         rm -f $DIR/$tfile
12133         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12134 }
12135 run_test 126 "check that the fsgid provided by the client is taken into account"
12136
12137 test_127a() { # bug 15521
12138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12139         local name count samp unit min max sum sumsq
12140
12141         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12142         echo "stats before reset"
12143         $LCTL get_param osc.*.stats
12144         $LCTL set_param osc.*.stats=0
12145         local fsize=$((2048 * 1024))
12146
12147         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12148         cancel_lru_locks osc
12149         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12150
12151         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12152         stack_trap "rm -f $TMP/$tfile.tmp"
12153         while read name count samp unit min max sum sumsq; do
12154                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12155                 [ ! $min ] && error "Missing min value for $name proc entry"
12156                 eval $name=$count || error "Wrong proc format"
12157
12158                 case $name in
12159                 read_bytes|write_bytes)
12160                         [[ "$unit" =~ "bytes" ]] ||
12161                                 error "unit is not 'bytes': $unit"
12162                         (( $min >= 4096 )) || error "min is too small: $min"
12163                         (( $min <= $fsize )) || error "min is too big: $min"
12164                         (( $max >= 4096 )) || error "max is too small: $max"
12165                         (( $max <= $fsize )) || error "max is too big: $max"
12166                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12167                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12168                                 error "sumsquare is too small: $sumsq"
12169                         (( $sumsq <= $fsize * $fsize )) ||
12170                                 error "sumsquare is too big: $sumsq"
12171                         ;;
12172                 ost_read|ost_write)
12173                         [[ "$unit" =~ "usec" ]] ||
12174                                 error "unit is not 'usec': $unit"
12175                         ;;
12176                 *)      ;;
12177                 esac
12178         done < $DIR/$tfile.tmp
12179
12180         #check that we actually got some stats
12181         [ "$read_bytes" ] || error "Missing read_bytes stats"
12182         [ "$write_bytes" ] || error "Missing write_bytes stats"
12183         [ "$read_bytes" != 0 ] || error "no read done"
12184         [ "$write_bytes" != 0 ] || error "no write done"
12185 }
12186 run_test 127a "verify the client stats are sane"
12187
12188 test_127b() { # bug LU-333
12189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12190         local name count samp unit min max sum sumsq
12191
12192         echo "stats before reset"
12193         $LCTL get_param llite.*.stats
12194         $LCTL set_param llite.*.stats=0
12195
12196         # perform 2 reads and writes so MAX is different from SUM.
12197         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12198         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12199         cancel_lru_locks osc
12200         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12201         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12202
12203         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12204         stack_trap "rm -f $TMP/$tfile.tmp"
12205         while read name count samp unit min max sum sumsq; do
12206                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12207                 eval $name=$count || error "Wrong proc format"
12208
12209                 case $name in
12210                 read_bytes|write_bytes)
12211                         [[ "$unit" =~ "bytes" ]] ||
12212                                 error "unit is not 'bytes': $unit"
12213                         (( $count == 2 )) || error "count is not 2: $count"
12214                         (( $min == $PAGE_SIZE )) ||
12215                                 error "min is not $PAGE_SIZE: $min"
12216                         (( $max == $PAGE_SIZE )) ||
12217                                 error "max is not $PAGE_SIZE: $max"
12218                         (( $sum == $PAGE_SIZE * 2 )) ||
12219                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12220                         ;;
12221                 read|write)
12222                         [[ "$unit" =~ "usec" ]] ||
12223                                 error "unit is not 'usec': $unit"
12224                         ;;
12225                 *)      ;;
12226                 esac
12227         done < $TMP/$tfile.tmp
12228
12229         #check that we actually got some stats
12230         [ "$read_bytes" ] || error "Missing read_bytes stats"
12231         [ "$write_bytes" ] || error "Missing write_bytes stats"
12232         [ "$read_bytes" != 0 ] || error "no read done"
12233         [ "$write_bytes" != 0 ] || error "no write done"
12234 }
12235 run_test 127b "verify the llite client stats are sane"
12236
12237 test_127c() { # LU-12394
12238         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12239         local size
12240         local bsize
12241         local reads
12242         local writes
12243         local count
12244
12245         $LCTL set_param llite.*.extents_stats=1
12246         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12247
12248         # Use two stripes so there is enough space in default config
12249         $LFS setstripe -c 2 $DIR/$tfile
12250
12251         # Extent stats start at 0-4K and go in power of two buckets
12252         # LL_HIST_START = 12 --> 2^12 = 4K
12253         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12254         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12255         # small configs
12256         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12257                 do
12258                 # Write and read, 2x each, second time at a non-zero offset
12259                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12260                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12261                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12262                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12263                 rm -f $DIR/$tfile
12264         done
12265
12266         $LCTL get_param llite.*.extents_stats
12267
12268         count=2
12269         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12270                 do
12271                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12272                                 grep -m 1 $bsize)
12273                 reads=$(echo $bucket | awk '{print $5}')
12274                 writes=$(echo $bucket | awk '{print $9}')
12275                 [ "$reads" -eq $count ] ||
12276                         error "$reads reads in < $bsize bucket, expect $count"
12277                 [ "$writes" -eq $count ] ||
12278                         error "$writes writes in < $bsize bucket, expect $count"
12279         done
12280
12281         # Test mmap write and read
12282         $LCTL set_param llite.*.extents_stats=c
12283         size=512
12284         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12285         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12286         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12287
12288         $LCTL get_param llite.*.extents_stats
12289
12290         count=$(((size*1024) / PAGE_SIZE))
12291
12292         bsize=$((2 * PAGE_SIZE / 1024))K
12293
12294         bucket=$($LCTL get_param -n llite.*.extents_stats |
12295                         grep -m 1 $bsize)
12296         reads=$(echo $bucket | awk '{print $5}')
12297         writes=$(echo $bucket | awk '{print $9}')
12298         # mmap writes fault in the page first, creating an additonal read
12299         [ "$reads" -eq $((2 * count)) ] ||
12300                 error "$reads reads in < $bsize bucket, expect $count"
12301         [ "$writes" -eq $count ] ||
12302                 error "$writes writes in < $bsize bucket, expect $count"
12303 }
12304 run_test 127c "test llite extent stats with regular & mmap i/o"
12305
12306 test_128() { # bug 15212
12307         touch $DIR/$tfile
12308         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12309                 find $DIR/$tfile
12310                 find $DIR/$tfile
12311         EOF
12312
12313         result=$(grep error $TMP/$tfile.log)
12314         rm -f $DIR/$tfile $TMP/$tfile.log
12315         [ -z "$result" ] ||
12316                 error "consecutive find's under interactive lfs failed"
12317 }
12318 run_test 128 "interactive lfs for 2 consecutive find's"
12319
12320 set_dir_limits () {
12321         local mntdev
12322         local canondev
12323         local node
12324
12325         local ldproc=/proc/fs/ldiskfs
12326         local facets=$(get_facets MDS)
12327
12328         for facet in ${facets//,/ }; do
12329                 canondev=$(ldiskfs_canon \
12330                            *.$(convert_facet2label $facet).mntdev $facet)
12331                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12332                         ldproc=/sys/fs/ldiskfs
12333                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12334                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12335         done
12336 }
12337
12338 check_mds_dmesg() {
12339         local facets=$(get_facets MDS)
12340         for facet in ${facets//,/ }; do
12341                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12342         done
12343         return 1
12344 }
12345
12346 test_129() {
12347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12348         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12349                 skip "Need MDS version with at least 2.5.56"
12350         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12351                 skip_env "ldiskfs only test"
12352         fi
12353         remote_mds_nodsh && skip "remote MDS with nodsh"
12354
12355         local ENOSPC=28
12356         local has_warning=false
12357
12358         rm -rf $DIR/$tdir
12359         mkdir -p $DIR/$tdir
12360
12361         # block size of mds1
12362         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12363         set_dir_limits $maxsize $((maxsize * 6 / 8))
12364         stack_trap "set_dir_limits 0 0"
12365         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12366         local dirsize=$(stat -c%s "$DIR/$tdir")
12367         local nfiles=0
12368         while (( $dirsize <= $maxsize )); do
12369                 $MCREATE $DIR/$tdir/file_base_$nfiles
12370                 rc=$?
12371                 # check two errors:
12372                 # ENOSPC for ext4 max_dir_size, which has been used since
12373                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12374                 if (( rc == ENOSPC )); then
12375                         set_dir_limits 0 0
12376                         echo "rc=$rc returned as expected after $nfiles files"
12377
12378                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12379                                 error "create failed w/o dir size limit"
12380
12381                         # messages may be rate limited if test is run repeatedly
12382                         check_mds_dmesg '"is approaching max"' ||
12383                                 echo "warning message should be output"
12384                         check_mds_dmesg '"has reached max"' ||
12385                                 echo "reached message should be output"
12386
12387                         dirsize=$(stat -c%s "$DIR/$tdir")
12388
12389                         [[ $dirsize -ge $maxsize ]] && return 0
12390                         error "dirsize $dirsize < $maxsize after $nfiles files"
12391                 elif (( rc != 0 )); then
12392                         break
12393                 fi
12394                 nfiles=$((nfiles + 1))
12395                 dirsize=$(stat -c%s "$DIR/$tdir")
12396         done
12397
12398         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12399 }
12400 run_test 129 "test directory size limit ========================"
12401
12402 OLDIFS="$IFS"
12403 cleanup_130() {
12404         trap 0
12405         IFS="$OLDIFS"
12406 }
12407
12408 test_130a() {
12409         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12410         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12411
12412         trap cleanup_130 EXIT RETURN
12413
12414         local fm_file=$DIR/$tfile
12415         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12416         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12417                 error "dd failed for $fm_file"
12418
12419         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12420         filefrag -ves $fm_file
12421         RC=$?
12422         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12423                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12424         [ $RC != 0 ] && error "filefrag $fm_file failed"
12425
12426         filefrag_op=$(filefrag -ve -k $fm_file |
12427                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12428         lun=$($LFS getstripe -i $fm_file)
12429
12430         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12431         IFS=$'\n'
12432         tot_len=0
12433         for line in $filefrag_op
12434         do
12435                 frag_lun=`echo $line | cut -d: -f5`
12436                 ext_len=`echo $line | cut -d: -f4`
12437                 if (( $frag_lun != $lun )); then
12438                         cleanup_130
12439                         error "FIEMAP on 1-stripe file($fm_file) failed"
12440                         return
12441                 fi
12442                 (( tot_len += ext_len ))
12443         done
12444
12445         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12446                 cleanup_130
12447                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12448                 return
12449         fi
12450
12451         cleanup_130
12452
12453         echo "FIEMAP on single striped file succeeded"
12454 }
12455 run_test 130a "FIEMAP (1-stripe file)"
12456
12457 test_130b() {
12458         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12459
12460         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12461         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12462
12463         trap cleanup_130 EXIT RETURN
12464
12465         local fm_file=$DIR/$tfile
12466         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12467                         error "setstripe on $fm_file"
12468         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12469                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12470
12471         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12472                 error "dd failed on $fm_file"
12473
12474         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12475         filefrag_op=$(filefrag -ve -k $fm_file |
12476                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12477
12478         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12479                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12480
12481         IFS=$'\n'
12482         tot_len=0
12483         num_luns=1
12484         for line in $filefrag_op
12485         do
12486                 frag_lun=$(echo $line | cut -d: -f5 |
12487                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12488                 ext_len=$(echo $line | cut -d: -f4)
12489                 if (( $frag_lun != $last_lun )); then
12490                         if (( tot_len != 1024 )); then
12491                                 cleanup_130
12492                                 error "FIEMAP on $fm_file failed; returned " \
12493                                 "len $tot_len for OST $last_lun instead of 1024"
12494                                 return
12495                         else
12496                                 (( num_luns += 1 ))
12497                                 tot_len=0
12498                         fi
12499                 fi
12500                 (( tot_len += ext_len ))
12501                 last_lun=$frag_lun
12502         done
12503         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12504                 cleanup_130
12505                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12506                         "luns or wrong len for OST $last_lun"
12507                 return
12508         fi
12509
12510         cleanup_130
12511
12512         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12513 }
12514 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12515
12516 test_130c() {
12517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12518
12519         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12520         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12521
12522         trap cleanup_130 EXIT RETURN
12523
12524         local fm_file=$DIR/$tfile
12525         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12526         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12527                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12528
12529         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12530                         error "dd failed on $fm_file"
12531
12532         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12533         filefrag_op=$(filefrag -ve -k $fm_file |
12534                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12535
12536         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12537                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12538
12539         IFS=$'\n'
12540         tot_len=0
12541         num_luns=1
12542         for line in $filefrag_op
12543         do
12544                 frag_lun=$(echo $line | cut -d: -f5 |
12545                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12546                 ext_len=$(echo $line | cut -d: -f4)
12547                 if (( $frag_lun != $last_lun )); then
12548                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12549                         if (( logical != 512 )); then
12550                                 cleanup_130
12551                                 error "FIEMAP on $fm_file failed; returned " \
12552                                 "logical start for lun $logical instead of 512"
12553                                 return
12554                         fi
12555                         if (( tot_len != 512 )); then
12556                                 cleanup_130
12557                                 error "FIEMAP on $fm_file failed; returned " \
12558                                 "len $tot_len for OST $last_lun instead of 1024"
12559                                 return
12560                         else
12561                                 (( num_luns += 1 ))
12562                                 tot_len=0
12563                         fi
12564                 fi
12565                 (( tot_len += ext_len ))
12566                 last_lun=$frag_lun
12567         done
12568         if (( num_luns != 2 || tot_len != 512 )); then
12569                 cleanup_130
12570                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12571                         "luns or wrong len for OST $last_lun"
12572                 return
12573         fi
12574
12575         cleanup_130
12576
12577         echo "FIEMAP on 2-stripe file with hole succeeded"
12578 }
12579 run_test 130c "FIEMAP (2-stripe file with hole)"
12580
12581 test_130d() {
12582         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12583
12584         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12585         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12586
12587         trap cleanup_130 EXIT RETURN
12588
12589         local fm_file=$DIR/$tfile
12590         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12591                         error "setstripe on $fm_file"
12592         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12593                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12594
12595         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12596         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12597                 error "dd failed on $fm_file"
12598
12599         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12600         filefrag_op=$(filefrag -ve -k $fm_file |
12601                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12602
12603         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12604                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12605
12606         IFS=$'\n'
12607         tot_len=0
12608         num_luns=1
12609         for line in $filefrag_op
12610         do
12611                 frag_lun=$(echo $line | cut -d: -f5 |
12612                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12613                 ext_len=$(echo $line | cut -d: -f4)
12614                 if (( $frag_lun != $last_lun )); then
12615                         if (( tot_len != 1024 )); then
12616                                 cleanup_130
12617                                 error "FIEMAP on $fm_file failed; returned " \
12618                                 "len $tot_len for OST $last_lun instead of 1024"
12619                                 return
12620                         else
12621                                 (( num_luns += 1 ))
12622                                 tot_len=0
12623                         fi
12624                 fi
12625                 (( tot_len += ext_len ))
12626                 last_lun=$frag_lun
12627         done
12628         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12629                 cleanup_130
12630                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12631                         "luns or wrong len for OST $last_lun"
12632                 return
12633         fi
12634
12635         cleanup_130
12636
12637         echo "FIEMAP on N-stripe file succeeded"
12638 }
12639 run_test 130d "FIEMAP (N-stripe file)"
12640
12641 test_130e() {
12642         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12643
12644         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12645         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12646
12647         trap cleanup_130 EXIT RETURN
12648
12649         local fm_file=$DIR/$tfile
12650         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12651         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12652                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12653
12654         NUM_BLKS=512
12655         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12656         for ((i = 0; i < $NUM_BLKS; i++))
12657         do
12658                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12659         done
12660
12661         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12662         filefrag_op=$(filefrag -ve -k $fm_file |
12663                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12664
12665         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12666                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12667
12668         IFS=$'\n'
12669         tot_len=0
12670         num_luns=1
12671         for line in $filefrag_op
12672         do
12673                 frag_lun=$(echo $line | cut -d: -f5 |
12674                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12675                 ext_len=$(echo $line | cut -d: -f4)
12676                 if (( $frag_lun != $last_lun )); then
12677                         if (( tot_len != $EXPECTED_LEN )); then
12678                                 cleanup_130
12679                                 error "FIEMAP on $fm_file failed; returned " \
12680                                 "len $tot_len for OST $last_lun instead " \
12681                                 "of $EXPECTED_LEN"
12682                                 return
12683                         else
12684                                 (( num_luns += 1 ))
12685                                 tot_len=0
12686                         fi
12687                 fi
12688                 (( tot_len += ext_len ))
12689                 last_lun=$frag_lun
12690         done
12691         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12692                 cleanup_130
12693                 error "FIEMAP on $fm_file failed; returned wrong number " \
12694                         "of luns or wrong len for OST $last_lun"
12695                 return
12696         fi
12697
12698         cleanup_130
12699
12700         echo "FIEMAP with continuation calls succeeded"
12701 }
12702 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12703
12704 test_130f() {
12705         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12706         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12707
12708         local fm_file=$DIR/$tfile
12709         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12710                 error "multiop create with lov_delay_create on $fm_file"
12711
12712         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12713         filefrag_extents=$(filefrag -vek $fm_file |
12714                            awk '/extents? found/ { print $2 }')
12715         if [[ "$filefrag_extents" != "0" ]]; then
12716                 error "FIEMAP on $fm_file failed; " \
12717                       "returned $filefrag_extents expected 0"
12718         fi
12719
12720         rm -f $fm_file
12721 }
12722 run_test 130f "FIEMAP (unstriped file)"
12723
12724 # Test for writev/readv
12725 test_131a() {
12726         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12727                 error "writev test failed"
12728         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12729                 error "readv failed"
12730         rm -f $DIR/$tfile
12731 }
12732 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12733
12734 test_131b() {
12735         local fsize=$((524288 + 1048576 + 1572864))
12736         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12737                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12738                         error "append writev test failed"
12739
12740         ((fsize += 1572864 + 1048576))
12741         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12742                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12743                         error "append writev test failed"
12744         rm -f $DIR/$tfile
12745 }
12746 run_test 131b "test append writev"
12747
12748 test_131c() {
12749         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12750         error "NOT PASS"
12751 }
12752 run_test 131c "test read/write on file w/o objects"
12753
12754 test_131d() {
12755         rwv -f $DIR/$tfile -w -n 1 1572864
12756         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12757         if [ "$NOB" != 1572864 ]; then
12758                 error "Short read filed: read $NOB bytes instead of 1572864"
12759         fi
12760         rm -f $DIR/$tfile
12761 }
12762 run_test 131d "test short read"
12763
12764 test_131e() {
12765         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12766         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12767         error "read hitting hole failed"
12768         rm -f $DIR/$tfile
12769 }
12770 run_test 131e "test read hitting hole"
12771
12772 check_stats() {
12773         local facet=$1
12774         local op=$2
12775         local want=${3:-0}
12776         local res
12777
12778         case $facet in
12779         mds*) res=$(do_facet $facet \
12780                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12781                  ;;
12782         ost*) res=$(do_facet $facet \
12783                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12784                  ;;
12785         *) error "Wrong facet '$facet'" ;;
12786         esac
12787         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12788         # if the argument $3 is zero, it means any stat increment is ok.
12789         if [[ $want -gt 0 ]]; then
12790                 local count=$(echo $res | awk '{ print $2 }')
12791                 [[ $count -ne $want ]] &&
12792                         error "The $op counter on $facet is $count, not $want"
12793         fi
12794 }
12795
12796 test_133a() {
12797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12798         remote_ost_nodsh && skip "remote OST with nodsh"
12799         remote_mds_nodsh && skip "remote MDS with nodsh"
12800         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12801                 skip_env "MDS doesn't support rename stats"
12802
12803         local testdir=$DIR/${tdir}/stats_testdir
12804
12805         mkdir -p $DIR/${tdir}
12806
12807         # clear stats.
12808         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12809         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12810
12811         # verify mdt stats first.
12812         mkdir ${testdir} || error "mkdir failed"
12813         check_stats $SINGLEMDS "mkdir" 1
12814         touch ${testdir}/${tfile} || error "touch failed"
12815         check_stats $SINGLEMDS "open" 1
12816         check_stats $SINGLEMDS "close" 1
12817         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12818                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12819                 check_stats $SINGLEMDS "mknod" 2
12820         }
12821         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12822         check_stats $SINGLEMDS "unlink" 1
12823         rm -f ${testdir}/${tfile} || error "file remove failed"
12824         check_stats $SINGLEMDS "unlink" 2
12825
12826         # remove working dir and check mdt stats again.
12827         rmdir ${testdir} || error "rmdir failed"
12828         check_stats $SINGLEMDS "rmdir" 1
12829
12830         local testdir1=$DIR/${tdir}/stats_testdir1
12831         mkdir -p ${testdir}
12832         mkdir -p ${testdir1}
12833         touch ${testdir1}/test1
12834         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12835         check_stats $SINGLEMDS "crossdir_rename" 1
12836
12837         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12838         check_stats $SINGLEMDS "samedir_rename" 1
12839
12840         rm -rf $DIR/${tdir}
12841 }
12842 run_test 133a "Verifying MDT stats ========================================"
12843
12844 test_133b() {
12845         local res
12846
12847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12848         remote_ost_nodsh && skip "remote OST with nodsh"
12849         remote_mds_nodsh && skip "remote MDS with nodsh"
12850
12851         local testdir=$DIR/${tdir}/stats_testdir
12852
12853         mkdir -p ${testdir} || error "mkdir failed"
12854         touch ${testdir}/${tfile} || error "touch failed"
12855         cancel_lru_locks mdc
12856
12857         # clear stats.
12858         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12859         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12860
12861         # extra mdt stats verification.
12862         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12863         check_stats $SINGLEMDS "setattr" 1
12864         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12865         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12866         then            # LU-1740
12867                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12868                 check_stats $SINGLEMDS "getattr" 1
12869         fi
12870         rm -rf $DIR/${tdir}
12871
12872         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12873         # so the check below is not reliable
12874         [ $MDSCOUNT -eq 1 ] || return 0
12875
12876         # Sleep to avoid a cached response.
12877         #define OBD_STATFS_CACHE_SECONDS 1
12878         sleep 2
12879         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12880         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12881         $LFS df || error "lfs failed"
12882         check_stats $SINGLEMDS "statfs" 1
12883
12884         # check aggregated statfs (LU-10018)
12885         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12886                 return 0
12887         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12888                 return 0
12889         sleep 2
12890         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12891         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12892         df $DIR
12893         check_stats $SINGLEMDS "statfs" 1
12894
12895         # We want to check that the client didn't send OST_STATFS to
12896         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12897         # extra care is needed here.
12898         if remote_mds; then
12899                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12900                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12901
12902                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12903                 [ "$res" ] && error "OST got STATFS"
12904         fi
12905
12906         return 0
12907 }
12908 run_test 133b "Verifying extra MDT stats =================================="
12909
12910 test_133c() {
12911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12912         remote_ost_nodsh && skip "remote OST with nodsh"
12913         remote_mds_nodsh && skip "remote MDS with nodsh"
12914
12915         local testdir=$DIR/$tdir/stats_testdir
12916
12917         test_mkdir -p $testdir
12918
12919         # verify obdfilter stats.
12920         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12921         sync
12922         cancel_lru_locks osc
12923         wait_delete_completed
12924
12925         # clear stats.
12926         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12927         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12928
12929         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12930                 error "dd failed"
12931         sync
12932         cancel_lru_locks osc
12933         check_stats ost1 "write" 1
12934
12935         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12936         check_stats ost1 "read" 1
12937
12938         > $testdir/$tfile || error "truncate failed"
12939         check_stats ost1 "punch" 1
12940
12941         rm -f $testdir/$tfile || error "file remove failed"
12942         wait_delete_completed
12943         check_stats ost1 "destroy" 1
12944
12945         rm -rf $DIR/$tdir
12946 }
12947 run_test 133c "Verifying OST stats ========================================"
12948
12949 order_2() {
12950         local value=$1
12951         local orig=$value
12952         local order=1
12953
12954         while [ $value -ge 2 ]; do
12955                 order=$((order*2))
12956                 value=$((value/2))
12957         done
12958
12959         if [ $orig -gt $order ]; then
12960                 order=$((order*2))
12961         fi
12962         echo $order
12963 }
12964
12965 size_in_KMGT() {
12966     local value=$1
12967     local size=('K' 'M' 'G' 'T');
12968     local i=0
12969     local size_string=$value
12970
12971     while [ $value -ge 1024 ]; do
12972         if [ $i -gt 3 ]; then
12973             #T is the biggest unit we get here, if that is bigger,
12974             #just return XXXT
12975             size_string=${value}T
12976             break
12977         fi
12978         value=$((value >> 10))
12979         if [ $value -lt 1024 ]; then
12980             size_string=${value}${size[$i]}
12981             break
12982         fi
12983         i=$((i + 1))
12984     done
12985
12986     echo $size_string
12987 }
12988
12989 get_rename_size() {
12990         local size=$1
12991         local context=${2:-.}
12992         local sample=$(do_facet $SINGLEMDS $LCTL \
12993                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12994                 grep -A1 $context |
12995                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12996         echo $sample
12997 }
12998
12999 test_133d() {
13000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13001         remote_ost_nodsh && skip "remote OST with nodsh"
13002         remote_mds_nodsh && skip "remote MDS with nodsh"
13003         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13004                 skip_env "MDS doesn't support rename stats"
13005
13006         local testdir1=$DIR/${tdir}/stats_testdir1
13007         local testdir2=$DIR/${tdir}/stats_testdir2
13008         mkdir -p $DIR/${tdir}
13009
13010         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13011
13012         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13013         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13014
13015         createmany -o $testdir1/test 512 || error "createmany failed"
13016
13017         # check samedir rename size
13018         mv ${testdir1}/test0 ${testdir1}/test_0
13019
13020         local testdir1_size=$(ls -l $DIR/${tdir} |
13021                 awk '/stats_testdir1/ {print $5}')
13022         local testdir2_size=$(ls -l $DIR/${tdir} |
13023                 awk '/stats_testdir2/ {print $5}')
13024
13025         testdir1_size=$(order_2 $testdir1_size)
13026         testdir2_size=$(order_2 $testdir2_size)
13027
13028         testdir1_size=$(size_in_KMGT $testdir1_size)
13029         testdir2_size=$(size_in_KMGT $testdir2_size)
13030
13031         echo "source rename dir size: ${testdir1_size}"
13032         echo "target rename dir size: ${testdir2_size}"
13033
13034         local cmd="do_facet $SINGLEMDS $LCTL "
13035         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13036
13037         eval $cmd || error "$cmd failed"
13038         local samedir=$($cmd | grep 'same_dir')
13039         local same_sample=$(get_rename_size $testdir1_size)
13040         [ -z "$samedir" ] && error "samedir_rename_size count error"
13041         [[ $same_sample -eq 1 ]] ||
13042                 error "samedir_rename_size error $same_sample"
13043         echo "Check same dir rename stats success"
13044
13045         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13046
13047         # check crossdir rename size
13048         mv ${testdir1}/test_0 ${testdir2}/test_0
13049
13050         testdir1_size=$(ls -l $DIR/${tdir} |
13051                 awk '/stats_testdir1/ {print $5}')
13052         testdir2_size=$(ls -l $DIR/${tdir} |
13053                 awk '/stats_testdir2/ {print $5}')
13054
13055         testdir1_size=$(order_2 $testdir1_size)
13056         testdir2_size=$(order_2 $testdir2_size)
13057
13058         testdir1_size=$(size_in_KMGT $testdir1_size)
13059         testdir2_size=$(size_in_KMGT $testdir2_size)
13060
13061         echo "source rename dir size: ${testdir1_size}"
13062         echo "target rename dir size: ${testdir2_size}"
13063
13064         eval $cmd || error "$cmd failed"
13065         local crossdir=$($cmd | grep 'crossdir')
13066         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13067         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13068         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13069         [[ $src_sample -eq 1 ]] ||
13070                 error "crossdir_rename_size error $src_sample"
13071         [[ $tgt_sample -eq 1 ]] ||
13072                 error "crossdir_rename_size error $tgt_sample"
13073         echo "Check cross dir rename stats success"
13074         rm -rf $DIR/${tdir}
13075 }
13076 run_test 133d "Verifying rename_stats ========================================"
13077
13078 test_133e() {
13079         remote_mds_nodsh && skip "remote MDS with nodsh"
13080         remote_ost_nodsh && skip "remote OST with nodsh"
13081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13082
13083         local testdir=$DIR/${tdir}/stats_testdir
13084         local ctr f0 f1 bs=32768 count=42 sum
13085
13086         mkdir -p ${testdir} || error "mkdir failed"
13087
13088         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13089
13090         for ctr in {write,read}_bytes; do
13091                 sync
13092                 cancel_lru_locks osc
13093
13094                 do_facet ost1 $LCTL set_param -n \
13095                         "obdfilter.*.exports.clear=clear"
13096
13097                 if [ $ctr = write_bytes ]; then
13098                         f0=/dev/zero
13099                         f1=${testdir}/${tfile}
13100                 else
13101                         f0=${testdir}/${tfile}
13102                         f1=/dev/null
13103                 fi
13104
13105                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13106                         error "dd failed"
13107                 sync
13108                 cancel_lru_locks osc
13109
13110                 sum=$(do_facet ost1 $LCTL get_param \
13111                         "obdfilter.*.exports.*.stats" |
13112                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13113                                 $1 == ctr { sum += $7 }
13114                                 END { printf("%0.0f", sum) }')
13115
13116                 if ((sum != bs * count)); then
13117                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13118                 fi
13119         done
13120
13121         rm -rf $DIR/${tdir}
13122 }
13123 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13124
13125 test_133f() {
13126         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13127                 skip "too old lustre for get_param -R ($facet_ver)"
13128
13129         # verifying readability.
13130         $LCTL get_param -R '*' &> /dev/null
13131
13132         # Verifing writability with badarea_io.
13133         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13134                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13135                 error "client badarea_io failed"
13136
13137         # remount the FS in case writes/reads /proc break the FS
13138         cleanup || error "failed to unmount"
13139         setup || error "failed to setup"
13140 }
13141 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13142
13143 test_133g() {
13144         remote_mds_nodsh && skip "remote MDS with nodsh"
13145         remote_ost_nodsh && skip "remote OST with nodsh"
13146
13147         local facet
13148         for facet in mds1 ost1; do
13149                 local facet_ver=$(lustre_version_code $facet)
13150                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13151                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13152                 else
13153                         log "$facet: too old lustre for get_param -R"
13154                 fi
13155                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13156                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13157                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13158                                 xargs badarea_io" ||
13159                                         error "$facet badarea_io failed"
13160                 else
13161                         skip_noexit "$facet: too old lustre for get_param -R"
13162                 fi
13163         done
13164
13165         # remount the FS in case writes/reads /proc break the FS
13166         cleanup || error "failed to unmount"
13167         setup || error "failed to setup"
13168 }
13169 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13170
13171 test_133h() {
13172         remote_mds_nodsh && skip "remote MDS with nodsh"
13173         remote_ost_nodsh && skip "remote OST with nodsh"
13174         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13175                 skip "Need MDS version at least 2.9.54"
13176
13177         local facet
13178         for facet in client mds1 ost1; do
13179                 # Get the list of files that are missing the terminating newline
13180                 local plist=$(do_facet $facet
13181                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13182                 local ent
13183                 for ent in $plist; do
13184                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13185                                 awk -v FS='\v' -v RS='\v\v' \
13186                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13187                                         print FILENAME}'" 2>/dev/null)
13188                         [ -z $missing ] || {
13189                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13190                                 error "file does not end with newline: $facet-$ent"
13191                         }
13192                 done
13193         done
13194 }
13195 run_test 133h "Proc files should end with newlines"
13196
13197 test_134a() {
13198         remote_mds_nodsh && skip "remote MDS with nodsh"
13199         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13200                 skip "Need MDS version at least 2.7.54"
13201
13202         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13203         cancel_lru_locks mdc
13204
13205         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13206         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13207         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13208
13209         local nr=1000
13210         createmany -o $DIR/$tdir/f $nr ||
13211                 error "failed to create $nr files in $DIR/$tdir"
13212         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13213
13214         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13215         do_facet mds1 $LCTL set_param fail_loc=0x327
13216         do_facet mds1 $LCTL set_param fail_val=500
13217         touch $DIR/$tdir/m
13218
13219         echo "sleep 10 seconds ..."
13220         sleep 10
13221         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13222
13223         do_facet mds1 $LCTL set_param fail_loc=0
13224         do_facet mds1 $LCTL set_param fail_val=0
13225         [ $lck_cnt -lt $unused ] ||
13226                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13227
13228         rm $DIR/$tdir/m
13229         unlinkmany $DIR/$tdir/f $nr
13230 }
13231 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13232
13233 test_134b() {
13234         remote_mds_nodsh && skip "remote MDS with nodsh"
13235         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13236                 skip "Need MDS version at least 2.7.54"
13237
13238         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13239         cancel_lru_locks mdc
13240
13241         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13242                         ldlm.lock_reclaim_threshold_mb)
13243         # disable reclaim temporarily
13244         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13245
13246         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13247         do_facet mds1 $LCTL set_param fail_loc=0x328
13248         do_facet mds1 $LCTL set_param fail_val=500
13249
13250         $LCTL set_param debug=+trace
13251
13252         local nr=600
13253         createmany -o $DIR/$tdir/f $nr &
13254         local create_pid=$!
13255
13256         echo "Sleep $TIMEOUT seconds ..."
13257         sleep $TIMEOUT
13258         if ! ps -p $create_pid  > /dev/null 2>&1; then
13259                 do_facet mds1 $LCTL set_param fail_loc=0
13260                 do_facet mds1 $LCTL set_param fail_val=0
13261                 do_facet mds1 $LCTL set_param \
13262                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13263                 error "createmany finished incorrectly!"
13264         fi
13265         do_facet mds1 $LCTL set_param fail_loc=0
13266         do_facet mds1 $LCTL set_param fail_val=0
13267         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13268         wait $create_pid || return 1
13269
13270         unlinkmany $DIR/$tdir/f $nr
13271 }
13272 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13273
13274 test_135() {
13275         remote_mds_nodsh && skip "remote MDS with nodsh"
13276         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13277                 skip "Need MDS version at least 2.13.50"
13278         local fname
13279
13280         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13281
13282 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13283         #set only one record at plain llog
13284         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13285
13286         #fill already existed plain llog each 64767
13287         #wrapping whole catalog
13288         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13289
13290         createmany -o $DIR/$tdir/$tfile_ 64700
13291         for (( i = 0; i < 64700; i = i + 2 ))
13292         do
13293                 rm $DIR/$tdir/$tfile_$i &
13294                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13295                 local pid=$!
13296                 wait $pid
13297         done
13298
13299         #waiting osp synchronization
13300         wait_delete_completed
13301 }
13302 run_test 135 "Race catalog processing"
13303
13304 test_136() {
13305         remote_mds_nodsh && skip "remote MDS with nodsh"
13306         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13307                 skip "Need MDS version at least 2.13.50"
13308         local fname
13309
13310         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13311         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13312         #set only one record at plain llog
13313 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13314         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13315
13316         #fill already existed 2 plain llogs each 64767
13317         #wrapping whole catalog
13318         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13319         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13320         wait_delete_completed
13321
13322         createmany -o $DIR/$tdir/$tfile_ 10
13323         sleep 25
13324
13325         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13326         for (( i = 0; i < 10; i = i + 3 ))
13327         do
13328                 rm $DIR/$tdir/$tfile_$i &
13329                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13330                 local pid=$!
13331                 wait $pid
13332                 sleep 7
13333                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13334         done
13335
13336         #waiting osp synchronization
13337         wait_delete_completed
13338 }
13339 run_test 136 "Race catalog processing 2"
13340
13341 test_140() { #bug-17379
13342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13343
13344         test_mkdir $DIR/$tdir
13345         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13346         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13347
13348         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13349         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13350         local i=0
13351         while i=$((i + 1)); do
13352                 test_mkdir $i
13353                 cd $i || error "Changing to $i"
13354                 ln -s ../stat stat || error "Creating stat symlink"
13355                 # Read the symlink until ELOOP present,
13356                 # not LBUGing the system is considered success,
13357                 # we didn't overrun the stack.
13358                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13359                 if [ $ret -ne 0 ]; then
13360                         if [ $ret -eq 40 ]; then
13361                                 break  # -ELOOP
13362                         else
13363                                 error "Open stat symlink"
13364                                         return
13365                         fi
13366                 fi
13367         done
13368         i=$((i - 1))
13369         echo "The symlink depth = $i"
13370         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13371                 error "Invalid symlink depth"
13372
13373         # Test recursive symlink
13374         ln -s symlink_self symlink_self
13375         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13376         echo "open symlink_self returns $ret"
13377         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13378 }
13379 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13380
13381 test_150a() {
13382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13383
13384         local TF="$TMP/$tfile"
13385
13386         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13387         cp $TF $DIR/$tfile
13388         cancel_lru_locks $OSC
13389         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13390         remount_client $MOUNT
13391         df -P $MOUNT
13392         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13393
13394         $TRUNCATE $TF 6000
13395         $TRUNCATE $DIR/$tfile 6000
13396         cancel_lru_locks $OSC
13397         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13398
13399         echo "12345" >>$TF
13400         echo "12345" >>$DIR/$tfile
13401         cancel_lru_locks $OSC
13402         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13403
13404         echo "12345" >>$TF
13405         echo "12345" >>$DIR/$tfile
13406         cancel_lru_locks $OSC
13407         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13408
13409         rm -f $TF
13410         true
13411 }
13412 run_test 150a "truncate/append tests"
13413
13414 test_150b() {
13415         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13416         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13417                 skip "Need OST version at least 2.13.53"
13418         touch $DIR/$tfile
13419         check_fallocate $DIR/$tfile || error "fallocate failed"
13420 }
13421 run_test 150b "Verify fallocate (prealloc) functionality"
13422
13423 test_150c() {
13424         local bytes
13425         local want
13426
13427         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13428         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13429                 skip "Need OST version at least 2.13.53"
13430
13431         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13432         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13433         sync; sync_all_data
13434         cancel_lru_locks $OSC
13435         sleep 5
13436         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13437         want=$((OSTCOUNT * 1048576))
13438
13439         # Must allocate all requested space, not more than 5% extra
13440         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13441                 error "bytes $bytes is not $want"
13442 }
13443 run_test 150c "Verify fallocate Size and Blocks"
13444
13445 test_150d() {
13446         local bytes
13447         local want
13448
13449         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13450         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13451                 skip "Need OST version at least 2.13.53"
13452
13453         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13454         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13455         sync; sync_all_data
13456         cancel_lru_locks $OSC
13457         sleep 5
13458         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13459         want=$((OSTCOUNT * 1048576))
13460
13461         # Must allocate all requested space, not more than 5% extra
13462         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13463                 error "bytes $bytes is not $want"
13464 }
13465 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13466
13467 test_150e() {
13468         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13469         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13470                 skip "Need OST version at least 2.13.55"
13471
13472         echo "df before:"
13473         $LFS df
13474         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13475                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13476
13477         # Find OST with Minimum Size
13478         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13479                        sort -un | head -1)
13480
13481         # Get 90% of the available space
13482         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13483
13484         fallocate -l${space}k $DIR/$tfile ||
13485                 error "fallocate ${space}k $DIR/$tfile failed"
13486         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13487
13488         # get size immediately after fallocate. This should be correctly
13489         # updated
13490         local size=$(stat -c '%s' $DIR/$tfile)
13491         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13492
13493         # Sleep for a while for statfs to get updated. And not pull from cache.
13494         sleep 2
13495
13496         echo "df after fallocate:"
13497         $LFS df
13498
13499         (( size / 1024 == space )) || error "size $size != requested $space"
13500         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13501                 error "used $used < space $space"
13502
13503         rm $DIR/$tfile || error "rm failed"
13504         sync
13505         wait_delete_completed
13506
13507         echo "df after unlink:"
13508         $LFS df
13509 }
13510 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13511
13512 #LU-2902 roc_hit was not able to read all values from lproc
13513 function roc_hit_init() {
13514         local list=$(comma_list $(osts_nodes))
13515         local dir=$DIR/$tdir-check
13516         local file=$dir/$tfile
13517         local BEFORE
13518         local AFTER
13519         local idx
13520
13521         test_mkdir $dir
13522         #use setstripe to do a write to every ost
13523         for i in $(seq 0 $((OSTCOUNT-1))); do
13524                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13525                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13526                 idx=$(printf %04x $i)
13527                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13528                         awk '$1 == "cache_access" {sum += $7}
13529                                 END { printf("%0.0f", sum) }')
13530
13531                 cancel_lru_locks osc
13532                 cat $file >/dev/null
13533
13534                 AFTER=$(get_osd_param $list *OST*$idx stats |
13535                         awk '$1 == "cache_access" {sum += $7}
13536                                 END { printf("%0.0f", sum) }')
13537
13538                 echo BEFORE:$BEFORE AFTER:$AFTER
13539                 if ! let "AFTER - BEFORE == 4"; then
13540                         rm -rf $dir
13541                         error "roc_hit is not safe to use"
13542                 fi
13543                 rm $file
13544         done
13545
13546         rm -rf $dir
13547 }
13548
13549 function roc_hit() {
13550         local list=$(comma_list $(osts_nodes))
13551         echo $(get_osd_param $list '' stats |
13552                 awk '$1 == "cache_hit" {sum += $7}
13553                         END { printf("%0.0f", sum) }')
13554 }
13555
13556 function set_cache() {
13557         local on=1
13558
13559         if [ "$2" == "off" ]; then
13560                 on=0;
13561         fi
13562         local list=$(comma_list $(osts_nodes))
13563         set_osd_param $list '' $1_cache_enable $on
13564
13565         cancel_lru_locks osc
13566 }
13567
13568 test_151() {
13569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13570         remote_ost_nodsh && skip "remote OST with nodsh"
13571
13572         local CPAGES=3
13573         local list=$(comma_list $(osts_nodes))
13574
13575         # check whether obdfilter is cache capable at all
13576         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13577                 skip "not cache-capable obdfilter"
13578         fi
13579
13580         # check cache is enabled on all obdfilters
13581         if get_osd_param $list '' read_cache_enable | grep 0; then
13582                 skip "oss cache is disabled"
13583         fi
13584
13585         set_osd_param $list '' writethrough_cache_enable 1
13586
13587         # check write cache is enabled on all obdfilters
13588         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13589                 skip "oss write cache is NOT enabled"
13590         fi
13591
13592         roc_hit_init
13593
13594         #define OBD_FAIL_OBD_NO_LRU  0x609
13595         do_nodes $list $LCTL set_param fail_loc=0x609
13596
13597         # pages should be in the case right after write
13598         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13599                 error "dd failed"
13600
13601         local BEFORE=$(roc_hit)
13602         cancel_lru_locks osc
13603         cat $DIR/$tfile >/dev/null
13604         local AFTER=$(roc_hit)
13605
13606         do_nodes $list $LCTL set_param fail_loc=0
13607
13608         if ! let "AFTER - BEFORE == CPAGES"; then
13609                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13610         fi
13611
13612         cancel_lru_locks osc
13613         # invalidates OST cache
13614         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13615         set_osd_param $list '' read_cache_enable 0
13616         cat $DIR/$tfile >/dev/null
13617
13618         # now data shouldn't be found in the cache
13619         BEFORE=$(roc_hit)
13620         cancel_lru_locks osc
13621         cat $DIR/$tfile >/dev/null
13622         AFTER=$(roc_hit)
13623         if let "AFTER - BEFORE != 0"; then
13624                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13625         fi
13626
13627         set_osd_param $list '' read_cache_enable 1
13628         rm -f $DIR/$tfile
13629 }
13630 run_test 151 "test cache on oss and controls ==============================="
13631
13632 test_152() {
13633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13634
13635         local TF="$TMP/$tfile"
13636
13637         # simulate ENOMEM during write
13638 #define OBD_FAIL_OST_NOMEM      0x226
13639         lctl set_param fail_loc=0x80000226
13640         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13641         cp $TF $DIR/$tfile
13642         sync || error "sync failed"
13643         lctl set_param fail_loc=0
13644
13645         # discard client's cache
13646         cancel_lru_locks osc
13647
13648         # simulate ENOMEM during read
13649         lctl set_param fail_loc=0x80000226
13650         cmp $TF $DIR/$tfile || error "cmp failed"
13651         lctl set_param fail_loc=0
13652
13653         rm -f $TF
13654 }
13655 run_test 152 "test read/write with enomem ============================"
13656
13657 test_153() {
13658         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13659 }
13660 run_test 153 "test if fdatasync does not crash ======================="
13661
13662 dot_lustre_fid_permission_check() {
13663         local fid=$1
13664         local ffid=$MOUNT/.lustre/fid/$fid
13665         local test_dir=$2
13666
13667         echo "stat fid $fid"
13668         stat $ffid > /dev/null || error "stat $ffid failed."
13669         echo "touch fid $fid"
13670         touch $ffid || error "touch $ffid failed."
13671         echo "write to fid $fid"
13672         cat /etc/hosts > $ffid || error "write $ffid failed."
13673         echo "read fid $fid"
13674         diff /etc/hosts $ffid || error "read $ffid failed."
13675         echo "append write to fid $fid"
13676         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13677         echo "rename fid $fid"
13678         mv $ffid $test_dir/$tfile.1 &&
13679                 error "rename $ffid to $tfile.1 should fail."
13680         touch $test_dir/$tfile.1
13681         mv $test_dir/$tfile.1 $ffid &&
13682                 error "rename $tfile.1 to $ffid should fail."
13683         rm -f $test_dir/$tfile.1
13684         echo "truncate fid $fid"
13685         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13686         echo "link fid $fid"
13687         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13688         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13689                 echo "setfacl fid $fid"
13690                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13691                 echo "getfacl fid $fid"
13692                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13693         fi
13694         echo "unlink fid $fid"
13695         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13696         echo "mknod fid $fid"
13697         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13698
13699         fid=[0xf00000400:0x1:0x0]
13700         ffid=$MOUNT/.lustre/fid/$fid
13701
13702         echo "stat non-exist fid $fid"
13703         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13704         echo "write to non-exist fid $fid"
13705         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13706         echo "link new fid $fid"
13707         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13708
13709         mkdir -p $test_dir/$tdir
13710         touch $test_dir/$tdir/$tfile
13711         fid=$($LFS path2fid $test_dir/$tdir)
13712         rc=$?
13713         [ $rc -ne 0 ] &&
13714                 error "error: could not get fid for $test_dir/$dir/$tfile."
13715
13716         ffid=$MOUNT/.lustre/fid/$fid
13717
13718         echo "ls $fid"
13719         ls $ffid > /dev/null || error "ls $ffid failed."
13720         echo "touch $fid/$tfile.1"
13721         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13722
13723         echo "touch $MOUNT/.lustre/fid/$tfile"
13724         touch $MOUNT/.lustre/fid/$tfile && \
13725                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13726
13727         echo "setxattr to $MOUNT/.lustre/fid"
13728         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13729
13730         echo "listxattr for $MOUNT/.lustre/fid"
13731         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13732
13733         echo "delxattr from $MOUNT/.lustre/fid"
13734         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13735
13736         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13737         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13738                 error "touch invalid fid should fail."
13739
13740         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13741         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13742                 error "touch non-normal fid should fail."
13743
13744         echo "rename $tdir to $MOUNT/.lustre/fid"
13745         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13746                 error "rename to $MOUNT/.lustre/fid should fail."
13747
13748         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13749         then            # LU-3547
13750                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13751                 local new_obf_mode=777
13752
13753                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13754                 chmod $new_obf_mode $DIR/.lustre/fid ||
13755                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13756
13757                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13758                 [ $obf_mode -eq $new_obf_mode ] ||
13759                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13760
13761                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13762                 chmod $old_obf_mode $DIR/.lustre/fid ||
13763                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13764         fi
13765
13766         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13767         fid=$($LFS path2fid $test_dir/$tfile-2)
13768
13769         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13770         then # LU-5424
13771                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13772                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13773                         error "create lov data thru .lustre failed"
13774         fi
13775         echo "cp /etc/passwd $test_dir/$tfile-2"
13776         cp /etc/passwd $test_dir/$tfile-2 ||
13777                 error "copy to $test_dir/$tfile-2 failed."
13778         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13779         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13780                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13781
13782         rm -rf $test_dir/tfile.lnk
13783         rm -rf $test_dir/$tfile-2
13784 }
13785
13786 test_154A() {
13787         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13788                 skip "Need MDS version at least 2.4.1"
13789
13790         local tf=$DIR/$tfile
13791         touch $tf
13792
13793         local fid=$($LFS path2fid $tf)
13794         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13795
13796         # check that we get the same pathname back
13797         local rootpath
13798         local found
13799         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13800                 echo "$rootpath $fid"
13801                 found=$($LFS fid2path $rootpath "$fid")
13802                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13803                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13804         done
13805
13806         # check wrong root path format
13807         rootpath=$MOUNT"_wrong"
13808         found=$($LFS fid2path $rootpath "$fid")
13809         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13810 }
13811 run_test 154A "lfs path2fid and fid2path basic checks"
13812
13813 test_154B() {
13814         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13815                 skip "Need MDS version at least 2.4.1"
13816
13817         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13818         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13819         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13820         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13821
13822         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13823         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13824
13825         # check that we get the same pathname
13826         echo "PFID: $PFID, name: $name"
13827         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13828         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13829         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13830                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13831
13832         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13833 }
13834 run_test 154B "verify the ll_decode_linkea tool"
13835
13836 test_154a() {
13837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13838         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13839         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13840                 skip "Need MDS version at least 2.2.51"
13841         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13842
13843         cp /etc/hosts $DIR/$tfile
13844
13845         fid=$($LFS path2fid $DIR/$tfile)
13846         rc=$?
13847         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13848
13849         dot_lustre_fid_permission_check "$fid" $DIR ||
13850                 error "dot lustre permission check $fid failed"
13851
13852         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13853
13854         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13855
13856         touch $MOUNT/.lustre/file &&
13857                 error "creation is not allowed under .lustre"
13858
13859         mkdir $MOUNT/.lustre/dir &&
13860                 error "mkdir is not allowed under .lustre"
13861
13862         rm -rf $DIR/$tfile
13863 }
13864 run_test 154a "Open-by-FID"
13865
13866 test_154b() {
13867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13868         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13870         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13871                 skip "Need MDS version at least 2.2.51"
13872
13873         local remote_dir=$DIR/$tdir/remote_dir
13874         local MDTIDX=1
13875         local rc=0
13876
13877         mkdir -p $DIR/$tdir
13878         $LFS mkdir -i $MDTIDX $remote_dir ||
13879                 error "create remote directory failed"
13880
13881         cp /etc/hosts $remote_dir/$tfile
13882
13883         fid=$($LFS path2fid $remote_dir/$tfile)
13884         rc=$?
13885         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13886
13887         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13888                 error "dot lustre permission check $fid failed"
13889         rm -rf $DIR/$tdir
13890 }
13891 run_test 154b "Open-by-FID for remote directory"
13892
13893 test_154c() {
13894         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13895                 skip "Need MDS version at least 2.4.1"
13896
13897         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13898         local FID1=$($LFS path2fid $DIR/$tfile.1)
13899         local FID2=$($LFS path2fid $DIR/$tfile.2)
13900         local FID3=$($LFS path2fid $DIR/$tfile.3)
13901
13902         local N=1
13903         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13904                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13905                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13906                 local want=FID$N
13907                 [ "$FID" = "${!want}" ] ||
13908                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13909                 N=$((N + 1))
13910         done
13911
13912         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13913         do
13914                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13915                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13916                 N=$((N + 1))
13917         done
13918 }
13919 run_test 154c "lfs path2fid and fid2path multiple arguments"
13920
13921 test_154d() {
13922         remote_mds_nodsh && skip "remote MDS with nodsh"
13923         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13924                 skip "Need MDS version at least 2.5.53"
13925
13926         if remote_mds; then
13927                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13928         else
13929                 nid="0@lo"
13930         fi
13931         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13932         local fd
13933         local cmd
13934
13935         rm -f $DIR/$tfile
13936         touch $DIR/$tfile
13937
13938         local fid=$($LFS path2fid $DIR/$tfile)
13939         # Open the file
13940         fd=$(free_fd)
13941         cmd="exec $fd<$DIR/$tfile"
13942         eval $cmd
13943         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13944         echo "$fid_list" | grep "$fid"
13945         rc=$?
13946
13947         cmd="exec $fd>/dev/null"
13948         eval $cmd
13949         if [ $rc -ne 0 ]; then
13950                 error "FID $fid not found in open files list $fid_list"
13951         fi
13952 }
13953 run_test 154d "Verify open file fid"
13954
13955 test_154e()
13956 {
13957         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13958                 skip "Need MDS version at least 2.6.50"
13959
13960         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13961                 error ".lustre returned by readdir"
13962         fi
13963 }
13964 run_test 154e ".lustre is not returned by readdir"
13965
13966 test_154f() {
13967         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13968
13969         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13970         test_mkdir -p -c1 $DIR/$tdir/d
13971         # test dirs inherit from its stripe
13972         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13973         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13974         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13975         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13976         touch $DIR/f
13977
13978         # get fid of parents
13979         local FID0=$($LFS path2fid $DIR/$tdir/d)
13980         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13981         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13982         local FID3=$($LFS path2fid $DIR)
13983
13984         # check that path2fid --parents returns expected <parent_fid>/name
13985         # 1) test for a directory (single parent)
13986         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13987         [ "$parent" == "$FID0/foo1" ] ||
13988                 error "expected parent: $FID0/foo1, got: $parent"
13989
13990         # 2) test for a file with nlink > 1 (multiple parents)
13991         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13992         echo "$parent" | grep -F "$FID1/$tfile" ||
13993                 error "$FID1/$tfile not returned in parent list"
13994         echo "$parent" | grep -F "$FID2/link" ||
13995                 error "$FID2/link not returned in parent list"
13996
13997         # 3) get parent by fid
13998         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13999         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14000         echo "$parent" | grep -F "$FID1/$tfile" ||
14001                 error "$FID1/$tfile not returned in parent list (by fid)"
14002         echo "$parent" | grep -F "$FID2/link" ||
14003                 error "$FID2/link not returned in parent list (by fid)"
14004
14005         # 4) test for entry in root directory
14006         parent=$($LFS path2fid --parents $DIR/f)
14007         echo "$parent" | grep -F "$FID3/f" ||
14008                 error "$FID3/f not returned in parent list"
14009
14010         # 5) test it on root directory
14011         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14012                 error "$MOUNT should not have parents"
14013
14014         # enable xattr caching and check that linkea is correctly updated
14015         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14016         save_lustre_params client "llite.*.xattr_cache" > $save
14017         lctl set_param llite.*.xattr_cache 1
14018
14019         # 6.1) linkea update on rename
14020         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14021
14022         # get parents by fid
14023         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14024         # foo1 should no longer be returned in parent list
14025         echo "$parent" | grep -F "$FID1" &&
14026                 error "$FID1 should no longer be in parent list"
14027         # the new path should appear
14028         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14029                 error "$FID2/$tfile.moved is not in parent list"
14030
14031         # 6.2) linkea update on unlink
14032         rm -f $DIR/$tdir/d/foo2/link
14033         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14034         # foo2/link should no longer be returned in parent list
14035         echo "$parent" | grep -F "$FID2/link" &&
14036                 error "$FID2/link should no longer be in parent list"
14037         true
14038
14039         rm -f $DIR/f
14040         restore_lustre_params < $save
14041         rm -f $save
14042 }
14043 run_test 154f "get parent fids by reading link ea"
14044
14045 test_154g()
14046 {
14047         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14048         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14049            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14050                 skip "Need MDS version at least 2.6.92"
14051
14052         mkdir -p $DIR/$tdir
14053         llapi_fid_test -d $DIR/$tdir
14054 }
14055 run_test 154g "various llapi FID tests"
14056
14057 test_155_small_load() {
14058     local temp=$TMP/$tfile
14059     local file=$DIR/$tfile
14060
14061     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14062         error "dd of=$temp bs=6096 count=1 failed"
14063     cp $temp $file
14064     cancel_lru_locks $OSC
14065     cmp $temp $file || error "$temp $file differ"
14066
14067     $TRUNCATE $temp 6000
14068     $TRUNCATE $file 6000
14069     cmp $temp $file || error "$temp $file differ (truncate1)"
14070
14071     echo "12345" >>$temp
14072     echo "12345" >>$file
14073     cmp $temp $file || error "$temp $file differ (append1)"
14074
14075     echo "12345" >>$temp
14076     echo "12345" >>$file
14077     cmp $temp $file || error "$temp $file differ (append2)"
14078
14079     rm -f $temp $file
14080     true
14081 }
14082
14083 test_155_big_load() {
14084         remote_ost_nodsh && skip "remote OST with nodsh"
14085
14086         local temp=$TMP/$tfile
14087         local file=$DIR/$tfile
14088
14089         free_min_max
14090         local cache_size=$(do_facet ost$((MAXI+1)) \
14091                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14092         local large_file_size=$((cache_size * 2))
14093
14094         echo "OSS cache size: $cache_size KB"
14095         echo "Large file size: $large_file_size KB"
14096
14097         [ $MAXV -le $large_file_size ] &&
14098                 skip_env "max available OST size needs > $large_file_size KB"
14099
14100         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14101
14102         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14103                 error "dd of=$temp bs=$large_file_size count=1k failed"
14104         cp $temp $file
14105         ls -lh $temp $file
14106         cancel_lru_locks osc
14107         cmp $temp $file || error "$temp $file differ"
14108
14109         rm -f $temp $file
14110         true
14111 }
14112
14113 save_writethrough() {
14114         local facets=$(get_facets OST)
14115
14116         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14117 }
14118
14119 test_155a() {
14120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14121
14122         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14123
14124         save_writethrough $p
14125
14126         set_cache read on
14127         set_cache writethrough on
14128         test_155_small_load
14129         restore_lustre_params < $p
14130         rm -f $p
14131 }
14132 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14133
14134 test_155b() {
14135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14136
14137         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14138
14139         save_writethrough $p
14140
14141         set_cache read on
14142         set_cache writethrough off
14143         test_155_small_load
14144         restore_lustre_params < $p
14145         rm -f $p
14146 }
14147 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14148
14149 test_155c() {
14150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14151
14152         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14153
14154         save_writethrough $p
14155
14156         set_cache read off
14157         set_cache writethrough on
14158         test_155_small_load
14159         restore_lustre_params < $p
14160         rm -f $p
14161 }
14162 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14163
14164 test_155d() {
14165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14166
14167         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14168
14169         save_writethrough $p
14170
14171         set_cache read off
14172         set_cache writethrough off
14173         test_155_small_load
14174         restore_lustre_params < $p
14175         rm -f $p
14176 }
14177 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14178
14179 test_155e() {
14180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14181
14182         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14183
14184         save_writethrough $p
14185
14186         set_cache read on
14187         set_cache writethrough on
14188         test_155_big_load
14189         restore_lustre_params < $p
14190         rm -f $p
14191 }
14192 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14193
14194 test_155f() {
14195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14196
14197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14198
14199         save_writethrough $p
14200
14201         set_cache read on
14202         set_cache writethrough off
14203         test_155_big_load
14204         restore_lustre_params < $p
14205         rm -f $p
14206 }
14207 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14208
14209 test_155g() {
14210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14211
14212         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14213
14214         save_writethrough $p
14215
14216         set_cache read off
14217         set_cache writethrough on
14218         test_155_big_load
14219         restore_lustre_params < $p
14220         rm -f $p
14221 }
14222 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14223
14224 test_155h() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226
14227         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14228
14229         save_writethrough $p
14230
14231         set_cache read off
14232         set_cache writethrough off
14233         test_155_big_load
14234         restore_lustre_params < $p
14235         rm -f $p
14236 }
14237 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14238
14239 test_156() {
14240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14241         remote_ost_nodsh && skip "remote OST with nodsh"
14242         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14243                 skip "stats not implemented on old servers"
14244         [ "$ost1_FSTYPE" = "zfs" ] &&
14245                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14246
14247         local CPAGES=3
14248         local BEFORE
14249         local AFTER
14250         local file="$DIR/$tfile"
14251         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14252
14253         save_writethrough $p
14254         roc_hit_init
14255
14256         log "Turn on read and write cache"
14257         set_cache read on
14258         set_cache writethrough on
14259
14260         log "Write data and read it back."
14261         log "Read should be satisfied from the cache."
14262         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14263         BEFORE=$(roc_hit)
14264         cancel_lru_locks osc
14265         cat $file >/dev/null
14266         AFTER=$(roc_hit)
14267         if ! let "AFTER - BEFORE == CPAGES"; then
14268                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14269         else
14270                 log "cache hits: before: $BEFORE, after: $AFTER"
14271         fi
14272
14273         log "Read again; it should be satisfied from the cache."
14274         BEFORE=$AFTER
14275         cancel_lru_locks osc
14276         cat $file >/dev/null
14277         AFTER=$(roc_hit)
14278         if ! let "AFTER - BEFORE == CPAGES"; then
14279                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14280         else
14281                 log "cache hits:: before: $BEFORE, after: $AFTER"
14282         fi
14283
14284         log "Turn off the read cache and turn on the write cache"
14285         set_cache read off
14286         set_cache writethrough on
14287
14288         log "Read again; it should be satisfied from the cache."
14289         BEFORE=$(roc_hit)
14290         cancel_lru_locks osc
14291         cat $file >/dev/null
14292         AFTER=$(roc_hit)
14293         if ! let "AFTER - BEFORE == CPAGES"; then
14294                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14295         else
14296                 log "cache hits:: before: $BEFORE, after: $AFTER"
14297         fi
14298
14299         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14300                 # > 2.12.56 uses pagecache if cached
14301                 log "Read again; it should not be satisfied from the cache."
14302                 BEFORE=$AFTER
14303                 cancel_lru_locks osc
14304                 cat $file >/dev/null
14305                 AFTER=$(roc_hit)
14306                 if ! let "AFTER - BEFORE == 0"; then
14307                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14308                 else
14309                         log "cache hits:: before: $BEFORE, after: $AFTER"
14310                 fi
14311         fi
14312
14313         log "Write data and read it back."
14314         log "Read should be satisfied from the cache."
14315         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14316         BEFORE=$(roc_hit)
14317         cancel_lru_locks osc
14318         cat $file >/dev/null
14319         AFTER=$(roc_hit)
14320         if ! let "AFTER - BEFORE == CPAGES"; then
14321                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14322         else
14323                 log "cache hits:: before: $BEFORE, after: $AFTER"
14324         fi
14325
14326         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14327                 # > 2.12.56 uses pagecache if cached
14328                 log "Read again; it should not be satisfied from the cache."
14329                 BEFORE=$AFTER
14330                 cancel_lru_locks osc
14331                 cat $file >/dev/null
14332                 AFTER=$(roc_hit)
14333                 if ! let "AFTER - BEFORE == 0"; then
14334                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14335                 else
14336                         log "cache hits:: before: $BEFORE, after: $AFTER"
14337                 fi
14338         fi
14339
14340         log "Turn off read and write cache"
14341         set_cache read off
14342         set_cache writethrough off
14343
14344         log "Write data and read it back"
14345         log "It should not be satisfied from the cache."
14346         rm -f $file
14347         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14348         cancel_lru_locks osc
14349         BEFORE=$(roc_hit)
14350         cat $file >/dev/null
14351         AFTER=$(roc_hit)
14352         if ! let "AFTER - BEFORE == 0"; then
14353                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14354         else
14355                 log "cache hits:: before: $BEFORE, after: $AFTER"
14356         fi
14357
14358         log "Turn on the read cache and turn off the write cache"
14359         set_cache read on
14360         set_cache writethrough off
14361
14362         log "Write data and read it back"
14363         log "It should not be satisfied from the cache."
14364         rm -f $file
14365         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14366         BEFORE=$(roc_hit)
14367         cancel_lru_locks osc
14368         cat $file >/dev/null
14369         AFTER=$(roc_hit)
14370         if ! let "AFTER - BEFORE == 0"; then
14371                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14372         else
14373                 log "cache hits:: before: $BEFORE, after: $AFTER"
14374         fi
14375
14376         log "Read again; it should be satisfied from the cache."
14377         BEFORE=$(roc_hit)
14378         cancel_lru_locks osc
14379         cat $file >/dev/null
14380         AFTER=$(roc_hit)
14381         if ! let "AFTER - BEFORE == CPAGES"; then
14382                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14383         else
14384                 log "cache hits:: before: $BEFORE, after: $AFTER"
14385         fi
14386
14387         restore_lustre_params < $p
14388         rm -f $p $file
14389 }
14390 run_test 156 "Verification of tunables"
14391
14392 test_160a() {
14393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14394         remote_mds_nodsh && skip "remote MDS with nodsh"
14395         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14396                 skip "Need MDS version at least 2.2.0"
14397
14398         changelog_register || error "changelog_register failed"
14399         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14400         changelog_users $SINGLEMDS | grep -q $cl_user ||
14401                 error "User $cl_user not found in changelog_users"
14402
14403         # change something
14404         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14405         changelog_clear 0 || error "changelog_clear failed"
14406         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14407         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14408         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14409         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14410         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14411         rm $DIR/$tdir/pics/desktop.jpg
14412
14413         changelog_dump | tail -10
14414
14415         echo "verifying changelog mask"
14416         changelog_chmask "-MKDIR"
14417         changelog_chmask "-CLOSE"
14418
14419         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14420         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14421
14422         changelog_chmask "+MKDIR"
14423         changelog_chmask "+CLOSE"
14424
14425         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14426         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14427
14428         changelog_dump | tail -10
14429         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14430         CLOSES=$(changelog_dump | grep -c "CLOSE")
14431         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14432         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14433
14434         # verify contents
14435         echo "verifying target fid"
14436         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14437         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14438         [ "$fidc" == "$fidf" ] ||
14439                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14440         echo "verifying parent fid"
14441         # The FID returned from the Changelog may be the directory shard on
14442         # a different MDT, and not the FID returned by path2fid on the parent.
14443         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14444         # since this is what will matter when recreating this file in the tree.
14445         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14446         local pathp=$($LFS fid2path $MOUNT "$fidp")
14447         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14448                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14449
14450         echo "getting records for $cl_user"
14451         changelog_users $SINGLEMDS
14452         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14453         local nclr=3
14454         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14455                 error "changelog_clear failed"
14456         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14457         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14458         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14459                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14460
14461         local min0_rec=$(changelog_users $SINGLEMDS |
14462                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14463         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14464                           awk '{ print $1; exit; }')
14465
14466         changelog_dump | tail -n 5
14467         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14468         [ $first_rec == $((min0_rec + 1)) ] ||
14469                 error "first index should be $min0_rec + 1 not $first_rec"
14470
14471         # LU-3446 changelog index reset on MDT restart
14472         local cur_rec1=$(changelog_users $SINGLEMDS |
14473                          awk '/^current.index:/ { print $NF }')
14474         changelog_clear 0 ||
14475                 error "clear all changelog records for $cl_user failed"
14476         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14477         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14478                 error "Fail to start $SINGLEMDS"
14479         local cur_rec2=$(changelog_users $SINGLEMDS |
14480                          awk '/^current.index:/ { print $NF }')
14481         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14482         [ $cur_rec1 == $cur_rec2 ] ||
14483                 error "current index should be $cur_rec1 not $cur_rec2"
14484
14485         echo "verifying users from this test are deregistered"
14486         changelog_deregister || error "changelog_deregister failed"
14487         changelog_users $SINGLEMDS | grep -q $cl_user &&
14488                 error "User '$cl_user' still in changelog_users"
14489
14490         # lctl get_param -n mdd.*.changelog_users
14491         # current index: 144
14492         # ID    index (idle seconds)
14493         # cl3   144 (2)
14494         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14495                 # this is the normal case where all users were deregistered
14496                 # make sure no new records are added when no users are present
14497                 local last_rec1=$(changelog_users $SINGLEMDS |
14498                                   awk '/^current.index:/ { print $NF }')
14499                 touch $DIR/$tdir/chloe
14500                 local last_rec2=$(changelog_users $SINGLEMDS |
14501                                   awk '/^current.index:/ { print $NF }')
14502                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14503                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14504         else
14505                 # any changelog users must be leftovers from a previous test
14506                 changelog_users $SINGLEMDS
14507                 echo "other changelog users; can't verify off"
14508         fi
14509 }
14510 run_test 160a "changelog sanity"
14511
14512 test_160b() { # LU-3587
14513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14514         remote_mds_nodsh && skip "remote MDS with nodsh"
14515         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14516                 skip "Need MDS version at least 2.2.0"
14517
14518         changelog_register || error "changelog_register failed"
14519         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14520         changelog_users $SINGLEMDS | grep -q $cl_user ||
14521                 error "User '$cl_user' not found in changelog_users"
14522
14523         local longname1=$(str_repeat a 255)
14524         local longname2=$(str_repeat b 255)
14525
14526         cd $DIR
14527         echo "creating very long named file"
14528         touch $longname1 || error "create of '$longname1' failed"
14529         echo "renaming very long named file"
14530         mv $longname1 $longname2
14531
14532         changelog_dump | grep RENME | tail -n 5
14533         rm -f $longname2
14534 }
14535 run_test 160b "Verify that very long rename doesn't crash in changelog"
14536
14537 test_160c() {
14538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14539         remote_mds_nodsh && skip "remote MDS with nodsh"
14540
14541         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14542                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14543                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14544                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14545
14546         local rc=0
14547
14548         # Registration step
14549         changelog_register || error "changelog_register failed"
14550
14551         rm -rf $DIR/$tdir
14552         mkdir -p $DIR/$tdir
14553         $MCREATE $DIR/$tdir/foo_160c
14554         changelog_chmask "-TRUNC"
14555         $TRUNCATE $DIR/$tdir/foo_160c 200
14556         changelog_chmask "+TRUNC"
14557         $TRUNCATE $DIR/$tdir/foo_160c 199
14558         changelog_dump | tail -n 5
14559         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14560         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14561 }
14562 run_test 160c "verify that changelog log catch the truncate event"
14563
14564 test_160d() {
14565         remote_mds_nodsh && skip "remote MDS with nodsh"
14566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14568         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14569                 skip "Need MDS version at least 2.7.60"
14570
14571         # Registration step
14572         changelog_register || error "changelog_register failed"
14573
14574         mkdir -p $DIR/$tdir/migrate_dir
14575         changelog_clear 0 || error "changelog_clear failed"
14576
14577         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14578         changelog_dump | tail -n 5
14579         local migrates=$(changelog_dump | grep -c "MIGRT")
14580         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14581 }
14582 run_test 160d "verify that changelog log catch the migrate event"
14583
14584 test_160e() {
14585         remote_mds_nodsh && skip "remote MDS with nodsh"
14586
14587         # Create a user
14588         changelog_register || error "changelog_register failed"
14589
14590         # Delete a future user (expect fail)
14591         local MDT0=$(facet_svc $SINGLEMDS)
14592         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14593         local rc=$?
14594
14595         if [ $rc -eq 0 ]; then
14596                 error "Deleted non-existant user cl77"
14597         elif [ $rc -ne 2 ]; then
14598                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14599         fi
14600
14601         # Clear to a bad index (1 billion should be safe)
14602         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14603         rc=$?
14604
14605         if [ $rc -eq 0 ]; then
14606                 error "Successfully cleared to invalid CL index"
14607         elif [ $rc -ne 22 ]; then
14608                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14609         fi
14610 }
14611 run_test 160e "changelog negative testing (should return errors)"
14612
14613 test_160f() {
14614         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14615         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14616                 skip "Need MDS version at least 2.10.56"
14617
14618         local mdts=$(comma_list $(mdts_nodes))
14619
14620         # Create a user
14621         changelog_register || error "first changelog_register failed"
14622         changelog_register || error "second changelog_register failed"
14623         local cl_users
14624         declare -A cl_user1
14625         declare -A cl_user2
14626         local user_rec1
14627         local user_rec2
14628         local i
14629
14630         # generate some changelog records to accumulate on each MDT
14631         # use fnv1a because created files should be evenly distributed
14632         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14633                 error "test_mkdir $tdir failed"
14634         log "$(date +%s): creating first files"
14635         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14636                 error "create $DIR/$tdir/$tfile failed"
14637
14638         # check changelogs have been generated
14639         local start=$SECONDS
14640         local idle_time=$((MDSCOUNT * 5 + 5))
14641         local nbcl=$(changelog_dump | wc -l)
14642         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14643
14644         for param in "changelog_max_idle_time=$idle_time" \
14645                      "changelog_gc=1" \
14646                      "changelog_min_gc_interval=2" \
14647                      "changelog_min_free_cat_entries=3"; do
14648                 local MDT0=$(facet_svc $SINGLEMDS)
14649                 local var="${param%=*}"
14650                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14651
14652                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14653                 do_nodes $mdts $LCTL set_param mdd.*.$param
14654         done
14655
14656         # force cl_user2 to be idle (1st part), but also cancel the
14657         # cl_user1 records so that it is not evicted later in the test.
14658         local sleep1=$((idle_time / 2))
14659         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14660         sleep $sleep1
14661
14662         # simulate changelog catalog almost full
14663         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14664         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14665
14666         for i in $(seq $MDSCOUNT); do
14667                 cl_users=(${CL_USERS[mds$i]})
14668                 cl_user1[mds$i]="${cl_users[0]}"
14669                 cl_user2[mds$i]="${cl_users[1]}"
14670
14671                 [ -n "${cl_user1[mds$i]}" ] ||
14672                         error "mds$i: no user registered"
14673                 [ -n "${cl_user2[mds$i]}" ] ||
14674                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14675
14676                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14677                 [ -n "$user_rec1" ] ||
14678                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14679                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14680                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14681                 [ -n "$user_rec2" ] ||
14682                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14683                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14684                      "$user_rec1 + 2 == $user_rec2"
14685                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14686                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14687                               "$user_rec1 + 2, but is $user_rec2"
14688                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14689                 [ -n "$user_rec2" ] ||
14690                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14691                 [ $user_rec1 == $user_rec2 ] ||
14692                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14693                               "$user_rec1, but is $user_rec2"
14694         done
14695
14696         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14697         local sleep2=$((idle_time - (SECONDS - start) + 1))
14698         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14699         sleep $sleep2
14700
14701         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14702         # cl_user1 should be OK because it recently processed records.
14703         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14704         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14705                 error "create $DIR/$tdir/${tfile}b failed"
14706
14707         # ensure gc thread is done
14708         for i in $(mdts_nodes); do
14709                 wait_update $i \
14710                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14711                         error "$i: GC-thread not done"
14712         done
14713
14714         local first_rec
14715         for i in $(seq $MDSCOUNT); do
14716                 # check cl_user1 still registered
14717                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14718                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14719                 # check cl_user2 unregistered
14720                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14721                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14722
14723                 # check changelogs are present and starting at $user_rec1 + 1
14724                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14725                 [ -n "$user_rec1" ] ||
14726                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14727                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14728                             awk '{ print $1; exit; }')
14729
14730                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14731                 [ $((user_rec1 + 1)) == $first_rec ] ||
14732                         error "mds$i: first index should be $user_rec1 + 1, " \
14733                               "but is $first_rec"
14734         done
14735 }
14736 run_test 160f "changelog garbage collect (timestamped users)"
14737
14738 test_160g() {
14739         remote_mds_nodsh && skip "remote MDS with nodsh"
14740         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14741                 skip "Need MDS version at least 2.10.56"
14742
14743         local mdts=$(comma_list $(mdts_nodes))
14744
14745         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14746         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14747
14748         # Create a user
14749         changelog_register || error "first changelog_register failed"
14750         changelog_register || error "second changelog_register failed"
14751         local cl_users
14752         declare -A cl_user1
14753         declare -A cl_user2
14754         local user_rec1
14755         local user_rec2
14756         local i
14757
14758         # generate some changelog records to accumulate on each MDT
14759         # use fnv1a because created files should be evenly distributed
14760         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14761                 error "mkdir $tdir failed"
14762         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14763                 error "create $DIR/$tdir/$tfile failed"
14764
14765         # check changelogs have been generated
14766         local nbcl=$(changelog_dump | wc -l)
14767         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14768
14769         # reduce the max_idle_indexes value to make sure we exceed it
14770         max_ndx=$((nbcl / 2 - 1))
14771
14772         for param in "changelog_max_idle_indexes=$max_ndx" \
14773                      "changelog_gc=1" \
14774                      "changelog_min_gc_interval=2" \
14775                      "changelog_min_free_cat_entries=3"; do
14776                 local MDT0=$(facet_svc $SINGLEMDS)
14777                 local var="${param%=*}"
14778                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14779
14780                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14781                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14782                         error "unable to set mdd.*.$param"
14783         done
14784
14785         # simulate changelog catalog almost full
14786         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14787         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14788
14789         for i in $(seq $MDSCOUNT); do
14790                 cl_users=(${CL_USERS[mds$i]})
14791                 cl_user1[mds$i]="${cl_users[0]}"
14792                 cl_user2[mds$i]="${cl_users[1]}"
14793
14794                 [ -n "${cl_user1[mds$i]}" ] ||
14795                         error "mds$i: no user registered"
14796                 [ -n "${cl_user2[mds$i]}" ] ||
14797                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14798
14799                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14800                 [ -n "$user_rec1" ] ||
14801                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14802                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14803                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14804                 [ -n "$user_rec2" ] ||
14805                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14806                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14807                      "$user_rec1 + 2 == $user_rec2"
14808                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14809                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14810                               "$user_rec1 + 2, but is $user_rec2"
14811                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14812                 [ -n "$user_rec2" ] ||
14813                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14814                 [ $user_rec1 == $user_rec2 ] ||
14815                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14816                               "$user_rec1, but is $user_rec2"
14817         done
14818
14819         # ensure we are past the previous changelog_min_gc_interval set above
14820         sleep 2
14821
14822         # generate one more changelog to trigger fail_loc
14823         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14824                 error "create $DIR/$tdir/${tfile}bis failed"
14825
14826         # ensure gc thread is done
14827         for i in $(mdts_nodes); do
14828                 wait_update $i \
14829                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14830                         error "$i: GC-thread not done"
14831         done
14832
14833         local first_rec
14834         for i in $(seq $MDSCOUNT); do
14835                 # check cl_user1 still registered
14836                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14837                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14838                 # check cl_user2 unregistered
14839                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14840                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14841
14842                 # check changelogs are present and starting at $user_rec1 + 1
14843                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14844                 [ -n "$user_rec1" ] ||
14845                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14846                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14847                             awk '{ print $1; exit; }')
14848
14849                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14850                 [ $((user_rec1 + 1)) == $first_rec ] ||
14851                         error "mds$i: first index should be $user_rec1 + 1, " \
14852                               "but is $first_rec"
14853         done
14854 }
14855 run_test 160g "changelog garbage collect (old users)"
14856
14857 test_160h() {
14858         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14859         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14860                 skip "Need MDS version at least 2.10.56"
14861
14862         local mdts=$(comma_list $(mdts_nodes))
14863
14864         # Create a user
14865         changelog_register || error "first changelog_register failed"
14866         changelog_register || error "second changelog_register failed"
14867         local cl_users
14868         declare -A cl_user1
14869         declare -A cl_user2
14870         local user_rec1
14871         local user_rec2
14872         local i
14873
14874         # generate some changelog records to accumulate on each MDT
14875         # use fnv1a because created files should be evenly distributed
14876         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14877                 error "test_mkdir $tdir failed"
14878         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14879                 error "create $DIR/$tdir/$tfile failed"
14880
14881         # check changelogs have been generated
14882         local nbcl=$(changelog_dump | wc -l)
14883         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14884
14885         for param in "changelog_max_idle_time=10" \
14886                      "changelog_gc=1" \
14887                      "changelog_min_gc_interval=2"; do
14888                 local MDT0=$(facet_svc $SINGLEMDS)
14889                 local var="${param%=*}"
14890                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14891
14892                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14893                 do_nodes $mdts $LCTL set_param mdd.*.$param
14894         done
14895
14896         # force cl_user2 to be idle (1st part)
14897         sleep 9
14898
14899         for i in $(seq $MDSCOUNT); do
14900                 cl_users=(${CL_USERS[mds$i]})
14901                 cl_user1[mds$i]="${cl_users[0]}"
14902                 cl_user2[mds$i]="${cl_users[1]}"
14903
14904                 [ -n "${cl_user1[mds$i]}" ] ||
14905                         error "mds$i: no user registered"
14906                 [ -n "${cl_user2[mds$i]}" ] ||
14907                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14908
14909                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14910                 [ -n "$user_rec1" ] ||
14911                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14912                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14913                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14914                 [ -n "$user_rec2" ] ||
14915                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14916                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14917                      "$user_rec1 + 2 == $user_rec2"
14918                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14919                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14920                               "$user_rec1 + 2, but is $user_rec2"
14921                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14922                 [ -n "$user_rec2" ] ||
14923                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14924                 [ $user_rec1 == $user_rec2 ] ||
14925                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14926                               "$user_rec1, but is $user_rec2"
14927         done
14928
14929         # force cl_user2 to be idle (2nd part) and to reach
14930         # changelog_max_idle_time
14931         sleep 2
14932
14933         # force each GC-thread start and block then
14934         # one per MDT/MDD, set fail_val accordingly
14935         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14936         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14937
14938         # generate more changelogs to trigger fail_loc
14939         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14940                 error "create $DIR/$tdir/${tfile}bis failed"
14941
14942         # stop MDT to stop GC-thread, should be done in back-ground as it will
14943         # block waiting for the thread to be released and exit
14944         declare -A stop_pids
14945         for i in $(seq $MDSCOUNT); do
14946                 stop mds$i &
14947                 stop_pids[mds$i]=$!
14948         done
14949
14950         for i in $(mdts_nodes); do
14951                 local facet
14952                 local nb=0
14953                 local facets=$(facets_up_on_host $i)
14954
14955                 for facet in ${facets//,/ }; do
14956                         if [[ $facet == mds* ]]; then
14957                                 nb=$((nb + 1))
14958                         fi
14959                 done
14960                 # ensure each MDS's gc threads are still present and all in "R"
14961                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14962                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14963                         error "$i: expected $nb GC-thread"
14964                 wait_update $i \
14965                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14966                         "R" 20 ||
14967                         error "$i: GC-thread not found in R-state"
14968                 # check umounts of each MDT on MDS have reached kthread_stop()
14969                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14970                         error "$i: expected $nb umount"
14971                 wait_update $i \
14972                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14973                         error "$i: umount not found in D-state"
14974         done
14975
14976         # release all GC-threads
14977         do_nodes $mdts $LCTL set_param fail_loc=0
14978
14979         # wait for MDT stop to complete
14980         for i in $(seq $MDSCOUNT); do
14981                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14982         done
14983
14984         # XXX
14985         # may try to check if any orphan changelog records are present
14986         # via ldiskfs/zfs and llog_reader...
14987
14988         # re-start/mount MDTs
14989         for i in $(seq $MDSCOUNT); do
14990                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14991                         error "Fail to start mds$i"
14992         done
14993
14994         local first_rec
14995         for i in $(seq $MDSCOUNT); do
14996                 # check cl_user1 still registered
14997                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14998                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14999                 # check cl_user2 unregistered
15000                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15001                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15002
15003                 # check changelogs are present and starting at $user_rec1 + 1
15004                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15005                 [ -n "$user_rec1" ] ||
15006                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15007                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15008                             awk '{ print $1; exit; }')
15009
15010                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15011                 [ $((user_rec1 + 1)) == $first_rec ] ||
15012                         error "mds$i: first index should be $user_rec1 + 1, " \
15013                               "but is $first_rec"
15014         done
15015 }
15016 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15017               "during mount"
15018
15019 test_160i() {
15020
15021         local mdts=$(comma_list $(mdts_nodes))
15022
15023         changelog_register || error "first changelog_register failed"
15024
15025         # generate some changelog records to accumulate on each MDT
15026         # use fnv1a because created files should be evenly distributed
15027         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15028                 error "mkdir $tdir failed"
15029         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15030                 error "create $DIR/$tdir/$tfile failed"
15031
15032         # check changelogs have been generated
15033         local nbcl=$(changelog_dump | wc -l)
15034         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15035
15036         # simulate race between register and unregister
15037         # XXX as fail_loc is set per-MDS, with DNE configs the race
15038         # simulation will only occur for one MDT per MDS and for the
15039         # others the normal race scenario will take place
15040         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15041         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15042         do_nodes $mdts $LCTL set_param fail_val=1
15043
15044         # unregister 1st user
15045         changelog_deregister &
15046         local pid1=$!
15047         # wait some time for deregister work to reach race rdv
15048         sleep 2
15049         # register 2nd user
15050         changelog_register || error "2nd user register failed"
15051
15052         wait $pid1 || error "1st user deregister failed"
15053
15054         local i
15055         local last_rec
15056         declare -A LAST_REC
15057         for i in $(seq $MDSCOUNT); do
15058                 if changelog_users mds$i | grep "^cl"; then
15059                         # make sure new records are added with one user present
15060                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15061                                           awk '/^current.index:/ { print $NF }')
15062                 else
15063                         error "mds$i has no user registered"
15064                 fi
15065         done
15066
15067         # generate more changelog records to accumulate on each MDT
15068         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15069                 error "create $DIR/$tdir/${tfile}bis failed"
15070
15071         for i in $(seq $MDSCOUNT); do
15072                 last_rec=$(changelog_users $SINGLEMDS |
15073                            awk '/^current.index:/ { print $NF }')
15074                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15075                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15076                         error "changelogs are off on mds$i"
15077         done
15078 }
15079 run_test 160i "changelog user register/unregister race"
15080
15081 test_160j() {
15082         remote_mds_nodsh && skip "remote MDS with nodsh"
15083         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15084                 skip "Need MDS version at least 2.12.56"
15085
15086         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15087         stack_trap "umount $MOUNT2" EXIT
15088
15089         changelog_register || error "first changelog_register failed"
15090         stack_trap "changelog_deregister" EXIT
15091
15092         # generate some changelog
15093         # use fnv1a because created files should be evenly distributed
15094         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15095                 error "mkdir $tdir failed"
15096         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15097                 error "create $DIR/$tdir/${tfile}bis failed"
15098
15099         # open the changelog device
15100         exec 3>/dev/changelog-$FSNAME-MDT0000
15101         stack_trap "exec 3>&-" EXIT
15102         exec 4</dev/changelog-$FSNAME-MDT0000
15103         stack_trap "exec 4<&-" EXIT
15104
15105         # umount the first lustre mount
15106         umount $MOUNT
15107         stack_trap "mount_client $MOUNT" EXIT
15108
15109         # read changelog
15110         cat <&4 >/dev/null || error "read changelog failed"
15111
15112         # clear changelog
15113         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15114         changelog_users $SINGLEMDS | grep -q $cl_user ||
15115                 error "User $cl_user not found in changelog_users"
15116
15117         printf 'clear:'$cl_user':0' >&3
15118 }
15119 run_test 160j "client can be umounted  while its chanangelog is being used"
15120
15121 test_160k() {
15122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15123         remote_mds_nodsh && skip "remote MDS with nodsh"
15124
15125         mkdir -p $DIR/$tdir/1/1
15126
15127         changelog_register || error "changelog_register failed"
15128         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15129
15130         changelog_users $SINGLEMDS | grep -q $cl_user ||
15131                 error "User '$cl_user' not found in changelog_users"
15132 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15133         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15134         rmdir $DIR/$tdir/1/1 & sleep 1
15135         mkdir $DIR/$tdir/2
15136         touch $DIR/$tdir/2/2
15137         rm -rf $DIR/$tdir/2
15138
15139         wait
15140         sleep 4
15141
15142         changelog_dump | grep rmdir || error "rmdir not recorded"
15143
15144         rm -rf $DIR/$tdir
15145         changelog_deregister
15146 }
15147 run_test 160k "Verify that changelog records are not lost"
15148
15149 # Verifies that a file passed as a parameter has recently had an operation
15150 # performed on it that has generated an MTIME changelog which contains the
15151 # correct parent FID. As files might reside on a different MDT from the
15152 # parent directory in DNE configurations, the FIDs are translated to paths
15153 # before being compared, which should be identical
15154 compare_mtime_changelog() {
15155         local file="${1}"
15156         local mdtidx
15157         local mtime
15158         local cl_fid
15159         local pdir
15160         local dir
15161
15162         mdtidx=$($LFS getstripe --mdt-index $file)
15163         mdtidx=$(printf "%04x" $mdtidx)
15164
15165         # Obtain the parent FID from the MTIME changelog
15166         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15167         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15168
15169         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15170         [ -z "$cl_fid" ] && error "parent FID not present"
15171
15172         # Verify that the path for the parent FID is the same as the path for
15173         # the test directory
15174         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15175
15176         dir=$(dirname $1)
15177
15178         [[ "${pdir%/}" == "$dir" ]] ||
15179                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15180 }
15181
15182 test_160l() {
15183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15184
15185         remote_mds_nodsh && skip "remote MDS with nodsh"
15186         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15187                 skip "Need MDS version at least 2.13.55"
15188
15189         local cl_user
15190
15191         changelog_register || error "changelog_register failed"
15192         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15193
15194         changelog_users $SINGLEMDS | grep -q $cl_user ||
15195                 error "User '$cl_user' not found in changelog_users"
15196
15197         # Clear some types so that MTIME changelogs are generated
15198         changelog_chmask "-CREAT"
15199         changelog_chmask "-CLOSE"
15200
15201         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15202
15203         # Test CL_MTIME during setattr
15204         touch $DIR/$tdir/$tfile
15205         compare_mtime_changelog $DIR/$tdir/$tfile
15206
15207         # Test CL_MTIME during close
15208         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15209         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15210 }
15211 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15212
15213 test_161a() {
15214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15215
15216         test_mkdir -c1 $DIR/$tdir
15217         cp /etc/hosts $DIR/$tdir/$tfile
15218         test_mkdir -c1 $DIR/$tdir/foo1
15219         test_mkdir -c1 $DIR/$tdir/foo2
15220         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15221         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15222         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15223         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15224         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15225         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15226                 $LFS fid2path $DIR $FID
15227                 error "bad link ea"
15228         fi
15229         # middle
15230         rm $DIR/$tdir/foo2/zachary
15231         # last
15232         rm $DIR/$tdir/foo2/thor
15233         # first
15234         rm $DIR/$tdir/$tfile
15235         # rename
15236         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15237         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15238                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15239         rm $DIR/$tdir/foo2/maggie
15240
15241         # overflow the EA
15242         local longname=$tfile.avg_len_is_thirty_two_
15243         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15244                 error_noexit 'failed to unlink many hardlinks'" EXIT
15245         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15246                 error "failed to hardlink many files"
15247         links=$($LFS fid2path $DIR $FID | wc -l)
15248         echo -n "${links}/1000 links in link EA"
15249         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15250 }
15251 run_test 161a "link ea sanity"
15252
15253 test_161b() {
15254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15255         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15256
15257         local MDTIDX=1
15258         local remote_dir=$DIR/$tdir/remote_dir
15259
15260         mkdir -p $DIR/$tdir
15261         $LFS mkdir -i $MDTIDX $remote_dir ||
15262                 error "create remote directory failed"
15263
15264         cp /etc/hosts $remote_dir/$tfile
15265         mkdir -p $remote_dir/foo1
15266         mkdir -p $remote_dir/foo2
15267         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15268         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15269         ln $remote_dir/$tfile $remote_dir/foo1/luna
15270         ln $remote_dir/$tfile $remote_dir/foo2/thor
15271
15272         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15273                      tr -d ']')
15274         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15275                 $LFS fid2path $DIR $FID
15276                 error "bad link ea"
15277         fi
15278         # middle
15279         rm $remote_dir/foo2/zachary
15280         # last
15281         rm $remote_dir/foo2/thor
15282         # first
15283         rm $remote_dir/$tfile
15284         # rename
15285         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15286         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15287         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15288                 $LFS fid2path $DIR $FID
15289                 error "bad link rename"
15290         fi
15291         rm $remote_dir/foo2/maggie
15292
15293         # overflow the EA
15294         local longname=filename_avg_len_is_thirty_two_
15295         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15296                 error "failed to hardlink many files"
15297         links=$($LFS fid2path $DIR $FID | wc -l)
15298         echo -n "${links}/1000 links in link EA"
15299         [[ ${links} -gt 60 ]] ||
15300                 error "expected at least 60 links in link EA"
15301         unlinkmany $remote_dir/foo2/$longname 1000 ||
15302         error "failed to unlink many hardlinks"
15303 }
15304 run_test 161b "link ea sanity under remote directory"
15305
15306 test_161c() {
15307         remote_mds_nodsh && skip "remote MDS with nodsh"
15308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15309         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15310                 skip "Need MDS version at least 2.1.5"
15311
15312         # define CLF_RENAME_LAST 0x0001
15313         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15314         changelog_register || error "changelog_register failed"
15315
15316         rm -rf $DIR/$tdir
15317         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15318         touch $DIR/$tdir/foo_161c
15319         touch $DIR/$tdir/bar_161c
15320         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15321         changelog_dump | grep RENME | tail -n 5
15322         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15323         changelog_clear 0 || error "changelog_clear failed"
15324         if [ x$flags != "x0x1" ]; then
15325                 error "flag $flags is not 0x1"
15326         fi
15327
15328         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15329         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15330         touch $DIR/$tdir/foo_161c
15331         touch $DIR/$tdir/bar_161c
15332         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15333         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15334         changelog_dump | grep RENME | tail -n 5
15335         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15336         changelog_clear 0 || error "changelog_clear failed"
15337         if [ x$flags != "x0x0" ]; then
15338                 error "flag $flags is not 0x0"
15339         fi
15340         echo "rename overwrite a target having nlink > 1," \
15341                 "changelog record has flags of $flags"
15342
15343         # rename doesn't overwrite a target (changelog flag 0x0)
15344         touch $DIR/$tdir/foo_161c
15345         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15346         changelog_dump | grep RENME | tail -n 5
15347         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15348         changelog_clear 0 || error "changelog_clear failed"
15349         if [ x$flags != "x0x0" ]; then
15350                 error "flag $flags is not 0x0"
15351         fi
15352         echo "rename doesn't overwrite a target," \
15353                 "changelog record has flags of $flags"
15354
15355         # define CLF_UNLINK_LAST 0x0001
15356         # unlink a file having nlink = 1 (changelog flag 0x1)
15357         rm -f $DIR/$tdir/foo2_161c
15358         changelog_dump | grep UNLNK | tail -n 5
15359         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15360         changelog_clear 0 || error "changelog_clear failed"
15361         if [ x$flags != "x0x1" ]; then
15362                 error "flag $flags is not 0x1"
15363         fi
15364         echo "unlink a file having nlink = 1," \
15365                 "changelog record has flags of $flags"
15366
15367         # unlink a file having nlink > 1 (changelog flag 0x0)
15368         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15369         rm -f $DIR/$tdir/foobar_161c
15370         changelog_dump | grep UNLNK | tail -n 5
15371         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15372         changelog_clear 0 || error "changelog_clear failed"
15373         if [ x$flags != "x0x0" ]; then
15374                 error "flag $flags is not 0x0"
15375         fi
15376         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15377 }
15378 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15379
15380 test_161d() {
15381         remote_mds_nodsh && skip "remote MDS with nodsh"
15382         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15383
15384         local pid
15385         local fid
15386
15387         changelog_register || error "changelog_register failed"
15388
15389         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15390         # interfer with $MOUNT/.lustre/fid/ access
15391         mkdir $DIR/$tdir
15392         [[ $? -eq 0 ]] || error "mkdir failed"
15393
15394         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15395         $LCTL set_param fail_loc=0x8000140c
15396         # 5s pause
15397         $LCTL set_param fail_val=5
15398
15399         # create file
15400         echo foofoo > $DIR/$tdir/$tfile &
15401         pid=$!
15402
15403         # wait for create to be delayed
15404         sleep 2
15405
15406         ps -p $pid
15407         [[ $? -eq 0 ]] || error "create should be blocked"
15408
15409         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15410         stack_trap "rm -f $tempfile"
15411         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15412         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15413         # some delay may occur during ChangeLog publishing and file read just
15414         # above, that could allow file write to happen finally
15415         [[ -s $tempfile ]] && echo "file should be empty"
15416
15417         $LCTL set_param fail_loc=0
15418
15419         wait $pid
15420         [[ $? -eq 0 ]] || error "create failed"
15421 }
15422 run_test 161d "create with concurrent .lustre/fid access"
15423
15424 check_path() {
15425         local expected="$1"
15426         shift
15427         local fid="$2"
15428
15429         local path
15430         path=$($LFS fid2path "$@")
15431         local rc=$?
15432
15433         if [ $rc -ne 0 ]; then
15434                 error "path looked up of '$expected' failed: rc=$rc"
15435         elif [ "$path" != "$expected" ]; then
15436                 error "path looked up '$path' instead of '$expected'"
15437         else
15438                 echo "FID '$fid' resolves to path '$path' as expected"
15439         fi
15440 }
15441
15442 test_162a() { # was test_162
15443         test_mkdir -p -c1 $DIR/$tdir/d2
15444         touch $DIR/$tdir/d2/$tfile
15445         touch $DIR/$tdir/d2/x1
15446         touch $DIR/$tdir/d2/x2
15447         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15448         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15449         # regular file
15450         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15451         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15452
15453         # softlink
15454         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15455         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15456         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15457
15458         # softlink to wrong file
15459         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15460         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15461         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15462
15463         # hardlink
15464         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15465         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15466         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15467         # fid2path dir/fsname should both work
15468         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15469         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15470
15471         # hardlink count: check that there are 2 links
15472         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15473         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15474
15475         # hardlink indexing: remove the first link
15476         rm $DIR/$tdir/d2/p/q/r/hlink
15477         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15478 }
15479 run_test 162a "path lookup sanity"
15480
15481 test_162b() {
15482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15483         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15484
15485         mkdir $DIR/$tdir
15486         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15487                                 error "create striped dir failed"
15488
15489         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15490                                         tail -n 1 | awk '{print $2}')
15491         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15492
15493         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15494         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15495
15496         # regular file
15497         for ((i=0;i<5;i++)); do
15498                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15499                         error "get fid for f$i failed"
15500                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15501
15502                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15503                         error "get fid for d$i failed"
15504                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15505         done
15506
15507         return 0
15508 }
15509 run_test 162b "striped directory path lookup sanity"
15510
15511 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15512 test_162c() {
15513         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15514                 skip "Need MDS version at least 2.7.51"
15515
15516         local lpath=$tdir.local
15517         local rpath=$tdir.remote
15518
15519         test_mkdir $DIR/$lpath
15520         test_mkdir $DIR/$rpath
15521
15522         for ((i = 0; i <= 101; i++)); do
15523                 lpath="$lpath/$i"
15524                 mkdir $DIR/$lpath
15525                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15526                         error "get fid for local directory $DIR/$lpath failed"
15527                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15528
15529                 rpath="$rpath/$i"
15530                 test_mkdir $DIR/$rpath
15531                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15532                         error "get fid for remote directory $DIR/$rpath failed"
15533                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15534         done
15535
15536         return 0
15537 }
15538 run_test 162c "fid2path works with paths 100 or more directories deep"
15539
15540 oalr_event_count() {
15541         local event="${1}"
15542         local trace="${2}"
15543
15544         awk -v name="${FSNAME}-OST0000" \
15545             -v event="${event}" \
15546             '$1 == "TRACE" && $2 == event && $3 == name' \
15547             "${trace}" |
15548         wc -l
15549 }
15550
15551 oalr_expect_event_count() {
15552         local event="${1}"
15553         local trace="${2}"
15554         local expect="${3}"
15555         local count
15556
15557         count=$(oalr_event_count "${event}" "${trace}")
15558         if ((count == expect)); then
15559                 return 0
15560         fi
15561
15562         error_noexit "${event} event count was '${count}', expected ${expect}"
15563         cat "${trace}" >&2
15564         exit 1
15565 }
15566
15567 cleanup_165() {
15568         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15569         stop ost1
15570         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15571 }
15572
15573 setup_165() {
15574         sync # Flush previous IOs so we can count log entries.
15575         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15576         stack_trap cleanup_165 EXIT
15577 }
15578
15579 test_165a() {
15580         local trace="/tmp/${tfile}.trace"
15581         local rc
15582         local count
15583
15584         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15585                 skip "OFD access log unsupported"
15586
15587         setup_165
15588         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15589         sleep 5
15590
15591         do_facet ost1 ofd_access_log_reader --list
15592         stop ost1
15593
15594         do_facet ost1 killall -TERM ofd_access_log_reader
15595         wait
15596         rc=$?
15597
15598         if ((rc != 0)); then
15599                 error "ofd_access_log_reader exited with rc = '${rc}'"
15600         fi
15601
15602         # Parse trace file for discovery events:
15603         oalr_expect_event_count alr_log_add "${trace}" 1
15604         oalr_expect_event_count alr_log_eof "${trace}" 1
15605         oalr_expect_event_count alr_log_free "${trace}" 1
15606 }
15607 run_test 165a "ofd access log discovery"
15608
15609 test_165b() {
15610         local trace="/tmp/${tfile}.trace"
15611         local file="${DIR}/${tfile}"
15612         local pfid1
15613         local pfid2
15614         local -a entry
15615         local rc
15616         local count
15617         local size
15618         local flags
15619
15620         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15621                 skip "OFD access log unsupported"
15622
15623         setup_165
15624         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15625         sleep 5
15626
15627         do_facet ost1 ofd_access_log_reader --list
15628
15629         lfs setstripe -c 1 -i 0 "${file}"
15630         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15631                 error "cannot create '${file}'"
15632
15633         sleep 5
15634         do_facet ost1 killall -TERM ofd_access_log_reader
15635         wait
15636         rc=$?
15637
15638         if ((rc != 0)); then
15639                 error "ofd_access_log_reader exited with rc = '${rc}'"
15640         fi
15641
15642         oalr_expect_event_count alr_log_entry "${trace}" 1
15643
15644         pfid1=$($LFS path2fid "${file}")
15645
15646         # 1     2             3   4    5     6   7    8    9     10
15647         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15648         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15649
15650         echo "entry = '${entry[*]}'" >&2
15651
15652         pfid2=${entry[4]}
15653         if [[ "${pfid1}" != "${pfid2}" ]]; then
15654                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15655         fi
15656
15657         size=${entry[8]}
15658         if ((size != 1048576)); then
15659                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15660         fi
15661
15662         flags=${entry[10]}
15663         if [[ "${flags}" != "w" ]]; then
15664                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15665         fi
15666
15667         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15668         sleep 5
15669
15670         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15671                 error "cannot read '${file}'"
15672         sleep 5
15673
15674         do_facet ost1 killall -TERM ofd_access_log_reader
15675         wait
15676         rc=$?
15677
15678         if ((rc != 0)); then
15679                 error "ofd_access_log_reader exited with rc = '${rc}'"
15680         fi
15681
15682         oalr_expect_event_count alr_log_entry "${trace}" 1
15683
15684         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15685         echo "entry = '${entry[*]}'" >&2
15686
15687         pfid2=${entry[4]}
15688         if [[ "${pfid1}" != "${pfid2}" ]]; then
15689                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15690         fi
15691
15692         size=${entry[8]}
15693         if ((size != 524288)); then
15694                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15695         fi
15696
15697         flags=${entry[10]}
15698         if [[ "${flags}" != "r" ]]; then
15699                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15700         fi
15701 }
15702 run_test 165b "ofd access log entries are produced and consumed"
15703
15704 test_165c() {
15705         local trace="/tmp/${tfile}.trace"
15706         local file="${DIR}/${tdir}/${tfile}"
15707
15708         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15709                 skip "OFD access log unsupported"
15710
15711         test_mkdir "${DIR}/${tdir}"
15712
15713         setup_165
15714         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15715         sleep 5
15716
15717         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15718
15719         # 4096 / 64 = 64. Create twice as many entries.
15720         for ((i = 0; i < 128; i++)); do
15721                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15722                         error "cannot create file"
15723         done
15724
15725         sync
15726
15727         do_facet ost1 killall -TERM ofd_access_log_reader
15728         wait
15729         rc=$?
15730         if ((rc != 0)); then
15731                 error "ofd_access_log_reader exited with rc = '${rc}'"
15732         fi
15733
15734         unlinkmany  "${file}-%d" 128
15735 }
15736 run_test 165c "full ofd access logs do not block IOs"
15737
15738 oal_get_read_count() {
15739         local stats="$1"
15740
15741         # STATS lustre-OST0001 alr_read_count 1
15742
15743         do_facet ost1 cat "${stats}" |
15744         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15745              END { print count; }'
15746 }
15747
15748 oal_expect_read_count() {
15749         local stats="$1"
15750         local count
15751         local expect="$2"
15752
15753         # Ask ofd_access_log_reader to write stats.
15754         do_facet ost1 killall -USR1 ofd_access_log_reader
15755
15756         # Allow some time for things to happen.
15757         sleep 1
15758
15759         count=$(oal_get_read_count "${stats}")
15760         if ((count == expect)); then
15761                 return 0
15762         fi
15763
15764         error_noexit "bad read count, got ${count}, expected ${expect}"
15765         do_facet ost1 cat "${stats}" >&2
15766         exit 1
15767 }
15768
15769 test_165d() {
15770         local stats="/tmp/${tfile}.stats"
15771         local file="${DIR}/${tdir}/${tfile}"
15772         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15773
15774         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15775                 skip "OFD access log unsupported"
15776
15777         test_mkdir "${DIR}/${tdir}"
15778
15779         setup_165
15780         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15781         sleep 5
15782
15783         lfs setstripe -c 1 -i 0 "${file}"
15784
15785         do_facet ost1 lctl set_param "${param}=rw"
15786         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15787                 error "cannot create '${file}'"
15788         oal_expect_read_count "${stats}" 1
15789
15790         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15791                 error "cannot read '${file}'"
15792         oal_expect_read_count "${stats}" 2
15793
15794         do_facet ost1 lctl set_param "${param}=r"
15795         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15796                 error "cannot create '${file}'"
15797         oal_expect_read_count "${stats}" 2
15798
15799         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15800                 error "cannot read '${file}'"
15801         oal_expect_read_count "${stats}" 3
15802
15803         do_facet ost1 lctl set_param "${param}=w"
15804         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15805                 error "cannot create '${file}'"
15806         oal_expect_read_count "${stats}" 4
15807
15808         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15809                 error "cannot read '${file}'"
15810         oal_expect_read_count "${stats}" 4
15811
15812         do_facet ost1 lctl set_param "${param}=0"
15813         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15814                 error "cannot create '${file}'"
15815         oal_expect_read_count "${stats}" 4
15816
15817         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15818                 error "cannot read '${file}'"
15819         oal_expect_read_count "${stats}" 4
15820
15821         do_facet ost1 killall -TERM ofd_access_log_reader
15822         wait
15823         rc=$?
15824         if ((rc != 0)); then
15825                 error "ofd_access_log_reader exited with rc = '${rc}'"
15826         fi
15827 }
15828 run_test 165d "ofd_access_log mask works"
15829
15830 test_165e() {
15831         local stats="/tmp/${tfile}.stats"
15832         local file0="${DIR}/${tdir}-0/${tfile}"
15833         local file1="${DIR}/${tdir}-1/${tfile}"
15834
15835         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15836                 skip "OFD access log unsupported"
15837
15838         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15839
15840         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15841         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15842
15843         lfs setstripe -c 1 -i 0 "${file0}"
15844         lfs setstripe -c 1 -i 0 "${file1}"
15845
15846         setup_165
15847         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15848         sleep 5
15849
15850         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15851                 error "cannot create '${file0}'"
15852         sync
15853         oal_expect_read_count "${stats}" 0
15854
15855         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15856                 error "cannot create '${file1}'"
15857         sync
15858         oal_expect_read_count "${stats}" 1
15859
15860         do_facet ost1 killall -TERM ofd_access_log_reader
15861         wait
15862         rc=$?
15863         if ((rc != 0)); then
15864                 error "ofd_access_log_reader exited with rc = '${rc}'"
15865         fi
15866 }
15867 run_test 165e "ofd_access_log MDT index filter works"
15868
15869 test_165f() {
15870         local trace="/tmp/${tfile}.trace"
15871         local rc
15872         local count
15873
15874         setup_165
15875         do_facet ost1 timeout 60 ofd_access_log_reader \
15876                 --exit-on-close --debug=- --trace=- > "${trace}" &
15877         sleep 5
15878         stop ost1
15879
15880         wait
15881         rc=$?
15882
15883         if ((rc != 0)); then
15884                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15885                 cat "${trace}"
15886                 exit 1
15887         fi
15888 }
15889 run_test 165f "ofd_access_log_reader --exit-on-close works"
15890
15891 test_169() {
15892         # do directio so as not to populate the page cache
15893         log "creating a 10 Mb file"
15894         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15895                 error "multiop failed while creating a file"
15896         log "starting reads"
15897         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15898         log "truncating the file"
15899         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15900                 error "multiop failed while truncating the file"
15901         log "killing dd"
15902         kill %+ || true # reads might have finished
15903         echo "wait until dd is finished"
15904         wait
15905         log "removing the temporary file"
15906         rm -rf $DIR/$tfile || error "tmp file removal failed"
15907 }
15908 run_test 169 "parallel read and truncate should not deadlock"
15909
15910 test_170() {
15911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15912
15913         $LCTL clear     # bug 18514
15914         $LCTL debug_daemon start $TMP/${tfile}_log_good
15915         touch $DIR/$tfile
15916         $LCTL debug_daemon stop
15917         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15918                 error "sed failed to read log_good"
15919
15920         $LCTL debug_daemon start $TMP/${tfile}_log_good
15921         rm -rf $DIR/$tfile
15922         $LCTL debug_daemon stop
15923
15924         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15925                error "lctl df log_bad failed"
15926
15927         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15928         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15929
15930         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15931         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15932
15933         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15934                 error "bad_line good_line1 good_line2 are empty"
15935
15936         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15937         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15938         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15939
15940         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15941         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15942         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15943
15944         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15945                 error "bad_line_new good_line_new are empty"
15946
15947         local expected_good=$((good_line1 + good_line2*2))
15948
15949         rm -f $TMP/${tfile}*
15950         # LU-231, short malformed line may not be counted into bad lines
15951         if [ $bad_line -ne $bad_line_new ] &&
15952                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15953                 error "expected $bad_line bad lines, but got $bad_line_new"
15954                 return 1
15955         fi
15956
15957         if [ $expected_good -ne $good_line_new ]; then
15958                 error "expected $expected_good good lines, but got $good_line_new"
15959                 return 2
15960         fi
15961         true
15962 }
15963 run_test 170 "test lctl df to handle corrupted log ====================="
15964
15965 test_171() { # bug20592
15966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15967
15968         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15969         $LCTL set_param fail_loc=0x50e
15970         $LCTL set_param fail_val=3000
15971         multiop_bg_pause $DIR/$tfile O_s || true
15972         local MULTIPID=$!
15973         kill -USR1 $MULTIPID
15974         # cause log dump
15975         sleep 3
15976         wait $MULTIPID
15977         if dmesg | grep "recursive fault"; then
15978                 error "caught a recursive fault"
15979         fi
15980         $LCTL set_param fail_loc=0
15981         true
15982 }
15983 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15984
15985 # it would be good to share it with obdfilter-survey/iokit-libecho code
15986 setup_obdecho_osc () {
15987         local rc=0
15988         local ost_nid=$1
15989         local obdfilter_name=$2
15990         echo "Creating new osc for $obdfilter_name on $ost_nid"
15991         # make sure we can find loopback nid
15992         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15993
15994         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15995                            ${obdfilter_name}_osc_UUID || rc=2; }
15996         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15997                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15998         return $rc
15999 }
16000
16001 cleanup_obdecho_osc () {
16002         local obdfilter_name=$1
16003         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16004         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16005         return 0
16006 }
16007
16008 obdecho_test() {
16009         local OBD=$1
16010         local node=$2
16011         local pages=${3:-64}
16012         local rc=0
16013         local id
16014
16015         local count=10
16016         local obd_size=$(get_obd_size $node $OBD)
16017         local page_size=$(get_page_size $node)
16018         if [[ -n "$obd_size" ]]; then
16019                 local new_count=$((obd_size / (pages * page_size / 1024)))
16020                 [[ $new_count -ge $count ]] || count=$new_count
16021         fi
16022
16023         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16024         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16025                            rc=2; }
16026         if [ $rc -eq 0 ]; then
16027             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16028             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16029         fi
16030         echo "New object id is $id"
16031         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16032                            rc=4; }
16033         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16034                            "test_brw $count w v $pages $id" || rc=4; }
16035         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16036                            rc=4; }
16037         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16038                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16039         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16040                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16041         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16042         return $rc
16043 }
16044
16045 test_180a() {
16046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16047
16048         if ! [ -d /sys/fs/lustre/echo_client ] &&
16049            ! module_loaded obdecho; then
16050                 load_module obdecho/obdecho &&
16051                         stack_trap "rmmod obdecho" EXIT ||
16052                         error "unable to load obdecho on client"
16053         fi
16054
16055         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16056         local host=$($LCTL get_param -n osc.$osc.import |
16057                      awk '/current_connection:/ { print $2 }' )
16058         local target=$($LCTL get_param -n osc.$osc.import |
16059                        awk '/target:/ { print $2 }' )
16060         target=${target%_UUID}
16061
16062         if [ -n "$target" ]; then
16063                 setup_obdecho_osc $host $target &&
16064                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16065                         { error "obdecho setup failed with $?"; return; }
16066
16067                 obdecho_test ${target}_osc client ||
16068                         error "obdecho_test failed on ${target}_osc"
16069         else
16070                 $LCTL get_param osc.$osc.import
16071                 error "there is no osc.$osc.import target"
16072         fi
16073 }
16074 run_test 180a "test obdecho on osc"
16075
16076 test_180b() {
16077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16078         remote_ost_nodsh && skip "remote OST with nodsh"
16079
16080         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16081                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16082                 error "failed to load module obdecho"
16083
16084         local target=$(do_facet ost1 $LCTL dl |
16085                        awk '/obdfilter/ { print $4; exit; }')
16086
16087         if [ -n "$target" ]; then
16088                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16089         else
16090                 do_facet ost1 $LCTL dl
16091                 error "there is no obdfilter target on ost1"
16092         fi
16093 }
16094 run_test 180b "test obdecho directly on obdfilter"
16095
16096 test_180c() { # LU-2598
16097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16098         remote_ost_nodsh && skip "remote OST with nodsh"
16099         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16100                 skip "Need MDS version at least 2.4.0"
16101
16102         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16103                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16104                 error "failed to load module obdecho"
16105
16106         local target=$(do_facet ost1 $LCTL dl |
16107                        awk '/obdfilter/ { print $4; exit; }')
16108
16109         if [ -n "$target" ]; then
16110                 local pages=16384 # 64MB bulk I/O RPC size
16111
16112                 obdecho_test "$target" ost1 "$pages" ||
16113                         error "obdecho_test with pages=$pages failed with $?"
16114         else
16115                 do_facet ost1 $LCTL dl
16116                 error "there is no obdfilter target on ost1"
16117         fi
16118 }
16119 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16120
16121 test_181() { # bug 22177
16122         test_mkdir $DIR/$tdir
16123         # create enough files to index the directory
16124         createmany -o $DIR/$tdir/foobar 4000
16125         # print attributes for debug purpose
16126         lsattr -d .
16127         # open dir
16128         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16129         MULTIPID=$!
16130         # remove the files & current working dir
16131         unlinkmany $DIR/$tdir/foobar 4000
16132         rmdir $DIR/$tdir
16133         kill -USR1 $MULTIPID
16134         wait $MULTIPID
16135         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16136         return 0
16137 }
16138 run_test 181 "Test open-unlinked dir ========================"
16139
16140 test_182() {
16141         local fcount=1000
16142         local tcount=10
16143
16144         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16145
16146         $LCTL set_param mdc.*.rpc_stats=clear
16147
16148         for (( i = 0; i < $tcount; i++ )) ; do
16149                 mkdir $DIR/$tdir/$i
16150         done
16151
16152         for (( i = 0; i < $tcount; i++ )) ; do
16153                 createmany -o $DIR/$tdir/$i/f- $fcount &
16154         done
16155         wait
16156
16157         for (( i = 0; i < $tcount; i++ )) ; do
16158                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16159         done
16160         wait
16161
16162         $LCTL get_param mdc.*.rpc_stats
16163
16164         rm -rf $DIR/$tdir
16165 }
16166 run_test 182 "Test parallel modify metadata operations ================"
16167
16168 test_183() { # LU-2275
16169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16170         remote_mds_nodsh && skip "remote MDS with nodsh"
16171         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16172                 skip "Need MDS version at least 2.3.56"
16173
16174         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16175         echo aaa > $DIR/$tdir/$tfile
16176
16177 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16178         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16179
16180         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16181         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16182
16183         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16184
16185         # Flush negative dentry cache
16186         touch $DIR/$tdir/$tfile
16187
16188         # We are not checking for any leaked references here, they'll
16189         # become evident next time we do cleanup with module unload.
16190         rm -rf $DIR/$tdir
16191 }
16192 run_test 183 "No crash or request leak in case of strange dispositions ========"
16193
16194 # test suite 184 is for LU-2016, LU-2017
16195 test_184a() {
16196         check_swap_layouts_support
16197
16198         dir0=$DIR/$tdir/$testnum
16199         test_mkdir -p -c1 $dir0
16200         ref1=/etc/passwd
16201         ref2=/etc/group
16202         file1=$dir0/f1
16203         file2=$dir0/f2
16204         $LFS setstripe -c1 $file1
16205         cp $ref1 $file1
16206         $LFS setstripe -c2 $file2
16207         cp $ref2 $file2
16208         gen1=$($LFS getstripe -g $file1)
16209         gen2=$($LFS getstripe -g $file2)
16210
16211         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16212         gen=$($LFS getstripe -g $file1)
16213         [[ $gen1 != $gen ]] ||
16214                 "Layout generation on $file1 does not change"
16215         gen=$($LFS getstripe -g $file2)
16216         [[ $gen2 != $gen ]] ||
16217                 "Layout generation on $file2 does not change"
16218
16219         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16220         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16221
16222         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16223 }
16224 run_test 184a "Basic layout swap"
16225
16226 test_184b() {
16227         check_swap_layouts_support
16228
16229         dir0=$DIR/$tdir/$testnum
16230         mkdir -p $dir0 || error "creating dir $dir0"
16231         file1=$dir0/f1
16232         file2=$dir0/f2
16233         file3=$dir0/f3
16234         dir1=$dir0/d1
16235         dir2=$dir0/d2
16236         mkdir $dir1 $dir2
16237         $LFS setstripe -c1 $file1
16238         $LFS setstripe -c2 $file2
16239         $LFS setstripe -c1 $file3
16240         chown $RUNAS_ID $file3
16241         gen1=$($LFS getstripe -g $file1)
16242         gen2=$($LFS getstripe -g $file2)
16243
16244         $LFS swap_layouts $dir1 $dir2 &&
16245                 error "swap of directories layouts should fail"
16246         $LFS swap_layouts $dir1 $file1 &&
16247                 error "swap of directory and file layouts should fail"
16248         $RUNAS $LFS swap_layouts $file1 $file2 &&
16249                 error "swap of file we cannot write should fail"
16250         $LFS swap_layouts $file1 $file3 &&
16251                 error "swap of file with different owner should fail"
16252         /bin/true # to clear error code
16253 }
16254 run_test 184b "Forbidden layout swap (will generate errors)"
16255
16256 test_184c() {
16257         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16258         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16259         check_swap_layouts_support
16260         check_swap_layout_no_dom $DIR
16261
16262         local dir0=$DIR/$tdir/$testnum
16263         mkdir -p $dir0 || error "creating dir $dir0"
16264
16265         local ref1=$dir0/ref1
16266         local ref2=$dir0/ref2
16267         local file1=$dir0/file1
16268         local file2=$dir0/file2
16269         # create a file large enough for the concurrent test
16270         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16271         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16272         echo "ref file size: ref1($(stat -c %s $ref1))," \
16273              "ref2($(stat -c %s $ref2))"
16274
16275         cp $ref2 $file2
16276         dd if=$ref1 of=$file1 bs=16k &
16277         local DD_PID=$!
16278
16279         # Make sure dd starts to copy file, but wait at most 5 seconds
16280         local loops=0
16281         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16282
16283         $LFS swap_layouts $file1 $file2
16284         local rc=$?
16285         wait $DD_PID
16286         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16287         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16288
16289         # how many bytes copied before swapping layout
16290         local copied=$(stat -c %s $file2)
16291         local remaining=$(stat -c %s $ref1)
16292         remaining=$((remaining - copied))
16293         echo "Copied $copied bytes before swapping layout..."
16294
16295         cmp -n $copied $file1 $ref2 | grep differ &&
16296                 error "Content mismatch [0, $copied) of ref2 and file1"
16297         cmp -n $copied $file2 $ref1 ||
16298                 error "Content mismatch [0, $copied) of ref1 and file2"
16299         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16300                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16301
16302         # clean up
16303         rm -f $ref1 $ref2 $file1 $file2
16304 }
16305 run_test 184c "Concurrent write and layout swap"
16306
16307 test_184d() {
16308         check_swap_layouts_support
16309         check_swap_layout_no_dom $DIR
16310         [ -z "$(which getfattr 2>/dev/null)" ] &&
16311                 skip_env "no getfattr command"
16312
16313         local file1=$DIR/$tdir/$tfile-1
16314         local file2=$DIR/$tdir/$tfile-2
16315         local file3=$DIR/$tdir/$tfile-3
16316         local lovea1
16317         local lovea2
16318
16319         mkdir -p $DIR/$tdir
16320         touch $file1 || error "create $file1 failed"
16321         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16322                 error "create $file2 failed"
16323         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16324                 error "create $file3 failed"
16325         lovea1=$(get_layout_param $file1)
16326
16327         $LFS swap_layouts $file2 $file3 ||
16328                 error "swap $file2 $file3 layouts failed"
16329         $LFS swap_layouts $file1 $file2 ||
16330                 error "swap $file1 $file2 layouts failed"
16331
16332         lovea2=$(get_layout_param $file2)
16333         echo "$lovea1"
16334         echo "$lovea2"
16335         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16336
16337         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16338         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16339 }
16340 run_test 184d "allow stripeless layouts swap"
16341
16342 test_184e() {
16343         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16344                 skip "Need MDS version at least 2.6.94"
16345         check_swap_layouts_support
16346         check_swap_layout_no_dom $DIR
16347         [ -z "$(which getfattr 2>/dev/null)" ] &&
16348                 skip_env "no getfattr command"
16349
16350         local file1=$DIR/$tdir/$tfile-1
16351         local file2=$DIR/$tdir/$tfile-2
16352         local file3=$DIR/$tdir/$tfile-3
16353         local lovea
16354
16355         mkdir -p $DIR/$tdir
16356         touch $file1 || error "create $file1 failed"
16357         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16358                 error "create $file2 failed"
16359         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16360                 error "create $file3 failed"
16361
16362         $LFS swap_layouts $file1 $file2 ||
16363                 error "swap $file1 $file2 layouts failed"
16364
16365         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16366         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16367
16368         echo 123 > $file1 || error "Should be able to write into $file1"
16369
16370         $LFS swap_layouts $file1 $file3 ||
16371                 error "swap $file1 $file3 layouts failed"
16372
16373         echo 123 > $file1 || error "Should be able to write into $file1"
16374
16375         rm -rf $file1 $file2 $file3
16376 }
16377 run_test 184e "Recreate layout after stripeless layout swaps"
16378
16379 test_184f() {
16380         # Create a file with name longer than sizeof(struct stat) ==
16381         # 144 to see if we can get chars from the file name to appear
16382         # in the returned striping. Note that 'f' == 0x66.
16383         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16384
16385         mkdir -p $DIR/$tdir
16386         mcreate $DIR/$tdir/$file
16387         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16388                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16389         fi
16390 }
16391 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16392
16393 test_185() { # LU-2441
16394         # LU-3553 - no volatile file support in old servers
16395         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16396                 skip "Need MDS version at least 2.3.60"
16397
16398         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16399         touch $DIR/$tdir/spoo
16400         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16401         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16402                 error "cannot create/write a volatile file"
16403         [ "$FILESET" == "" ] &&
16404         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16405                 error "FID is still valid after close"
16406
16407         multiop_bg_pause $DIR/$tdir vVw4096_c
16408         local multi_pid=$!
16409
16410         local OLD_IFS=$IFS
16411         IFS=":"
16412         local fidv=($fid)
16413         IFS=$OLD_IFS
16414         # assume that the next FID for this client is sequential, since stdout
16415         # is unfortunately eaten by multiop_bg_pause
16416         local n=$((${fidv[1]} + 1))
16417         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16418         if [ "$FILESET" == "" ]; then
16419                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16420                         error "FID is missing before close"
16421         fi
16422         kill -USR1 $multi_pid
16423         # 1 second delay, so if mtime change we will see it
16424         sleep 1
16425         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16426         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16427 }
16428 run_test 185 "Volatile file support"
16429
16430 function create_check_volatile() {
16431         local idx=$1
16432         local tgt
16433
16434         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16435         local PID=$!
16436         sleep 1
16437         local FID=$(cat /tmp/${tfile}.fid)
16438         [ "$FID" == "" ] && error "can't get FID for volatile"
16439         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16440         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16441         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16442         kill -USR1 $PID
16443         wait
16444         sleep 1
16445         cancel_lru_locks mdc # flush opencache
16446         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16447         return 0
16448 }
16449
16450 test_185a(){
16451         # LU-12516 - volatile creation via .lustre
16452         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16453                 skip "Need MDS version at least 2.3.55"
16454
16455         create_check_volatile 0
16456         [ $MDSCOUNT -lt 2 ] && return 0
16457
16458         # DNE case
16459         create_check_volatile 1
16460
16461         return 0
16462 }
16463 run_test 185a "Volatile file creation in .lustre/fid/"
16464
16465 test_187a() {
16466         remote_mds_nodsh && skip "remote MDS with nodsh"
16467         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16468                 skip "Need MDS version at least 2.3.0"
16469
16470         local dir0=$DIR/$tdir/$testnum
16471         mkdir -p $dir0 || error "creating dir $dir0"
16472
16473         local file=$dir0/file1
16474         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16475         local dv1=$($LFS data_version $file)
16476         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16477         local dv2=$($LFS data_version $file)
16478         [[ $dv1 != $dv2 ]] ||
16479                 error "data version did not change on write $dv1 == $dv2"
16480
16481         # clean up
16482         rm -f $file1
16483 }
16484 run_test 187a "Test data version change"
16485
16486 test_187b() {
16487         remote_mds_nodsh && skip "remote MDS with nodsh"
16488         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16489                 skip "Need MDS version at least 2.3.0"
16490
16491         local dir0=$DIR/$tdir/$testnum
16492         mkdir -p $dir0 || error "creating dir $dir0"
16493
16494         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16495         [[ ${DV[0]} != ${DV[1]} ]] ||
16496                 error "data version did not change on write"\
16497                       " ${DV[0]} == ${DV[1]}"
16498
16499         # clean up
16500         rm -f $file1
16501 }
16502 run_test 187b "Test data version change on volatile file"
16503
16504 test_200() {
16505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16506         remote_mgs_nodsh && skip "remote MGS with nodsh"
16507         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16508
16509         local POOL=${POOL:-cea1}
16510         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16511         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16512         # Pool OST targets
16513         local first_ost=0
16514         local last_ost=$(($OSTCOUNT - 1))
16515         local ost_step=2
16516         local ost_list=$(seq $first_ost $ost_step $last_ost)
16517         local ost_range="$first_ost $last_ost $ost_step"
16518         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16519         local file_dir=$POOL_ROOT/file_tst
16520         local subdir=$test_path/subdir
16521         local rc=0
16522
16523         while : ; do
16524                 # former test_200a test_200b
16525                 pool_add $POOL                          || { rc=$? ; break; }
16526                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16527                 # former test_200c test_200d
16528                 mkdir -p $test_path
16529                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16530                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16531                 mkdir -p $subdir
16532                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16533                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16534                                                         || { rc=$? ; break; }
16535                 # former test_200e test_200f
16536                 local files=$((OSTCOUNT*3))
16537                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16538                                                         || { rc=$? ; break; }
16539                 pool_create_files $POOL $file_dir $files "$ost_list" \
16540                                                         || { rc=$? ; break; }
16541                 # former test_200g test_200h
16542                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16543                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16544
16545                 # former test_201a test_201b test_201c
16546                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16547
16548                 local f=$test_path/$tfile
16549                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16550                 pool_remove $POOL $f                    || { rc=$? ; break; }
16551                 break
16552         done
16553
16554         destroy_test_pools
16555
16556         return $rc
16557 }
16558 run_test 200 "OST pools"
16559
16560 # usage: default_attr <count | size | offset>
16561 default_attr() {
16562         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16563 }
16564
16565 # usage: check_default_stripe_attr
16566 check_default_stripe_attr() {
16567         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16568         case $1 in
16569         --stripe-count|-c)
16570                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16571         --stripe-size|-S)
16572                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16573         --stripe-index|-i)
16574                 EXPECTED=-1;;
16575         *)
16576                 error "unknown getstripe attr '$1'"
16577         esac
16578
16579         [ $ACTUAL == $EXPECTED ] ||
16580                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16581 }
16582
16583 test_204a() {
16584         test_mkdir $DIR/$tdir
16585         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16586
16587         check_default_stripe_attr --stripe-count
16588         check_default_stripe_attr --stripe-size
16589         check_default_stripe_attr --stripe-index
16590 }
16591 run_test 204a "Print default stripe attributes"
16592
16593 test_204b() {
16594         test_mkdir $DIR/$tdir
16595         $LFS setstripe --stripe-count 1 $DIR/$tdir
16596
16597         check_default_stripe_attr --stripe-size
16598         check_default_stripe_attr --stripe-index
16599 }
16600 run_test 204b "Print default stripe size and offset"
16601
16602 test_204c() {
16603         test_mkdir $DIR/$tdir
16604         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16605
16606         check_default_stripe_attr --stripe-count
16607         check_default_stripe_attr --stripe-index
16608 }
16609 run_test 204c "Print default stripe count and offset"
16610
16611 test_204d() {
16612         test_mkdir $DIR/$tdir
16613         $LFS setstripe --stripe-index 0 $DIR/$tdir
16614
16615         check_default_stripe_attr --stripe-count
16616         check_default_stripe_attr --stripe-size
16617 }
16618 run_test 204d "Print default stripe count and size"
16619
16620 test_204e() {
16621         test_mkdir $DIR/$tdir
16622         $LFS setstripe -d $DIR/$tdir
16623
16624         check_default_stripe_attr --stripe-count --raw
16625         check_default_stripe_attr --stripe-size --raw
16626         check_default_stripe_attr --stripe-index --raw
16627 }
16628 run_test 204e "Print raw stripe attributes"
16629
16630 test_204f() {
16631         test_mkdir $DIR/$tdir
16632         $LFS setstripe --stripe-count 1 $DIR/$tdir
16633
16634         check_default_stripe_attr --stripe-size --raw
16635         check_default_stripe_attr --stripe-index --raw
16636 }
16637 run_test 204f "Print raw stripe size and offset"
16638
16639 test_204g() {
16640         test_mkdir $DIR/$tdir
16641         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16642
16643         check_default_stripe_attr --stripe-count --raw
16644         check_default_stripe_attr --stripe-index --raw
16645 }
16646 run_test 204g "Print raw stripe count and offset"
16647
16648 test_204h() {
16649         test_mkdir $DIR/$tdir
16650         $LFS setstripe --stripe-index 0 $DIR/$tdir
16651
16652         check_default_stripe_attr --stripe-count --raw
16653         check_default_stripe_attr --stripe-size --raw
16654 }
16655 run_test 204h "Print raw stripe count and size"
16656
16657 # Figure out which job scheduler is being used, if any,
16658 # or use a fake one
16659 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16660         JOBENV=SLURM_JOB_ID
16661 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16662         JOBENV=LSB_JOBID
16663 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16664         JOBENV=PBS_JOBID
16665 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16666         JOBENV=LOADL_STEP_ID
16667 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16668         JOBENV=JOB_ID
16669 else
16670         $LCTL list_param jobid_name > /dev/null 2>&1
16671         if [ $? -eq 0 ]; then
16672                 JOBENV=nodelocal
16673         else
16674                 JOBENV=FAKE_JOBID
16675         fi
16676 fi
16677 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16678
16679 verify_jobstats() {
16680         local cmd=($1)
16681         shift
16682         local facets="$@"
16683
16684 # we don't really need to clear the stats for this test to work, since each
16685 # command has a unique jobid, but it makes debugging easier if needed.
16686 #       for facet in $facets; do
16687 #               local dev=$(convert_facet2label $facet)
16688 #               # clear old jobstats
16689 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16690 #       done
16691
16692         # use a new JobID for each test, or we might see an old one
16693         [ "$JOBENV" = "FAKE_JOBID" ] &&
16694                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16695
16696         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16697
16698         [ "$JOBENV" = "nodelocal" ] && {
16699                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16700                 $LCTL set_param jobid_name=$FAKE_JOBID
16701                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16702         }
16703
16704         log "Test: ${cmd[*]}"
16705         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16706
16707         if [ $JOBENV = "FAKE_JOBID" ]; then
16708                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16709         else
16710                 ${cmd[*]}
16711         fi
16712
16713         # all files are created on OST0000
16714         for facet in $facets; do
16715                 local stats="*.$(convert_facet2label $facet).job_stats"
16716
16717                 # strip out libtool wrappers for in-tree executables
16718                 if [ $(do_facet $facet lctl get_param $stats |
16719                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16720                         do_facet $facet lctl get_param $stats
16721                         error "No jobstats for $JOBVAL found on $facet::$stats"
16722                 fi
16723         done
16724 }
16725
16726 jobstats_set() {
16727         local new_jobenv=$1
16728
16729         set_persistent_param_and_check client "jobid_var" \
16730                 "$FSNAME.sys.jobid_var" $new_jobenv
16731 }
16732
16733 test_205a() { # Job stats
16734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16735         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16736                 skip "Need MDS version with at least 2.7.1"
16737         remote_mgs_nodsh && skip "remote MGS with nodsh"
16738         remote_mds_nodsh && skip "remote MDS with nodsh"
16739         remote_ost_nodsh && skip "remote OST with nodsh"
16740         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16741                 skip "Server doesn't support jobstats"
16742         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16743
16744         local old_jobenv=$($LCTL get_param -n jobid_var)
16745         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16746
16747         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16748                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16749         else
16750                 stack_trap "do_facet mgs $PERM_CMD \
16751                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16752         fi
16753         changelog_register
16754
16755         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16756                                 mdt.*.job_cleanup_interval | head -n 1)
16757         local new_interval=5
16758         do_facet $SINGLEMDS \
16759                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16760         stack_trap "do_facet $SINGLEMDS \
16761                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16762         local start=$SECONDS
16763
16764         local cmd
16765         # mkdir
16766         cmd="mkdir $DIR/$tdir"
16767         verify_jobstats "$cmd" "$SINGLEMDS"
16768         # rmdir
16769         cmd="rmdir $DIR/$tdir"
16770         verify_jobstats "$cmd" "$SINGLEMDS"
16771         # mkdir on secondary MDT
16772         if [ $MDSCOUNT -gt 1 ]; then
16773                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16774                 verify_jobstats "$cmd" "mds2"
16775         fi
16776         # mknod
16777         cmd="mknod $DIR/$tfile c 1 3"
16778         verify_jobstats "$cmd" "$SINGLEMDS"
16779         # unlink
16780         cmd="rm -f $DIR/$tfile"
16781         verify_jobstats "$cmd" "$SINGLEMDS"
16782         # create all files on OST0000 so verify_jobstats can find OST stats
16783         # open & close
16784         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16785         verify_jobstats "$cmd" "$SINGLEMDS"
16786         # setattr
16787         cmd="touch $DIR/$tfile"
16788         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16789         # write
16790         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16791         verify_jobstats "$cmd" "ost1"
16792         # read
16793         cancel_lru_locks osc
16794         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16795         verify_jobstats "$cmd" "ost1"
16796         # truncate
16797         cmd="$TRUNCATE $DIR/$tfile 0"
16798         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16799         # rename
16800         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16801         verify_jobstats "$cmd" "$SINGLEMDS"
16802         # jobstats expiry - sleep until old stats should be expired
16803         local left=$((new_interval + 5 - (SECONDS - start)))
16804         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16805                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16806                         "0" $left
16807         cmd="mkdir $DIR/$tdir.expire"
16808         verify_jobstats "$cmd" "$SINGLEMDS"
16809         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16810             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16811
16812         # Ensure that jobid are present in changelog (if supported by MDS)
16813         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16814                 changelog_dump | tail -10
16815                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16816                 [ $jobids -eq 9 ] ||
16817                         error "Wrong changelog jobid count $jobids != 9"
16818
16819                 # LU-5862
16820                 JOBENV="disable"
16821                 jobstats_set $JOBENV
16822                 touch $DIR/$tfile
16823                 changelog_dump | grep $tfile
16824                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16825                 [ $jobids -eq 0 ] ||
16826                         error "Unexpected jobids when jobid_var=$JOBENV"
16827         fi
16828
16829         # test '%j' access to environment variable - if supported
16830         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16831                 JOBENV="JOBCOMPLEX"
16832                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16833
16834                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16835         fi
16836
16837         # test '%j' access to per-session jobid - if supported
16838         if lctl list_param jobid_this_session > /dev/null 2>&1
16839         then
16840                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16841                 lctl set_param jobid_this_session=$USER
16842
16843                 JOBENV="JOBCOMPLEX"
16844                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16845
16846                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16847         fi
16848 }
16849 run_test 205a "Verify job stats"
16850
16851 # LU-13117, LU-13597
16852 test_205b() {
16853         job_stats="mdt.*.job_stats"
16854         $LCTL set_param $job_stats=clear
16855         # Setting jobid_var to USER might not be supported
16856         $LCTL set_param jobid_var=USER || true
16857         $LCTL set_param jobid_name="%e.%u"
16858         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16859         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16860                 grep "job_id:.*foolish" &&
16861                         error "Unexpected jobid found"
16862         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16863                 grep "open:.*min.*max.*sum" ||
16864                         error "wrong job_stats format found"
16865 }
16866 run_test 205b "Verify job stats jobid and output format"
16867
16868 # LU-13733
16869 test_205c() {
16870         $LCTL set_param llite.*.stats=0
16871         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16872         $LCTL get_param llite.*.stats
16873         $LCTL get_param llite.*.stats | grep \
16874                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16875                         error "wrong client stats format found"
16876 }
16877 run_test 205c "Verify client stats format"
16878
16879 # LU-1480, LU-1773 and LU-1657
16880 test_206() {
16881         mkdir -p $DIR/$tdir
16882         $LFS setstripe -c -1 $DIR/$tdir
16883 #define OBD_FAIL_LOV_INIT 0x1403
16884         $LCTL set_param fail_loc=0xa0001403
16885         $LCTL set_param fail_val=1
16886         touch $DIR/$tdir/$tfile || true
16887 }
16888 run_test 206 "fail lov_init_raid0() doesn't lbug"
16889
16890 test_207a() {
16891         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16892         local fsz=`stat -c %s $DIR/$tfile`
16893         cancel_lru_locks mdc
16894
16895         # do not return layout in getattr intent
16896 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16897         $LCTL set_param fail_loc=0x170
16898         local sz=`stat -c %s $DIR/$tfile`
16899
16900         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16901
16902         rm -rf $DIR/$tfile
16903 }
16904 run_test 207a "can refresh layout at glimpse"
16905
16906 test_207b() {
16907         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16908         local cksum=`md5sum $DIR/$tfile`
16909         local fsz=`stat -c %s $DIR/$tfile`
16910         cancel_lru_locks mdc
16911         cancel_lru_locks osc
16912
16913         # do not return layout in getattr intent
16914 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16915         $LCTL set_param fail_loc=0x171
16916
16917         # it will refresh layout after the file is opened but before read issues
16918         echo checksum is "$cksum"
16919         echo "$cksum" |md5sum -c --quiet || error "file differs"
16920
16921         rm -rf $DIR/$tfile
16922 }
16923 run_test 207b "can refresh layout at open"
16924
16925 test_208() {
16926         # FIXME: in this test suite, only RD lease is used. This is okay
16927         # for now as only exclusive open is supported. After generic lease
16928         # is done, this test suite should be revised. - Jinshan
16929
16930         remote_mds_nodsh && skip "remote MDS with nodsh"
16931         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16932                 skip "Need MDS version at least 2.4.52"
16933
16934         echo "==== test 1: verify get lease work"
16935         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16936
16937         echo "==== test 2: verify lease can be broken by upcoming open"
16938         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16939         local PID=$!
16940         sleep 1
16941
16942         $MULTIOP $DIR/$tfile oO_RDONLY:c
16943         kill -USR1 $PID && wait $PID || error "break lease error"
16944
16945         echo "==== test 3: verify lease can't be granted if an open already exists"
16946         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16947         local PID=$!
16948         sleep 1
16949
16950         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16951         kill -USR1 $PID && wait $PID || error "open file error"
16952
16953         echo "==== test 4: lease can sustain over recovery"
16954         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16955         PID=$!
16956         sleep 1
16957
16958         fail mds1
16959
16960         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16961
16962         echo "==== test 5: lease broken can't be regained by replay"
16963         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16964         PID=$!
16965         sleep 1
16966
16967         # open file to break lease and then recovery
16968         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16969         fail mds1
16970
16971         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16972
16973         rm -f $DIR/$tfile
16974 }
16975 run_test 208 "Exclusive open"
16976
16977 test_209() {
16978         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16979                 skip_env "must have disp_stripe"
16980
16981         touch $DIR/$tfile
16982         sync; sleep 5; sync;
16983
16984         echo 3 > /proc/sys/vm/drop_caches
16985         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16986                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16987         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16988
16989         # open/close 500 times
16990         for i in $(seq 500); do
16991                 cat $DIR/$tfile
16992         done
16993
16994         echo 3 > /proc/sys/vm/drop_caches
16995         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16996                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16997         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16998
16999         echo "before: $req_before, after: $req_after"
17000         [ $((req_after - req_before)) -ge 300 ] &&
17001                 error "open/close requests are not freed"
17002         return 0
17003 }
17004 run_test 209 "read-only open/close requests should be freed promptly"
17005
17006 test_210() {
17007         local pid
17008
17009         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17010         pid=$!
17011         sleep 1
17012
17013         $LFS getstripe $DIR/$tfile
17014         kill -USR1 $pid
17015         wait $pid || error "multiop failed"
17016
17017         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17018         pid=$!
17019         sleep 1
17020
17021         $LFS getstripe $DIR/$tfile
17022         kill -USR1 $pid
17023         wait $pid || error "multiop failed"
17024 }
17025 run_test 210 "lfs getstripe does not break leases"
17026
17027 test_212() {
17028         size=`date +%s`
17029         size=$((size % 8192 + 1))
17030         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17031         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17032         rm -f $DIR/f212 $DIR/f212.xyz
17033 }
17034 run_test 212 "Sendfile test ============================================"
17035
17036 test_213() {
17037         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17038         cancel_lru_locks osc
17039         lctl set_param fail_loc=0x8000040f
17040         # generate a read lock
17041         cat $DIR/$tfile > /dev/null
17042         # write to the file, it will try to cancel the above read lock.
17043         cat /etc/hosts >> $DIR/$tfile
17044 }
17045 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17046
17047 test_214() { # for bug 20133
17048         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17049         for (( i=0; i < 340; i++ )) ; do
17050                 touch $DIR/$tdir/d214c/a$i
17051         done
17052
17053         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17054         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17055         ls $DIR/d214c || error "ls $DIR/d214c failed"
17056         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17057         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17058 }
17059 run_test 214 "hash-indexed directory test - bug 20133"
17060
17061 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17062 create_lnet_proc_files() {
17063         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17064 }
17065
17066 # counterpart of create_lnet_proc_files
17067 remove_lnet_proc_files() {
17068         rm -f $TMP/lnet_$1.sys
17069 }
17070
17071 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17072 # 3rd arg as regexp for body
17073 check_lnet_proc_stats() {
17074         local l=$(cat "$TMP/lnet_$1" |wc -l)
17075         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17076
17077         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17078 }
17079
17080 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17081 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17082 # optional and can be regexp for 2nd line (lnet.routes case)
17083 check_lnet_proc_entry() {
17084         local blp=2          # blp stands for 'position of 1st line of body'
17085         [ -z "$5" ] || blp=3 # lnet.routes case
17086
17087         local l=$(cat "$TMP/lnet_$1" |wc -l)
17088         # subtracting one from $blp because the body can be empty
17089         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17090
17091         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17092                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17093
17094         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17095                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17096
17097         # bail out if any unexpected line happened
17098         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17099         [ "$?" != 0 ] || error "$2 misformatted"
17100 }
17101
17102 test_215() { # for bugs 18102, 21079, 21517
17103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17104
17105         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17106         local P='[1-9][0-9]*'           # positive numeric
17107         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17108         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17109         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17110         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17111
17112         local L1 # regexp for 1st line
17113         local L2 # regexp for 2nd line (optional)
17114         local BR # regexp for the rest (body)
17115
17116         # lnet.stats should look as 11 space-separated non-negative numerics
17117         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17118         create_lnet_proc_files "stats"
17119         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17120         remove_lnet_proc_files "stats"
17121
17122         # lnet.routes should look like this:
17123         # Routing disabled/enabled
17124         # net hops priority state router
17125         # where net is a string like tcp0, hops > 0, priority >= 0,
17126         # state is up/down,
17127         # router is a string like 192.168.1.1@tcp2
17128         L1="^Routing (disabled|enabled)$"
17129         L2="^net +hops +priority +state +router$"
17130         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17131         create_lnet_proc_files "routes"
17132         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17133         remove_lnet_proc_files "routes"
17134
17135         # lnet.routers should look like this:
17136         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17137         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17138         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17139         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17140         L1="^ref +rtr_ref +alive +router$"
17141         BR="^$P +$P +(up|down) +$NID$"
17142         create_lnet_proc_files "routers"
17143         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17144         remove_lnet_proc_files "routers"
17145
17146         # lnet.peers should look like this:
17147         # nid refs state last max rtr min tx min queue
17148         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17149         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17150         # numeric (0 or >0 or <0), queue >= 0.
17151         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17152         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17153         create_lnet_proc_files "peers"
17154         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17155         remove_lnet_proc_files "peers"
17156
17157         # lnet.buffers  should look like this:
17158         # pages count credits min
17159         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17160         L1="^pages +count +credits +min$"
17161         BR="^ +$N +$N +$I +$I$"
17162         create_lnet_proc_files "buffers"
17163         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17164         remove_lnet_proc_files "buffers"
17165
17166         # lnet.nis should look like this:
17167         # nid status alive refs peer rtr max tx min
17168         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17169         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17170         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17171         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17172         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17173         create_lnet_proc_files "nis"
17174         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17175         remove_lnet_proc_files "nis"
17176
17177         # can we successfully write to lnet.stats?
17178         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17179 }
17180 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17181
17182 test_216() { # bug 20317
17183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17184         remote_ost_nodsh && skip "remote OST with nodsh"
17185
17186         local node
17187         local facets=$(get_facets OST)
17188         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17189
17190         save_lustre_params client "osc.*.contention_seconds" > $p
17191         save_lustre_params $facets \
17192                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17193         save_lustre_params $facets \
17194                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17195         save_lustre_params $facets \
17196                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17197         clear_stats osc.*.osc_stats
17198
17199         # agressive lockless i/o settings
17200         do_nodes $(comma_list $(osts_nodes)) \
17201                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17202                         ldlm.namespaces.filter-*.contended_locks=0 \
17203                         ldlm.namespaces.filter-*.contention_seconds=60"
17204         lctl set_param -n osc.*.contention_seconds=60
17205
17206         $DIRECTIO write $DIR/$tfile 0 10 4096
17207         $CHECKSTAT -s 40960 $DIR/$tfile
17208
17209         # disable lockless i/o
17210         do_nodes $(comma_list $(osts_nodes)) \
17211                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17212                         ldlm.namespaces.filter-*.contended_locks=32 \
17213                         ldlm.namespaces.filter-*.contention_seconds=0"
17214         lctl set_param -n osc.*.contention_seconds=0
17215         clear_stats osc.*.osc_stats
17216
17217         dd if=/dev/zero of=$DIR/$tfile count=0
17218         $CHECKSTAT -s 0 $DIR/$tfile
17219
17220         restore_lustre_params <$p
17221         rm -f $p
17222         rm $DIR/$tfile
17223 }
17224 run_test 216 "check lockless direct write updates file size and kms correctly"
17225
17226 test_217() { # bug 22430
17227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17228
17229         local node
17230         local nid
17231
17232         for node in $(nodes_list); do
17233                 nid=$(host_nids_address $node $NETTYPE)
17234                 if [[ $nid = *-* ]] ; then
17235                         echo "lctl ping $(h2nettype $nid)"
17236                         lctl ping $(h2nettype $nid)
17237                 else
17238                         echo "skipping $node (no hyphen detected)"
17239                 fi
17240         done
17241 }
17242 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17243
17244 test_218() {
17245        # do directio so as not to populate the page cache
17246        log "creating a 10 Mb file"
17247        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17248        log "starting reads"
17249        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17250        log "truncating the file"
17251        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17252        log "killing dd"
17253        kill %+ || true # reads might have finished
17254        echo "wait until dd is finished"
17255        wait
17256        log "removing the temporary file"
17257        rm -rf $DIR/$tfile || error "tmp file removal failed"
17258 }
17259 run_test 218 "parallel read and truncate should not deadlock"
17260
17261 test_219() {
17262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17263
17264         # write one partial page
17265         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17266         # set no grant so vvp_io_commit_write will do sync write
17267         $LCTL set_param fail_loc=0x411
17268         # write a full page at the end of file
17269         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17270
17271         $LCTL set_param fail_loc=0
17272         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17273         $LCTL set_param fail_loc=0x411
17274         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17275
17276         # LU-4201
17277         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17278         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17279 }
17280 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17281
17282 test_220() { #LU-325
17283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17284         remote_ost_nodsh && skip "remote OST with nodsh"
17285         remote_mds_nodsh && skip "remote MDS with nodsh"
17286         remote_mgs_nodsh && skip "remote MGS with nodsh"
17287
17288         local OSTIDX=0
17289
17290         # create on MDT0000 so the last_id and next_id are correct
17291         mkdir $DIR/$tdir
17292         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17293         OST=${OST%_UUID}
17294
17295         # on the mdt's osc
17296         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17297         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17298                         osp.$mdtosc_proc1.prealloc_last_id)
17299         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17300                         osp.$mdtosc_proc1.prealloc_next_id)
17301
17302         $LFS df -i
17303
17304         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17305         #define OBD_FAIL_OST_ENOINO              0x229
17306         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17307         create_pool $FSNAME.$TESTNAME || return 1
17308         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17309
17310         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17311
17312         MDSOBJS=$((last_id - next_id))
17313         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17314
17315         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17316         echo "OST still has $count kbytes free"
17317
17318         echo "create $MDSOBJS files @next_id..."
17319         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17320
17321         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17322                         osp.$mdtosc_proc1.prealloc_last_id)
17323         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17324                         osp.$mdtosc_proc1.prealloc_next_id)
17325
17326         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17327         $LFS df -i
17328
17329         echo "cleanup..."
17330
17331         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17332         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17333
17334         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17335                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17336         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17337                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17338         echo "unlink $MDSOBJS files @$next_id..."
17339         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17340 }
17341 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17342
17343 test_221() {
17344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17345
17346         dd if=`which date` of=$MOUNT/date oflag=sync
17347         chmod +x $MOUNT/date
17348
17349         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17350         $LCTL set_param fail_loc=0x80001401
17351
17352         $MOUNT/date > /dev/null
17353         rm -f $MOUNT/date
17354 }
17355 run_test 221 "make sure fault and truncate race to not cause OOM"
17356
17357 test_222a () {
17358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17359
17360         rm -rf $DIR/$tdir
17361         test_mkdir $DIR/$tdir
17362         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17363         createmany -o $DIR/$tdir/$tfile 10
17364         cancel_lru_locks mdc
17365         cancel_lru_locks osc
17366         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17367         $LCTL set_param fail_loc=0x31a
17368         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17369         $LCTL set_param fail_loc=0
17370         rm -r $DIR/$tdir
17371 }
17372 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17373
17374 test_222b () {
17375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17376
17377         rm -rf $DIR/$tdir
17378         test_mkdir $DIR/$tdir
17379         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17380         createmany -o $DIR/$tdir/$tfile 10
17381         cancel_lru_locks mdc
17382         cancel_lru_locks osc
17383         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17384         $LCTL set_param fail_loc=0x31a
17385         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17386         $LCTL set_param fail_loc=0
17387 }
17388 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17389
17390 test_223 () {
17391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17392
17393         rm -rf $DIR/$tdir
17394         test_mkdir $DIR/$tdir
17395         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17396         createmany -o $DIR/$tdir/$tfile 10
17397         cancel_lru_locks mdc
17398         cancel_lru_locks osc
17399         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17400         $LCTL set_param fail_loc=0x31b
17401         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17402         $LCTL set_param fail_loc=0
17403         rm -r $DIR/$tdir
17404 }
17405 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17406
17407 test_224a() { # LU-1039, MRP-303
17408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17409
17410         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17411         $LCTL set_param fail_loc=0x508
17412         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17413         $LCTL set_param fail_loc=0
17414         df $DIR
17415 }
17416 run_test 224a "Don't panic on bulk IO failure"
17417
17418 test_224b() { # LU-1039, MRP-303
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420
17421         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17422         cancel_lru_locks osc
17423         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17424         $LCTL set_param fail_loc=0x515
17425         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17426         $LCTL set_param fail_loc=0
17427         df $DIR
17428 }
17429 run_test 224b "Don't panic on bulk IO failure"
17430
17431 test_224c() { # LU-6441
17432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17433         remote_mds_nodsh && skip "remote MDS with nodsh"
17434
17435         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17436         save_writethrough $p
17437         set_cache writethrough on
17438
17439         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17440         local at_max=$($LCTL get_param -n at_max)
17441         local timeout=$($LCTL get_param -n timeout)
17442         local test_at="at_max"
17443         local param_at="$FSNAME.sys.at_max"
17444         local test_timeout="timeout"
17445         local param_timeout="$FSNAME.sys.timeout"
17446
17447         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17448
17449         set_persistent_param_and_check client "$test_at" "$param_at" 0
17450         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17451
17452         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17453         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17454         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17455         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17456         sync
17457         do_facet ost1 "$LCTL set_param fail_loc=0"
17458
17459         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17460         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17461                 $timeout
17462
17463         $LCTL set_param -n $pages_per_rpc
17464         restore_lustre_params < $p
17465         rm -f $p
17466 }
17467 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17468
17469 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17470 test_225a () {
17471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17472         if [ -z ${MDSSURVEY} ]; then
17473                 skip_env "mds-survey not found"
17474         fi
17475         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17476                 skip "Need MDS version at least 2.2.51"
17477
17478         local mds=$(facet_host $SINGLEMDS)
17479         local target=$(do_nodes $mds 'lctl dl' |
17480                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17481
17482         local cmd1="file_count=1000 thrhi=4"
17483         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17484         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17485         local cmd="$cmd1 $cmd2 $cmd3"
17486
17487         rm -f ${TMP}/mds_survey*
17488         echo + $cmd
17489         eval $cmd || error "mds-survey with zero-stripe failed"
17490         cat ${TMP}/mds_survey*
17491         rm -f ${TMP}/mds_survey*
17492 }
17493 run_test 225a "Metadata survey sanity with zero-stripe"
17494
17495 test_225b () {
17496         if [ -z ${MDSSURVEY} ]; then
17497                 skip_env "mds-survey not found"
17498         fi
17499         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17500                 skip "Need MDS version at least 2.2.51"
17501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17502         remote_mds_nodsh && skip "remote MDS with nodsh"
17503         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17504                 skip_env "Need to mount OST to test"
17505         fi
17506
17507         local mds=$(facet_host $SINGLEMDS)
17508         local target=$(do_nodes $mds 'lctl dl' |
17509                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17510
17511         local cmd1="file_count=1000 thrhi=4"
17512         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17513         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17514         local cmd="$cmd1 $cmd2 $cmd3"
17515
17516         rm -f ${TMP}/mds_survey*
17517         echo + $cmd
17518         eval $cmd || error "mds-survey with stripe_count failed"
17519         cat ${TMP}/mds_survey*
17520         rm -f ${TMP}/mds_survey*
17521 }
17522 run_test 225b "Metadata survey sanity with stripe_count = 1"
17523
17524 mcreate_path2fid () {
17525         local mode=$1
17526         local major=$2
17527         local minor=$3
17528         local name=$4
17529         local desc=$5
17530         local path=$DIR/$tdir/$name
17531         local fid
17532         local rc
17533         local fid_path
17534
17535         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17536                 error "cannot create $desc"
17537
17538         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17539         rc=$?
17540         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17541
17542         fid_path=$($LFS fid2path $MOUNT $fid)
17543         rc=$?
17544         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17545
17546         [ "$path" == "$fid_path" ] ||
17547                 error "fid2path returned $fid_path, expected $path"
17548
17549         echo "pass with $path and $fid"
17550 }
17551
17552 test_226a () {
17553         rm -rf $DIR/$tdir
17554         mkdir -p $DIR/$tdir
17555
17556         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17557         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17558         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17559         mcreate_path2fid 0040666 0 0 dir "directory"
17560         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17561         mcreate_path2fid 0100666 0 0 file "regular file"
17562         mcreate_path2fid 0120666 0 0 link "symbolic link"
17563         mcreate_path2fid 0140666 0 0 sock "socket"
17564 }
17565 run_test 226a "call path2fid and fid2path on files of all type"
17566
17567 test_226b () {
17568         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17569
17570         local MDTIDX=1
17571
17572         rm -rf $DIR/$tdir
17573         mkdir -p $DIR/$tdir
17574         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17575                 error "create remote directory failed"
17576         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17577         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17578                                 "character special file (null)"
17579         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17580                                 "character special file (no device)"
17581         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17582         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17583                                 "block special file (loop)"
17584         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17585         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17586         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17587 }
17588 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17589
17590 test_226c () {
17591         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17592         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17593                 skip "Need MDS version at least 2.13.55"
17594
17595         local submnt=/mnt/submnt
17596         local srcfile=/etc/passwd
17597         local dstfile=$submnt/passwd
17598         local path
17599         local fid
17600
17601         rm -rf $DIR/$tdir
17602         rm -rf $submnt
17603         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17604                 error "create remote directory failed"
17605         mkdir -p $submnt || error "create $submnt failed"
17606         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17607                 error "mount $submnt failed"
17608         stack_trap "umount $submnt" EXIT
17609
17610         cp $srcfile $dstfile
17611         fid=$($LFS path2fid $dstfile)
17612         path=$($LFS fid2path $submnt "$fid")
17613         [ "$path" = "$dstfile" ] ||
17614                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17615 }
17616 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17617
17618 # LU-1299 Executing or running ldd on a truncated executable does not
17619 # cause an out-of-memory condition.
17620 test_227() {
17621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17622         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17623
17624         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17625         chmod +x $MOUNT/date
17626
17627         $MOUNT/date > /dev/null
17628         ldd $MOUNT/date > /dev/null
17629         rm -f $MOUNT/date
17630 }
17631 run_test 227 "running truncated executable does not cause OOM"
17632
17633 # LU-1512 try to reuse idle OI blocks
17634 test_228a() {
17635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17636         remote_mds_nodsh && skip "remote MDS with nodsh"
17637         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17638
17639         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17640         local myDIR=$DIR/$tdir
17641
17642         mkdir -p $myDIR
17643         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17644         $LCTL set_param fail_loc=0x80001002
17645         createmany -o $myDIR/t- 10000
17646         $LCTL set_param fail_loc=0
17647         # The guard is current the largest FID holder
17648         touch $myDIR/guard
17649         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17650                     tr -d '[')
17651         local IDX=$(($SEQ % 64))
17652
17653         do_facet $SINGLEMDS sync
17654         # Make sure journal flushed.
17655         sleep 6
17656         local blk1=$(do_facet $SINGLEMDS \
17657                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17658                      grep Blockcount | awk '{print $4}')
17659
17660         # Remove old files, some OI blocks will become idle.
17661         unlinkmany $myDIR/t- 10000
17662         # Create new files, idle OI blocks should be reused.
17663         createmany -o $myDIR/t- 2000
17664         do_facet $SINGLEMDS sync
17665         # Make sure journal flushed.
17666         sleep 6
17667         local blk2=$(do_facet $SINGLEMDS \
17668                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17669                      grep Blockcount | awk '{print $4}')
17670
17671         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17672 }
17673 run_test 228a "try to reuse idle OI blocks"
17674
17675 test_228b() {
17676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17677         remote_mds_nodsh && skip "remote MDS with nodsh"
17678         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17679
17680         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17681         local myDIR=$DIR/$tdir
17682
17683         mkdir -p $myDIR
17684         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17685         $LCTL set_param fail_loc=0x80001002
17686         createmany -o $myDIR/t- 10000
17687         $LCTL set_param fail_loc=0
17688         # The guard is current the largest FID holder
17689         touch $myDIR/guard
17690         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17691                     tr -d '[')
17692         local IDX=$(($SEQ % 64))
17693
17694         do_facet $SINGLEMDS sync
17695         # Make sure journal flushed.
17696         sleep 6
17697         local blk1=$(do_facet $SINGLEMDS \
17698                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17699                      grep Blockcount | awk '{print $4}')
17700
17701         # Remove old files, some OI blocks will become idle.
17702         unlinkmany $myDIR/t- 10000
17703
17704         # stop the MDT
17705         stop $SINGLEMDS || error "Fail to stop MDT."
17706         # remount the MDT
17707         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17708
17709         df $MOUNT || error "Fail to df."
17710         # Create new files, idle OI blocks should be reused.
17711         createmany -o $myDIR/t- 2000
17712         do_facet $SINGLEMDS sync
17713         # Make sure journal flushed.
17714         sleep 6
17715         local blk2=$(do_facet $SINGLEMDS \
17716                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17717                      grep Blockcount | awk '{print $4}')
17718
17719         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17720 }
17721 run_test 228b "idle OI blocks can be reused after MDT restart"
17722
17723 #LU-1881
17724 test_228c() {
17725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17726         remote_mds_nodsh && skip "remote MDS with nodsh"
17727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17728
17729         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17730         local myDIR=$DIR/$tdir
17731
17732         mkdir -p $myDIR
17733         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17734         $LCTL set_param fail_loc=0x80001002
17735         # 20000 files can guarantee there are index nodes in the OI file
17736         createmany -o $myDIR/t- 20000
17737         $LCTL set_param fail_loc=0
17738         # The guard is current the largest FID holder
17739         touch $myDIR/guard
17740         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17741                     tr -d '[')
17742         local IDX=$(($SEQ % 64))
17743
17744         do_facet $SINGLEMDS sync
17745         # Make sure journal flushed.
17746         sleep 6
17747         local blk1=$(do_facet $SINGLEMDS \
17748                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17749                      grep Blockcount | awk '{print $4}')
17750
17751         # Remove old files, some OI blocks will become idle.
17752         unlinkmany $myDIR/t- 20000
17753         rm -f $myDIR/guard
17754         # The OI file should become empty now
17755
17756         # Create new files, idle OI blocks should be reused.
17757         createmany -o $myDIR/t- 2000
17758         do_facet $SINGLEMDS sync
17759         # Make sure journal flushed.
17760         sleep 6
17761         local blk2=$(do_facet $SINGLEMDS \
17762                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17763                      grep Blockcount | awk '{print $4}')
17764
17765         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17766 }
17767 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17768
17769 test_229() { # LU-2482, LU-3448
17770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17771         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17772         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17773                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17774
17775         rm -f $DIR/$tfile
17776
17777         # Create a file with a released layout and stripe count 2.
17778         $MULTIOP $DIR/$tfile H2c ||
17779                 error "failed to create file with released layout"
17780
17781         $LFS getstripe -v $DIR/$tfile
17782
17783         local pattern=$($LFS getstripe -L $DIR/$tfile)
17784         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17785
17786         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17787                 error "getstripe"
17788         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17789         stat $DIR/$tfile || error "failed to stat released file"
17790
17791         chown $RUNAS_ID $DIR/$tfile ||
17792                 error "chown $RUNAS_ID $DIR/$tfile failed"
17793
17794         chgrp $RUNAS_ID $DIR/$tfile ||
17795                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17796
17797         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17798         rm $DIR/$tfile || error "failed to remove released file"
17799 }
17800 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17801
17802 test_230a() {
17803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17804         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17805         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17806                 skip "Need MDS version at least 2.11.52"
17807
17808         local MDTIDX=1
17809
17810         test_mkdir $DIR/$tdir
17811         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17812         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17813         [ $mdt_idx -ne 0 ] &&
17814                 error "create local directory on wrong MDT $mdt_idx"
17815
17816         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17817                         error "create remote directory failed"
17818         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17819         [ $mdt_idx -ne $MDTIDX ] &&
17820                 error "create remote directory on wrong MDT $mdt_idx"
17821
17822         createmany -o $DIR/$tdir/test_230/t- 10 ||
17823                 error "create files on remote directory failed"
17824         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17825         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17826         rm -r $DIR/$tdir || error "unlink remote directory failed"
17827 }
17828 run_test 230a "Create remote directory and files under the remote directory"
17829
17830 test_230b() {
17831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17833         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17834                 skip "Need MDS version at least 2.11.52"
17835
17836         local MDTIDX=1
17837         local mdt_index
17838         local i
17839         local file
17840         local pid
17841         local stripe_count
17842         local migrate_dir=$DIR/$tdir/migrate_dir
17843         local other_dir=$DIR/$tdir/other_dir
17844
17845         test_mkdir $DIR/$tdir
17846         test_mkdir -i0 -c1 $migrate_dir
17847         test_mkdir -i0 -c1 $other_dir
17848         for ((i=0; i<10; i++)); do
17849                 mkdir -p $migrate_dir/dir_${i}
17850                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17851                         error "create files under remote dir failed $i"
17852         done
17853
17854         cp /etc/passwd $migrate_dir/$tfile
17855         cp /etc/passwd $other_dir/$tfile
17856         chattr +SAD $migrate_dir
17857         chattr +SAD $migrate_dir/$tfile
17858
17859         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17860         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17861         local old_dir_mode=$(stat -c%f $migrate_dir)
17862         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17863
17864         mkdir -p $migrate_dir/dir_default_stripe2
17865         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17866         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17867
17868         mkdir -p $other_dir
17869         ln $migrate_dir/$tfile $other_dir/luna
17870         ln $migrate_dir/$tfile $migrate_dir/sofia
17871         ln $other_dir/$tfile $migrate_dir/david
17872         ln -s $migrate_dir/$tfile $other_dir/zachary
17873         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17874         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17875
17876         local len
17877         local lnktgt
17878
17879         # inline symlink
17880         for len in 58 59 60; do
17881                 lnktgt=$(str_repeat 'l' $len)
17882                 touch $migrate_dir/$lnktgt
17883                 ln -s $lnktgt $migrate_dir/${len}char_ln
17884         done
17885
17886         # PATH_MAX
17887         for len in 4094 4095; do
17888                 lnktgt=$(str_repeat 'l' $len)
17889                 ln -s $lnktgt $migrate_dir/${len}char_ln
17890         done
17891
17892         # NAME_MAX
17893         for len in 254 255; do
17894                 touch $migrate_dir/$(str_repeat 'l' $len)
17895         done
17896
17897         $LFS migrate -m $MDTIDX $migrate_dir ||
17898                 error "fails on migrating remote dir to MDT1"
17899
17900         echo "migratate to MDT1, then checking.."
17901         for ((i = 0; i < 10; i++)); do
17902                 for file in $(find $migrate_dir/dir_${i}); do
17903                         mdt_index=$($LFS getstripe -m $file)
17904                         # broken symlink getstripe will fail
17905                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17906                                 error "$file is not on MDT${MDTIDX}"
17907                 done
17908         done
17909
17910         # the multiple link file should still in MDT0
17911         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17912         [ $mdt_index == 0 ] ||
17913                 error "$file is not on MDT${MDTIDX}"
17914
17915         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17916         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17917                 error " expect $old_dir_flag get $new_dir_flag"
17918
17919         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17920         [ "$old_file_flag" = "$new_file_flag" ] ||
17921                 error " expect $old_file_flag get $new_file_flag"
17922
17923         local new_dir_mode=$(stat -c%f $migrate_dir)
17924         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17925                 error "expect mode $old_dir_mode get $new_dir_mode"
17926
17927         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17928         [ "$old_file_mode" = "$new_file_mode" ] ||
17929                 error "expect mode $old_file_mode get $new_file_mode"
17930
17931         diff /etc/passwd $migrate_dir/$tfile ||
17932                 error "$tfile different after migration"
17933
17934         diff /etc/passwd $other_dir/luna ||
17935                 error "luna different after migration"
17936
17937         diff /etc/passwd $migrate_dir/sofia ||
17938                 error "sofia different after migration"
17939
17940         diff /etc/passwd $migrate_dir/david ||
17941                 error "david different after migration"
17942
17943         diff /etc/passwd $other_dir/zachary ||
17944                 error "zachary different after migration"
17945
17946         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17947                 error "${tfile}_ln different after migration"
17948
17949         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17950                 error "${tfile}_ln_other different after migration"
17951
17952         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17953         [ $stripe_count = 2 ] ||
17954                 error "dir strpe_count $d != 2 after migration."
17955
17956         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17957         [ $stripe_count = 2 ] ||
17958                 error "file strpe_count $d != 2 after migration."
17959
17960         #migrate back to MDT0
17961         MDTIDX=0
17962
17963         $LFS migrate -m $MDTIDX $migrate_dir ||
17964                 error "fails on migrating remote dir to MDT0"
17965
17966         echo "migrate back to MDT0, checking.."
17967         for file in $(find $migrate_dir); do
17968                 mdt_index=$($LFS getstripe -m $file)
17969                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17970                         error "$file is not on MDT${MDTIDX}"
17971         done
17972
17973         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17974         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17975                 error " expect $old_dir_flag get $new_dir_flag"
17976
17977         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17978         [ "$old_file_flag" = "$new_file_flag" ] ||
17979                 error " expect $old_file_flag get $new_file_flag"
17980
17981         local new_dir_mode=$(stat -c%f $migrate_dir)
17982         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17983                 error "expect mode $old_dir_mode get $new_dir_mode"
17984
17985         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17986         [ "$old_file_mode" = "$new_file_mode" ] ||
17987                 error "expect mode $old_file_mode get $new_file_mode"
17988
17989         diff /etc/passwd ${migrate_dir}/$tfile ||
17990                 error "$tfile different after migration"
17991
17992         diff /etc/passwd ${other_dir}/luna ||
17993                 error "luna different after migration"
17994
17995         diff /etc/passwd ${migrate_dir}/sofia ||
17996                 error "sofia different after migration"
17997
17998         diff /etc/passwd ${other_dir}/zachary ||
17999                 error "zachary different after migration"
18000
18001         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18002                 error "${tfile}_ln different after migration"
18003
18004         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18005                 error "${tfile}_ln_other different after migration"
18006
18007         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18008         [ $stripe_count = 2 ] ||
18009                 error "dir strpe_count $d != 2 after migration."
18010
18011         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18012         [ $stripe_count = 2 ] ||
18013                 error "file strpe_count $d != 2 after migration."
18014
18015         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18016 }
18017 run_test 230b "migrate directory"
18018
18019 test_230c() {
18020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18021         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18022         remote_mds_nodsh && skip "remote MDS with nodsh"
18023         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18024                 skip "Need MDS version at least 2.11.52"
18025
18026         local MDTIDX=1
18027         local total=3
18028         local mdt_index
18029         local file
18030         local migrate_dir=$DIR/$tdir/migrate_dir
18031
18032         #If migrating directory fails in the middle, all entries of
18033         #the directory is still accessiable.
18034         test_mkdir $DIR/$tdir
18035         test_mkdir -i0 -c1 $migrate_dir
18036         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18037         stat $migrate_dir
18038         createmany -o $migrate_dir/f $total ||
18039                 error "create files under ${migrate_dir} failed"
18040
18041         # fail after migrating top dir, and this will fail only once, so the
18042         # first sub file migration will fail (currently f3), others succeed.
18043         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18044         do_facet mds1 lctl set_param fail_loc=0x1801
18045         local t=$(ls $migrate_dir | wc -l)
18046         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18047                 error "migrate should fail"
18048         local u=$(ls $migrate_dir | wc -l)
18049         [ "$u" == "$t" ] || error "$u != $t during migration"
18050
18051         # add new dir/file should succeed
18052         mkdir $migrate_dir/dir ||
18053                 error "mkdir failed under migrating directory"
18054         touch $migrate_dir/file ||
18055                 error "create file failed under migrating directory"
18056
18057         # add file with existing name should fail
18058         for file in $migrate_dir/f*; do
18059                 stat $file > /dev/null || error "stat $file failed"
18060                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18061                         error "open(O_CREAT|O_EXCL) $file should fail"
18062                 $MULTIOP $file m && error "create $file should fail"
18063                 touch $DIR/$tdir/remote_dir/$tfile ||
18064                         error "touch $tfile failed"
18065                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18066                         error "link $file should fail"
18067                 mdt_index=$($LFS getstripe -m $file)
18068                 if [ $mdt_index == 0 ]; then
18069                         # file failed to migrate is not allowed to rename to
18070                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18071                                 error "rename to $file should fail"
18072                 else
18073                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18074                                 error "rename to $file failed"
18075                 fi
18076                 echo hello >> $file || error "write $file failed"
18077         done
18078
18079         # resume migration with different options should fail
18080         $LFS migrate -m 0 $migrate_dir &&
18081                 error "migrate -m 0 $migrate_dir should fail"
18082
18083         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18084                 error "migrate -c 2 $migrate_dir should fail"
18085
18086         # resume migration should succeed
18087         $LFS migrate -m $MDTIDX $migrate_dir ||
18088                 error "migrate $migrate_dir failed"
18089
18090         echo "Finish migration, then checking.."
18091         for file in $(find $migrate_dir); do
18092                 mdt_index=$($LFS getstripe -m $file)
18093                 [ $mdt_index == $MDTIDX ] ||
18094                         error "$file is not on MDT${MDTIDX}"
18095         done
18096
18097         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18098 }
18099 run_test 230c "check directory accessiblity if migration failed"
18100
18101 test_230d() {
18102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18103         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18104         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18105                 skip "Need MDS version at least 2.11.52"
18106         # LU-11235
18107         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18108
18109         local migrate_dir=$DIR/$tdir/migrate_dir
18110         local old_index
18111         local new_index
18112         local old_count
18113         local new_count
18114         local new_hash
18115         local mdt_index
18116         local i
18117         local j
18118
18119         old_index=$((RANDOM % MDSCOUNT))
18120         old_count=$((MDSCOUNT - old_index))
18121         new_index=$((RANDOM % MDSCOUNT))
18122         new_count=$((MDSCOUNT - new_index))
18123         new_hash=1 # for all_char
18124
18125         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18126         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18127
18128         test_mkdir $DIR/$tdir
18129         test_mkdir -i $old_index -c $old_count $migrate_dir
18130
18131         for ((i=0; i<100; i++)); do
18132                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18133                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18134                         error "create files under remote dir failed $i"
18135         done
18136
18137         echo -n "Migrate from MDT$old_index "
18138         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18139         echo -n "to MDT$new_index"
18140         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18141         echo
18142
18143         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18144         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18145                 error "migrate remote dir error"
18146
18147         echo "Finish migration, then checking.."
18148         for file in $(find $migrate_dir); do
18149                 mdt_index=$($LFS getstripe -m $file)
18150                 if [ $mdt_index -lt $new_index ] ||
18151                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18152                         error "$file is on MDT$mdt_index"
18153                 fi
18154         done
18155
18156         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18157 }
18158 run_test 230d "check migrate big directory"
18159
18160 test_230e() {
18161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18162         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18163         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18164                 skip "Need MDS version at least 2.11.52"
18165
18166         local i
18167         local j
18168         local a_fid
18169         local b_fid
18170
18171         mkdir -p $DIR/$tdir
18172         mkdir $DIR/$tdir/migrate_dir
18173         mkdir $DIR/$tdir/other_dir
18174         touch $DIR/$tdir/migrate_dir/a
18175         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18176         ls $DIR/$tdir/other_dir
18177
18178         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18179                 error "migrate dir fails"
18180
18181         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18182         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18183
18184         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18185         [ $mdt_index == 0 ] || error "a is not on MDT0"
18186
18187         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18188                 error "migrate dir fails"
18189
18190         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18191         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18192
18193         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18194         [ $mdt_index == 1 ] || error "a is not on MDT1"
18195
18196         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18197         [ $mdt_index == 1 ] || error "b is not on MDT1"
18198
18199         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18200         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18201
18202         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18203
18204         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18205 }
18206 run_test 230e "migrate mulitple local link files"
18207
18208 test_230f() {
18209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18211         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18212                 skip "Need MDS version at least 2.11.52"
18213
18214         local a_fid
18215         local ln_fid
18216
18217         mkdir -p $DIR/$tdir
18218         mkdir $DIR/$tdir/migrate_dir
18219         $LFS mkdir -i1 $DIR/$tdir/other_dir
18220         touch $DIR/$tdir/migrate_dir/a
18221         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18222         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18223         ls $DIR/$tdir/other_dir
18224
18225         # a should be migrated to MDT1, since no other links on MDT0
18226         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18227                 error "#1 migrate dir fails"
18228         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18229         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18230         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18231         [ $mdt_index == 1 ] || error "a is not on MDT1"
18232
18233         # a should stay on MDT1, because it is a mulitple link file
18234         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18235                 error "#2 migrate dir fails"
18236         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18237         [ $mdt_index == 1 ] || error "a is not on MDT1"
18238
18239         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18240                 error "#3 migrate dir fails"
18241
18242         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18243         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18244         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18245
18246         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18247         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18248
18249         # a should be migrated to MDT0, since no other links on MDT1
18250         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18251                 error "#4 migrate dir fails"
18252         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18253         [ $mdt_index == 0 ] || error "a is not on MDT0"
18254
18255         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18256 }
18257 run_test 230f "migrate mulitple remote link files"
18258
18259 test_230g() {
18260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18262         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18263                 skip "Need MDS version at least 2.11.52"
18264
18265         mkdir -p $DIR/$tdir/migrate_dir
18266
18267         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18268                 error "migrating dir to non-exist MDT succeeds"
18269         true
18270 }
18271 run_test 230g "migrate dir to non-exist MDT"
18272
18273 test_230h() {
18274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18276         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18277                 skip "Need MDS version at least 2.11.52"
18278
18279         local mdt_index
18280
18281         mkdir -p $DIR/$tdir/migrate_dir
18282
18283         $LFS migrate -m1 $DIR &&
18284                 error "migrating mountpoint1 should fail"
18285
18286         $LFS migrate -m1 $DIR/$tdir/.. &&
18287                 error "migrating mountpoint2 should fail"
18288
18289         # same as mv
18290         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18291                 error "migrating $tdir/migrate_dir/.. should fail"
18292
18293         true
18294 }
18295 run_test 230h "migrate .. and root"
18296
18297 test_230i() {
18298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18300         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18301                 skip "Need MDS version at least 2.11.52"
18302
18303         mkdir -p $DIR/$tdir/migrate_dir
18304
18305         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18306                 error "migration fails with a tailing slash"
18307
18308         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18309                 error "migration fails with two tailing slashes"
18310 }
18311 run_test 230i "lfs migrate -m tolerates trailing slashes"
18312
18313 test_230j() {
18314         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18315         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18316                 skip "Need MDS version at least 2.11.52"
18317
18318         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18319         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18320                 error "create $tfile failed"
18321         cat /etc/passwd > $DIR/$tdir/$tfile
18322
18323         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18324
18325         cmp /etc/passwd $DIR/$tdir/$tfile ||
18326                 error "DoM file mismatch after migration"
18327 }
18328 run_test 230j "DoM file data not changed after dir migration"
18329
18330 test_230k() {
18331         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18332         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18333                 skip "Need MDS version at least 2.11.56"
18334
18335         local total=20
18336         local files_on_starting_mdt=0
18337
18338         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18339         $LFS getdirstripe $DIR/$tdir
18340         for i in $(seq $total); do
18341                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18342                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18343                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18344         done
18345
18346         echo "$files_on_starting_mdt files on MDT0"
18347
18348         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18349         $LFS getdirstripe $DIR/$tdir
18350
18351         files_on_starting_mdt=0
18352         for i in $(seq $total); do
18353                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18354                         error "file $tfile.$i mismatch after migration"
18355                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18356                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18357         done
18358
18359         echo "$files_on_starting_mdt files on MDT1 after migration"
18360         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18361
18362         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18363         $LFS getdirstripe $DIR/$tdir
18364
18365         files_on_starting_mdt=0
18366         for i in $(seq $total); do
18367                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18368                         error "file $tfile.$i mismatch after 2nd migration"
18369                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18370                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18371         done
18372
18373         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18374         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18375
18376         true
18377 }
18378 run_test 230k "file data not changed after dir migration"
18379
18380 test_230l() {
18381         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18382         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18383                 skip "Need MDS version at least 2.11.56"
18384
18385         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18386         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18387                 error "create files under remote dir failed $i"
18388         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18389 }
18390 run_test 230l "readdir between MDTs won't crash"
18391
18392 test_230m() {
18393         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18394         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18395                 skip "Need MDS version at least 2.11.56"
18396
18397         local MDTIDX=1
18398         local mig_dir=$DIR/$tdir/migrate_dir
18399         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18400         local shortstr="b"
18401         local val
18402
18403         echo "Creating files and dirs with xattrs"
18404         test_mkdir $DIR/$tdir
18405         test_mkdir -i0 -c1 $mig_dir
18406         mkdir $mig_dir/dir
18407         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18408                 error "cannot set xattr attr1 on dir"
18409         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18410                 error "cannot set xattr attr2 on dir"
18411         touch $mig_dir/dir/f0
18412         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18413                 error "cannot set xattr attr1 on file"
18414         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18415                 error "cannot set xattr attr2 on file"
18416         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18417         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18418         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18419         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18420         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18421         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18422         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18423         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18424         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18425
18426         echo "Migrating to MDT1"
18427         $LFS migrate -m $MDTIDX $mig_dir ||
18428                 error "fails on migrating dir to MDT1"
18429
18430         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18431         echo "Checking xattrs"
18432         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18433         [ "$val" = $longstr ] ||
18434                 error "expecting xattr1 $longstr on dir, found $val"
18435         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18436         [ "$val" = $shortstr ] ||
18437                 error "expecting xattr2 $shortstr on dir, found $val"
18438         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18439         [ "$val" = $longstr ] ||
18440                 error "expecting xattr1 $longstr on file, found $val"
18441         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18442         [ "$val" = $shortstr ] ||
18443                 error "expecting xattr2 $shortstr on file, found $val"
18444 }
18445 run_test 230m "xattrs not changed after dir migration"
18446
18447 test_230n() {
18448         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18449         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18450                 skip "Need MDS version at least 2.13.53"
18451
18452         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18453         cat /etc/hosts > $DIR/$tdir/$tfile
18454         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18455         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18456
18457         cmp /etc/hosts $DIR/$tdir/$tfile ||
18458                 error "File data mismatch after migration"
18459 }
18460 run_test 230n "Dir migration with mirrored file"
18461
18462 test_230o() {
18463         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18464         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18465                 skip "Need MDS version at least 2.13.52"
18466
18467         local mdts=$(comma_list $(mdts_nodes))
18468         local timeout=100
18469
18470         local restripe_status
18471         local delta
18472         local i
18473         local j
18474
18475         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18476
18477         # in case "crush" hash type is not set
18478         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18479
18480         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18481                            mdt.*MDT0000.enable_dir_restripe)
18482         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18483         stack_trap "do_nodes $mdts $LCTL set_param \
18484                     mdt.*.enable_dir_restripe=$restripe_status"
18485
18486         mkdir $DIR/$tdir
18487         createmany -m $DIR/$tdir/f 100 ||
18488                 error "create files under remote dir failed $i"
18489         createmany -d $DIR/$tdir/d 100 ||
18490                 error "create dirs under remote dir failed $i"
18491
18492         for i in $(seq 2 $MDSCOUNT); do
18493                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18494                 $LFS setdirstripe -c $i $DIR/$tdir ||
18495                         error "split -c $i $tdir failed"
18496                 wait_update $HOSTNAME \
18497                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18498                         error "dir split not finished"
18499                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18500                         awk '/migrate/ {sum += $2} END { print sum }')
18501                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18502                 # delta is around total_files/stripe_count
18503                 [ $delta -lt $((200 /(i - 1))) ] ||
18504                         error "$delta files migrated"
18505         done
18506 }
18507 run_test 230o "dir split"
18508
18509 test_230p() {
18510         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18511         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18512                 skip "Need MDS version at least 2.13.52"
18513
18514         local mdts=$(comma_list $(mdts_nodes))
18515         local timeout=100
18516
18517         local restripe_status
18518         local delta
18519         local i
18520         local j
18521
18522         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18523
18524         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18525
18526         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18527                            mdt.*MDT0000.enable_dir_restripe)
18528         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18529         stack_trap "do_nodes $mdts $LCTL set_param \
18530                     mdt.*.enable_dir_restripe=$restripe_status"
18531
18532         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18533         createmany -m $DIR/$tdir/f 100 ||
18534                 error "create files under remote dir failed $i"
18535         createmany -d $DIR/$tdir/d 100 ||
18536                 error "create dirs under remote dir failed $i"
18537
18538         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18539                 local mdt_hash="crush"
18540
18541                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18542                 $LFS setdirstripe -c $i $DIR/$tdir ||
18543                         error "split -c $i $tdir failed"
18544                 [ $i -eq 1 ] && mdt_hash="none"
18545                 wait_update $HOSTNAME \
18546                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18547                         error "dir merge not finished"
18548                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18549                         awk '/migrate/ {sum += $2} END { print sum }')
18550                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18551                 # delta is around total_files/stripe_count
18552                 [ $delta -lt $((200 / i)) ] ||
18553                         error "$delta files migrated"
18554         done
18555 }
18556 run_test 230p "dir merge"
18557
18558 test_230q() {
18559         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18560         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18561                 skip "Need MDS version at least 2.13.52"
18562
18563         local mdts=$(comma_list $(mdts_nodes))
18564         local saved_threshold=$(do_facet mds1 \
18565                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18566         local saved_delta=$(do_facet mds1 \
18567                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18568         local threshold=100
18569         local delta=2
18570         local total=0
18571         local stripe_count=0
18572         local stripe_index
18573         local nr_files
18574
18575         # test with fewer files on ZFS
18576         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18577
18578         stack_trap "do_nodes $mdts $LCTL set_param \
18579                     mdt.*.dir_split_count=$saved_threshold"
18580         stack_trap "do_nodes $mdts $LCTL set_param \
18581                     mdt.*.dir_split_delta=$saved_delta"
18582         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18583         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18584         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18585         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18586         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18587         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18588
18589         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18590         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18591
18592         while [ $stripe_count -lt $MDSCOUNT ]; do
18593                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18594                         error "create sub files failed"
18595                 stat $DIR/$tdir > /dev/null
18596                 total=$((total + threshold * 3 / 2))
18597                 stripe_count=$((stripe_count + delta))
18598                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18599
18600                 wait_update $HOSTNAME \
18601                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18602                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18603
18604                 wait_update $HOSTNAME \
18605                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18606                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18607
18608                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18609                            grep -w $stripe_index | wc -l)
18610                 echo "$nr_files files on MDT$stripe_index after split"
18611                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18612                         error "$nr_files files on MDT$stripe_index after split"
18613
18614                 nr_files=$(ls $DIR/$tdir | wc -w)
18615                 [ $nr_files -eq $total ] ||
18616                         error "total sub files $nr_files != $total"
18617         done
18618 }
18619 run_test 230q "dir auto split"
18620
18621 test_230r() {
18622         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18623         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18624         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18625                 skip "Need MDS version at least 2.13.54"
18626
18627         # maximum amount of local locks:
18628         # parent striped dir - 2 locks
18629         # new stripe in parent to migrate to - 1 lock
18630         # source and target - 2 locks
18631         # Total 5 locks for regular file
18632         mkdir -p $DIR/$tdir
18633         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18634         touch $DIR/$tdir/dir1/eee
18635
18636         # create 4 hardlink for 4 more locks
18637         # Total: 9 locks > RS_MAX_LOCKS (8)
18638         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18639         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18640         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18641         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18642         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18643         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18644         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18645         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18646
18647         cancel_lru_locks mdc
18648
18649         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18650                 error "migrate dir fails"
18651
18652         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18653 }
18654 run_test 230r "migrate with too many local locks"
18655
18656 test_231a()
18657 {
18658         # For simplicity this test assumes that max_pages_per_rpc
18659         # is the same across all OSCs
18660         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18661         local bulk_size=$((max_pages * PAGE_SIZE))
18662         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18663                                        head -n 1)
18664
18665         mkdir -p $DIR/$tdir
18666         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18667                 error "failed to set stripe with -S ${brw_size}M option"
18668
18669         # clear the OSC stats
18670         $LCTL set_param osc.*.stats=0 &>/dev/null
18671         stop_writeback
18672
18673         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18674         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18675                 oflag=direct &>/dev/null || error "dd failed"
18676
18677         sync; sleep 1; sync # just to be safe
18678         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18679         if [ x$nrpcs != "x1" ]; then
18680                 $LCTL get_param osc.*.stats
18681                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18682         fi
18683
18684         start_writeback
18685         # Drop the OSC cache, otherwise we will read from it
18686         cancel_lru_locks osc
18687
18688         # clear the OSC stats
18689         $LCTL set_param osc.*.stats=0 &>/dev/null
18690
18691         # Client reads $bulk_size.
18692         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18693                 iflag=direct &>/dev/null || error "dd failed"
18694
18695         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18696         if [ x$nrpcs != "x1" ]; then
18697                 $LCTL get_param osc.*.stats
18698                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18699         fi
18700 }
18701 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18702
18703 test_231b() {
18704         mkdir -p $DIR/$tdir
18705         local i
18706         for i in {0..1023}; do
18707                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18708                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18709                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18710         done
18711         sync
18712 }
18713 run_test 231b "must not assert on fully utilized OST request buffer"
18714
18715 test_232a() {
18716         mkdir -p $DIR/$tdir
18717         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18718
18719         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18720         do_facet ost1 $LCTL set_param fail_loc=0x31c
18721
18722         # ignore dd failure
18723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18724
18725         do_facet ost1 $LCTL set_param fail_loc=0
18726         umount_client $MOUNT || error "umount failed"
18727         mount_client $MOUNT || error "mount failed"
18728         stop ost1 || error "cannot stop ost1"
18729         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18730 }
18731 run_test 232a "failed lock should not block umount"
18732
18733 test_232b() {
18734         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18735                 skip "Need MDS version at least 2.10.58"
18736
18737         mkdir -p $DIR/$tdir
18738         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18739         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18740         sync
18741         cancel_lru_locks osc
18742
18743         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18744         do_facet ost1 $LCTL set_param fail_loc=0x31c
18745
18746         # ignore failure
18747         $LFS data_version $DIR/$tdir/$tfile || true
18748
18749         do_facet ost1 $LCTL set_param fail_loc=0
18750         umount_client $MOUNT || error "umount failed"
18751         mount_client $MOUNT || error "mount failed"
18752         stop ost1 || error "cannot stop ost1"
18753         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18754 }
18755 run_test 232b "failed data version lock should not block umount"
18756
18757 test_233a() {
18758         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18759                 skip "Need MDS version at least 2.3.64"
18760         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18761
18762         local fid=$($LFS path2fid $MOUNT)
18763
18764         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18765                 error "cannot access $MOUNT using its FID '$fid'"
18766 }
18767 run_test 233a "checking that OBF of the FS root succeeds"
18768
18769 test_233b() {
18770         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18771                 skip "Need MDS version at least 2.5.90"
18772         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18773
18774         local fid=$($LFS path2fid $MOUNT/.lustre)
18775
18776         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18777                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18778
18779         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18780         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18781                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18782 }
18783 run_test 233b "checking that OBF of the FS .lustre succeeds"
18784
18785 test_234() {
18786         local p="$TMP/sanityN-$TESTNAME.parameters"
18787         save_lustre_params client "llite.*.xattr_cache" > $p
18788         lctl set_param llite.*.xattr_cache 1 ||
18789                 skip_env "xattr cache is not supported"
18790
18791         mkdir -p $DIR/$tdir || error "mkdir failed"
18792         touch $DIR/$tdir/$tfile || error "touch failed"
18793         # OBD_FAIL_LLITE_XATTR_ENOMEM
18794         $LCTL set_param fail_loc=0x1405
18795         getfattr -n user.attr $DIR/$tdir/$tfile &&
18796                 error "getfattr should have failed with ENOMEM"
18797         $LCTL set_param fail_loc=0x0
18798         rm -rf $DIR/$tdir
18799
18800         restore_lustre_params < $p
18801         rm -f $p
18802 }
18803 run_test 234 "xattr cache should not crash on ENOMEM"
18804
18805 test_235() {
18806         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18807                 skip "Need MDS version at least 2.4.52"
18808
18809         flock_deadlock $DIR/$tfile
18810         local RC=$?
18811         case $RC in
18812                 0)
18813                 ;;
18814                 124) error "process hangs on a deadlock"
18815                 ;;
18816                 *) error "error executing flock_deadlock $DIR/$tfile"
18817                 ;;
18818         esac
18819 }
18820 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18821
18822 #LU-2935
18823 test_236() {
18824         check_swap_layouts_support
18825
18826         local ref1=/etc/passwd
18827         local ref2=/etc/group
18828         local file1=$DIR/$tdir/f1
18829         local file2=$DIR/$tdir/f2
18830
18831         test_mkdir -c1 $DIR/$tdir
18832         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18833         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18834         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18835         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18836         local fd=$(free_fd)
18837         local cmd="exec $fd<>$file2"
18838         eval $cmd
18839         rm $file2
18840         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18841                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18842         cmd="exec $fd>&-"
18843         eval $cmd
18844         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18845
18846         #cleanup
18847         rm -rf $DIR/$tdir
18848 }
18849 run_test 236 "Layout swap on open unlinked file"
18850
18851 # LU-4659 linkea consistency
18852 test_238() {
18853         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18854                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18855                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18856                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18857
18858         touch $DIR/$tfile
18859         ln $DIR/$tfile $DIR/$tfile.lnk
18860         touch $DIR/$tfile.new
18861         mv $DIR/$tfile.new $DIR/$tfile
18862         local fid1=$($LFS path2fid $DIR/$tfile)
18863         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18864         local path1=$($LFS fid2path $FSNAME "$fid1")
18865         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18866         local path2=$($LFS fid2path $FSNAME "$fid2")
18867         [ $tfile.lnk == $path2 ] ||
18868                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18869         rm -f $DIR/$tfile*
18870 }
18871 run_test 238 "Verify linkea consistency"
18872
18873 test_239A() { # was test_239
18874         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18875                 skip "Need MDS version at least 2.5.60"
18876
18877         local list=$(comma_list $(mdts_nodes))
18878
18879         mkdir -p $DIR/$tdir
18880         createmany -o $DIR/$tdir/f- 5000
18881         unlinkmany $DIR/$tdir/f- 5000
18882         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18883                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18884         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18885                         osp.*MDT*.sync_in_flight" | calc_sum)
18886         [ "$changes" -eq 0 ] || error "$changes not synced"
18887 }
18888 run_test 239A "osp_sync test"
18889
18890 test_239a() { #LU-5297
18891         remote_mds_nodsh && skip "remote MDS with nodsh"
18892
18893         touch $DIR/$tfile
18894         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18895         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18896         chgrp $RUNAS_GID $DIR/$tfile
18897         wait_delete_completed
18898 }
18899 run_test 239a "process invalid osp sync record correctly"
18900
18901 test_239b() { #LU-5297
18902         remote_mds_nodsh && skip "remote MDS with nodsh"
18903
18904         touch $DIR/$tfile1
18905         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18906         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18907         chgrp $RUNAS_GID $DIR/$tfile1
18908         wait_delete_completed
18909         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18910         touch $DIR/$tfile2
18911         chgrp $RUNAS_GID $DIR/$tfile2
18912         wait_delete_completed
18913 }
18914 run_test 239b "process osp sync record with ENOMEM error correctly"
18915
18916 test_240() {
18917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18918         remote_mds_nodsh && skip "remote MDS with nodsh"
18919
18920         mkdir -p $DIR/$tdir
18921
18922         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18923                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18924         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18925                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18926
18927         umount_client $MOUNT || error "umount failed"
18928         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18929         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18930         mount_client $MOUNT || error "failed to mount client"
18931
18932         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18933         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18934 }
18935 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18936
18937 test_241_bio() {
18938         local count=$1
18939         local bsize=$2
18940
18941         for LOOP in $(seq $count); do
18942                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18943                 cancel_lru_locks $OSC || true
18944         done
18945 }
18946
18947 test_241_dio() {
18948         local count=$1
18949         local bsize=$2
18950
18951         for LOOP in $(seq $1); do
18952                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18953                         2>/dev/null
18954         done
18955 }
18956
18957 test_241a() { # was test_241
18958         local bsize=$PAGE_SIZE
18959
18960         (( bsize < 40960 )) && bsize=40960
18961         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18962         ls -la $DIR/$tfile
18963         cancel_lru_locks $OSC
18964         test_241_bio 1000 $bsize &
18965         PID=$!
18966         test_241_dio 1000 $bsize
18967         wait $PID
18968 }
18969 run_test 241a "bio vs dio"
18970
18971 test_241b() {
18972         local bsize=$PAGE_SIZE
18973
18974         (( bsize < 40960 )) && bsize=40960
18975         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18976         ls -la $DIR/$tfile
18977         test_241_dio 1000 $bsize &
18978         PID=$!
18979         test_241_dio 1000 $bsize
18980         wait $PID
18981 }
18982 run_test 241b "dio vs dio"
18983
18984 test_242() {
18985         remote_mds_nodsh && skip "remote MDS with nodsh"
18986
18987         mkdir -p $DIR/$tdir
18988         touch $DIR/$tdir/$tfile
18989
18990         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18991         do_facet mds1 lctl set_param fail_loc=0x105
18992         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18993
18994         do_facet mds1 lctl set_param fail_loc=0
18995         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18996 }
18997 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18998
18999 test_243()
19000 {
19001         test_mkdir $DIR/$tdir
19002         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19003 }
19004 run_test 243 "various group lock tests"
19005
19006 test_244a()
19007 {
19008         test_mkdir $DIR/$tdir
19009         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19010         sendfile_grouplock $DIR/$tdir/$tfile || \
19011                 error "sendfile+grouplock failed"
19012         rm -rf $DIR/$tdir
19013 }
19014 run_test 244a "sendfile with group lock tests"
19015
19016 test_244b()
19017 {
19018         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19019
19020         local threads=50
19021         local size=$((1024*1024))
19022
19023         test_mkdir $DIR/$tdir
19024         for i in $(seq 1 $threads); do
19025                 local file=$DIR/$tdir/file_$((i / 10))
19026                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19027                 local pids[$i]=$!
19028         done
19029         for i in $(seq 1 $threads); do
19030                 wait ${pids[$i]}
19031         done
19032 }
19033 run_test 244b "multi-threaded write with group lock"
19034
19035 test_245() {
19036         local flagname="multi_mod_rpcs"
19037         local connect_data_name="max_mod_rpcs"
19038         local out
19039
19040         # check if multiple modify RPCs flag is set
19041         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19042                 grep "connect_flags:")
19043         echo "$out"
19044
19045         echo "$out" | grep -qw $flagname
19046         if [ $? -ne 0 ]; then
19047                 echo "connect flag $flagname is not set"
19048                 return
19049         fi
19050
19051         # check if multiple modify RPCs data is set
19052         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19053         echo "$out"
19054
19055         echo "$out" | grep -qw $connect_data_name ||
19056                 error "import should have connect data $connect_data_name"
19057 }
19058 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19059
19060 cleanup_247() {
19061         local submount=$1
19062
19063         trap 0
19064         umount_client $submount
19065         rmdir $submount
19066 }
19067
19068 test_247a() {
19069         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19070                 grep -q subtree ||
19071                 skip_env "Fileset feature is not supported"
19072
19073         local submount=${MOUNT}_$tdir
19074
19075         mkdir $MOUNT/$tdir
19076         mkdir -p $submount || error "mkdir $submount failed"
19077         FILESET="$FILESET/$tdir" mount_client $submount ||
19078                 error "mount $submount failed"
19079         trap "cleanup_247 $submount" EXIT
19080         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19081         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19082                 error "read $MOUNT/$tdir/$tfile failed"
19083         cleanup_247 $submount
19084 }
19085 run_test 247a "mount subdir as fileset"
19086
19087 test_247b() {
19088         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19089                 skip_env "Fileset feature is not supported"
19090
19091         local submount=${MOUNT}_$tdir
19092
19093         rm -rf $MOUNT/$tdir
19094         mkdir -p $submount || error "mkdir $submount failed"
19095         SKIP_FILESET=1
19096         FILESET="$FILESET/$tdir" mount_client $submount &&
19097                 error "mount $submount should fail"
19098         rmdir $submount
19099 }
19100 run_test 247b "mount subdir that dose not exist"
19101
19102 test_247c() {
19103         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19104                 skip_env "Fileset feature is not supported"
19105
19106         local submount=${MOUNT}_$tdir
19107
19108         mkdir -p $MOUNT/$tdir/dir1
19109         mkdir -p $submount || error "mkdir $submount failed"
19110         trap "cleanup_247 $submount" EXIT
19111         FILESET="$FILESET/$tdir" mount_client $submount ||
19112                 error "mount $submount failed"
19113         local fid=$($LFS path2fid $MOUNT/)
19114         $LFS fid2path $submount $fid && error "fid2path should fail"
19115         cleanup_247 $submount
19116 }
19117 run_test 247c "running fid2path outside subdirectory root"
19118
19119 test_247d() {
19120         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19121                 skip "Fileset feature is not supported"
19122
19123         local submount=${MOUNT}_$tdir
19124
19125         mkdir -p $MOUNT/$tdir/dir1
19126         mkdir -p $submount || error "mkdir $submount failed"
19127         FILESET="$FILESET/$tdir" mount_client $submount ||
19128                 error "mount $submount failed"
19129         trap "cleanup_247 $submount" EXIT
19130
19131         local td=$submount/dir1
19132         local fid=$($LFS path2fid $td)
19133         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19134
19135         # check that we get the same pathname back
19136         local rootpath
19137         local found
19138         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19139                 echo "$rootpath $fid"
19140                 found=$($LFS fid2path $rootpath "$fid")
19141                 [ -n "found" ] || error "fid2path should succeed"
19142                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19143         done
19144         # check wrong root path format
19145         rootpath=$submount"_wrong"
19146         found=$($LFS fid2path $rootpath "$fid")
19147         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19148
19149         cleanup_247 $submount
19150 }
19151 run_test 247d "running fid2path inside subdirectory root"
19152
19153 # LU-8037
19154 test_247e() {
19155         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19156                 grep -q subtree ||
19157                 skip "Fileset feature is not supported"
19158
19159         local submount=${MOUNT}_$tdir
19160
19161         mkdir $MOUNT/$tdir
19162         mkdir -p $submount || error "mkdir $submount failed"
19163         FILESET="$FILESET/.." mount_client $submount &&
19164                 error "mount $submount should fail"
19165         rmdir $submount
19166 }
19167 run_test 247e "mount .. as fileset"
19168
19169 test_247f() {
19170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19171         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19172                 skip "Need at least version 2.13.52"
19173         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19174                 grep -q subtree ||
19175                 skip "Fileset feature is not supported"
19176
19177         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19178         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19179                 error "mkdir remote failed"
19180         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19181         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19182                 error "mkdir striped failed"
19183         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19184
19185         local submount=${MOUNT}_$tdir
19186
19187         mkdir -p $submount || error "mkdir $submount failed"
19188
19189         local dir
19190         local fileset=$FILESET
19191
19192         for dir in $tdir/remote $tdir/remote/subdir \
19193                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19194                 FILESET="$fileset/$dir" mount_client $submount ||
19195                         error "mount $dir failed"
19196                 umount_client $submount
19197         done
19198 }
19199 run_test 247f "mount striped or remote directory as fileset"
19200
19201 test_248a() {
19202         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19203         [ -z "$fast_read_sav" ] && skip "no fast read support"
19204
19205         # create a large file for fast read verification
19206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19207
19208         # make sure the file is created correctly
19209         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19210                 { rm -f $DIR/$tfile; skip "file creation error"; }
19211
19212         echo "Test 1: verify that fast read is 4 times faster on cache read"
19213
19214         # small read with fast read enabled
19215         $LCTL set_param -n llite.*.fast_read=1
19216         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19217                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19218                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19219         # small read with fast read disabled
19220         $LCTL set_param -n llite.*.fast_read=0
19221         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19222                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19223                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19224
19225         # verify that fast read is 4 times faster for cache read
19226         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19227                 error_not_in_vm "fast read was not 4 times faster: " \
19228                            "$t_fast vs $t_slow"
19229
19230         echo "Test 2: verify the performance between big and small read"
19231         $LCTL set_param -n llite.*.fast_read=1
19232
19233         # 1k non-cache read
19234         cancel_lru_locks osc
19235         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19236                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19237                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19238
19239         # 1M non-cache read
19240         cancel_lru_locks osc
19241         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19242                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19243                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19244
19245         # verify that big IO is not 4 times faster than small IO
19246         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19247                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19248
19249         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19250         rm -f $DIR/$tfile
19251 }
19252 run_test 248a "fast read verification"
19253
19254 test_248b() {
19255         # Default short_io_bytes=16384, try both smaller and larger sizes.
19256         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19257         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19258         echo "bs=53248 count=113 normal buffered write"
19259         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19260                 error "dd of initial data file failed"
19261         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19262
19263         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19264         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19265                 error "dd with sync normal writes failed"
19266         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19267
19268         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19269         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19270                 error "dd with sync small writes failed"
19271         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19272
19273         cancel_lru_locks osc
19274
19275         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19276         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19277         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19278         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19279                 iflag=direct || error "dd with O_DIRECT small read failed"
19280         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19281         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19282                 error "compare $TMP/$tfile.1 failed"
19283
19284         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19285         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19286
19287         # just to see what the maximum tunable value is, and test parsing
19288         echo "test invalid parameter 2MB"
19289         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19290                 error "too-large short_io_bytes allowed"
19291         echo "test maximum parameter 512KB"
19292         # if we can set a larger short_io_bytes, run test regardless of version
19293         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19294                 # older clients may not allow setting it this large, that's OK
19295                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19296                         skip "Need at least client version 2.13.50"
19297                 error "medium short_io_bytes failed"
19298         fi
19299         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19300         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19301
19302         echo "test large parameter 64KB"
19303         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19304         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19305
19306         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19307         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19308                 error "dd with sync large writes failed"
19309         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19310
19311         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19312         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19313         num=$((113 * 4096 / PAGE_SIZE))
19314         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19315         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19316                 error "dd with O_DIRECT large writes failed"
19317         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19318                 error "compare $DIR/$tfile.3 failed"
19319
19320         cancel_lru_locks osc
19321
19322         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19323         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19324                 error "dd with O_DIRECT large read failed"
19325         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19326                 error "compare $TMP/$tfile.2 failed"
19327
19328         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19329         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19330                 error "dd with O_DIRECT large read failed"
19331         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19332                 error "compare $TMP/$tfile.3 failed"
19333 }
19334 run_test 248b "test short_io read and write for both small and large sizes"
19335
19336 test_249() { # LU-7890
19337         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19338                 skip "Need at least version 2.8.54"
19339
19340         rm -f $DIR/$tfile
19341         $LFS setstripe -c 1 $DIR/$tfile
19342         # Offset 2T == 4k * 512M
19343         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19344                 error "dd to 2T offset failed"
19345 }
19346 run_test 249 "Write above 2T file size"
19347
19348 test_250() {
19349         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19350          && skip "no 16TB file size limit on ZFS"
19351
19352         $LFS setstripe -c 1 $DIR/$tfile
19353         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19354         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19355         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19356         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19357                 conv=notrunc,fsync && error "append succeeded"
19358         return 0
19359 }
19360 run_test 250 "Write above 16T limit"
19361
19362 test_251() {
19363         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19364
19365         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19366         #Skip once - writing the first stripe will succeed
19367         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19368         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19369                 error "short write happened"
19370
19371         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19372         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19373                 error "short read happened"
19374
19375         rm -f $DIR/$tfile
19376 }
19377 run_test 251 "Handling short read and write correctly"
19378
19379 test_252() {
19380         remote_mds_nodsh && skip "remote MDS with nodsh"
19381         remote_ost_nodsh && skip "remote OST with nodsh"
19382         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19383                 skip_env "ldiskfs only test"
19384         fi
19385
19386         local tgt
19387         local dev
19388         local out
19389         local uuid
19390         local num
19391         local gen
19392
19393         # check lr_reader on OST0000
19394         tgt=ost1
19395         dev=$(facet_device $tgt)
19396         out=$(do_facet $tgt $LR_READER $dev)
19397         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19398         echo "$out"
19399         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19400         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19401                 error "Invalid uuid returned by $LR_READER on target $tgt"
19402         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19403
19404         # check lr_reader -c on MDT0000
19405         tgt=mds1
19406         dev=$(facet_device $tgt)
19407         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19408                 skip "$LR_READER does not support additional options"
19409         fi
19410         out=$(do_facet $tgt $LR_READER -c $dev)
19411         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19412         echo "$out"
19413         num=$(echo "$out" | grep -c "mdtlov")
19414         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19415                 error "Invalid number of mdtlov clients returned by $LR_READER"
19416         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19417
19418         # check lr_reader -cr on MDT0000
19419         out=$(do_facet $tgt $LR_READER -cr $dev)
19420         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19421         echo "$out"
19422         echo "$out" | grep -q "^reply_data:$" ||
19423                 error "$LR_READER should have returned 'reply_data' section"
19424         num=$(echo "$out" | grep -c "client_generation")
19425         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19426 }
19427 run_test 252 "check lr_reader tool"
19428
19429 test_253() {
19430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19431         remote_mds_nodsh && skip "remote MDS with nodsh"
19432         remote_mgs_nodsh && skip "remote MGS with nodsh"
19433
19434         local ostidx=0
19435         local rc=0
19436         local ost_name=$(ostname_from_index $ostidx)
19437
19438         # on the mdt's osc
19439         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19440         do_facet $SINGLEMDS $LCTL get_param -n \
19441                 osp.$mdtosc_proc1.reserved_mb_high ||
19442                 skip  "remote MDS does not support reserved_mb_high"
19443
19444         rm -rf $DIR/$tdir
19445         wait_mds_ost_sync
19446         wait_delete_completed
19447         mkdir $DIR/$tdir
19448
19449         pool_add $TESTNAME || error "Pool creation failed"
19450         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19451
19452         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19453                 error "Setstripe failed"
19454
19455         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19456
19457         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19458                     grep "watermarks")
19459         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19460
19461         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19462                         osp.$mdtosc_proc1.prealloc_status)
19463         echo "prealloc_status $oa_status"
19464
19465         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19466                 error "File creation should fail"
19467
19468         #object allocation was stopped, but we still able to append files
19469         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19470                 oflag=append || error "Append failed"
19471
19472         rm -f $DIR/$tdir/$tfile.0
19473
19474         # For this test, we want to delete the files we created to go out of
19475         # space but leave the watermark, so we remain nearly out of space
19476         ost_watermarks_enospc_delete_files $tfile $ostidx
19477
19478         wait_delete_completed
19479
19480         sleep_maxage
19481
19482         for i in $(seq 10 12); do
19483                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19484                         2>/dev/null || error "File creation failed after rm"
19485         done
19486
19487         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19488                         osp.$mdtosc_proc1.prealloc_status)
19489         echo "prealloc_status $oa_status"
19490
19491         if (( oa_status != 0 )); then
19492                 error "Object allocation still disable after rm"
19493         fi
19494 }
19495 run_test 253 "Check object allocation limit"
19496
19497 test_254() {
19498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19499         remote_mds_nodsh && skip "remote MDS with nodsh"
19500         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19501                 skip "MDS does not support changelog_size"
19502
19503         local cl_user
19504         local MDT0=$(facet_svc $SINGLEMDS)
19505
19506         changelog_register || error "changelog_register failed"
19507
19508         changelog_clear 0 || error "changelog_clear failed"
19509
19510         local size1=$(do_facet $SINGLEMDS \
19511                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19512         echo "Changelog size $size1"
19513
19514         rm -rf $DIR/$tdir
19515         $LFS mkdir -i 0 $DIR/$tdir
19516         # change something
19517         mkdir -p $DIR/$tdir/pics/2008/zachy
19518         touch $DIR/$tdir/pics/2008/zachy/timestamp
19519         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19520         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19521         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19522         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19523         rm $DIR/$tdir/pics/desktop.jpg
19524
19525         local size2=$(do_facet $SINGLEMDS \
19526                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19527         echo "Changelog size after work $size2"
19528
19529         (( $size2 > $size1 )) ||
19530                 error "new Changelog size=$size2 less than old size=$size1"
19531 }
19532 run_test 254 "Check changelog size"
19533
19534 ladvise_no_type()
19535 {
19536         local type=$1
19537         local file=$2
19538
19539         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19540                 awk -F: '{print $2}' | grep $type > /dev/null
19541         if [ $? -ne 0 ]; then
19542                 return 0
19543         fi
19544         return 1
19545 }
19546
19547 ladvise_no_ioctl()
19548 {
19549         local file=$1
19550
19551         lfs ladvise -a willread $file > /dev/null 2>&1
19552         if [ $? -eq 0 ]; then
19553                 return 1
19554         fi
19555
19556         lfs ladvise -a willread $file 2>&1 |
19557                 grep "Inappropriate ioctl for device" > /dev/null
19558         if [ $? -eq 0 ]; then
19559                 return 0
19560         fi
19561         return 1
19562 }
19563
19564 percent() {
19565         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19566 }
19567
19568 # run a random read IO workload
19569 # usage: random_read_iops <filename> <filesize> <iosize>
19570 random_read_iops() {
19571         local file=$1
19572         local fsize=$2
19573         local iosize=${3:-4096}
19574
19575         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19576                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19577 }
19578
19579 drop_file_oss_cache() {
19580         local file="$1"
19581         local nodes="$2"
19582
19583         $LFS ladvise -a dontneed $file 2>/dev/null ||
19584                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19585 }
19586
19587 ladvise_willread_performance()
19588 {
19589         local repeat=10
19590         local average_origin=0
19591         local average_cache=0
19592         local average_ladvise=0
19593
19594         for ((i = 1; i <= $repeat; i++)); do
19595                 echo "Iter $i/$repeat: reading without willread hint"
19596                 cancel_lru_locks osc
19597                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19598                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19599                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19600                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19601
19602                 cancel_lru_locks osc
19603                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19604                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19605                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19606
19607                 cancel_lru_locks osc
19608                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19609                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19610                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19611                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19612                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19613         done
19614         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19615         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19616         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19617
19618         speedup_cache=$(percent $average_cache $average_origin)
19619         speedup_ladvise=$(percent $average_ladvise $average_origin)
19620
19621         echo "Average uncached read: $average_origin"
19622         echo "Average speedup with OSS cached read: " \
19623                 "$average_cache = +$speedup_cache%"
19624         echo "Average speedup with ladvise willread: " \
19625                 "$average_ladvise = +$speedup_ladvise%"
19626
19627         local lowest_speedup=20
19628         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19629                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19630                         "got $average_cache%. Skipping ladvise willread check."
19631                 return 0
19632         fi
19633
19634         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19635         # it is still good to run until then to exercise 'ladvise willread'
19636         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19637                 [ "$ost1_FSTYPE" = "zfs" ] &&
19638                 echo "osd-zfs does not support dontneed or drop_caches" &&
19639                 return 0
19640
19641         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19642         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19643                 error_not_in_vm "Speedup with willread is less than " \
19644                         "$lowest_speedup%, got $average_ladvise%"
19645 }
19646
19647 test_255a() {
19648         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19649                 skip "lustre < 2.8.54 does not support ladvise "
19650         remote_ost_nodsh && skip "remote OST with nodsh"
19651
19652         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19653
19654         ladvise_no_type willread $DIR/$tfile &&
19655                 skip "willread ladvise is not supported"
19656
19657         ladvise_no_ioctl $DIR/$tfile &&
19658                 skip "ladvise ioctl is not supported"
19659
19660         local size_mb=100
19661         local size=$((size_mb * 1048576))
19662         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19663                 error "dd to $DIR/$tfile failed"
19664
19665         lfs ladvise -a willread $DIR/$tfile ||
19666                 error "Ladvise failed with no range argument"
19667
19668         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19669                 error "Ladvise failed with no -l or -e argument"
19670
19671         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19672                 error "Ladvise failed with only -e argument"
19673
19674         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19675                 error "Ladvise failed with only -l argument"
19676
19677         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19678                 error "End offset should not be smaller than start offset"
19679
19680         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19681                 error "End offset should not be equal to start offset"
19682
19683         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19684                 error "Ladvise failed with overflowing -s argument"
19685
19686         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19687                 error "Ladvise failed with overflowing -e argument"
19688
19689         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19690                 error "Ladvise failed with overflowing -l argument"
19691
19692         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19693                 error "Ladvise succeeded with conflicting -l and -e arguments"
19694
19695         echo "Synchronous ladvise should wait"
19696         local delay=4
19697 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19698         do_nodes $(comma_list $(osts_nodes)) \
19699                 $LCTL set_param fail_val=$delay fail_loc=0x237
19700
19701         local start_ts=$SECONDS
19702         lfs ladvise -a willread $DIR/$tfile ||
19703                 error "Ladvise failed with no range argument"
19704         local end_ts=$SECONDS
19705         local inteval_ts=$((end_ts - start_ts))
19706
19707         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19708                 error "Synchronous advice didn't wait reply"
19709         fi
19710
19711         echo "Asynchronous ladvise shouldn't wait"
19712         local start_ts=$SECONDS
19713         lfs ladvise -a willread -b $DIR/$tfile ||
19714                 error "Ladvise failed with no range argument"
19715         local end_ts=$SECONDS
19716         local inteval_ts=$((end_ts - start_ts))
19717
19718         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19719                 error "Asynchronous advice blocked"
19720         fi
19721
19722         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19723         ladvise_willread_performance
19724 }
19725 run_test 255a "check 'lfs ladvise -a willread'"
19726
19727 facet_meminfo() {
19728         local facet=$1
19729         local info=$2
19730
19731         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19732 }
19733
19734 test_255b() {
19735         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19736                 skip "lustre < 2.8.54 does not support ladvise "
19737         remote_ost_nodsh && skip "remote OST with nodsh"
19738
19739         lfs setstripe -c 1 -i 0 $DIR/$tfile
19740
19741         ladvise_no_type dontneed $DIR/$tfile &&
19742                 skip "dontneed ladvise is not supported"
19743
19744         ladvise_no_ioctl $DIR/$tfile &&
19745                 skip "ladvise ioctl is not supported"
19746
19747         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19748                 [ "$ost1_FSTYPE" = "zfs" ] &&
19749                 skip "zfs-osd does not support 'ladvise dontneed'"
19750
19751         local size_mb=100
19752         local size=$((size_mb * 1048576))
19753         # In order to prevent disturbance of other processes, only check 3/4
19754         # of the memory usage
19755         local kibibytes=$((size_mb * 1024 * 3 / 4))
19756
19757         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19758                 error "dd to $DIR/$tfile failed"
19759
19760         #force write to complete before dropping OST cache & checking memory
19761         sync
19762
19763         local total=$(facet_meminfo ost1 MemTotal)
19764         echo "Total memory: $total KiB"
19765
19766         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19767         local before_read=$(facet_meminfo ost1 Cached)
19768         echo "Cache used before read: $before_read KiB"
19769
19770         lfs ladvise -a willread $DIR/$tfile ||
19771                 error "Ladvise willread failed"
19772         local after_read=$(facet_meminfo ost1 Cached)
19773         echo "Cache used after read: $after_read KiB"
19774
19775         lfs ladvise -a dontneed $DIR/$tfile ||
19776                 error "Ladvise dontneed again failed"
19777         local no_read=$(facet_meminfo ost1 Cached)
19778         echo "Cache used after dontneed ladvise: $no_read KiB"
19779
19780         if [ $total -lt $((before_read + kibibytes)) ]; then
19781                 echo "Memory is too small, abort checking"
19782                 return 0
19783         fi
19784
19785         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19786                 error "Ladvise willread should use more memory" \
19787                         "than $kibibytes KiB"
19788         fi
19789
19790         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19791                 error "Ladvise dontneed should release more memory" \
19792                         "than $kibibytes KiB"
19793         fi
19794 }
19795 run_test 255b "check 'lfs ladvise -a dontneed'"
19796
19797 test_255c() {
19798         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19799                 skip "lustre < 2.10.50 does not support lockahead"
19800
19801         local count
19802         local new_count
19803         local difference
19804         local i
19805         local rc
19806
19807         test_mkdir -p $DIR/$tdir
19808         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19809
19810         #test 10 returns only success/failure
19811         i=10
19812         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19813         rc=$?
19814         if [ $rc -eq 255 ]; then
19815                 error "Ladvise test${i} failed, ${rc}"
19816         fi
19817
19818         #test 11 counts lock enqueue requests, all others count new locks
19819         i=11
19820         count=$(do_facet ost1 \
19821                 $LCTL get_param -n ost.OSS.ost.stats)
19822         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19823
19824         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19825         rc=$?
19826         if [ $rc -eq 255 ]; then
19827                 error "Ladvise test${i} failed, ${rc}"
19828         fi
19829
19830         new_count=$(do_facet ost1 \
19831                 $LCTL get_param -n ost.OSS.ost.stats)
19832         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19833                    awk '{ print $2 }')
19834
19835         difference="$((new_count - count))"
19836         if [ $difference -ne $rc ]; then
19837                 error "Ladvise test${i}, bad enqueue count, returned " \
19838                       "${rc}, actual ${difference}"
19839         fi
19840
19841         for i in $(seq 12 21); do
19842                 # If we do not do this, we run the risk of having too many
19843                 # locks and starting lock cancellation while we are checking
19844                 # lock counts.
19845                 cancel_lru_locks osc
19846
19847                 count=$($LCTL get_param -n \
19848                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19849
19850                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19851                 rc=$?
19852                 if [ $rc -eq 255 ]; then
19853                         error "Ladvise test ${i} failed, ${rc}"
19854                 fi
19855
19856                 new_count=$($LCTL get_param -n \
19857                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19858                 difference="$((new_count - count))"
19859
19860                 # Test 15 output is divided by 100 to map down to valid return
19861                 if [ $i -eq 15 ]; then
19862                         rc="$((rc * 100))"
19863                 fi
19864
19865                 if [ $difference -ne $rc ]; then
19866                         error "Ladvise test ${i}, bad lock count, returned " \
19867                               "${rc}, actual ${difference}"
19868                 fi
19869         done
19870
19871         #test 22 returns only success/failure
19872         i=22
19873         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19874         rc=$?
19875         if [ $rc -eq 255 ]; then
19876                 error "Ladvise test${i} failed, ${rc}"
19877         fi
19878 }
19879 run_test 255c "suite of ladvise lockahead tests"
19880
19881 test_256() {
19882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19883         remote_mds_nodsh && skip "remote MDS with nodsh"
19884         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19885         changelog_users $SINGLEMDS | grep "^cl" &&
19886                 skip "active changelog user"
19887
19888         local cl_user
19889         local cat_sl
19890         local mdt_dev
19891
19892         mdt_dev=$(mdsdevname 1)
19893         echo $mdt_dev
19894
19895         changelog_register || error "changelog_register failed"
19896
19897         rm -rf $DIR/$tdir
19898         mkdir -p $DIR/$tdir
19899
19900         changelog_clear 0 || error "changelog_clear failed"
19901
19902         # change something
19903         touch $DIR/$tdir/{1..10}
19904
19905         # stop the MDT
19906         stop $SINGLEMDS || error "Fail to stop MDT"
19907
19908         # remount the MDT
19909
19910         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19911
19912         #after mount new plainllog is used
19913         touch $DIR/$tdir/{11..19}
19914         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19915         stack_trap "rm -f $tmpfile"
19916         cat_sl=$(do_facet $SINGLEMDS "sync; \
19917                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19918                  llog_reader $tmpfile | grep -c type=1064553b")
19919         do_facet $SINGLEMDS llog_reader $tmpfile
19920
19921         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19922
19923         changelog_clear 0 || error "changelog_clear failed"
19924
19925         cat_sl=$(do_facet $SINGLEMDS "sync; \
19926                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19927                  llog_reader $tmpfile | grep -c type=1064553b")
19928
19929         if (( cat_sl == 2 )); then
19930                 error "Empty plain llog was not deleted from changelog catalog"
19931         elif (( cat_sl != 1 )); then
19932                 error "Active plain llog shouldn't be deleted from catalog"
19933         fi
19934 }
19935 run_test 256 "Check llog delete for empty and not full state"
19936
19937 test_257() {
19938         remote_mds_nodsh && skip "remote MDS with nodsh"
19939         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19940                 skip "Need MDS version at least 2.8.55"
19941
19942         test_mkdir $DIR/$tdir
19943
19944         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19945                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19946         stat $DIR/$tdir
19947
19948 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19949         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19950         local facet=mds$((mdtidx + 1))
19951         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19952         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19953
19954         stop $facet || error "stop MDS failed"
19955         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19956                 error "start MDS fail"
19957         wait_recovery_complete $facet
19958 }
19959 run_test 257 "xattr locks are not lost"
19960
19961 # Verify we take the i_mutex when security requires it
19962 test_258a() {
19963 #define OBD_FAIL_IMUTEX_SEC 0x141c
19964         $LCTL set_param fail_loc=0x141c
19965         touch $DIR/$tfile
19966         chmod u+s $DIR/$tfile
19967         chmod a+rwx $DIR/$tfile
19968         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19969         RC=$?
19970         if [ $RC -ne 0 ]; then
19971                 error "error, failed to take i_mutex, rc=$?"
19972         fi
19973         rm -f $DIR/$tfile
19974 }
19975 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19976
19977 # Verify we do NOT take the i_mutex in the normal case
19978 test_258b() {
19979 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19980         $LCTL set_param fail_loc=0x141d
19981         touch $DIR/$tfile
19982         chmod a+rwx $DIR
19983         chmod a+rw $DIR/$tfile
19984         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19985         RC=$?
19986         if [ $RC -ne 0 ]; then
19987                 error "error, took i_mutex unnecessarily, rc=$?"
19988         fi
19989         rm -f $DIR/$tfile
19990
19991 }
19992 run_test 258b "verify i_mutex security behavior"
19993
19994 test_259() {
19995         local file=$DIR/$tfile
19996         local before
19997         local after
19998
19999         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20000
20001         stack_trap "rm -f $file" EXIT
20002
20003         wait_delete_completed
20004         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20005         echo "before: $before"
20006
20007         $LFS setstripe -i 0 -c 1 $file
20008         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20009         sync_all_data
20010         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20011         echo "after write: $after"
20012
20013 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20014         do_facet ost1 $LCTL set_param fail_loc=0x2301
20015         $TRUNCATE $file 0
20016         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20017         echo "after truncate: $after"
20018
20019         stop ost1
20020         do_facet ost1 $LCTL set_param fail_loc=0
20021         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20022         sleep 2
20023         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20024         echo "after restart: $after"
20025         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20026                 error "missing truncate?"
20027
20028         return 0
20029 }
20030 run_test 259 "crash at delayed truncate"
20031
20032 test_260() {
20033 #define OBD_FAIL_MDC_CLOSE               0x806
20034         $LCTL set_param fail_loc=0x80000806
20035         touch $DIR/$tfile
20036
20037 }
20038 run_test 260 "Check mdc_close fail"
20039
20040 ### Data-on-MDT sanity tests ###
20041 test_270a() {
20042         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20043                 skip "Need MDS version at least 2.10.55 for DoM"
20044
20045         # create DoM file
20046         local dom=$DIR/$tdir/dom_file
20047         local tmp=$DIR/$tdir/tmp_file
20048
20049         mkdir -p $DIR/$tdir
20050
20051         # basic checks for DoM component creation
20052         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20053                 error "Can set MDT layout to non-first entry"
20054
20055         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20056                 error "Can define multiple entries as MDT layout"
20057
20058         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20059
20060         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20061         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20062         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20063
20064         local mdtidx=$($LFS getstripe -m $dom)
20065         local mdtname=MDT$(printf %04x $mdtidx)
20066         local facet=mds$((mdtidx + 1))
20067         local space_check=1
20068
20069         # Skip free space checks with ZFS
20070         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20071
20072         # write
20073         sync
20074         local size_tmp=$((65536 * 3))
20075         local mdtfree1=$(do_facet $facet \
20076                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20077
20078         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20079         # check also direct IO along write
20080         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20081         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20082         sync
20083         cmp $tmp $dom || error "file data is different"
20084         [ $(stat -c%s $dom) == $size_tmp ] ||
20085                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20086         if [ $space_check == 1 ]; then
20087                 local mdtfree2=$(do_facet $facet \
20088                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20089
20090                 # increase in usage from by $size_tmp
20091                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20092                         error "MDT free space wrong after write: " \
20093                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20094         fi
20095
20096         # truncate
20097         local size_dom=10000
20098
20099         $TRUNCATE $dom $size_dom
20100         [ $(stat -c%s $dom) == $size_dom ] ||
20101                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20102         if [ $space_check == 1 ]; then
20103                 mdtfree1=$(do_facet $facet \
20104                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20105                 # decrease in usage from $size_tmp to new $size_dom
20106                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20107                   $(((size_tmp - size_dom) / 1024)) ] ||
20108                         error "MDT free space is wrong after truncate: " \
20109                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20110         fi
20111
20112         # append
20113         cat $tmp >> $dom
20114         sync
20115         size_dom=$((size_dom + size_tmp))
20116         [ $(stat -c%s $dom) == $size_dom ] ||
20117                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20118         if [ $space_check == 1 ]; then
20119                 mdtfree2=$(do_facet $facet \
20120                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20121                 # increase in usage by $size_tmp from previous
20122                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20123                         error "MDT free space is wrong after append: " \
20124                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20125         fi
20126
20127         # delete
20128         rm $dom
20129         if [ $space_check == 1 ]; then
20130                 mdtfree1=$(do_facet $facet \
20131                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20132                 # decrease in usage by $size_dom from previous
20133                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20134                         error "MDT free space is wrong after removal: " \
20135                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20136         fi
20137
20138         # combined striping
20139         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20140                 error "Can't create DoM + OST striping"
20141
20142         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20143         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20144         # check also direct IO along write
20145         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20146         sync
20147         cmp $tmp $dom || error "file data is different"
20148         [ $(stat -c%s $dom) == $size_tmp ] ||
20149                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20150         rm $dom $tmp
20151
20152         return 0
20153 }
20154 run_test 270a "DoM: basic functionality tests"
20155
20156 test_270b() {
20157         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20158                 skip "Need MDS version at least 2.10.55"
20159
20160         local dom=$DIR/$tdir/dom_file
20161         local max_size=1048576
20162
20163         mkdir -p $DIR/$tdir
20164         $LFS setstripe -E $max_size -L mdt $dom
20165
20166         # truncate over the limit
20167         $TRUNCATE $dom $(($max_size + 1)) &&
20168                 error "successful truncate over the maximum size"
20169         # write over the limit
20170         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20171                 error "successful write over the maximum size"
20172         # append over the limit
20173         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20174         echo "12345" >> $dom && error "successful append over the maximum size"
20175         rm $dom
20176
20177         return 0
20178 }
20179 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20180
20181 test_270c() {
20182         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20183                 skip "Need MDS version at least 2.10.55"
20184
20185         mkdir -p $DIR/$tdir
20186         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20187
20188         # check files inherit DoM EA
20189         touch $DIR/$tdir/first
20190         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20191                 error "bad pattern"
20192         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20193                 error "bad stripe count"
20194         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20195                 error "bad stripe size"
20196
20197         # check directory inherits DoM EA and uses it as default
20198         mkdir $DIR/$tdir/subdir
20199         touch $DIR/$tdir/subdir/second
20200         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20201                 error "bad pattern in sub-directory"
20202         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20203                 error "bad stripe count in sub-directory"
20204         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20205                 error "bad stripe size in sub-directory"
20206         return 0
20207 }
20208 run_test 270c "DoM: DoM EA inheritance tests"
20209
20210 test_270d() {
20211         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20212                 skip "Need MDS version at least 2.10.55"
20213
20214         mkdir -p $DIR/$tdir
20215         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20216
20217         # inherit default DoM striping
20218         mkdir $DIR/$tdir/subdir
20219         touch $DIR/$tdir/subdir/f1
20220
20221         # change default directory striping
20222         $LFS setstripe -c 1 $DIR/$tdir/subdir
20223         touch $DIR/$tdir/subdir/f2
20224         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20225                 error "wrong default striping in file 2"
20226         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20227                 error "bad pattern in file 2"
20228         return 0
20229 }
20230 run_test 270d "DoM: change striping from DoM to RAID0"
20231
20232 test_270e() {
20233         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20234                 skip "Need MDS version at least 2.10.55"
20235
20236         mkdir -p $DIR/$tdir/dom
20237         mkdir -p $DIR/$tdir/norm
20238         DOMFILES=20
20239         NORMFILES=10
20240         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20241         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20242
20243         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20244         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20245
20246         # find DoM files by layout
20247         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20248         [ $NUM -eq  $DOMFILES ] ||
20249                 error "lfs find -L: found $NUM, expected $DOMFILES"
20250         echo "Test 1: lfs find 20 DOM files by layout: OK"
20251
20252         # there should be 1 dir with default DOM striping
20253         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20254         [ $NUM -eq  1 ] ||
20255                 error "lfs find -L: found $NUM, expected 1 dir"
20256         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20257
20258         # find DoM files by stripe size
20259         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20260         [ $NUM -eq  $DOMFILES ] ||
20261                 error "lfs find -S: found $NUM, expected $DOMFILES"
20262         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20263
20264         # find files by stripe offset except DoM files
20265         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20266         [ $NUM -eq  $NORMFILES ] ||
20267                 error "lfs find -i: found $NUM, expected $NORMFILES"
20268         echo "Test 5: lfs find no DOM files by stripe index: OK"
20269         return 0
20270 }
20271 run_test 270e "DoM: lfs find with DoM files test"
20272
20273 test_270f() {
20274         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20275                 skip "Need MDS version at least 2.10.55"
20276
20277         local mdtname=${FSNAME}-MDT0000-mdtlov
20278         local dom=$DIR/$tdir/dom_file
20279         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20280                                                 lod.$mdtname.dom_stripesize)
20281         local dom_limit=131072
20282
20283         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20284         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20285                                                 lod.$mdtname.dom_stripesize)
20286         [ ${dom_limit} -eq ${dom_current} ] ||
20287                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20288
20289         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20290         $LFS setstripe -d $DIR/$tdir
20291         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20292                 error "Can't set directory default striping"
20293
20294         # exceed maximum stripe size
20295         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20296                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20297         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20298                 error "Able to create DoM component size more than LOD limit"
20299
20300         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20301         dom_current=$(do_facet mds1 $LCTL get_param -n \
20302                                                 lod.$mdtname.dom_stripesize)
20303         [ 0 -eq ${dom_current} ] ||
20304                 error "Can't set zero DoM stripe limit"
20305         rm $dom
20306
20307         # attempt to create DoM file on server with disabled DoM should
20308         # remove DoM entry from layout and be succeed
20309         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20310                 error "Can't create DoM file (DoM is disabled)"
20311         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20312                 error "File has DoM component while DoM is disabled"
20313         rm $dom
20314
20315         # attempt to create DoM file with only DoM stripe should return error
20316         $LFS setstripe -E $dom_limit -L mdt $dom &&
20317                 error "Able to create DoM-only file while DoM is disabled"
20318
20319         # too low values to be aligned with smallest stripe size 64K
20320         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20321         dom_current=$(do_facet mds1 $LCTL get_param -n \
20322                                                 lod.$mdtname.dom_stripesize)
20323         [ 30000 -eq ${dom_current} ] &&
20324                 error "Can set too small DoM stripe limit"
20325
20326         # 64K is a minimal stripe size in Lustre, expect limit of that size
20327         [ 65536 -eq ${dom_current} ] ||
20328                 error "Limit is not set to 64K but ${dom_current}"
20329
20330         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20331         dom_current=$(do_facet mds1 $LCTL get_param -n \
20332                                                 lod.$mdtname.dom_stripesize)
20333         echo $dom_current
20334         [ 2147483648 -eq ${dom_current} ] &&
20335                 error "Can set too large DoM stripe limit"
20336
20337         do_facet mds1 $LCTL set_param -n \
20338                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20339         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20340                 error "Can't create DoM component size after limit change"
20341         do_facet mds1 $LCTL set_param -n \
20342                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20343         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20344                 error "Can't create DoM file after limit decrease"
20345         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20346                 error "Can create big DoM component after limit decrease"
20347         touch ${dom}_def ||
20348                 error "Can't create file with old default layout"
20349
20350         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20351         return 0
20352 }
20353 run_test 270f "DoM: maximum DoM stripe size checks"
20354
20355 test_270g() {
20356         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20357                 skip "Need MDS version at least 2.13.52"
20358         local dom=$DIR/$tdir/$tfile
20359
20360         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20361         local lodname=${FSNAME}-MDT0000-mdtlov
20362
20363         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20364         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20365         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20366         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20367
20368         local dom_limit=1024
20369         local dom_threshold="50%"
20370
20371         $LFS setstripe -d $DIR/$tdir
20372         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20373                 error "Can't set directory default striping"
20374
20375         do_facet mds1 $LCTL set_param -n \
20376                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20377         # set 0 threshold and create DOM file to change tunable stripesize
20378         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20379         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20380                 error "Failed to create $dom file"
20381         # now tunable dom_cur_stripesize should reach maximum
20382         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20383                                         lod.${lodname}.dom_stripesize_cur_kb)
20384         [[ $dom_current == $dom_limit ]] ||
20385                 error "Current DOM stripesize is not maximum"
20386         rm $dom
20387
20388         # set threshold for further tests
20389         do_facet mds1 $LCTL set_param -n \
20390                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20391         echo "DOM threshold is $dom_threshold free space"
20392         local dom_def
20393         local dom_set
20394         # Spoof bfree to exceed threshold
20395         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20396         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20397         for spfree in 40 20 0 15 30 55; do
20398                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20399                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20400                         error "Failed to create $dom file"
20401                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20402                                         lod.${lodname}.dom_stripesize_cur_kb)
20403                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20404                 [[ $dom_def != $dom_current ]] ||
20405                         error "Default stripe size was not changed"
20406                 if [[ $spfree > 0 ]] ; then
20407                         dom_set=$($LFS getstripe -S $dom)
20408                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20409                                 error "DOM component size is still old"
20410                 else
20411                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20412                                 error "DoM component is set with no free space"
20413                 fi
20414                 rm $dom
20415                 dom_current=$dom_def
20416         done
20417 }
20418 run_test 270g "DoM: default DoM stripe size depends on free space"
20419
20420 test_270h() {
20421         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20422                 skip "Need MDS version at least 2.13.53"
20423
20424         local mdtname=${FSNAME}-MDT0000-mdtlov
20425         local dom=$DIR/$tdir/$tfile
20426         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20427
20428         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20429         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20430
20431         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20432         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20433                 error "can't create OST file"
20434         # mirrored file with DOM entry in the second mirror
20435         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20436                 error "can't create mirror with DoM component"
20437
20438         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20439
20440         # DOM component in the middle and has other enries in the same mirror,
20441         # should succeed but lost DoM component
20442         $LFS setstripe --copy=${dom}_1 $dom ||
20443                 error "Can't create file from OST|DOM mirror layout"
20444         # check new file has no DoM layout after all
20445         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20446                 error "File has DoM component while DoM is disabled"
20447 }
20448 run_test 270h "DoM: DoM stripe removal when disabled on server"
20449
20450 test_271a() {
20451         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20452                 skip "Need MDS version at least 2.10.55"
20453
20454         local dom=$DIR/$tdir/dom
20455
20456         mkdir -p $DIR/$tdir
20457
20458         $LFS setstripe -E 1024K -L mdt $dom
20459
20460         lctl set_param -n mdc.*.stats=clear
20461         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20462         cat $dom > /dev/null
20463         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20464         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20465         ls $dom
20466         rm -f $dom
20467 }
20468 run_test 271a "DoM: data is cached for read after write"
20469
20470 test_271b() {
20471         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20472                 skip "Need MDS version at least 2.10.55"
20473
20474         local dom=$DIR/$tdir/dom
20475
20476         mkdir -p $DIR/$tdir
20477
20478         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20479
20480         lctl set_param -n mdc.*.stats=clear
20481         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20482         cancel_lru_locks mdc
20483         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20484         # second stat to check size is cached on client
20485         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20486         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20487         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20488         rm -f $dom
20489 }
20490 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20491
20492 test_271ba() {
20493         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20494                 skip "Need MDS version at least 2.10.55"
20495
20496         local dom=$DIR/$tdir/dom
20497
20498         mkdir -p $DIR/$tdir
20499
20500         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20501
20502         lctl set_param -n mdc.*.stats=clear
20503         lctl set_param -n osc.*.stats=clear
20504         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20505         cancel_lru_locks mdc
20506         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20507         # second stat to check size is cached on client
20508         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20509         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20510         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20511         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20512         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20513         rm -f $dom
20514 }
20515 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20516
20517
20518 get_mdc_stats() {
20519         local mdtidx=$1
20520         local param=$2
20521         local mdt=MDT$(printf %04x $mdtidx)
20522
20523         if [ -z $param ]; then
20524                 lctl get_param -n mdc.*$mdt*.stats
20525         else
20526                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20527         fi
20528 }
20529
20530 test_271c() {
20531         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20532                 skip "Need MDS version at least 2.10.55"
20533
20534         local dom=$DIR/$tdir/dom
20535
20536         mkdir -p $DIR/$tdir
20537
20538         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20539
20540         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20541         local facet=mds$((mdtidx + 1))
20542
20543         cancel_lru_locks mdc
20544         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20545         createmany -o $dom 1000
20546         lctl set_param -n mdc.*.stats=clear
20547         smalliomany -w $dom 1000 200
20548         get_mdc_stats $mdtidx
20549         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20550         # Each file has 1 open, 1 IO enqueues, total 2000
20551         # but now we have also +1 getxattr for security.capability, total 3000
20552         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20553         unlinkmany $dom 1000
20554
20555         cancel_lru_locks mdc
20556         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20557         createmany -o $dom 1000
20558         lctl set_param -n mdc.*.stats=clear
20559         smalliomany -w $dom 1000 200
20560         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20561         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20562         # for OPEN and IO lock.
20563         [ $((enq - enq_2)) -ge 1000 ] ||
20564                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20565         unlinkmany $dom 1000
20566         return 0
20567 }
20568 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20569
20570 cleanup_271def_tests() {
20571         trap 0
20572         rm -f $1
20573 }
20574
20575 test_271d() {
20576         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20577                 skip "Need MDS version at least 2.10.57"
20578
20579         local dom=$DIR/$tdir/dom
20580         local tmp=$TMP/$tfile
20581         trap "cleanup_271def_tests $tmp" EXIT
20582
20583         mkdir -p $DIR/$tdir
20584
20585         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20586
20587         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20588
20589         cancel_lru_locks mdc
20590         dd if=/dev/urandom of=$tmp bs=1000 count=1
20591         dd if=$tmp of=$dom bs=1000 count=1
20592         cancel_lru_locks mdc
20593
20594         cat /etc/hosts >> $tmp
20595         lctl set_param -n mdc.*.stats=clear
20596
20597         # append data to the same file it should update local page
20598         echo "Append to the same page"
20599         cat /etc/hosts >> $dom
20600         local num=$(get_mdc_stats $mdtidx ost_read)
20601         local ra=$(get_mdc_stats $mdtidx req_active)
20602         local rw=$(get_mdc_stats $mdtidx req_waittime)
20603
20604         [ -z $num ] || error "$num READ RPC occured"
20605         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20606         echo "... DONE"
20607
20608         # compare content
20609         cmp $tmp $dom || error "file miscompare"
20610
20611         cancel_lru_locks mdc
20612         lctl set_param -n mdc.*.stats=clear
20613
20614         echo "Open and read file"
20615         cat $dom > /dev/null
20616         local num=$(get_mdc_stats $mdtidx ost_read)
20617         local ra=$(get_mdc_stats $mdtidx req_active)
20618         local rw=$(get_mdc_stats $mdtidx req_waittime)
20619
20620         [ -z $num ] || error "$num READ RPC occured"
20621         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20622         echo "... DONE"
20623
20624         # compare content
20625         cmp $tmp $dom || error "file miscompare"
20626
20627         return 0
20628 }
20629 run_test 271d "DoM: read on open (1K file in reply buffer)"
20630
20631 test_271f() {
20632         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20633                 skip "Need MDS version at least 2.10.57"
20634
20635         local dom=$DIR/$tdir/dom
20636         local tmp=$TMP/$tfile
20637         trap "cleanup_271def_tests $tmp" EXIT
20638
20639         mkdir -p $DIR/$tdir
20640
20641         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20642
20643         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20644
20645         cancel_lru_locks mdc
20646         dd if=/dev/urandom of=$tmp bs=265000 count=1
20647         dd if=$tmp of=$dom bs=265000 count=1
20648         cancel_lru_locks mdc
20649         cat /etc/hosts >> $tmp
20650         lctl set_param -n mdc.*.stats=clear
20651
20652         echo "Append to the same page"
20653         cat /etc/hosts >> $dom
20654         local num=$(get_mdc_stats $mdtidx ost_read)
20655         local ra=$(get_mdc_stats $mdtidx req_active)
20656         local rw=$(get_mdc_stats $mdtidx req_waittime)
20657
20658         [ -z $num ] || error "$num READ RPC occured"
20659         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20660         echo "... DONE"
20661
20662         # compare content
20663         cmp $tmp $dom || error "file miscompare"
20664
20665         cancel_lru_locks mdc
20666         lctl set_param -n mdc.*.stats=clear
20667
20668         echo "Open and read file"
20669         cat $dom > /dev/null
20670         local num=$(get_mdc_stats $mdtidx ost_read)
20671         local ra=$(get_mdc_stats $mdtidx req_active)
20672         local rw=$(get_mdc_stats $mdtidx req_waittime)
20673
20674         [ -z $num ] && num=0
20675         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20676         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20677         echo "... DONE"
20678
20679         # compare content
20680         cmp $tmp $dom || error "file miscompare"
20681
20682         return 0
20683 }
20684 run_test 271f "DoM: read on open (200K file and read tail)"
20685
20686 test_271g() {
20687         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20688                 skip "Skipping due to old client or server version"
20689
20690         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20691         # to get layout
20692         $CHECKSTAT -t file $DIR1/$tfile
20693
20694         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20695         MULTIOP_PID=$!
20696         sleep 1
20697         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20698         $LCTL set_param fail_loc=0x80000314
20699         rm $DIR1/$tfile || error "Unlink fails"
20700         RC=$?
20701         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20702         [ $RC -eq 0 ] || error "Failed write to stale object"
20703 }
20704 run_test 271g "Discard DoM data vs client flush race"
20705
20706 test_272a() {
20707         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20708                 skip "Need MDS version at least 2.11.50"
20709
20710         local dom=$DIR/$tdir/dom
20711         mkdir -p $DIR/$tdir
20712
20713         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20714         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20715                 error "failed to write data into $dom"
20716         local old_md5=$(md5sum $dom)
20717
20718         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20719                 error "failed to migrate to the same DoM component"
20720
20721         local new_md5=$(md5sum $dom)
20722
20723         [ "$old_md5" == "$new_md5" ] ||
20724                 error "md5sum differ: $old_md5, $new_md5"
20725
20726         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20727                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20728 }
20729 run_test 272a "DoM migration: new layout with the same DOM component"
20730
20731 test_272b() {
20732         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20733                 skip "Need MDS version at least 2.11.50"
20734
20735         local dom=$DIR/$tdir/dom
20736         mkdir -p $DIR/$tdir
20737         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20738
20739         local mdtidx=$($LFS getstripe -m $dom)
20740         local mdtname=MDT$(printf %04x $mdtidx)
20741         local facet=mds$((mdtidx + 1))
20742
20743         local mdtfree1=$(do_facet $facet \
20744                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20745         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20746                 error "failed to write data into $dom"
20747         local old_md5=$(md5sum $dom)
20748         cancel_lru_locks mdc
20749         local mdtfree1=$(do_facet $facet \
20750                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20751
20752         $LFS migrate -c2 $dom ||
20753                 error "failed to migrate to the new composite layout"
20754         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20755                 error "MDT stripe was not removed"
20756
20757         cancel_lru_locks mdc
20758         local new_md5=$(md5sum $dom)
20759         [ "$old_md5" == "$new_md5" ] ||
20760                 error "$old_md5 != $new_md5"
20761
20762         # Skip free space checks with ZFS
20763         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20764                 local mdtfree2=$(do_facet $facet \
20765                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20766                 [ $mdtfree2 -gt $mdtfree1 ] ||
20767                         error "MDT space is not freed after migration"
20768         fi
20769         return 0
20770 }
20771 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20772
20773 test_272c() {
20774         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20775                 skip "Need MDS version at least 2.11.50"
20776
20777         local dom=$DIR/$tdir/$tfile
20778         mkdir -p $DIR/$tdir
20779         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20780
20781         local mdtidx=$($LFS getstripe -m $dom)
20782         local mdtname=MDT$(printf %04x $mdtidx)
20783         local facet=mds$((mdtidx + 1))
20784
20785         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20786                 error "failed to write data into $dom"
20787         local old_md5=$(md5sum $dom)
20788         cancel_lru_locks mdc
20789         local mdtfree1=$(do_facet $facet \
20790                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20791
20792         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20793                 error "failed to migrate to the new composite layout"
20794         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20795                 error "MDT stripe was not removed"
20796
20797         cancel_lru_locks mdc
20798         local new_md5=$(md5sum $dom)
20799         [ "$old_md5" == "$new_md5" ] ||
20800                 error "$old_md5 != $new_md5"
20801
20802         # Skip free space checks with ZFS
20803         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20804                 local mdtfree2=$(do_facet $facet \
20805                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20806                 [ $mdtfree2 -gt $mdtfree1 ] ||
20807                         error "MDS space is not freed after migration"
20808         fi
20809         return 0
20810 }
20811 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20812
20813 test_272d() {
20814         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20815                 skip "Need MDS version at least 2.12.55"
20816
20817         local dom=$DIR/$tdir/$tfile
20818         mkdir -p $DIR/$tdir
20819         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20820
20821         local mdtidx=$($LFS getstripe -m $dom)
20822         local mdtname=MDT$(printf %04x $mdtidx)
20823         local facet=mds$((mdtidx + 1))
20824
20825         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20826                 error "failed to write data into $dom"
20827         local old_md5=$(md5sum $dom)
20828         cancel_lru_locks mdc
20829         local mdtfree1=$(do_facet $facet \
20830                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20831
20832         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20833                 error "failed mirroring to the new composite layout"
20834         $LFS mirror resync $dom ||
20835                 error "failed mirror resync"
20836         $LFS mirror split --mirror-id 1 -d $dom ||
20837                 error "failed mirror split"
20838
20839         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20840                 error "MDT stripe was not removed"
20841
20842         cancel_lru_locks mdc
20843         local new_md5=$(md5sum $dom)
20844         [ "$old_md5" == "$new_md5" ] ||
20845                 error "$old_md5 != $new_md5"
20846
20847         # Skip free space checks with ZFS
20848         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20849                 local mdtfree2=$(do_facet $facet \
20850                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20851                 [ $mdtfree2 -gt $mdtfree1 ] ||
20852                         error "MDS space is not freed after DOM mirror deletion"
20853         fi
20854         return 0
20855 }
20856 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20857
20858 test_272e() {
20859         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20860                 skip "Need MDS version at least 2.12.55"
20861
20862         local dom=$DIR/$tdir/$tfile
20863         mkdir -p $DIR/$tdir
20864         $LFS setstripe -c 2 $dom
20865
20866         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20867                 error "failed to write data into $dom"
20868         local old_md5=$(md5sum $dom)
20869         cancel_lru_locks mdc
20870
20871         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20872                 error "failed mirroring to the DOM layout"
20873         $LFS mirror resync $dom ||
20874                 error "failed mirror resync"
20875         $LFS mirror split --mirror-id 1 -d $dom ||
20876                 error "failed mirror split"
20877
20878         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20879                 error "MDT stripe was not removed"
20880
20881         cancel_lru_locks mdc
20882         local new_md5=$(md5sum $dom)
20883         [ "$old_md5" == "$new_md5" ] ||
20884                 error "$old_md5 != $new_md5"
20885
20886         return 0
20887 }
20888 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20889
20890 test_272f() {
20891         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20892                 skip "Need MDS version at least 2.12.55"
20893
20894         local dom=$DIR/$tdir/$tfile
20895         mkdir -p $DIR/$tdir
20896         $LFS setstripe -c 2 $dom
20897
20898         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20899                 error "failed to write data into $dom"
20900         local old_md5=$(md5sum $dom)
20901         cancel_lru_locks mdc
20902
20903         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20904                 error "failed migrating to the DOM file"
20905
20906         cancel_lru_locks mdc
20907         local new_md5=$(md5sum $dom)
20908         [ "$old_md5" != "$new_md5" ] &&
20909                 error "$old_md5 != $new_md5"
20910
20911         return 0
20912 }
20913 run_test 272f "DoM migration: OST-striped file to DOM file"
20914
20915 test_273a() {
20916         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20917                 skip "Need MDS version at least 2.11.50"
20918
20919         # Layout swap cannot be done if either file has DOM component,
20920         # this will never be supported, migration should be used instead
20921
20922         local dom=$DIR/$tdir/$tfile
20923         mkdir -p $DIR/$tdir
20924
20925         $LFS setstripe -c2 ${dom}_plain
20926         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20927         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20928                 error "can swap layout with DoM component"
20929         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20930                 error "can swap layout with DoM component"
20931
20932         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20933         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20934                 error "can swap layout with DoM component"
20935         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20936                 error "can swap layout with DoM component"
20937         return 0
20938 }
20939 run_test 273a "DoM: layout swapping should fail with DOM"
20940
20941 test_275() {
20942         remote_ost_nodsh && skip "remote OST with nodsh"
20943         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20944                 skip "Need OST version >= 2.10.57"
20945
20946         local file=$DIR/$tfile
20947         local oss
20948
20949         oss=$(comma_list $(osts_nodes))
20950
20951         dd if=/dev/urandom of=$file bs=1M count=2 ||
20952                 error "failed to create a file"
20953         cancel_lru_locks osc
20954
20955         #lock 1
20956         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20957                 error "failed to read a file"
20958
20959 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20960         $LCTL set_param fail_loc=0x8000031f
20961
20962         cancel_lru_locks osc &
20963         sleep 1
20964
20965 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20966         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20967         #IO takes another lock, but matches the PENDING one
20968         #and places it to the IO RPC
20969         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20970                 error "failed to read a file with PENDING lock"
20971 }
20972 run_test 275 "Read on a canceled duplicate lock"
20973
20974 test_276() {
20975         remote_ost_nodsh && skip "remote OST with nodsh"
20976         local pid
20977
20978         do_facet ost1 "(while true; do \
20979                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20980                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20981         pid=$!
20982
20983         for LOOP in $(seq 20); do
20984                 stop ost1
20985                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20986         done
20987         kill -9 $pid
20988         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20989                 rm $TMP/sanity_276_pid"
20990 }
20991 run_test 276 "Race between mount and obd_statfs"
20992
20993 test_277() {
20994         $LCTL set_param ldlm.namespaces.*.lru_size=0
20995         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20996         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20997                         grep ^used_mb | awk '{print $2}')
20998         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20999         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21000                 oflag=direct conv=notrunc
21001         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21002                         grep ^used_mb | awk '{print $2}')
21003         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21004 }
21005 run_test 277 "Direct IO shall drop page cache"
21006
21007 test_278() {
21008         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21009         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21010         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21011                 skip "needs the same host for mdt1 mdt2" && return
21012
21013         local pid1
21014         local pid2
21015
21016 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21017         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21018         stop mds2 &
21019         pid2=$!
21020
21021         stop mds1
21022
21023         echo "Starting MDTs"
21024         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21025         wait $pid2
21026 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21027 #will return NULL
21028         do_facet mds2 $LCTL set_param fail_loc=0
21029
21030         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21031         wait_recovery_complete mds2
21032 }
21033 run_test 278 "Race starting MDS between MDTs stop/start"
21034
21035 test_280() {
21036         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21037                 skip "Need MGS version at least 2.13.52"
21038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21039         combined_mgs_mds || skip "needs combined MGS/MDT"
21040
21041         umount_client $MOUNT
21042 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21043         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21044
21045         mount_client $MOUNT &
21046         sleep 1
21047         stop mgs || error "stop mgs failed"
21048         #for a race mgs would crash
21049         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21050         mount_client $MOUNT || error "mount client failed"
21051 }
21052 run_test 280 "Race between MGS umount and client llog processing"
21053
21054 cleanup_test_300() {
21055         trap 0
21056         umask $SAVE_UMASK
21057 }
21058 test_striped_dir() {
21059         local mdt_index=$1
21060         local stripe_count
21061         local stripe_index
21062
21063         mkdir -p $DIR/$tdir
21064
21065         SAVE_UMASK=$(umask)
21066         trap cleanup_test_300 RETURN EXIT
21067
21068         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21069                                                 $DIR/$tdir/striped_dir ||
21070                 error "set striped dir error"
21071
21072         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21073         [ "$mode" = "755" ] || error "expect 755 got $mode"
21074
21075         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21076                 error "getdirstripe failed"
21077         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21078         if [ "$stripe_count" != "2" ]; then
21079                 error "1:stripe_count is $stripe_count, expect 2"
21080         fi
21081         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21082         if [ "$stripe_count" != "2" ]; then
21083                 error "2:stripe_count is $stripe_count, expect 2"
21084         fi
21085
21086         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21087         if [ "$stripe_index" != "$mdt_index" ]; then
21088                 error "stripe_index is $stripe_index, expect $mdt_index"
21089         fi
21090
21091         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21092                 error "nlink error after create striped dir"
21093
21094         mkdir $DIR/$tdir/striped_dir/a
21095         mkdir $DIR/$tdir/striped_dir/b
21096
21097         stat $DIR/$tdir/striped_dir/a ||
21098                 error "create dir under striped dir failed"
21099         stat $DIR/$tdir/striped_dir/b ||
21100                 error "create dir under striped dir failed"
21101
21102         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21103                 error "nlink error after mkdir"
21104
21105         rmdir $DIR/$tdir/striped_dir/a
21106         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21107                 error "nlink error after rmdir"
21108
21109         rmdir $DIR/$tdir/striped_dir/b
21110         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21111                 error "nlink error after rmdir"
21112
21113         chattr +i $DIR/$tdir/striped_dir
21114         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21115                 error "immutable flags not working under striped dir!"
21116         chattr -i $DIR/$tdir/striped_dir
21117
21118         rmdir $DIR/$tdir/striped_dir ||
21119                 error "rmdir striped dir error"
21120
21121         cleanup_test_300
21122
21123         true
21124 }
21125
21126 test_300a() {
21127         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21128                 skip "skipped for lustre < 2.7.0"
21129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21130         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21131
21132         test_striped_dir 0 || error "failed on striped dir on MDT0"
21133         test_striped_dir 1 || error "failed on striped dir on MDT0"
21134 }
21135 run_test 300a "basic striped dir sanity test"
21136
21137 test_300b() {
21138         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21139                 skip "skipped for lustre < 2.7.0"
21140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21142
21143         local i
21144         local mtime1
21145         local mtime2
21146         local mtime3
21147
21148         test_mkdir $DIR/$tdir || error "mkdir fail"
21149         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21150                 error "set striped dir error"
21151         for i in {0..9}; do
21152                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21153                 sleep 1
21154                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21155                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21156                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21157                 sleep 1
21158                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21159                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21160                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21161         done
21162         true
21163 }
21164 run_test 300b "check ctime/mtime for striped dir"
21165
21166 test_300c() {
21167         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21168                 skip "skipped for lustre < 2.7.0"
21169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21171
21172         local file_count
21173
21174         mkdir -p $DIR/$tdir
21175         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21176                 error "set striped dir error"
21177
21178         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21179                 error "chown striped dir failed"
21180
21181         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21182                 error "create 5k files failed"
21183
21184         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21185
21186         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21187
21188         rm -rf $DIR/$tdir
21189 }
21190 run_test 300c "chown && check ls under striped directory"
21191
21192 test_300d() {
21193         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21194                 skip "skipped for lustre < 2.7.0"
21195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21197
21198         local stripe_count
21199         local file
21200
21201         mkdir -p $DIR/$tdir
21202         $LFS setstripe -c 2 $DIR/$tdir
21203
21204         #local striped directory
21205         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21206                 error "set striped dir error"
21207         #look at the directories for debug purposes
21208         ls -l $DIR/$tdir
21209         $LFS getdirstripe $DIR/$tdir
21210         ls -l $DIR/$tdir/striped_dir
21211         $LFS getdirstripe $DIR/$tdir/striped_dir
21212         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21213                 error "create 10 files failed"
21214
21215         #remote striped directory
21216         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21217                 error "set striped dir error"
21218         #look at the directories for debug purposes
21219         ls -l $DIR/$tdir
21220         $LFS getdirstripe $DIR/$tdir
21221         ls -l $DIR/$tdir/remote_striped_dir
21222         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21223         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21224                 error "create 10 files failed"
21225
21226         for file in $(find $DIR/$tdir); do
21227                 stripe_count=$($LFS getstripe -c $file)
21228                 [ $stripe_count -eq 2 ] ||
21229                         error "wrong stripe $stripe_count for $file"
21230         done
21231
21232         rm -rf $DIR/$tdir
21233 }
21234 run_test 300d "check default stripe under striped directory"
21235
21236 test_300e() {
21237         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21238                 skip "Need MDS version at least 2.7.55"
21239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21241
21242         local stripe_count
21243         local file
21244
21245         mkdir -p $DIR/$tdir
21246
21247         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21248                 error "set striped dir error"
21249
21250         touch $DIR/$tdir/striped_dir/a
21251         touch $DIR/$tdir/striped_dir/b
21252         touch $DIR/$tdir/striped_dir/c
21253
21254         mkdir $DIR/$tdir/striped_dir/dir_a
21255         mkdir $DIR/$tdir/striped_dir/dir_b
21256         mkdir $DIR/$tdir/striped_dir/dir_c
21257
21258         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21259                 error "set striped adir under striped dir error"
21260
21261         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21262                 error "set striped bdir under striped dir error"
21263
21264         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21265                 error "set striped cdir under striped dir error"
21266
21267         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21268                 error "rename dir under striped dir fails"
21269
21270         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21271                 error "rename dir under different stripes fails"
21272
21273         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21274                 error "rename file under striped dir should succeed"
21275
21276         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21277                 error "rename dir under striped dir should succeed"
21278
21279         rm -rf $DIR/$tdir
21280 }
21281 run_test 300e "check rename under striped directory"
21282
21283 test_300f() {
21284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21286         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21287                 skip "Need MDS version at least 2.7.55"
21288
21289         local stripe_count
21290         local file
21291
21292         rm -rf $DIR/$tdir
21293         mkdir -p $DIR/$tdir
21294
21295         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21296                 error "set striped dir error"
21297
21298         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21299                 error "set striped dir error"
21300
21301         touch $DIR/$tdir/striped_dir/a
21302         mkdir $DIR/$tdir/striped_dir/dir_a
21303         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21304                 error "create striped dir under striped dir fails"
21305
21306         touch $DIR/$tdir/striped_dir1/b
21307         mkdir $DIR/$tdir/striped_dir1/dir_b
21308         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21309                 error "create striped dir under striped dir fails"
21310
21311         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21312                 error "rename dir under different striped dir should fail"
21313
21314         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21315                 error "rename striped dir under diff striped dir should fail"
21316
21317         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21318                 error "rename file under diff striped dirs fails"
21319
21320         rm -rf $DIR/$tdir
21321 }
21322 run_test 300f "check rename cross striped directory"
21323
21324 test_300_check_default_striped_dir()
21325 {
21326         local dirname=$1
21327         local default_count=$2
21328         local default_index=$3
21329         local stripe_count
21330         local stripe_index
21331         local dir_stripe_index
21332         local dir
21333
21334         echo "checking $dirname $default_count $default_index"
21335         $LFS setdirstripe -D -c $default_count -i $default_index \
21336                                 -t all_char $DIR/$tdir/$dirname ||
21337                 error "set default stripe on striped dir error"
21338         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21339         [ $stripe_count -eq $default_count ] ||
21340                 error "expect $default_count get $stripe_count for $dirname"
21341
21342         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21343         [ $stripe_index -eq $default_index ] ||
21344                 error "expect $default_index get $stripe_index for $dirname"
21345
21346         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21347                                                 error "create dirs failed"
21348
21349         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21350         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21351         for dir in $(find $DIR/$tdir/$dirname/*); do
21352                 stripe_count=$($LFS getdirstripe -c $dir)
21353                 [ $stripe_count -eq $default_count ] ||
21354                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21355                 error "stripe count $default_count != $stripe_count for $dir"
21356
21357                 stripe_index=$($LFS getdirstripe -i $dir)
21358                 [ $default_index -eq -1 ] ||
21359                         [ $stripe_index -eq $default_index ] ||
21360                         error "$stripe_index != $default_index for $dir"
21361
21362                 #check default stripe
21363                 stripe_count=$($LFS getdirstripe -D -c $dir)
21364                 [ $stripe_count -eq $default_count ] ||
21365                 error "default count $default_count != $stripe_count for $dir"
21366
21367                 stripe_index=$($LFS getdirstripe -D -i $dir)
21368                 [ $stripe_index -eq $default_index ] ||
21369                 error "default index $default_index != $stripe_index for $dir"
21370         done
21371         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21372 }
21373
21374 test_300g() {
21375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21376         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21377                 skip "Need MDS version at least 2.7.55"
21378
21379         local dir
21380         local stripe_count
21381         local stripe_index
21382
21383         mkdir $DIR/$tdir
21384         mkdir $DIR/$tdir/normal_dir
21385
21386         #Checking when client cache stripe index
21387         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21388         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21389                 error "create striped_dir failed"
21390
21391         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21392                 error "create dir0 fails"
21393         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21394         [ $stripe_index -eq 0 ] ||
21395                 error "dir0 expect index 0 got $stripe_index"
21396
21397         mkdir $DIR/$tdir/striped_dir/dir1 ||
21398                 error "create dir1 fails"
21399         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21400         [ $stripe_index -eq 1 ] ||
21401                 error "dir1 expect index 1 got $stripe_index"
21402
21403         #check default stripe count/stripe index
21404         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21405         test_300_check_default_striped_dir normal_dir 1 0
21406         test_300_check_default_striped_dir normal_dir 2 1
21407         test_300_check_default_striped_dir normal_dir 2 -1
21408
21409         #delete default stripe information
21410         echo "delete default stripeEA"
21411         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21412                 error "set default stripe on striped dir error"
21413
21414         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21415         for dir in $(find $DIR/$tdir/normal_dir/*); do
21416                 stripe_count=$($LFS getdirstripe -c $dir)
21417                 [ $stripe_count -eq 0 ] ||
21418                         error "expect 1 get $stripe_count for $dir"
21419                 stripe_index=$($LFS getdirstripe -i $dir)
21420                 [ $stripe_index -eq 0 ] ||
21421                         error "expect 0 get $stripe_index for $dir"
21422         done
21423 }
21424 run_test 300g "check default striped directory for normal directory"
21425
21426 test_300h() {
21427         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21428         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21429                 skip "Need MDS version at least 2.7.55"
21430
21431         local dir
21432         local stripe_count
21433
21434         mkdir $DIR/$tdir
21435         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21436                 error "set striped dir error"
21437
21438         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21439         test_300_check_default_striped_dir striped_dir 1 0
21440         test_300_check_default_striped_dir striped_dir 2 1
21441         test_300_check_default_striped_dir striped_dir 2 -1
21442
21443         #delete default stripe information
21444         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21445                 error "set default stripe on striped dir error"
21446
21447         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21448         for dir in $(find $DIR/$tdir/striped_dir/*); do
21449                 stripe_count=$($LFS getdirstripe -c $dir)
21450                 [ $stripe_count -eq 0 ] ||
21451                         error "expect 1 get $stripe_count for $dir"
21452         done
21453 }
21454 run_test 300h "check default striped directory for striped directory"
21455
21456 test_300i() {
21457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21459         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21460                 skip "Need MDS version at least 2.7.55"
21461
21462         local stripe_count
21463         local file
21464
21465         mkdir $DIR/$tdir
21466
21467         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21468                 error "set striped dir error"
21469
21470         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21471                 error "create files under striped dir failed"
21472
21473         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21474                 error "set striped hashdir error"
21475
21476         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21477                 error "create dir0 under hash dir failed"
21478         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21479                 error "create dir1 under hash dir failed"
21480
21481         # unfortunately, we need to umount to clear dir layout cache for now
21482         # once we fully implement dir layout, we can drop this
21483         umount_client $MOUNT || error "umount failed"
21484         mount_client $MOUNT || error "mount failed"
21485
21486         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21487         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21488         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21489
21490         #set the stripe to be unknown hash type
21491         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21492         $LCTL set_param fail_loc=0x1901
21493         for ((i = 0; i < 10; i++)); do
21494                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21495                         error "stat f-$i failed"
21496                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21497         done
21498
21499         touch $DIR/$tdir/striped_dir/f0 &&
21500                 error "create under striped dir with unknown hash should fail"
21501
21502         $LCTL set_param fail_loc=0
21503
21504         umount_client $MOUNT || error "umount failed"
21505         mount_client $MOUNT || error "mount failed"
21506
21507         return 0
21508 }
21509 run_test 300i "client handle unknown hash type striped directory"
21510
21511 test_300j() {
21512         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21514         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21515                 skip "Need MDS version at least 2.7.55"
21516
21517         local stripe_count
21518         local file
21519
21520         mkdir $DIR/$tdir
21521
21522         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21523         $LCTL set_param fail_loc=0x1702
21524         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21525                 error "set striped dir error"
21526
21527         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21528                 error "create files under striped dir failed"
21529
21530         $LCTL set_param fail_loc=0
21531
21532         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21533
21534         return 0
21535 }
21536 run_test 300j "test large update record"
21537
21538 test_300k() {
21539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21541         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21542                 skip "Need MDS version at least 2.7.55"
21543
21544         # this test needs a huge transaction
21545         local kb
21546         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21547              osd*.$FSNAME-MDT0000.kbytestotal")
21548         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21549
21550         local stripe_count
21551         local file
21552
21553         mkdir $DIR/$tdir
21554
21555         #define OBD_FAIL_LARGE_STRIPE   0x1703
21556         $LCTL set_param fail_loc=0x1703
21557         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21558                 error "set striped dir error"
21559         $LCTL set_param fail_loc=0
21560
21561         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21562                 error "getstripeddir fails"
21563         rm -rf $DIR/$tdir/striped_dir ||
21564                 error "unlink striped dir fails"
21565
21566         return 0
21567 }
21568 run_test 300k "test large striped directory"
21569
21570 test_300l() {
21571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21573         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21574                 skip "Need MDS version at least 2.7.55"
21575
21576         local stripe_index
21577
21578         test_mkdir -p $DIR/$tdir/striped_dir
21579         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21580                         error "chown $RUNAS_ID failed"
21581         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21582                 error "set default striped dir failed"
21583
21584         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21585         $LCTL set_param fail_loc=0x80000158
21586         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21587
21588         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21589         [ $stripe_index -eq 1 ] ||
21590                 error "expect 1 get $stripe_index for $dir"
21591 }
21592 run_test 300l "non-root user to create dir under striped dir with stale layout"
21593
21594 test_300m() {
21595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21596         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21597         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21598                 skip "Need MDS version at least 2.7.55"
21599
21600         mkdir -p $DIR/$tdir/striped_dir
21601         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21602                 error "set default stripes dir error"
21603
21604         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21605
21606         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21607         [ $stripe_count -eq 0 ] ||
21608                         error "expect 0 get $stripe_count for a"
21609
21610         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21611                 error "set default stripes dir error"
21612
21613         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21614
21615         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21616         [ $stripe_count -eq 0 ] ||
21617                         error "expect 0 get $stripe_count for b"
21618
21619         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21620                 error "set default stripes dir error"
21621
21622         mkdir $DIR/$tdir/striped_dir/c &&
21623                 error "default stripe_index is invalid, mkdir c should fails"
21624
21625         rm -rf $DIR/$tdir || error "rmdir fails"
21626 }
21627 run_test 300m "setstriped directory on single MDT FS"
21628
21629 cleanup_300n() {
21630         local list=$(comma_list $(mdts_nodes))
21631
21632         trap 0
21633         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21634 }
21635
21636 test_300n() {
21637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21639         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21640                 skip "Need MDS version at least 2.7.55"
21641         remote_mds_nodsh && skip "remote MDS with nodsh"
21642
21643         local stripe_index
21644         local list=$(comma_list $(mdts_nodes))
21645
21646         trap cleanup_300n RETURN EXIT
21647         mkdir -p $DIR/$tdir
21648         chmod 777 $DIR/$tdir
21649         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21650                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21651                 error "create striped dir succeeds with gid=0"
21652
21653         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21654         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21655                 error "create striped dir fails with gid=-1"
21656
21657         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21658         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21659                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21660                 error "set default striped dir succeeds with gid=0"
21661
21662
21663         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21664         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21665                 error "set default striped dir fails with gid=-1"
21666
21667
21668         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21669         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21670                                         error "create test_dir fails"
21671         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21672                                         error "create test_dir1 fails"
21673         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21674                                         error "create test_dir2 fails"
21675         cleanup_300n
21676 }
21677 run_test 300n "non-root user to create dir under striped dir with default EA"
21678
21679 test_300o() {
21680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21681         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21682         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21683                 skip "Need MDS version at least 2.7.55"
21684
21685         local numfree1
21686         local numfree2
21687
21688         mkdir -p $DIR/$tdir
21689
21690         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21691         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21692         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21693                 skip "not enough free inodes $numfree1 $numfree2"
21694         fi
21695
21696         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21697         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21698         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21699                 skip "not enough free space $numfree1 $numfree2"
21700         fi
21701
21702         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21703                 error "setdirstripe fails"
21704
21705         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21706                 error "create dirs fails"
21707
21708         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21709         ls $DIR/$tdir/striped_dir > /dev/null ||
21710                 error "ls striped dir fails"
21711         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21712                 error "unlink big striped dir fails"
21713 }
21714 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21715
21716 test_300p() {
21717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21719         remote_mds_nodsh && skip "remote MDS with nodsh"
21720
21721         mkdir -p $DIR/$tdir
21722
21723         #define OBD_FAIL_OUT_ENOSPC     0x1704
21724         do_facet mds2 lctl set_param fail_loc=0x80001704
21725         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21726                  && error "create striped directory should fail"
21727
21728         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21729
21730         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21731         true
21732 }
21733 run_test 300p "create striped directory without space"
21734
21735 test_300q() {
21736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21737         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21738
21739         local fd=$(free_fd)
21740         local cmd="exec $fd<$tdir"
21741         cd $DIR
21742         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21743         eval $cmd
21744         cmd="exec $fd<&-"
21745         trap "eval $cmd" EXIT
21746         cd $tdir || error "cd $tdir fails"
21747         rmdir  ../$tdir || error "rmdir $tdir fails"
21748         mkdir local_dir && error "create dir succeeds"
21749         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21750         eval $cmd
21751         return 0
21752 }
21753 run_test 300q "create remote directory under orphan directory"
21754
21755 test_300r() {
21756         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21757                 skip "Need MDS version at least 2.7.55" && return
21758         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21759
21760         mkdir $DIR/$tdir
21761
21762         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21763                 error "set striped dir error"
21764
21765         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21766                 error "getstripeddir fails"
21767
21768         local stripe_count
21769         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21770                       awk '/lmv_stripe_count:/ { print $2 }')
21771
21772         [ $MDSCOUNT -ne $stripe_count ] &&
21773                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21774
21775         rm -rf $DIR/$tdir/striped_dir ||
21776                 error "unlink striped dir fails"
21777 }
21778 run_test 300r "test -1 striped directory"
21779
21780 test_300s_helper() {
21781         local count=$1
21782
21783         local stripe_dir=$DIR/$tdir/striped_dir.$count
21784
21785         $LFS mkdir -c $count $stripe_dir ||
21786                 error "lfs mkdir -c error"
21787
21788         $LFS getdirstripe $stripe_dir ||
21789                 error "lfs getdirstripe fails"
21790
21791         local stripe_count
21792         stripe_count=$($LFS getdirstripe $stripe_dir |
21793                       awk '/lmv_stripe_count:/ { print $2 }')
21794
21795         [ $count -ne $stripe_count ] &&
21796                 error_noexit "bad stripe count $stripe_count expected $count"
21797
21798         local dupe_stripes
21799         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21800                 awk '/0x/ {count[$1] += 1}; END {
21801                         for (idx in count) {
21802                                 if (count[idx]>1) {
21803                                         print "index " idx " count " count[idx]
21804                                 }
21805                         }
21806                 }')
21807
21808         if [[ -n "$dupe_stripes" ]] ; then
21809                 lfs getdirstripe $stripe_dir
21810                 error_noexit "Dupe MDT above: $dupe_stripes "
21811         fi
21812
21813         rm -rf $stripe_dir ||
21814                 error_noexit "unlink $stripe_dir fails"
21815 }
21816
21817 test_300s() {
21818         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21819                 skip "Need MDS version at least 2.7.55" && return
21820         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21821
21822         mkdir $DIR/$tdir
21823         for count in $(seq 2 $MDSCOUNT); do
21824                 test_300s_helper $count
21825         done
21826 }
21827 run_test 300s "test lfs mkdir -c without -i"
21828
21829
21830 prepare_remote_file() {
21831         mkdir $DIR/$tdir/src_dir ||
21832                 error "create remote source failed"
21833
21834         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21835                  error "cp to remote source failed"
21836         touch $DIR/$tdir/src_dir/a
21837
21838         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21839                 error "create remote target dir failed"
21840
21841         touch $DIR/$tdir/tgt_dir/b
21842
21843         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21844                 error "rename dir cross MDT failed!"
21845
21846         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21847                 error "src_child still exists after rename"
21848
21849         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21850                 error "missing file(a) after rename"
21851
21852         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21853                 error "diff after rename"
21854 }
21855
21856 test_310a() {
21857         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21859
21860         local remote_file=$DIR/$tdir/tgt_dir/b
21861
21862         mkdir -p $DIR/$tdir
21863
21864         prepare_remote_file || error "prepare remote file failed"
21865
21866         #open-unlink file
21867         $OPENUNLINK $remote_file $remote_file ||
21868                 error "openunlink $remote_file failed"
21869         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21870 }
21871 run_test 310a "open unlink remote file"
21872
21873 test_310b() {
21874         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21876
21877         local remote_file=$DIR/$tdir/tgt_dir/b
21878
21879         mkdir -p $DIR/$tdir
21880
21881         prepare_remote_file || error "prepare remote file failed"
21882
21883         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21884         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21885         $CHECKSTAT -t file $remote_file || error "check file failed"
21886 }
21887 run_test 310b "unlink remote file with multiple links while open"
21888
21889 test_310c() {
21890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21891         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21892
21893         local remote_file=$DIR/$tdir/tgt_dir/b
21894
21895         mkdir -p $DIR/$tdir
21896
21897         prepare_remote_file || error "prepare remote file failed"
21898
21899         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21900         multiop_bg_pause $remote_file O_uc ||
21901                         error "mulitop failed for remote file"
21902         MULTIPID=$!
21903         $MULTIOP $DIR/$tfile Ouc
21904         kill -USR1 $MULTIPID
21905         wait $MULTIPID
21906 }
21907 run_test 310c "open-unlink remote file with multiple links"
21908
21909 #LU-4825
21910 test_311() {
21911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21912         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21913         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21914                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21915         remote_mds_nodsh && skip "remote MDS with nodsh"
21916
21917         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21918         local mdts=$(comma_list $(mdts_nodes))
21919
21920         mkdir -p $DIR/$tdir
21921         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21922         createmany -o $DIR/$tdir/$tfile. 1000
21923
21924         # statfs data is not real time, let's just calculate it
21925         old_iused=$((old_iused + 1000))
21926
21927         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21928                         osp.*OST0000*MDT0000.create_count")
21929         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21930                                 osp.*OST0000*MDT0000.max_create_count")
21931         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21932
21933         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21934         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21935         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21936
21937         unlinkmany $DIR/$tdir/$tfile. 1000
21938
21939         do_nodes $mdts "$LCTL set_param -n \
21940                         osp.*OST0000*.max_create_count=$max_count"
21941         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21942                 do_nodes $mdts "$LCTL set_param -n \
21943                                 osp.*OST0000*.create_count=$count"
21944         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21945                         grep "=0" && error "create_count is zero"
21946
21947         local new_iused
21948         for i in $(seq 120); do
21949                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21950                 # system may be too busy to destroy all objs in time, use
21951                 # a somewhat small value to not fail autotest
21952                 [ $((old_iused - new_iused)) -gt 400 ] && break
21953                 sleep 1
21954         done
21955
21956         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21957         [ $((old_iused - new_iused)) -gt 400 ] ||
21958                 error "objs not destroyed after unlink"
21959 }
21960 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21961
21962 zfs_oid_to_objid()
21963 {
21964         local ost=$1
21965         local objid=$2
21966
21967         local vdevdir=$(dirname $(facet_vdevice $ost))
21968         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21969         local zfs_zapid=$(do_facet $ost $cmd |
21970                           grep -w "/O/0/d$((objid%32))" -C 5 |
21971                           awk '/Object/{getline; print $1}')
21972         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21973                           awk "/$objid = /"'{printf $3}')
21974
21975         echo $zfs_objid
21976 }
21977
21978 zfs_object_blksz() {
21979         local ost=$1
21980         local objid=$2
21981
21982         local vdevdir=$(dirname $(facet_vdevice $ost))
21983         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21984         local blksz=$(do_facet $ost $cmd $objid |
21985                       awk '/dblk/{getline; printf $4}')
21986
21987         case "${blksz: -1}" in
21988                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21989                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21990                 *) ;;
21991         esac
21992
21993         echo $blksz
21994 }
21995
21996 test_312() { # LU-4856
21997         remote_ost_nodsh && skip "remote OST with nodsh"
21998         [ "$ost1_FSTYPE" = "zfs" ] ||
21999                 skip_env "the test only applies to zfs"
22000
22001         local max_blksz=$(do_facet ost1 \
22002                           $ZFS get -p recordsize $(facet_device ost1) |
22003                           awk '!/VALUE/{print $3}')
22004
22005         # to make life a little bit easier
22006         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22007         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22008
22009         local tf=$DIR/$tdir/$tfile
22010         touch $tf
22011         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22012
22013         # Get ZFS object id
22014         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22015         # block size change by sequential overwrite
22016         local bs
22017
22018         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22019                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22020
22021                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22022                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22023         done
22024         rm -f $tf
22025
22026         # block size change by sequential append write
22027         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22028         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22029         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22030         local count
22031
22032         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22033                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22034                         oflag=sync conv=notrunc
22035
22036                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22037                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22038                         error "blksz error, actual $blksz, " \
22039                                 "expected: 2 * $count * $PAGE_SIZE"
22040         done
22041         rm -f $tf
22042
22043         # random write
22044         touch $tf
22045         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22046         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22047
22048         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22049         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22050         [ $blksz -eq $PAGE_SIZE ] ||
22051                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22052
22053         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22054         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22055         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22056
22057         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22058         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22059         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22060 }
22061 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22062
22063 test_313() {
22064         remote_ost_nodsh && skip "remote OST with nodsh"
22065
22066         local file=$DIR/$tfile
22067
22068         rm -f $file
22069         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22070
22071         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22072         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22073         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22074                 error "write should failed"
22075         do_facet ost1 "$LCTL set_param fail_loc=0"
22076         rm -f $file
22077 }
22078 run_test 313 "io should fail after last_rcvd update fail"
22079
22080 test_314() {
22081         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22082
22083         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22084         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22085         rm -f $DIR/$tfile
22086         wait_delete_completed
22087         do_facet ost1 "$LCTL set_param fail_loc=0"
22088 }
22089 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22090
22091 test_315() { # LU-618
22092         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22093
22094         local file=$DIR/$tfile
22095         rm -f $file
22096
22097         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22098                 error "multiop file write failed"
22099         $MULTIOP $file oO_RDONLY:r4063232_c &
22100         PID=$!
22101
22102         sleep 2
22103
22104         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22105         kill -USR1 $PID
22106
22107         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22108         rm -f $file
22109 }
22110 run_test 315 "read should be accounted"
22111
22112 test_316() {
22113         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22114         large_xattr_enabled || skip_env "ea_inode feature disabled"
22115
22116         rm -rf $DIR/$tdir/d
22117         mkdir -p $DIR/$tdir/d
22118         chown nobody $DIR/$tdir/d
22119         touch $DIR/$tdir/d/file
22120
22121         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22122 }
22123 run_test 316 "lfs mv"
22124
22125 test_317() {
22126         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22127                 skip "Need MDS version at least 2.11.53"
22128         if [ "$ost1_FSTYPE" == "zfs" ]; then
22129                 skip "LU-10370: no implementation for ZFS"
22130         fi
22131
22132         local trunc_sz
22133         local grant_blk_size
22134
22135         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22136                         awk '/grant_block_size:/ { print $2; exit; }')
22137         #
22138         # Create File of size 5M. Truncate it to below size's and verify
22139         # blocks count.
22140         #
22141         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22142                 error "Create file $DIR/$tfile failed"
22143         stack_trap "rm -f $DIR/$tfile" EXIT
22144
22145         for trunc_sz in 2097152 4097 4000 509 0; do
22146                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22147                         error "truncate $tfile to $trunc_sz failed"
22148                 local sz=$(stat --format=%s $DIR/$tfile)
22149                 local blk=$(stat --format=%b $DIR/$tfile)
22150                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22151                                      grant_blk_size) * 8))
22152
22153                 if [[ $blk -ne $trunc_blk ]]; then
22154                         $(which stat) $DIR/$tfile
22155                         error "Expected Block $trunc_blk got $blk for $tfile"
22156                 fi
22157
22158                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22159                         error "Expected Size $trunc_sz got $sz for $tfile"
22160         done
22161
22162         #
22163         # sparse file test
22164         # Create file with a hole and write actual two blocks. Block count
22165         # must be 16.
22166         #
22167         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22168                 conv=fsync || error "Create file : $DIR/$tfile"
22169
22170         # Calculate the final truncate size.
22171         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22172
22173         #
22174         # truncate to size $trunc_sz bytes. Strip the last block
22175         # The block count must drop to 8
22176         #
22177         $TRUNCATE $DIR/$tfile $trunc_sz ||
22178                 error "truncate $tfile to $trunc_sz failed"
22179
22180         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22181         sz=$(stat --format=%s $DIR/$tfile)
22182         blk=$(stat --format=%b $DIR/$tfile)
22183
22184         if [[ $blk -ne $trunc_bsz ]]; then
22185                 $(which stat) $DIR/$tfile
22186                 error "Expected Block $trunc_bsz got $blk for $tfile"
22187         fi
22188
22189         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22190                 error "Expected Size $trunc_sz got $sz for $tfile"
22191 }
22192 run_test 317 "Verify blocks get correctly update after truncate"
22193
22194 test_318() {
22195         local old_max_active=$($LCTL get_param -n \
22196                             llite.*.max_read_ahead_async_active 2>/dev/null)
22197
22198         $LCTL set_param llite.*.max_read_ahead_async_active=256
22199         local max_active=$($LCTL get_param -n \
22200                            llite.*.max_read_ahead_async_active 2>/dev/null)
22201         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22202
22203         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22204                 error "set max_read_ahead_async_active should succeed"
22205
22206         $LCTL set_param llite.*.max_read_ahead_async_active=512
22207         max_active=$($LCTL get_param -n \
22208                      llite.*.max_read_ahead_async_active 2>/dev/null)
22209         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22210
22211         # restore @max_active
22212         [ $old_max_active -ne 0 ] && $LCTL set_param \
22213                 llite.*.max_read_ahead_async_active=$old_max_active
22214
22215         local old_threshold=$($LCTL get_param -n \
22216                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22217         local max_per_file_mb=$($LCTL get_param -n \
22218                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22219
22220         local invalid=$(($max_per_file_mb + 1))
22221         $LCTL set_param \
22222                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22223                         && error "set $invalid should fail"
22224
22225         local valid=$(($invalid - 1))
22226         $LCTL set_param \
22227                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22228                         error "set $valid should succeed"
22229         local threshold=$($LCTL get_param -n \
22230                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22231         [ $threshold -eq $valid ] || error \
22232                 "expect threshold $valid got $threshold"
22233         $LCTL set_param \
22234                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22235 }
22236 run_test 318 "Verify async readahead tunables"
22237
22238 test_319() {
22239         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22240
22241         local before=$(date +%s)
22242         local evict
22243         local mdir=$DIR/$tdir
22244         local file=$mdir/xxx
22245
22246         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22247         touch $file
22248
22249 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22250         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22251         $LFS mv -m1 $file &
22252
22253         sleep 1
22254         dd if=$file of=/dev/null
22255         wait
22256         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22257           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22258
22259         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22260 }
22261 run_test 319 "lost lease lock on migrate error"
22262
22263 test_398a() { # LU-4198
22264         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22265         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22266
22267         # request a new lock on client
22268         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22269
22270         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22271         local lock_count=$($LCTL get_param -n \
22272                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22273         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22274
22275         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22276
22277         # no lock cached, should use lockless IO and not enqueue new lock
22278         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22279         lock_count=$($LCTL get_param -n \
22280                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22281         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22282 }
22283 run_test 398a "direct IO should cancel lock otherwise lockless"
22284
22285 test_398b() { # LU-4198
22286         which fio || skip_env "no fio installed"
22287         $LFS setstripe -c -1 $DIR/$tfile
22288
22289         local size=12
22290         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22291
22292         local njobs=4
22293         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22294         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22295                 --numjobs=$njobs --fallocate=none \
22296                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22297                 --filename=$DIR/$tfile &
22298         bg_pid=$!
22299
22300         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22301         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22302                 --numjobs=$njobs --fallocate=none \
22303                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22304                 --filename=$DIR/$tfile || true
22305         wait $bg_pid
22306
22307         rm -rf $DIR/$tfile
22308 }
22309 run_test 398b "DIO and buffer IO race"
22310
22311 test_398c() { # LU-4198
22312         which fio || skip_env "no fio installed"
22313
22314         saved_debug=$($LCTL get_param -n debug)
22315         $LCTL set_param debug=0
22316
22317         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22318         ((size /= 1024)) # by megabytes
22319         ((size /= 2)) # write half of the OST at most
22320         [ $size -gt 40 ] && size=40 #reduce test time anyway
22321
22322         $LFS setstripe -c 1 $DIR/$tfile
22323
22324         # it seems like ldiskfs reserves more space than necessary if the
22325         # writing blocks are not mapped, so it extends the file firstly
22326         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22327         cancel_lru_locks osc
22328
22329         # clear and verify rpc_stats later
22330         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22331
22332         local njobs=4
22333         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22334         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22335                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22336                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22337                 --filename=$DIR/$tfile
22338         [ $? -eq 0 ] || error "fio write error"
22339
22340         [ $($LCTL get_param -n \
22341          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22342                 error "Locks were requested while doing AIO"
22343
22344         # get the percentage of 1-page I/O
22345         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22346                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22347                 awk '{print $7}')
22348         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22349
22350         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22351         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22352                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22353                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22354                 --filename=$DIR/$tfile
22355         [ $? -eq 0 ] || error "fio mixed read write error"
22356
22357         echo "AIO with large block size ${size}M"
22358         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22359                 --numjobs=1 --fallocate=none --ioengine=libaio \
22360                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22361                 --filename=$DIR/$tfile
22362         [ $? -eq 0 ] || error "fio large block size failed"
22363
22364         rm -rf $DIR/$tfile
22365         $LCTL set_param debug="$saved_debug"
22366 }
22367 run_test 398c "run fio to test AIO"
22368
22369 test_398d() { #  LU-13846
22370         test -f aiocp || skip_env "no aiocp installed"
22371         local aio_file=$DIR/aio_file
22372
22373         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22374
22375         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22376         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22377
22378         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22379
22380         # make sure we don't crash and fail properly
22381         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22382                 error "aio not aligned with PAGE SIZE should fail"
22383
22384         rm -rf $DIR/$tfile $aio_file
22385 }
22386 run_test 398d "run aiocp to verify block size > stripe size"
22387
22388 test_398e() {
22389         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22390         touch $DIR/$tfile.new
22391         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22392 }
22393 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22394
22395 test_fake_rw() {
22396         local read_write=$1
22397         if [ "$read_write" = "write" ]; then
22398                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22399         elif [ "$read_write" = "read" ]; then
22400                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22401         else
22402                 error "argument error"
22403         fi
22404
22405         # turn off debug for performance testing
22406         local saved_debug=$($LCTL get_param -n debug)
22407         $LCTL set_param debug=0
22408
22409         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22410
22411         # get ost1 size - $FSNAME-OST0000
22412         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22413         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22414         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22415
22416         if [ "$read_write" = "read" ]; then
22417                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22418         fi
22419
22420         local start_time=$(date +%s.%N)
22421         $dd_cmd bs=1M count=$blocks oflag=sync ||
22422                 error "real dd $read_write error"
22423         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22424
22425         if [ "$read_write" = "write" ]; then
22426                 rm -f $DIR/$tfile
22427         fi
22428
22429         # define OBD_FAIL_OST_FAKE_RW           0x238
22430         do_facet ost1 $LCTL set_param fail_loc=0x238
22431
22432         local start_time=$(date +%s.%N)
22433         $dd_cmd bs=1M count=$blocks oflag=sync ||
22434                 error "fake dd $read_write error"
22435         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22436
22437         if [ "$read_write" = "write" ]; then
22438                 # verify file size
22439                 cancel_lru_locks osc
22440                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22441                         error "$tfile size not $blocks MB"
22442         fi
22443         do_facet ost1 $LCTL set_param fail_loc=0
22444
22445         echo "fake $read_write $duration_fake vs. normal $read_write" \
22446                 "$duration in seconds"
22447         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22448                 error_not_in_vm "fake write is slower"
22449
22450         $LCTL set_param -n debug="$saved_debug"
22451         rm -f $DIR/$tfile
22452 }
22453 test_399a() { # LU-7655 for OST fake write
22454         remote_ost_nodsh && skip "remote OST with nodsh"
22455
22456         test_fake_rw write
22457 }
22458 run_test 399a "fake write should not be slower than normal write"
22459
22460 test_399b() { # LU-8726 for OST fake read
22461         remote_ost_nodsh && skip "remote OST with nodsh"
22462         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22463                 skip_env "ldiskfs only test"
22464         fi
22465
22466         test_fake_rw read
22467 }
22468 run_test 399b "fake read should not be slower than normal read"
22469
22470 test_400a() { # LU-1606, was conf-sanity test_74
22471         if ! which $CC > /dev/null 2>&1; then
22472                 skip_env "$CC is not installed"
22473         fi
22474
22475         local extra_flags=''
22476         local out=$TMP/$tfile
22477         local prefix=/usr/include/lustre
22478         local prog
22479
22480         # Oleg removes c files in his test rig so test if any c files exist
22481         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22482                 skip_env "Needed c test files are missing"
22483
22484         if ! [[ -d $prefix ]]; then
22485                 # Assume we're running in tree and fixup the include path.
22486                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22487                 extra_flags+=" -L$LUSTRE/utils/.lib"
22488         fi
22489
22490         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22491                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22492                         error "client api broken"
22493         done
22494         rm -f $out
22495 }
22496 run_test 400a "Lustre client api program can compile and link"
22497
22498 test_400b() { # LU-1606, LU-5011
22499         local header
22500         local out=$TMP/$tfile
22501         local prefix=/usr/include/linux/lustre
22502
22503         # We use a hard coded prefix so that this test will not fail
22504         # when run in tree. There are headers in lustre/include/lustre/
22505         # that are not packaged (like lustre_idl.h) and have more
22506         # complicated include dependencies (like config.h and lnet/types.h).
22507         # Since this test about correct packaging we just skip them when
22508         # they don't exist (see below) rather than try to fixup cppflags.
22509
22510         if ! which $CC > /dev/null 2>&1; then
22511                 skip_env "$CC is not installed"
22512         fi
22513
22514         for header in $prefix/*.h; do
22515                 if ! [[ -f "$header" ]]; then
22516                         continue
22517                 fi
22518
22519                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22520                         continue # lustre_ioctl.h is internal header
22521                 fi
22522
22523                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22524                         error "cannot compile '$header'"
22525         done
22526         rm -f $out
22527 }
22528 run_test 400b "packaged headers can be compiled"
22529
22530 test_401a() { #LU-7437
22531         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22532         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22533
22534         #count the number of parameters by "list_param -R"
22535         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22536         #count the number of parameters by listing proc files
22537         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22538         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22539         echo "proc_dirs='$proc_dirs'"
22540         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22541         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22542                       sort -u | wc -l)
22543
22544         [ $params -eq $procs ] ||
22545                 error "found $params parameters vs. $procs proc files"
22546
22547         # test the list_param -D option only returns directories
22548         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22549         #count the number of parameters by listing proc directories
22550         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22551                 sort -u | wc -l)
22552
22553         [ $params -eq $procs ] ||
22554                 error "found $params parameters vs. $procs proc files"
22555 }
22556 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22557
22558 test_401b() {
22559         # jobid_var may not allow arbitrary values, so use jobid_name
22560         # if available
22561         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22562                 local testname=jobid_name tmp='testing%p'
22563         else
22564                 local testname=jobid_var tmp=testing
22565         fi
22566
22567         local save=$($LCTL get_param -n $testname)
22568
22569         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22570                 error "no error returned when setting bad parameters"
22571
22572         local jobid_new=$($LCTL get_param -n foe $testname baz)
22573         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22574
22575         $LCTL set_param -n fog=bam $testname=$save bat=fog
22576         local jobid_old=$($LCTL get_param -n foe $testname bag)
22577         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22578 }
22579 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22580
22581 test_401c() {
22582         # jobid_var may not allow arbitrary values, so use jobid_name
22583         # if available
22584         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22585                 local testname=jobid_name
22586         else
22587                 local testname=jobid_var
22588         fi
22589
22590         local jobid_var_old=$($LCTL get_param -n $testname)
22591         local jobid_var_new
22592
22593         $LCTL set_param $testname= &&
22594                 error "no error returned for 'set_param a='"
22595
22596         jobid_var_new=$($LCTL get_param -n $testname)
22597         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22598                 error "$testname was changed by setting without value"
22599
22600         $LCTL set_param $testname &&
22601                 error "no error returned for 'set_param a'"
22602
22603         jobid_var_new=$($LCTL get_param -n $testname)
22604         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22605                 error "$testname was changed by setting without value"
22606 }
22607 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22608
22609 test_401d() {
22610         # jobid_var may not allow arbitrary values, so use jobid_name
22611         # if available
22612         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22613                 local testname=jobid_name new_value='foo=bar%p'
22614         else
22615                 local testname=jobid_var new_valuie=foo=bar
22616         fi
22617
22618         local jobid_var_old=$($LCTL get_param -n $testname)
22619         local jobid_var_new
22620
22621         $LCTL set_param $testname=$new_value ||
22622                 error "'set_param a=b' did not accept a value containing '='"
22623
22624         jobid_var_new=$($LCTL get_param -n $testname)
22625         [[ "$jobid_var_new" == "$new_value" ]] ||
22626                 error "'set_param a=b' failed on a value containing '='"
22627
22628         # Reset the $testname to test the other format
22629         $LCTL set_param $testname=$jobid_var_old
22630         jobid_var_new=$($LCTL get_param -n $testname)
22631         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22632                 error "failed to reset $testname"
22633
22634         $LCTL set_param $testname $new_value ||
22635                 error "'set_param a b' did not accept a value containing '='"
22636
22637         jobid_var_new=$($LCTL get_param -n $testname)
22638         [[ "$jobid_var_new" == "$new_value" ]] ||
22639                 error "'set_param a b' failed on a value containing '='"
22640
22641         $LCTL set_param $testname $jobid_var_old
22642         jobid_var_new=$($LCTL get_param -n $testname)
22643         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22644                 error "failed to reset $testname"
22645 }
22646 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22647
22648 test_402() {
22649         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22650         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22651                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22652         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22653                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22654                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22655         remote_mds_nodsh && skip "remote MDS with nodsh"
22656
22657         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22658 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22659         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22660         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22661                 echo "Touch failed - OK"
22662 }
22663 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22664
22665 test_403() {
22666         local file1=$DIR/$tfile.1
22667         local file2=$DIR/$tfile.2
22668         local tfile=$TMP/$tfile
22669
22670         rm -f $file1 $file2 $tfile
22671
22672         touch $file1
22673         ln $file1 $file2
22674
22675         # 30 sec OBD_TIMEOUT in ll_getattr()
22676         # right before populating st_nlink
22677         $LCTL set_param fail_loc=0x80001409
22678         stat -c %h $file1 > $tfile &
22679
22680         # create an alias, drop all locks and reclaim the dentry
22681         < $file2
22682         cancel_lru_locks mdc
22683         cancel_lru_locks osc
22684         sysctl -w vm.drop_caches=2
22685
22686         wait
22687
22688         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22689
22690         rm -f $tfile $file1 $file2
22691 }
22692 run_test 403 "i_nlink should not drop to zero due to aliasing"
22693
22694 test_404() { # LU-6601
22695         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22696                 skip "Need server version newer than 2.8.52"
22697         remote_mds_nodsh && skip "remote MDS with nodsh"
22698
22699         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22700                 awk '/osp .*-osc-MDT/ { print $4}')
22701
22702         local osp
22703         for osp in $mosps; do
22704                 echo "Deactivate: " $osp
22705                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22706                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22707                         awk -vp=$osp '$4 == p { print $2 }')
22708                 [ $stat = IN ] || {
22709                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22710                         error "deactivate error"
22711                 }
22712                 echo "Activate: " $osp
22713                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22714                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22715                         awk -vp=$osp '$4 == p { print $2 }')
22716                 [ $stat = UP ] || {
22717                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22718                         error "activate error"
22719                 }
22720         done
22721 }
22722 run_test 404 "validate manual {de}activated works properly for OSPs"
22723
22724 test_405() {
22725         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22726         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22727                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22728                         skip "Layout swap lock is not supported"
22729
22730         check_swap_layouts_support
22731         check_swap_layout_no_dom $DIR
22732
22733         test_mkdir $DIR/$tdir
22734         swap_lock_test -d $DIR/$tdir ||
22735                 error "One layout swap locked test failed"
22736 }
22737 run_test 405 "Various layout swap lock tests"
22738
22739 test_406() {
22740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22741         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22742         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22744         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22745                 skip "Need MDS version at least 2.8.50"
22746
22747         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22748         local test_pool=$TESTNAME
22749
22750         pool_add $test_pool || error "pool_add failed"
22751         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22752                 error "pool_add_targets failed"
22753
22754         save_layout_restore_at_exit $MOUNT
22755
22756         # parent set default stripe count only, child will stripe from both
22757         # parent and fs default
22758         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22759                 error "setstripe $MOUNT failed"
22760         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22761         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22762         for i in $(seq 10); do
22763                 local f=$DIR/$tdir/$tfile.$i
22764                 touch $f || error "touch failed"
22765                 local count=$($LFS getstripe -c $f)
22766                 [ $count -eq $OSTCOUNT ] ||
22767                         error "$f stripe count $count != $OSTCOUNT"
22768                 local offset=$($LFS getstripe -i $f)
22769                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22770                 local size=$($LFS getstripe -S $f)
22771                 [ $size -eq $((def_stripe_size * 2)) ] ||
22772                         error "$f stripe size $size != $((def_stripe_size * 2))"
22773                 local pool=$($LFS getstripe -p $f)
22774                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22775         done
22776
22777         # change fs default striping, delete parent default striping, now child
22778         # will stripe from new fs default striping only
22779         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22780                 error "change $MOUNT default stripe failed"
22781         $LFS setstripe -c 0 $DIR/$tdir ||
22782                 error "delete $tdir default stripe failed"
22783         for i in $(seq 11 20); do
22784                 local f=$DIR/$tdir/$tfile.$i
22785                 touch $f || error "touch $f failed"
22786                 local count=$($LFS getstripe -c $f)
22787                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22788                 local offset=$($LFS getstripe -i $f)
22789                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22790                 local size=$($LFS getstripe -S $f)
22791                 [ $size -eq $def_stripe_size ] ||
22792                         error "$f stripe size $size != $def_stripe_size"
22793                 local pool=$($LFS getstripe -p $f)
22794                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22795         done
22796
22797         unlinkmany $DIR/$tdir/$tfile. 1 20
22798
22799         local f=$DIR/$tdir/$tfile
22800         pool_remove_all_targets $test_pool $f
22801         pool_remove $test_pool $f
22802 }
22803 run_test 406 "DNE support fs default striping"
22804
22805 test_407() {
22806         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22807         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22808                 skip "Need MDS version at least 2.8.55"
22809         remote_mds_nodsh && skip "remote MDS with nodsh"
22810
22811         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22812                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22813         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22814                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22815         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22816
22817         #define OBD_FAIL_DT_TXN_STOP    0x2019
22818         for idx in $(seq $MDSCOUNT); do
22819                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22820         done
22821         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22822         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22823                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22824         true
22825 }
22826 run_test 407 "transaction fail should cause operation fail"
22827
22828 test_408() {
22829         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22830
22831         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22832         lctl set_param fail_loc=0x8000040a
22833         # let ll_prepare_partial_page() fail
22834         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22835
22836         rm -f $DIR/$tfile
22837
22838         # create at least 100 unused inodes so that
22839         # shrink_icache_memory(0) should not return 0
22840         touch $DIR/$tfile-{0..100}
22841         rm -f $DIR/$tfile-{0..100}
22842         sync
22843
22844         echo 2 > /proc/sys/vm/drop_caches
22845 }
22846 run_test 408 "drop_caches should not hang due to page leaks"
22847
22848 test_409()
22849 {
22850         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22851
22852         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22853         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22854         touch $DIR/$tdir/guard || error "(2) Fail to create"
22855
22856         local PREFIX=$(str_repeat 'A' 128)
22857         echo "Create 1K hard links start at $(date)"
22858         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22859                 error "(3) Fail to hard link"
22860
22861         echo "Links count should be right although linkEA overflow"
22862         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22863         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22864         [ $linkcount -eq 1001 ] ||
22865                 error "(5) Unexpected hard links count: $linkcount"
22866
22867         echo "List all links start at $(date)"
22868         ls -l $DIR/$tdir/foo > /dev/null ||
22869                 error "(6) Fail to list $DIR/$tdir/foo"
22870
22871         echo "Unlink hard links start at $(date)"
22872         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22873                 error "(7) Fail to unlink"
22874         echo "Unlink hard links finished at $(date)"
22875 }
22876 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22877
22878 test_410()
22879 {
22880         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22881                 skip "Need client version at least 2.9.59"
22882         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22883                 skip "Need MODULES build"
22884
22885         # Create a file, and stat it from the kernel
22886         local testfile=$DIR/$tfile
22887         touch $testfile
22888
22889         local run_id=$RANDOM
22890         local my_ino=$(stat --format "%i" $testfile)
22891
22892         # Try to insert the module. This will always fail as the
22893         # module is designed to not be inserted.
22894         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22895             &> /dev/null
22896
22897         # Anything but success is a test failure
22898         dmesg | grep -q \
22899             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22900             error "no inode match"
22901 }
22902 run_test 410 "Test inode number returned from kernel thread"
22903
22904 cleanup_test411_cgroup() {
22905         trap 0
22906         rmdir "$1"
22907 }
22908
22909 test_411() {
22910         local cg_basedir=/sys/fs/cgroup/memory
22911         # LU-9966
22912         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22913                 skip "no setup for cgroup"
22914
22915         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22916                 error "test file creation failed"
22917         cancel_lru_locks osc
22918
22919         # Create a very small memory cgroup to force a slab allocation error
22920         local cgdir=$cg_basedir/osc_slab_alloc
22921         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22922         trap "cleanup_test411_cgroup $cgdir" EXIT
22923         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22924         echo 1M > $cgdir/memory.limit_in_bytes
22925
22926         # Should not LBUG, just be killed by oom-killer
22927         # dd will return 0 even allocation failure in some environment.
22928         # So don't check return value
22929         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22930         cleanup_test411_cgroup $cgdir
22931
22932         return 0
22933 }
22934 run_test 411 "Slab allocation error with cgroup does not LBUG"
22935
22936 test_412() {
22937         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22938         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22939                 skip "Need server version at least 2.10.55"
22940         fi
22941
22942         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22943                 error "mkdir failed"
22944         $LFS getdirstripe $DIR/$tdir
22945         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22946         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22947                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22948         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22949         [ $stripe_count -eq 2 ] ||
22950                 error "expect 2 get $stripe_count"
22951 }
22952 run_test 412 "mkdir on specific MDTs"
22953
22954 test_qos_mkdir() {
22955         local mkdir_cmd=$1
22956         local stripe_count=$2
22957         local mdts=$(comma_list $(mdts_nodes))
22958
22959         local testdir
22960         local lmv_qos_prio_free
22961         local lmv_qos_threshold_rr
22962         local lmv_qos_maxage
22963         local lod_qos_prio_free
22964         local lod_qos_threshold_rr
22965         local lod_qos_maxage
22966         local count
22967         local i
22968
22969         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22970         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22971         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22972                 head -n1)
22973         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22974         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22975         stack_trap "$LCTL set_param \
22976                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22977         stack_trap "$LCTL set_param \
22978                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22979         stack_trap "$LCTL set_param \
22980                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22981
22982         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22983                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22984         lod_qos_prio_free=${lod_qos_prio_free%%%}
22985         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22986                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22987         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22988         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22989                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22990         stack_trap "do_nodes $mdts $LCTL set_param \
22991                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22992         stack_trap "do_nodes $mdts $LCTL set_param \
22993                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22994                 EXIT
22995         stack_trap "do_nodes $mdts $LCTL set_param \
22996                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22997
22998         echo
22999         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23000
23001         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23002         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23003
23004         testdir=$DIR/$tdir-s$stripe_count/rr
23005
23006         for i in $(seq $((100 * MDSCOUNT))); do
23007                 eval $mkdir_cmd $testdir/subdir$i ||
23008                         error "$mkdir_cmd subdir$i failed"
23009         done
23010
23011         for i in $(seq $MDSCOUNT); do
23012                 count=$($LFS getdirstripe -i $testdir/* |
23013                                 grep ^$((i - 1))$ | wc -l)
23014                 echo "$count directories created on MDT$((i - 1))"
23015                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23016
23017                 if [ $stripe_count -gt 1 ]; then
23018                         count=$($LFS getdirstripe $testdir/* |
23019                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23020                         echo "$count stripes created on MDT$((i - 1))"
23021                         # deviation should < 5% of average
23022                         [ $count -lt $((95 * stripe_count)) ] ||
23023                         [ $count -gt $((105 * stripe_count)) ] &&
23024                                 error "stripes are not evenly distributed"
23025                 fi
23026         done
23027
23028         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23029         do_nodes $mdts $LCTL set_param \
23030                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23031
23032         echo
23033         echo "Check for uneven MDTs: "
23034
23035         local ffree
23036         local bavail
23037         local max
23038         local min
23039         local max_index
23040         local min_index
23041         local tmp
23042
23043         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23044         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23045         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23046
23047         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23048         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23049         max_index=0
23050         min_index=0
23051         for ((i = 1; i < ${#ffree[@]}; i++)); do
23052                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23053                 if [ $tmp -gt $max ]; then
23054                         max=$tmp
23055                         max_index=$i
23056                 fi
23057                 if [ $tmp -lt $min ]; then
23058                         min=$tmp
23059                         min_index=$i
23060                 fi
23061         done
23062
23063         [ ${ffree[min_index]} -eq 0 ] &&
23064                 skip "no free files in MDT$min_index"
23065         [ ${ffree[min_index]} -gt 100000000 ] &&
23066                 skip "too much free files in MDT$min_index"
23067
23068         # Check if we need to generate uneven MDTs
23069         local threshold=50
23070         local diff=$(((max - min) * 100 / min))
23071         local value="$(generate_string 1024)"
23072
23073         while [ $diff -lt $threshold ]; do
23074                 # generate uneven MDTs, create till $threshold% diff
23075                 echo -n "weight diff=$diff% must be > $threshold% ..."
23076                 count=$((${ffree[min_index]} / 10))
23077                 # 50 sec per 10000 files in vm
23078                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23079                         skip "$count files to create"
23080                 echo "Fill MDT$min_index with $count files"
23081                 [ -d $DIR/$tdir-MDT$min_index ] ||
23082                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23083                         error "mkdir $tdir-MDT$min_index failed"
23084                 for i in $(seq $count); do
23085                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23086                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23087                                 error "create f$j_$i failed"
23088                         setfattr -n user.413b -v $value \
23089                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23090                                 error "setfattr f$j_$i failed"
23091                 done
23092
23093                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23094                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23095                 max=$(((${ffree[max_index]} >> 8) * \
23096                         (${bavail[max_index]} * bsize >> 16)))
23097                 min=$(((${ffree[min_index]} >> 8) * \
23098                         (${bavail[min_index]} * bsize >> 16)))
23099                 diff=$(((max - min) * 100 / min))
23100         done
23101
23102         echo "MDT filesfree available: ${ffree[@]}"
23103         echo "MDT blocks available: ${bavail[@]}"
23104         echo "weight diff=$diff%"
23105
23106         echo
23107         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23108
23109         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23110         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23111         # decrease statfs age, so that it can be updated in time
23112         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23113         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23114
23115         sleep 1
23116
23117         testdir=$DIR/$tdir-s$stripe_count/qos
23118
23119         for i in $(seq $((100 * MDSCOUNT))); do
23120                 eval $mkdir_cmd $testdir/subdir$i ||
23121                         error "$mkdir_cmd subdir$i failed"
23122         done
23123
23124         for i in $(seq $MDSCOUNT); do
23125                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23126                         wc -l)
23127                 echo "$count directories created on MDT$((i - 1))"
23128
23129                 if [ $stripe_count -gt 1 ]; then
23130                         count=$($LFS getdirstripe $testdir/* |
23131                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23132                         echo "$count stripes created on MDT$((i - 1))"
23133                 fi
23134         done
23135
23136         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23137         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23138
23139         # D-value should > 10% of averge
23140         [ $((max - min)) -lt 10 ] &&
23141                 error "subdirs shouldn't be evenly distributed"
23142
23143         # ditto
23144         if [ $stripe_count -gt 1 ]; then
23145                 max=$($LFS getdirstripe $testdir/* |
23146                         grep -P "^\s+$max_index\t" | wc -l)
23147                 min=$($LFS getdirstripe $testdir/* |
23148                         grep -P "^\s+$min_index\t" | wc -l)
23149                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23150                         error "stripes shouldn't be evenly distributed"|| true
23151         fi
23152 }
23153
23154 test_413a() {
23155         [ $MDSCOUNT -lt 2 ] &&
23156                 skip "We need at least 2 MDTs for this test"
23157
23158         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23159                 skip "Need server version at least 2.12.52"
23160
23161         local stripe_count
23162
23163         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23164                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23165                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23166                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23167                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23168         done
23169 }
23170 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23171
23172 test_413b() {
23173         [ $MDSCOUNT -lt 2 ] &&
23174                 skip "We need at least 2 MDTs for this test"
23175
23176         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23177                 skip "Need server version at least 2.12.52"
23178
23179         local stripe_count
23180
23181         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23182                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23183                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23184                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23185                 $LFS setdirstripe -D -c $stripe_count \
23186                         $DIR/$tdir-s$stripe_count/rr ||
23187                         error "setdirstripe failed"
23188                 $LFS setdirstripe -D -c $stripe_count \
23189                         $DIR/$tdir-s$stripe_count/qos ||
23190                         error "setdirstripe failed"
23191                 test_qos_mkdir "mkdir" $stripe_count
23192         done
23193 }
23194 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23195
23196 test_414() {
23197 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23198         $LCTL set_param fail_loc=0x80000521
23199         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23200         rm -f $DIR/$tfile
23201 }
23202 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23203
23204 test_415() {
23205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23206         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23207                 skip "Need server version at least 2.11.52"
23208
23209         # LU-11102
23210         local total
23211         local setattr_pid
23212         local start_time
23213         local end_time
23214         local duration
23215
23216         total=500
23217         # this test may be slow on ZFS
23218         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23219
23220         # though this test is designed for striped directory, let's test normal
23221         # directory too since lock is always saved as CoS lock.
23222         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23223         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23224
23225         (
23226                 while true; do
23227                         touch $DIR/$tdir
23228                 done
23229         ) &
23230         setattr_pid=$!
23231
23232         start_time=$(date +%s)
23233         for i in $(seq $total); do
23234                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23235                         > /dev/null
23236         done
23237         end_time=$(date +%s)
23238         duration=$((end_time - start_time))
23239
23240         kill -9 $setattr_pid
23241
23242         echo "rename $total files took $duration sec"
23243         [ $duration -lt 100 ] || error "rename took $duration sec"
23244 }
23245 run_test 415 "lock revoke is not missing"
23246
23247 test_416() {
23248         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23249                 skip "Need server version at least 2.11.55"
23250
23251         # define OBD_FAIL_OSD_TXN_START    0x19a
23252         do_facet mds1 lctl set_param fail_loc=0x19a
23253
23254         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23255
23256         true
23257 }
23258 run_test 416 "transaction start failure won't cause system hung"
23259
23260 cleanup_417() {
23261         trap 0
23262         do_nodes $(comma_list $(mdts_nodes)) \
23263                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23264         do_nodes $(comma_list $(mdts_nodes)) \
23265                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23266         do_nodes $(comma_list $(mdts_nodes)) \
23267                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23268 }
23269
23270 test_417() {
23271         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23272         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23273                 skip "Need MDS version at least 2.11.56"
23274
23275         trap cleanup_417 RETURN EXIT
23276
23277         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23278         do_nodes $(comma_list $(mdts_nodes)) \
23279                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23280         $LFS migrate -m 0 $DIR/$tdir.1 &&
23281                 error "migrate dir $tdir.1 should fail"
23282
23283         do_nodes $(comma_list $(mdts_nodes)) \
23284                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23285         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23286                 error "create remote dir $tdir.2 should fail"
23287
23288         do_nodes $(comma_list $(mdts_nodes)) \
23289                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23290         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23291                 error "create striped dir $tdir.3 should fail"
23292         true
23293 }
23294 run_test 417 "disable remote dir, striped dir and dir migration"
23295
23296 # Checks that the outputs of df [-i] and lfs df [-i] match
23297 #
23298 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23299 check_lfs_df() {
23300         local dir=$2
23301         local inodes
23302         local df_out
23303         local lfs_df_out
23304         local count
23305         local passed=false
23306
23307         # blocks or inodes
23308         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23309
23310         for count in {1..100}; do
23311                 cancel_lru_locks
23312                 sync; sleep 0.2
23313
23314                 # read the lines of interest
23315                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23316                         error "df $inodes $dir | tail -n +2 failed"
23317                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23318                         error "lfs df $inodes $dir | grep summary: failed"
23319
23320                 # skip first substrings of each output as they are different
23321                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23322                 # compare the two outputs
23323                 passed=true
23324                 for i in {1..5}; do
23325                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23326                 done
23327                 $passed && break
23328         done
23329
23330         if ! $passed; then
23331                 df -P $inodes $dir
23332                 echo
23333                 lfs df $inodes $dir
23334                 error "df and lfs df $1 output mismatch: "      \
23335                       "df ${inodes}: ${df_out[*]}, "            \
23336                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23337         fi
23338 }
23339
23340 test_418() {
23341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23342
23343         local dir=$DIR/$tdir
23344         local numfiles=$((RANDOM % 4096 + 2))
23345         local numblocks=$((RANDOM % 256 + 1))
23346
23347         wait_delete_completed
23348         test_mkdir $dir
23349
23350         # check block output
23351         check_lfs_df blocks $dir
23352         # check inode output
23353         check_lfs_df inodes $dir
23354
23355         # create a single file and retest
23356         echo "Creating a single file and testing"
23357         createmany -o $dir/$tfile- 1 &>/dev/null ||
23358                 error "creating 1 file in $dir failed"
23359         check_lfs_df blocks $dir
23360         check_lfs_df inodes $dir
23361
23362         # create a random number of files
23363         echo "Creating $((numfiles - 1)) files and testing"
23364         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23365                 error "creating $((numfiles - 1)) files in $dir failed"
23366
23367         # write a random number of blocks to the first test file
23368         echo "Writing $numblocks 4K blocks and testing"
23369         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23370                 count=$numblocks &>/dev/null ||
23371                 error "dd to $dir/${tfile}-0 failed"
23372
23373         # retest
23374         check_lfs_df blocks $dir
23375         check_lfs_df inodes $dir
23376
23377         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23378                 error "unlinking $numfiles files in $dir failed"
23379 }
23380 run_test 418 "df and lfs df outputs match"
23381
23382 test_419()
23383 {
23384         local dir=$DIR/$tdir
23385
23386         mkdir -p $dir
23387         touch $dir/file
23388
23389         cancel_lru_locks mdc
23390
23391         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23392         $LCTL set_param fail_loc=0x1410
23393         cat $dir/file
23394         $LCTL set_param fail_loc=0
23395         rm -rf $dir
23396 }
23397 run_test 419 "Verify open file by name doesn't crash kernel"
23398
23399 test_420()
23400 {
23401         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23402                 skip "Need MDS version at least 2.12.53"
23403
23404         local SAVE_UMASK=$(umask)
23405         local dir=$DIR/$tdir
23406         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23407
23408         mkdir -p $dir
23409         umask 0000
23410         mkdir -m03777 $dir/testdir
23411         ls -dn $dir/testdir
23412         # Need to remove trailing '.' when SELinux is enabled
23413         local dirperms=$(ls -dn $dir/testdir |
23414                          awk '{ sub(/\.$/, "", $1); print $1}')
23415         [ $dirperms == "drwxrwsrwt" ] ||
23416                 error "incorrect perms on $dir/testdir"
23417
23418         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23419                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23420         ls -n $dir/testdir/testfile
23421         local fileperms=$(ls -n $dir/testdir/testfile |
23422                           awk '{ sub(/\.$/, "", $1); print $1}')
23423         [ $fileperms == "-rwxr-xr-x" ] ||
23424                 error "incorrect perms on $dir/testdir/testfile"
23425
23426         umask $SAVE_UMASK
23427 }
23428 run_test 420 "clear SGID bit on non-directories for non-members"
23429
23430 test_421a() {
23431         local cnt
23432         local fid1
23433         local fid2
23434
23435         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23436                 skip "Need MDS version at least 2.12.54"
23437
23438         test_mkdir $DIR/$tdir
23439         createmany -o $DIR/$tdir/f 3
23440         cnt=$(ls -1 $DIR/$tdir | wc -l)
23441         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23442
23443         fid1=$(lfs path2fid $DIR/$tdir/f1)
23444         fid2=$(lfs path2fid $DIR/$tdir/f2)
23445         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23446
23447         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23448         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23449
23450         cnt=$(ls -1 $DIR/$tdir | wc -l)
23451         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23452
23453         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23454         createmany -o $DIR/$tdir/f 3
23455         cnt=$(ls -1 $DIR/$tdir | wc -l)
23456         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23457
23458         fid1=$(lfs path2fid $DIR/$tdir/f1)
23459         fid2=$(lfs path2fid $DIR/$tdir/f2)
23460         echo "remove using fsname $FSNAME"
23461         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23462
23463         cnt=$(ls -1 $DIR/$tdir | wc -l)
23464         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23465 }
23466 run_test 421a "simple rm by fid"
23467
23468 test_421b() {
23469         local cnt
23470         local FID1
23471         local FID2
23472
23473         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23474                 skip "Need MDS version at least 2.12.54"
23475
23476         test_mkdir $DIR/$tdir
23477         createmany -o $DIR/$tdir/f 3
23478         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23479         MULTIPID=$!
23480
23481         FID1=$(lfs path2fid $DIR/$tdir/f1)
23482         FID2=$(lfs path2fid $DIR/$tdir/f2)
23483         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23484
23485         kill -USR1 $MULTIPID
23486         wait
23487
23488         cnt=$(ls $DIR/$tdir | wc -l)
23489         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23490 }
23491 run_test 421b "rm by fid on open file"
23492
23493 test_421c() {
23494         local cnt
23495         local FIDS
23496
23497         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23498                 skip "Need MDS version at least 2.12.54"
23499
23500         test_mkdir $DIR/$tdir
23501         createmany -o $DIR/$tdir/f 3
23502         touch $DIR/$tdir/$tfile
23503         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23504         cnt=$(ls -1 $DIR/$tdir | wc -l)
23505         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23506
23507         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23508         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23509
23510         cnt=$(ls $DIR/$tdir | wc -l)
23511         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23512 }
23513 run_test 421c "rm by fid against hardlinked files"
23514
23515 test_421d() {
23516         local cnt
23517         local FIDS
23518
23519         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23520                 skip "Need MDS version at least 2.12.54"
23521
23522         test_mkdir $DIR/$tdir
23523         createmany -o $DIR/$tdir/f 4097
23524         cnt=$(ls -1 $DIR/$tdir | wc -l)
23525         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23526
23527         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23528         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23529
23530         cnt=$(ls $DIR/$tdir | wc -l)
23531         rm -rf $DIR/$tdir
23532         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23533 }
23534 run_test 421d "rmfid en masse"
23535
23536 test_421e() {
23537         local cnt
23538         local FID
23539
23540         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23541         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23542                 skip "Need MDS version at least 2.12.54"
23543
23544         mkdir -p $DIR/$tdir
23545         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23546         createmany -o $DIR/$tdir/striped_dir/f 512
23547         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23548         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23549
23550         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23551                 sed "s/[/][^:]*://g")
23552         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23553
23554         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23555         rm -rf $DIR/$tdir
23556         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23557 }
23558 run_test 421e "rmfid in DNE"
23559
23560 test_421f() {
23561         local cnt
23562         local FID
23563
23564         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23565                 skip "Need MDS version at least 2.12.54"
23566
23567         test_mkdir $DIR/$tdir
23568         touch $DIR/$tdir/f
23569         cnt=$(ls -1 $DIR/$tdir | wc -l)
23570         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23571
23572         FID=$(lfs path2fid $DIR/$tdir/f)
23573         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23574         # rmfid should fail
23575         cnt=$(ls -1 $DIR/$tdir | wc -l)
23576         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23577
23578         chmod a+rw $DIR/$tdir
23579         ls -la $DIR/$tdir
23580         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23581         # rmfid should fail
23582         cnt=$(ls -1 $DIR/$tdir | wc -l)
23583         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23584
23585         rm -f $DIR/$tdir/f
23586         $RUNAS touch $DIR/$tdir/f
23587         FID=$(lfs path2fid $DIR/$tdir/f)
23588         echo "rmfid as root"
23589         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23590         cnt=$(ls -1 $DIR/$tdir | wc -l)
23591         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23592
23593         rm -f $DIR/$tdir/f
23594         $RUNAS touch $DIR/$tdir/f
23595         cnt=$(ls -1 $DIR/$tdir | wc -l)
23596         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23597         FID=$(lfs path2fid $DIR/$tdir/f)
23598         # rmfid w/o user_fid2path mount option should fail
23599         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23600         cnt=$(ls -1 $DIR/$tdir | wc -l)
23601         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23602
23603         umount_client $MOUNT || error "failed to umount client"
23604         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23605                 error "failed to mount client'"
23606
23607         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23608         # rmfid should succeed
23609         cnt=$(ls -1 $DIR/$tdir | wc -l)
23610         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23611
23612         # rmfid shouldn't allow to remove files due to dir's permission
23613         chmod a+rwx $DIR/$tdir
23614         touch $DIR/$tdir/f
23615         ls -la $DIR/$tdir
23616         FID=$(lfs path2fid $DIR/$tdir/f)
23617         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23618
23619         umount_client $MOUNT || error "failed to umount client"
23620         mount_client $MOUNT "$MOUNT_OPTS" ||
23621                 error "failed to mount client'"
23622
23623 }
23624 run_test 421f "rmfid checks permissions"
23625
23626 test_421g() {
23627         local cnt
23628         local FIDS
23629
23630         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23631         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23632                 skip "Need MDS version at least 2.12.54"
23633
23634         mkdir -p $DIR/$tdir
23635         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23636         createmany -o $DIR/$tdir/striped_dir/f 512
23637         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23638         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23639
23640         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23641                 sed "s/[/][^:]*://g")
23642
23643         rm -f $DIR/$tdir/striped_dir/f1*
23644         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23645         removed=$((512 - cnt))
23646
23647         # few files have been just removed, so we expect
23648         # rmfid to fail on their fids
23649         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23650         [ $removed != $errors ] && error "$errors != $removed"
23651
23652         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23653         rm -rf $DIR/$tdir
23654         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23655 }
23656 run_test 421g "rmfid to return errors properly"
23657
23658 test_422() {
23659         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23660         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23661         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23662         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23663         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23664
23665         local amc=$(at_max_get client)
23666         local amo=$(at_max_get mds1)
23667         local timeout=`lctl get_param -n timeout`
23668
23669         at_max_set 0 client
23670         at_max_set 0 mds1
23671
23672 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23673         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23674                         fail_val=$(((2*timeout + 10)*1000))
23675         touch $DIR/$tdir/d3/file &
23676         sleep 2
23677 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23678         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23679                         fail_val=$((2*timeout + 5))
23680         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23681         local pid=$!
23682         sleep 1
23683         kill -9 $pid
23684         sleep $((2 * timeout))
23685         echo kill $pid
23686         kill -9 $pid
23687         lctl mark touch
23688         touch $DIR/$tdir/d2/file3
23689         touch $DIR/$tdir/d2/file4
23690         touch $DIR/$tdir/d2/file5
23691
23692         wait
23693         at_max_set $amc client
23694         at_max_set $amo mds1
23695
23696         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23697         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23698                 error "Watchdog is always throttled"
23699 }
23700 run_test 422 "kill a process with RPC in progress"
23701
23702 stat_test() {
23703     df -h $MOUNT &
23704     df -h $MOUNT &
23705     df -h $MOUNT &
23706     df -h $MOUNT &
23707     df -h $MOUNT &
23708     df -h $MOUNT &
23709 }
23710
23711 test_423() {
23712     local _stats
23713     # ensure statfs cache is expired
23714     sleep 2;
23715
23716     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23717     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23718
23719     return 0
23720 }
23721 run_test 423 "statfs should return a right data"
23722
23723 test_424() {
23724 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23725         $LCTL set_param fail_loc=0x80000522
23726         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23727         rm -f $DIR/$tfile
23728 }
23729 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23730
23731 test_425() {
23732         test_mkdir -c -1 $DIR/$tdir
23733         $LFS setstripe -c -1 $DIR/$tdir
23734
23735         lru_resize_disable "" 100
23736         stack_trap "lru_resize_enable" EXIT
23737
23738         sleep 5
23739
23740         for i in $(seq $((MDSCOUNT * 125))); do
23741                 local t=$DIR/$tdir/$tfile_$i
23742
23743                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23744                         error_noexit "Create file $t"
23745         done
23746         stack_trap "rm -rf $DIR/$tdir" EXIT
23747
23748         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23749                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23750                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23751
23752                 [ $lock_count -le $lru_size ] ||
23753                         error "osc lock count $lock_count > lru size $lru_size"
23754         done
23755
23756         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23757                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23758                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23759
23760                 [ $lock_count -le $lru_size ] ||
23761                         error "mdc lock count $lock_count > lru size $lru_size"
23762         done
23763 }
23764 run_test 425 "lock count should not exceed lru size"
23765
23766 test_426() {
23767         splice-test -r $DIR/$tfile
23768         splice-test -rd $DIR/$tfile
23769         splice-test $DIR/$tfile
23770         splice-test -d $DIR/$tfile
23771 }
23772 run_test 426 "splice test on Lustre"
23773
23774 lseek_test_430() {
23775         local offset
23776         local file=$1
23777
23778         # data at [200K, 400K)
23779         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23780                 error "256K->512K dd fails"
23781         # data at [2M, 3M)
23782         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23783                 error "2M->3M dd fails"
23784         # data at [4M, 5M)
23785         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23786                 error "4M->5M dd fails"
23787         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23788         # start at first component hole #1
23789         printf "Seeking hole from 1000 ... "
23790         offset=$(lseek_test -l 1000 $file)
23791         echo $offset
23792         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23793         printf "Seeking data from 1000 ... "
23794         offset=$(lseek_test -d 1000 $file)
23795         echo $offset
23796         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23797
23798         # start at first component data block
23799         printf "Seeking hole from 300000 ... "
23800         offset=$(lseek_test -l 300000 $file)
23801         echo $offset
23802         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23803         printf "Seeking data from 300000 ... "
23804         offset=$(lseek_test -d 300000 $file)
23805         echo $offset
23806         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23807
23808         # start at the first component but beyond end of object size
23809         printf "Seeking hole from 1000000 ... "
23810         offset=$(lseek_test -l 1000000 $file)
23811         echo $offset
23812         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23813         printf "Seeking data from 1000000 ... "
23814         offset=$(lseek_test -d 1000000 $file)
23815         echo $offset
23816         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23817
23818         # start at second component stripe 2 (empty file)
23819         printf "Seeking hole from 1500000 ... "
23820         offset=$(lseek_test -l 1500000 $file)
23821         echo $offset
23822         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23823         printf "Seeking data from 1500000 ... "
23824         offset=$(lseek_test -d 1500000 $file)
23825         echo $offset
23826         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23827
23828         # start at second component stripe 1 (all data)
23829         printf "Seeking hole from 3000000 ... "
23830         offset=$(lseek_test -l 3000000 $file)
23831         echo $offset
23832         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23833         printf "Seeking data from 3000000 ... "
23834         offset=$(lseek_test -d 3000000 $file)
23835         echo $offset
23836         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23837
23838         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23839                 error "2nd dd fails"
23840         echo "Add data block at 640K...1280K"
23841
23842         # start at before new data block, in hole
23843         printf "Seeking hole from 600000 ... "
23844         offset=$(lseek_test -l 600000 $file)
23845         echo $offset
23846         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23847         printf "Seeking data from 600000 ... "
23848         offset=$(lseek_test -d 600000 $file)
23849         echo $offset
23850         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23851
23852         # start at the first component new data block
23853         printf "Seeking hole from 1000000 ... "
23854         offset=$(lseek_test -l 1000000 $file)
23855         echo $offset
23856         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23857         printf "Seeking data from 1000000 ... "
23858         offset=$(lseek_test -d 1000000 $file)
23859         echo $offset
23860         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23861
23862         # start at second component stripe 2, new data
23863         printf "Seeking hole from 1200000 ... "
23864         offset=$(lseek_test -l 1200000 $file)
23865         echo $offset
23866         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23867         printf "Seeking data from 1200000 ... "
23868         offset=$(lseek_test -d 1200000 $file)
23869         echo $offset
23870         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23871
23872         # start beyond file end
23873         printf "Using offset > filesize ... "
23874         lseek_test -l 4000000 $file && error "lseek should fail"
23875         printf "Using offset > filesize ... "
23876         lseek_test -d 4000000 $file && error "lseek should fail"
23877
23878         printf "Done\n\n"
23879 }
23880
23881 test_430a() {
23882         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23883                 skip "MDT does not support SEEK_HOLE"
23884
23885         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23886                 skip "OST does not support SEEK_HOLE"
23887
23888         local file=$DIR/$tdir/$tfile
23889
23890         mkdir -p $DIR/$tdir
23891
23892         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23893         # OST stripe #1 will have continuous data at [1M, 3M)
23894         # OST stripe #2 is empty
23895         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23896         lseek_test_430 $file
23897         rm $file
23898         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23899         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23900         lseek_test_430 $file
23901         rm $file
23902         $LFS setstripe -c2 -S 512K $file
23903         echo "Two stripes, stripe size 512K"
23904         lseek_test_430 $file
23905         rm $file
23906         # FLR with stale mirror
23907         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23908                        -N -c2 -S 1M $file
23909         echo "Mirrored file:"
23910         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23911         echo "Plain 2 stripes 1M"
23912         lseek_test_430 $file
23913         rm $file
23914 }
23915 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23916
23917 test_430b() {
23918         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23919                 skip "OST does not support SEEK_HOLE"
23920
23921         local offset
23922         local file=$DIR/$tdir/$tfile
23923
23924         mkdir -p $DIR/$tdir
23925         # Empty layout lseek should fail
23926         $MCREATE $file
23927         # seek from 0
23928         printf "Seeking hole from 0 ... "
23929         lseek_test -l 0 $file && error "lseek should fail"
23930         printf "Seeking data from 0 ... "
23931         lseek_test -d 0 $file && error "lseek should fail"
23932         rm $file
23933
23934         # 1M-hole file
23935         $LFS setstripe -E 1M -c2 -E eof $file
23936         $TRUNCATE $file 1048576
23937         printf "Seeking hole from 1000000 ... "
23938         offset=$(lseek_test -l 1000000 $file)
23939         echo $offset
23940         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23941         printf "Seeking data from 1000000 ... "
23942         lseek_test -d 1000000 $file && error "lseek should fail"
23943         # full first component, non-inited second one
23944         dd if=/dev/urandom of=$file bs=1M count=1
23945         printf "Seeking hole from 1000000 ... "
23946         offset=$(lseek_test -l 1000000 $file)
23947         echo $offset
23948         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23949         printf "Seeking hole from 1048576 ... "
23950         lseek_test -l 1048576 $file && error "lseek should fail"
23951         # init second component and truncate back
23952         echo "123" >> $file
23953         $TRUNCATE $file 1048576
23954         ls -lia $file
23955         printf "Seeking hole from 1000000 ... "
23956         offset=$(lseek_test -l 1000000 $file)
23957         echo $offset
23958         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23959         printf "Seeking hole from 1048576 ... "
23960         lseek_test -l 1048576 $file && error "lseek should fail"
23961         # boundary checks for big values
23962         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
23963         offset=$(lseek_test -d 0 $file.10g)
23964         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
23965         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
23966         offset=$(lseek_test -d 0 $file.100g)
23967         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
23968         return 0
23969 }
23970 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
23971
23972 test_430c() {
23973         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23974                 skip "OST does not support SEEK_HOLE"
23975
23976         local file=$DIR/$tdir/$tfile
23977         local start
23978
23979         mkdir -p $DIR/$tdir
23980         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
23981
23982         # cp version 8.33+ prefers lseek over fiemap
23983         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
23984                 start=$SECONDS
23985                 time cp $file /dev/null
23986                 (( SECONDS - start < 5 )) ||
23987                         error "cp: too long runtime $((SECONDS - start))"
23988
23989         fi
23990         # tar version 1.29+ supports SEEK_HOLE/DATA
23991         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
23992                 start=$SECONDS
23993                 time tar cS $file - | cat > /dev/null
23994                 (( SECONDS - start < 5 )) ||
23995                         error "tar: too long runtime $((SECONDS - start))"
23996         fi
23997 }
23998 run_test 430c "lseek: external tools check"
23999
24000 prep_801() {
24001         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24002         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24003                 skip "Need server version at least 2.9.55"
24004
24005         start_full_debug_logging
24006 }
24007
24008 post_801() {
24009         stop_full_debug_logging
24010 }
24011
24012 barrier_stat() {
24013         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24014                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24015                            awk '/The barrier for/ { print $7 }')
24016                 echo $st
24017         else
24018                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24019                 echo \'$st\'
24020         fi
24021 }
24022
24023 barrier_expired() {
24024         local expired
24025
24026         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24027                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24028                           awk '/will be expired/ { print $7 }')
24029         else
24030                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24031         fi
24032
24033         echo $expired
24034 }
24035
24036 test_801a() {
24037         prep_801
24038
24039         echo "Start barrier_freeze at: $(date)"
24040         #define OBD_FAIL_BARRIER_DELAY          0x2202
24041         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24042         # Do not reduce barrier time - See LU-11873
24043         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24044
24045         sleep 2
24046         local b_status=$(barrier_stat)
24047         echo "Got barrier status at: $(date)"
24048         [ "$b_status" = "'freezing_p1'" ] ||
24049                 error "(1) unexpected barrier status $b_status"
24050
24051         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24052         wait
24053         b_status=$(barrier_stat)
24054         [ "$b_status" = "'frozen'" ] ||
24055                 error "(2) unexpected barrier status $b_status"
24056
24057         local expired=$(barrier_expired)
24058         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24059         sleep $((expired + 3))
24060
24061         b_status=$(barrier_stat)
24062         [ "$b_status" = "'expired'" ] ||
24063                 error "(3) unexpected barrier status $b_status"
24064
24065         # Do not reduce barrier time - See LU-11873
24066         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24067                 error "(4) fail to freeze barrier"
24068
24069         b_status=$(barrier_stat)
24070         [ "$b_status" = "'frozen'" ] ||
24071                 error "(5) unexpected barrier status $b_status"
24072
24073         echo "Start barrier_thaw at: $(date)"
24074         #define OBD_FAIL_BARRIER_DELAY          0x2202
24075         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24076         do_facet mgs $LCTL barrier_thaw $FSNAME &
24077
24078         sleep 2
24079         b_status=$(barrier_stat)
24080         echo "Got barrier status at: $(date)"
24081         [ "$b_status" = "'thawing'" ] ||
24082                 error "(6) unexpected barrier status $b_status"
24083
24084         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24085         wait
24086         b_status=$(barrier_stat)
24087         [ "$b_status" = "'thawed'" ] ||
24088                 error "(7) unexpected barrier status $b_status"
24089
24090         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24091         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24092         do_facet mgs $LCTL barrier_freeze $FSNAME
24093
24094         b_status=$(barrier_stat)
24095         [ "$b_status" = "'failed'" ] ||
24096                 error "(8) unexpected barrier status $b_status"
24097
24098         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24099         do_facet mgs $LCTL barrier_thaw $FSNAME
24100
24101         post_801
24102 }
24103 run_test 801a "write barrier user interfaces and stat machine"
24104
24105 test_801b() {
24106         prep_801
24107
24108         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24109         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24110         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24111         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24112         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24113
24114         cancel_lru_locks mdc
24115
24116         # 180 seconds should be long enough
24117         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24118
24119         local b_status=$(barrier_stat)
24120         [ "$b_status" = "'frozen'" ] ||
24121                 error "(6) unexpected barrier status $b_status"
24122
24123         mkdir $DIR/$tdir/d0/d10 &
24124         mkdir_pid=$!
24125
24126         touch $DIR/$tdir/d1/f13 &
24127         touch_pid=$!
24128
24129         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24130         ln_pid=$!
24131
24132         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24133         mv_pid=$!
24134
24135         rm -f $DIR/$tdir/d4/f12 &
24136         rm_pid=$!
24137
24138         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24139
24140         # To guarantee taht the 'stat' is not blocked
24141         b_status=$(barrier_stat)
24142         [ "$b_status" = "'frozen'" ] ||
24143                 error "(8) unexpected barrier status $b_status"
24144
24145         # let above commands to run at background
24146         sleep 5
24147
24148         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24149         ps -p $touch_pid || error "(10) touch should be blocked"
24150         ps -p $ln_pid || error "(11) link should be blocked"
24151         ps -p $mv_pid || error "(12) rename should be blocked"
24152         ps -p $rm_pid || error "(13) unlink should be blocked"
24153
24154         b_status=$(barrier_stat)
24155         [ "$b_status" = "'frozen'" ] ||
24156                 error "(14) unexpected barrier status $b_status"
24157
24158         do_facet mgs $LCTL barrier_thaw $FSNAME
24159         b_status=$(barrier_stat)
24160         [ "$b_status" = "'thawed'" ] ||
24161                 error "(15) unexpected barrier status $b_status"
24162
24163         wait $mkdir_pid || error "(16) mkdir should succeed"
24164         wait $touch_pid || error "(17) touch should succeed"
24165         wait $ln_pid || error "(18) link should succeed"
24166         wait $mv_pid || error "(19) rename should succeed"
24167         wait $rm_pid || error "(20) unlink should succeed"
24168
24169         post_801
24170 }
24171 run_test 801b "modification will be blocked by write barrier"
24172
24173 test_801c() {
24174         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24175
24176         prep_801
24177
24178         stop mds2 || error "(1) Fail to stop mds2"
24179
24180         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24181
24182         local b_status=$(barrier_stat)
24183         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24184                 do_facet mgs $LCTL barrier_thaw $FSNAME
24185                 error "(2) unexpected barrier status $b_status"
24186         }
24187
24188         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24189                 error "(3) Fail to rescan barrier bitmap"
24190
24191         # Do not reduce barrier time - See LU-11873
24192         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24193
24194         b_status=$(barrier_stat)
24195         [ "$b_status" = "'frozen'" ] ||
24196                 error "(4) unexpected barrier status $b_status"
24197
24198         do_facet mgs $LCTL barrier_thaw $FSNAME
24199         b_status=$(barrier_stat)
24200         [ "$b_status" = "'thawed'" ] ||
24201                 error "(5) unexpected barrier status $b_status"
24202
24203         local devname=$(mdsdevname 2)
24204
24205         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24206
24207         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24208                 error "(7) Fail to rescan barrier bitmap"
24209
24210         post_801
24211 }
24212 run_test 801c "rescan barrier bitmap"
24213
24214 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24215 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24216 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24217 saved_MOUNT_OPTS=$MOUNT_OPTS
24218
24219 cleanup_802a() {
24220         trap 0
24221
24222         stopall
24223         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24224         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24225         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24226         MOUNT_OPTS=$saved_MOUNT_OPTS
24227         setupall
24228 }
24229
24230 test_802a() {
24231         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24232         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24233         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24234                 skip "Need server version at least 2.9.55"
24235
24236         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24237
24238         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24239
24240         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24241                 error "(2) Fail to copy"
24242
24243         trap cleanup_802a EXIT
24244
24245         # sync by force before remount as readonly
24246         sync; sync_all_data; sleep 3; sync_all_data
24247
24248         stopall
24249
24250         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24251         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24252         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24253
24254         echo "Mount the server as read only"
24255         setupall server_only || error "(3) Fail to start servers"
24256
24257         echo "Mount client without ro should fail"
24258         mount_client $MOUNT &&
24259                 error "(4) Mount client without 'ro' should fail"
24260
24261         echo "Mount client with ro should succeed"
24262         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24263         mount_client $MOUNT ||
24264                 error "(5) Mount client with 'ro' should succeed"
24265
24266         echo "Modify should be refused"
24267         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24268
24269         echo "Read should be allowed"
24270         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24271                 error "(7) Read should succeed under ro mode"
24272
24273         cleanup_802a
24274 }
24275 run_test 802a "simulate readonly device"
24276
24277 test_802b() {
24278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24279         remote_mds_nodsh && skip "remote MDS with nodsh"
24280
24281         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24282                 skip "readonly option not available"
24283
24284         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24285
24286         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24287                 error "(2) Fail to copy"
24288
24289         # write back all cached data before setting MDT to readonly
24290         cancel_lru_locks
24291         sync_all_data
24292
24293         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24294         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24295
24296         echo "Modify should be refused"
24297         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24298
24299         echo "Read should be allowed"
24300         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24301                 error "(7) Read should succeed under ro mode"
24302
24303         # disable readonly
24304         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24305 }
24306 run_test 802b "be able to set MDTs to readonly"
24307
24308 test_803a() {
24309         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24310         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24311                 skip "MDS needs to be newer than 2.10.54"
24312
24313         mkdir -p $DIR/$tdir
24314         # Create some objects on all MDTs to trigger related logs objects
24315         for idx in $(seq $MDSCOUNT); do
24316                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24317                         $DIR/$tdir/dir${idx} ||
24318                         error "Fail to create $DIR/$tdir/dir${idx}"
24319         done
24320
24321         sync; sleep 3
24322         wait_delete_completed # ensure old test cleanups are finished
24323         echo "before create:"
24324         $LFS df -i $MOUNT
24325         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24326
24327         for i in {1..10}; do
24328                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24329                         error "Fail to create $DIR/$tdir/foo$i"
24330         done
24331
24332         sync; sleep 3
24333         echo "after create:"
24334         $LFS df -i $MOUNT
24335         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24336
24337         # allow for an llog to be cleaned up during the test
24338         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24339                 error "before ($before_used) + 10 > after ($after_used)"
24340
24341         for i in {1..10}; do
24342                 rm -rf $DIR/$tdir/foo$i ||
24343                         error "Fail to remove $DIR/$tdir/foo$i"
24344         done
24345
24346         sleep 3 # avoid MDT return cached statfs
24347         wait_delete_completed
24348         echo "after unlink:"
24349         $LFS df -i $MOUNT
24350         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24351
24352         # allow for an llog to be created during the test
24353         [ $after_used -le $((before_used + 1)) ] ||
24354                 error "after ($after_used) > before ($before_used) + 1"
24355 }
24356 run_test 803a "verify agent object for remote object"
24357
24358 test_803b() {
24359         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24360         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24361                 skip "MDS needs to be newer than 2.13.56"
24362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24363
24364         for i in $(seq 0 $((MDSCOUNT - 1))); do
24365                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24366         done
24367
24368         local before=0
24369         local after=0
24370
24371         local tmp
24372
24373         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24374         for i in $(seq 0 $((MDSCOUNT - 1))); do
24375                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24376                         awk '/getattr/ { print $2 }')
24377                 before=$((before + tmp))
24378         done
24379         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24380         for i in $(seq 0 $((MDSCOUNT - 1))); do
24381                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24382                         awk '/getattr/ { print $2 }')
24383                 after=$((after + tmp))
24384         done
24385
24386         [ $before -eq $after ] || error "getattr count $before != $after"
24387 }
24388 run_test 803b "remote object can getattr from cache"
24389
24390 test_804() {
24391         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24392         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24393                 skip "MDS needs to be newer than 2.10.54"
24394         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24395
24396         mkdir -p $DIR/$tdir
24397         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24398                 error "Fail to create $DIR/$tdir/dir0"
24399
24400         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24401         local dev=$(mdsdevname 2)
24402
24403         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24404                 grep ${fid} || error "NOT found agent entry for dir0"
24405
24406         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24407                 error "Fail to create $DIR/$tdir/dir1"
24408
24409         touch $DIR/$tdir/dir1/foo0 ||
24410                 error "Fail to create $DIR/$tdir/dir1/foo0"
24411         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24412         local rc=0
24413
24414         for idx in $(seq $MDSCOUNT); do
24415                 dev=$(mdsdevname $idx)
24416                 do_facet mds${idx} \
24417                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24418                         grep ${fid} && rc=$idx
24419         done
24420
24421         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24422                 error "Fail to rename foo0 to foo1"
24423         if [ $rc -eq 0 ]; then
24424                 for idx in $(seq $MDSCOUNT); do
24425                         dev=$(mdsdevname $idx)
24426                         do_facet mds${idx} \
24427                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24428                         grep ${fid} && rc=$idx
24429                 done
24430         fi
24431
24432         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24433                 error "Fail to rename foo1 to foo2"
24434         if [ $rc -eq 0 ]; then
24435                 for idx in $(seq $MDSCOUNT); do
24436                         dev=$(mdsdevname $idx)
24437                         do_facet mds${idx} \
24438                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24439                         grep ${fid} && rc=$idx
24440                 done
24441         fi
24442
24443         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24444
24445         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24446                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24447         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24448                 error "Fail to rename foo2 to foo0"
24449         unlink $DIR/$tdir/dir1/foo0 ||
24450                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24451         rm -rf $DIR/$tdir/dir0 ||
24452                 error "Fail to rm $DIR/$tdir/dir0"
24453
24454         for idx in $(seq $MDSCOUNT); do
24455                 dev=$(mdsdevname $idx)
24456                 rc=0
24457
24458                 stop mds${idx}
24459                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24460                         rc=$?
24461                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24462                         error "mount mds$idx failed"
24463                 df $MOUNT > /dev/null 2>&1
24464
24465                 # e2fsck should not return error
24466                 [ $rc -eq 0 ] ||
24467                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24468         done
24469 }
24470 run_test 804 "verify agent entry for remote entry"
24471
24472 cleanup_805() {
24473         do_facet $SINGLEMDS zfs set quota=$old $fsset
24474         unlinkmany $DIR/$tdir/f- 1000000
24475         trap 0
24476 }
24477
24478 test_805() {
24479         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24480         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24481         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24482                 skip "netfree not implemented before 0.7"
24483         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24484                 skip "Need MDS version at least 2.10.57"
24485
24486         local fsset
24487         local freekb
24488         local usedkb
24489         local old
24490         local quota
24491         local pref="osd-zfs.$FSNAME-MDT0000."
24492
24493         # limit available space on MDS dataset to meet nospace issue
24494         # quickly. then ZFS 0.7.2 can use reserved space if asked
24495         # properly (using netfree flag in osd_declare_destroy()
24496         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24497         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24498                 gawk '{print $3}')
24499         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24500         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24501         let "usedkb=usedkb-freekb"
24502         let "freekb=freekb/2"
24503         if let "freekb > 5000"; then
24504                 let "freekb=5000"
24505         fi
24506         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24507         trap cleanup_805 EXIT
24508         mkdir $DIR/$tdir
24509         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24510                 error "Can't set PFL layout"
24511         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24512         rm -rf $DIR/$tdir || error "not able to remove"
24513         do_facet $SINGLEMDS zfs set quota=$old $fsset
24514         trap 0
24515 }
24516 run_test 805 "ZFS can remove from full fs"
24517
24518 # Size-on-MDS test
24519 check_lsom_data()
24520 {
24521         local file=$1
24522         local size=$($LFS getsom -s $file)
24523         local expect=$(stat -c %s $file)
24524
24525         [[ $size == $expect ]] ||
24526                 error "$file expected size: $expect, got: $size"
24527
24528         local blocks=$($LFS getsom -b $file)
24529         expect=$(stat -c %b $file)
24530         [[ $blocks == $expect ]] ||
24531                 error "$file expected blocks: $expect, got: $blocks"
24532 }
24533
24534 check_lsom_size()
24535 {
24536         local size=$($LFS getsom -s $1)
24537         local expect=$2
24538
24539         [[ $size == $expect ]] ||
24540                 error "$file expected size: $expect, got: $size"
24541 }
24542
24543 test_806() {
24544         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24545                 skip "Need MDS version at least 2.11.52"
24546
24547         local bs=1048576
24548
24549         touch $DIR/$tfile || error "touch $tfile failed"
24550
24551         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24552         save_lustre_params client "llite.*.xattr_cache" > $save
24553         lctl set_param llite.*.xattr_cache=0
24554         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24555
24556         # single-threaded write
24557         echo "Test SOM for single-threaded write"
24558         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24559                 error "write $tfile failed"
24560         check_lsom_size $DIR/$tfile $bs
24561
24562         local num=32
24563         local size=$(($num * $bs))
24564         local offset=0
24565         local i
24566
24567         echo "Test SOM for single client multi-threaded($num) write"
24568         $TRUNCATE $DIR/$tfile 0
24569         for ((i = 0; i < $num; i++)); do
24570                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24571                 local pids[$i]=$!
24572                 offset=$((offset + $bs))
24573         done
24574         for (( i=0; i < $num; i++ )); do
24575                 wait ${pids[$i]}
24576         done
24577         check_lsom_size $DIR/$tfile $size
24578
24579         $TRUNCATE $DIR/$tfile 0
24580         for ((i = 0; i < $num; i++)); do
24581                 offset=$((offset - $bs))
24582                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24583                 local pids[$i]=$!
24584         done
24585         for (( i=0; i < $num; i++ )); do
24586                 wait ${pids[$i]}
24587         done
24588         check_lsom_size $DIR/$tfile $size
24589
24590         # multi-client writes
24591         num=$(get_node_count ${CLIENTS//,/ })
24592         size=$(($num * $bs))
24593         offset=0
24594         i=0
24595
24596         echo "Test SOM for multi-client ($num) writes"
24597         $TRUNCATE $DIR/$tfile 0
24598         for client in ${CLIENTS//,/ }; do
24599                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24600                 local pids[$i]=$!
24601                 i=$((i + 1))
24602                 offset=$((offset + $bs))
24603         done
24604         for (( i=0; i < $num; i++ )); do
24605                 wait ${pids[$i]}
24606         done
24607         check_lsom_size $DIR/$tfile $offset
24608
24609         i=0
24610         $TRUNCATE $DIR/$tfile 0
24611         for client in ${CLIENTS//,/ }; do
24612                 offset=$((offset - $bs))
24613                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24614                 local pids[$i]=$!
24615                 i=$((i + 1))
24616         done
24617         for (( i=0; i < $num; i++ )); do
24618                 wait ${pids[$i]}
24619         done
24620         check_lsom_size $DIR/$tfile $size
24621
24622         # verify truncate
24623         echo "Test SOM for truncate"
24624         $TRUNCATE $DIR/$tfile 1048576
24625         check_lsom_size $DIR/$tfile 1048576
24626         $TRUNCATE $DIR/$tfile 1234
24627         check_lsom_size $DIR/$tfile 1234
24628
24629         # verify SOM blocks count
24630         echo "Verify SOM block count"
24631         $TRUNCATE $DIR/$tfile 0
24632         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24633                 error "failed to write file $tfile"
24634         check_lsom_data $DIR/$tfile
24635 }
24636 run_test 806 "Verify Lazy Size on MDS"
24637
24638 test_807() {
24639         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24640         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24641                 skip "Need MDS version at least 2.11.52"
24642
24643         # Registration step
24644         changelog_register || error "changelog_register failed"
24645         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24646         changelog_users $SINGLEMDS | grep -q $cl_user ||
24647                 error "User $cl_user not found in changelog_users"
24648
24649         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24650         save_lustre_params client "llite.*.xattr_cache" > $save
24651         lctl set_param llite.*.xattr_cache=0
24652         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24653
24654         rm -rf $DIR/$tdir || error "rm $tdir failed"
24655         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24656         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24657         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24658         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24659                 error "truncate $tdir/trunc failed"
24660
24661         local bs=1048576
24662         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24663                 error "write $tfile failed"
24664
24665         # multi-client wirtes
24666         local num=$(get_node_count ${CLIENTS//,/ })
24667         local offset=0
24668         local i=0
24669
24670         echo "Test SOM for multi-client ($num) writes"
24671         touch $DIR/$tfile || error "touch $tfile failed"
24672         $TRUNCATE $DIR/$tfile 0
24673         for client in ${CLIENTS//,/ }; do
24674                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24675                 local pids[$i]=$!
24676                 i=$((i + 1))
24677                 offset=$((offset + $bs))
24678         done
24679         for (( i=0; i < $num; i++ )); do
24680                 wait ${pids[$i]}
24681         done
24682
24683         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24684         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24685         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24686         check_lsom_data $DIR/$tdir/trunc
24687         check_lsom_data $DIR/$tdir/single_dd
24688         check_lsom_data $DIR/$tfile
24689
24690         rm -rf $DIR/$tdir
24691         # Deregistration step
24692         changelog_deregister || error "changelog_deregister failed"
24693 }
24694 run_test 807 "verify LSOM syncing tool"
24695
24696 check_som_nologged()
24697 {
24698         local lines=$($LFS changelog $FSNAME-MDT0000 |
24699                 grep 'x=trusted.som' | wc -l)
24700         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24701 }
24702
24703 test_808() {
24704         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24705                 skip "Need MDS version at least 2.11.55"
24706
24707         # Registration step
24708         changelog_register || error "changelog_register failed"
24709
24710         touch $DIR/$tfile || error "touch $tfile failed"
24711         check_som_nologged
24712
24713         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24714                 error "write $tfile failed"
24715         check_som_nologged
24716
24717         $TRUNCATE $DIR/$tfile 1234
24718         check_som_nologged
24719
24720         $TRUNCATE $DIR/$tfile 1048576
24721         check_som_nologged
24722
24723         # Deregistration step
24724         changelog_deregister || error "changelog_deregister failed"
24725 }
24726 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24727
24728 check_som_nodata()
24729 {
24730         $LFS getsom $1
24731         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24732 }
24733
24734 test_809() {
24735         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24736                 skip "Need MDS version at least 2.11.56"
24737
24738         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24739                 error "failed to create DoM-only file $DIR/$tfile"
24740         touch $DIR/$tfile || error "touch $tfile failed"
24741         check_som_nodata $DIR/$tfile
24742
24743         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24744                 error "write $tfile failed"
24745         check_som_nodata $DIR/$tfile
24746
24747         $TRUNCATE $DIR/$tfile 1234
24748         check_som_nodata $DIR/$tfile
24749
24750         $TRUNCATE $DIR/$tfile 4097
24751         check_som_nodata $DIR/$file
24752 }
24753 run_test 809 "Verify no SOM xattr store for DoM-only files"
24754
24755 test_810() {
24756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24757         $GSS && skip_env "could not run with gss"
24758         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24759                 skip "OST < 2.12.58 doesn't align checksum"
24760
24761         set_checksums 1
24762         stack_trap "set_checksums $ORIG_CSUM" EXIT
24763         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24764
24765         local csum
24766         local before
24767         local after
24768         for csum in $CKSUM_TYPES; do
24769                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24770                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24771                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24772                         eval set -- $i
24773                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24774                         before=$(md5sum $DIR/$tfile)
24775                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24776                         after=$(md5sum $DIR/$tfile)
24777                         [ "$before" == "$after" ] ||
24778                                 error "$csum: $before != $after bs=$1 seek=$2"
24779                 done
24780         done
24781 }
24782 run_test 810 "partial page writes on ZFS (LU-11663)"
24783
24784 test_812a() {
24785         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24786                 skip "OST < 2.12.51 doesn't support this fail_loc"
24787
24788         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24789         # ensure ost1 is connected
24790         stat $DIR/$tfile >/dev/null || error "can't stat"
24791         wait_osc_import_state client ost1 FULL
24792         # no locks, no reqs to let the connection idle
24793         cancel_lru_locks osc
24794
24795         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24796 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24797         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24798         wait_osc_import_state client ost1 CONNECTING
24799         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24800
24801         stat $DIR/$tfile >/dev/null || error "can't stat file"
24802 }
24803 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24804
24805 test_812b() { # LU-12378
24806         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24807                 skip "OST < 2.12.51 doesn't support this fail_loc"
24808
24809         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24810         # ensure ost1 is connected
24811         stat $DIR/$tfile >/dev/null || error "can't stat"
24812         wait_osc_import_state client ost1 FULL
24813         # no locks, no reqs to let the connection idle
24814         cancel_lru_locks osc
24815
24816         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24817 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24818         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24819         wait_osc_import_state client ost1 CONNECTING
24820         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24821
24822         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24823         wait_osc_import_state client ost1 IDLE
24824 }
24825 run_test 812b "do not drop no resend request for idle connect"
24826
24827 test_813() {
24828         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24829         [ -z "$file_heat_sav" ] && skip "no file heat support"
24830
24831         local readsample
24832         local writesample
24833         local readbyte
24834         local writebyte
24835         local readsample1
24836         local writesample1
24837         local readbyte1
24838         local writebyte1
24839
24840         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24841         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24842
24843         $LCTL set_param -n llite.*.file_heat=1
24844         echo "Turn on file heat"
24845         echo "Period second: $period_second, Decay percentage: $decay_pct"
24846
24847         echo "QQQQ" > $DIR/$tfile
24848         echo "QQQQ" > $DIR/$tfile
24849         echo "QQQQ" > $DIR/$tfile
24850         cat $DIR/$tfile > /dev/null
24851         cat $DIR/$tfile > /dev/null
24852         cat $DIR/$tfile > /dev/null
24853         cat $DIR/$tfile > /dev/null
24854
24855         local out=$($LFS heat_get $DIR/$tfile)
24856
24857         $LFS heat_get $DIR/$tfile
24858         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24859         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24860         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24861         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24862
24863         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24864         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24865         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24866         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24867
24868         sleep $((period_second + 3))
24869         echo "Sleep $((period_second + 3)) seconds..."
24870         # The recursion formula to calculate the heat of the file f is as
24871         # follow:
24872         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24873         # Where Hi is the heat value in the period between time points i*I and
24874         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24875         # to the weight of Ci.
24876         out=$($LFS heat_get $DIR/$tfile)
24877         $LFS heat_get $DIR/$tfile
24878         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24879         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24880         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24881         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24882
24883         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24884                 error "read sample ($readsample) is wrong"
24885         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24886                 error "write sample ($writesample) is wrong"
24887         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24888                 error "read bytes ($readbyte) is wrong"
24889         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24890                 error "write bytes ($writebyte) is wrong"
24891
24892         echo "QQQQ" > $DIR/$tfile
24893         echo "QQQQ" > $DIR/$tfile
24894         echo "QQQQ" > $DIR/$tfile
24895         cat $DIR/$tfile > /dev/null
24896         cat $DIR/$tfile > /dev/null
24897         cat $DIR/$tfile > /dev/null
24898         cat $DIR/$tfile > /dev/null
24899
24900         sleep $((period_second + 3))
24901         echo "Sleep $((period_second + 3)) seconds..."
24902
24903         out=$($LFS heat_get $DIR/$tfile)
24904         $LFS heat_get $DIR/$tfile
24905         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24906         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24907         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24908         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24909
24910         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24911                 4 * $decay_pct) / 100") -eq 1 ] ||
24912                 error "read sample ($readsample1) is wrong"
24913         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24914                 3 * $decay_pct) / 100") -eq 1 ] ||
24915                 error "write sample ($writesample1) is wrong"
24916         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24917                 20 * $decay_pct) / 100") -eq 1 ] ||
24918                 error "read bytes ($readbyte1) is wrong"
24919         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24920                 15 * $decay_pct) / 100") -eq 1 ] ||
24921                 error "write bytes ($writebyte1) is wrong"
24922
24923         echo "Turn off file heat for the file $DIR/$tfile"
24924         $LFS heat_set -o $DIR/$tfile
24925
24926         echo "QQQQ" > $DIR/$tfile
24927         echo "QQQQ" > $DIR/$tfile
24928         echo "QQQQ" > $DIR/$tfile
24929         cat $DIR/$tfile > /dev/null
24930         cat $DIR/$tfile > /dev/null
24931         cat $DIR/$tfile > /dev/null
24932         cat $DIR/$tfile > /dev/null
24933
24934         out=$($LFS heat_get $DIR/$tfile)
24935         $LFS heat_get $DIR/$tfile
24936         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24937         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24938         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24939         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24940
24941         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24942         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24943         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24944         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24945
24946         echo "Trun on file heat for the file $DIR/$tfile"
24947         $LFS heat_set -O $DIR/$tfile
24948
24949         echo "QQQQ" > $DIR/$tfile
24950         echo "QQQQ" > $DIR/$tfile
24951         echo "QQQQ" > $DIR/$tfile
24952         cat $DIR/$tfile > /dev/null
24953         cat $DIR/$tfile > /dev/null
24954         cat $DIR/$tfile > /dev/null
24955         cat $DIR/$tfile > /dev/null
24956
24957         out=$($LFS heat_get $DIR/$tfile)
24958         $LFS heat_get $DIR/$tfile
24959         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24960         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24961         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24962         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24963
24964         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24965         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24966         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24967         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24968
24969         $LFS heat_set -c $DIR/$tfile
24970         $LCTL set_param -n llite.*.file_heat=0
24971         echo "Turn off file heat support for the Lustre filesystem"
24972
24973         echo "QQQQ" > $DIR/$tfile
24974         echo "QQQQ" > $DIR/$tfile
24975         echo "QQQQ" > $DIR/$tfile
24976         cat $DIR/$tfile > /dev/null
24977         cat $DIR/$tfile > /dev/null
24978         cat $DIR/$tfile > /dev/null
24979         cat $DIR/$tfile > /dev/null
24980
24981         out=$($LFS heat_get $DIR/$tfile)
24982         $LFS heat_get $DIR/$tfile
24983         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24984         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24985         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24986         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24987
24988         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24989         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24990         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24991         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24992
24993         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24994         rm -f $DIR/$tfile
24995 }
24996 run_test 813 "File heat verfication"
24997
24998 test_814()
24999 {
25000         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25001         echo -n y >> $DIR/$tfile
25002         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25003         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25004 }
25005 run_test 814 "sparse cp works as expected (LU-12361)"
25006
25007 test_815()
25008 {
25009         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25010         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25011 }
25012 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25013
25014 test_816() {
25015         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25016         # ensure ost1 is connected
25017         stat $DIR/$tfile >/dev/null || error "can't stat"
25018         wait_osc_import_state client ost1 FULL
25019         # no locks, no reqs to let the connection idle
25020         cancel_lru_locks osc
25021         lru_resize_disable osc
25022         local before
25023         local now
25024         before=$($LCTL get_param -n \
25025                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25026
25027         wait_osc_import_state client ost1 IDLE
25028         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25029         now=$($LCTL get_param -n \
25030               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25031         [ $before == $now ] || error "lru_size changed $before != $now"
25032 }
25033 run_test 816 "do not reset lru_resize on idle reconnect"
25034
25035 cleanup_817() {
25036         umount $tmpdir
25037         exportfs -u localhost:$DIR/nfsexp
25038         rm -rf $DIR/nfsexp
25039 }
25040
25041 test_817() {
25042         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25043
25044         mkdir -p $DIR/nfsexp
25045         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25046                 error "failed to export nfs"
25047
25048         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25049         stack_trap cleanup_817 EXIT
25050
25051         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25052                 error "failed to mount nfs to $tmpdir"
25053
25054         cp /bin/true $tmpdir
25055         $DIR/nfsexp/true || error "failed to execute 'true' command"
25056 }
25057 run_test 817 "nfsd won't cache write lock for exec file"
25058
25059 test_818() {
25060         mkdir $DIR/$tdir
25061         $LFS setstripe -c1 -i0 $DIR/$tfile
25062         $LFS setstripe -c1 -i1 $DIR/$tfile
25063         stop $SINGLEMDS
25064         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25065         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25066         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25067                 error "start $SINGLEMDS failed"
25068         rm -rf $DIR/$tdir
25069 }
25070 run_test 818 "unlink with failed llog"
25071
25072 test_819a() {
25073         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25074         cancel_lru_locks osc
25075         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25076         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25077         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25078         rm -f $TDIR/$tfile
25079 }
25080 run_test 819a "too big niobuf in read"
25081
25082 test_819b() {
25083         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25084         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25085         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25086         cancel_lru_locks osc
25087         sleep 1
25088         rm -f $TDIR/$tfile
25089 }
25090 run_test 819b "too big niobuf in write"
25091
25092
25093 function test_820_start_ost() {
25094         sleep 5
25095
25096         for num in $(seq $OSTCOUNT); do
25097                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25098         done
25099 }
25100
25101 test_820() {
25102         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25103
25104         mkdir $DIR/$tdir
25105         umount_client $MOUNT || error "umount failed"
25106         for num in $(seq $OSTCOUNT); do
25107                 stop ost$num
25108         done
25109
25110         # mount client with no active OSTs
25111         # so that the client can't initialize max LOV EA size
25112         # from OSC notifications
25113         mount_client $MOUNT || error "mount failed"
25114         # delay OST starting to keep this 0 max EA size for a while
25115         test_820_start_ost &
25116
25117         # create a directory on MDS2
25118         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25119                 error "Failed to create directory"
25120         # open intent should update default EA size
25121         # see mdc_update_max_ea_from_body()
25122         # notice this is the very first RPC to MDS2
25123         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25124         ret=$?
25125         echo $out
25126         # With SSK, this situation can lead to -EPERM being returned.
25127         # In that case, simply retry.
25128         if [ $ret -ne 0 ] && $SHARED_KEY; then
25129                 if echo "$out" | grep -q "not permitted"; then
25130                         cp /etc/services $DIR/$tdir/mds2
25131                         ret=$?
25132                 fi
25133         fi
25134         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25135 }
25136 run_test 820 "update max EA from open intent"
25137
25138 #
25139 # tests that do cleanup/setup should be run at the end
25140 #
25141
25142 test_900() {
25143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25144         local ls
25145
25146         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25147         $LCTL set_param fail_loc=0x903
25148
25149         cancel_lru_locks MGC
25150
25151         FAIL_ON_ERROR=true cleanup
25152         FAIL_ON_ERROR=true setup
25153 }
25154 run_test 900 "umount should not race with any mgc requeue thread"
25155
25156 # LUS-6253/LU-11185
25157 test_901() {
25158         local oldc
25159         local newc
25160         local olds
25161         local news
25162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25163
25164         # some get_param have a bug to handle dot in param name
25165         cancel_lru_locks MGC
25166         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25167         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25168         umount_client $MOUNT || error "umount failed"
25169         mount_client $MOUNT || error "mount failed"
25170         cancel_lru_locks MGC
25171         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25172         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25173
25174         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25175         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25176
25177         return 0
25178 }
25179 run_test 901 "don't leak a mgc lock on client umount"
25180
25181 # LU-13377
25182 test_902() {
25183         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25184                 skip "client does not have LU-13377 fix"
25185         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25186         $LCTL set_param fail_loc=0x1415
25187         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25188         cancel_lru_locks osc
25189         rm -f $DIR/$tfile
25190 }
25191 run_test 902 "test short write doesn't hang lustre"
25192
25193 complete $SECONDS
25194 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25195 check_and_cleanup_lustre
25196 if [ "$I_MOUNTED" != "yes" ]; then
25197         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25198 fi
25199 exit_status