Whamcloud - gitweb
8a6313ddd2c7d6578d4a7896e60185dd852c42fa
[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 cleanup_test32_mount() {
3351         local rc=0
3352         trap 0
3353         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3354         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3355         losetup -d $loopdev || true
3356         rm -rf $DIR/$tdir
3357         return $rc
3358 }
3359
3360 test_32a() {
3361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3362
3363         echo "== more mountpoints and symlinks ================="
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3371         cleanup_test32_mount
3372 }
3373 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3374
3375 test_32b() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3384                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3385         cleanup_test32_mount
3386 }
3387 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3388
3389 test_32c() {
3390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3391
3392         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3393         trap cleanup_test32_mount EXIT
3394         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3395         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3396                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3397         test_mkdir -p $DIR/$tdir/d2/test_dir
3398         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3399                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3400         cleanup_test32_mount
3401 }
3402 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3403
3404 test_32d() {
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         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3414                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3415         cleanup_test32_mount
3416 }
3417 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3418
3419 test_32e() {
3420         rm -fr $DIR/$tdir
3421         test_mkdir -p $DIR/$tdir/tmp
3422         local tmp_dir=$DIR/$tdir/tmp
3423         ln -s $DIR/$tdir $tmp_dir/symlink11
3424         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3425         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3426         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3427 }
3428 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3429
3430 test_32f() {
3431         rm -fr $DIR/$tdir
3432         test_mkdir -p $DIR/$tdir/tmp
3433         local tmp_dir=$DIR/$tdir/tmp
3434         ln -s $DIR/$tdir $tmp_dir/symlink11
3435         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3436         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3437         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3438 }
3439 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3440
3441 test_32g() {
3442         local tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3448         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3449         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3450         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3451 }
3452 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3453
3454 test_32h() {
3455         rm -fr $DIR/$tdir $DIR/${tdir}2
3456         tmp_dir=$DIR/$tdir/tmp
3457         test_mkdir -p $tmp_dir
3458         test_mkdir $DIR/${tdir}2
3459         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3460         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3461         ls $tmp_dir/symlink12 || error "listing symlink12"
3462         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3463 }
3464 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3465
3466 test_32i() {
3467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3468
3469         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3470         trap cleanup_test32_mount EXIT
3471         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3472         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3473                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3474         touch $DIR/$tdir/test_file
3475         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3476                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3477         cleanup_test32_mount
3478 }
3479 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3480
3481 test_32j() {
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         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3491                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3492         cleanup_test32_mount
3493 }
3494 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3495
3496 test_32k() {
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         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         test_mkdir -p $DIR/$tdir/d2
3505         touch $DIR/$tdir/d2/test_file || error "touch failed"
3506         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3507                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3508         cleanup_test32_mount
3509 }
3510 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3511
3512 test_32l() {
3513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3514
3515         rm -fr $DIR/$tdir
3516         trap cleanup_test32_mount EXIT
3517         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3518         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3519                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3520         test_mkdir -p $DIR/$tdir/d2
3521         touch $DIR/$tdir/d2/test_file || error "touch failed"
3522         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3523                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3524         cleanup_test32_mount
3525 }
3526 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3527
3528 test_32m() {
3529         rm -fr $DIR/d32m
3530         test_mkdir -p $DIR/d32m/tmp
3531         TMP_DIR=$DIR/d32m/tmp
3532         ln -s $DIR $TMP_DIR/symlink11
3533         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3534         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3535                 error "symlink11 not a link"
3536         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3537                 error "symlink01 not a link"
3538 }
3539 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3540
3541 test_32n() {
3542         rm -fr $DIR/d32n
3543         test_mkdir -p $DIR/d32n/tmp
3544         TMP_DIR=$DIR/d32n/tmp
3545         ln -s $DIR $TMP_DIR/symlink11
3546         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3547         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3548         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3549 }
3550 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3551
3552 test_32o() {
3553         touch $DIR/$tfile
3554         test_mkdir -p $DIR/d32o/tmp
3555         TMP_DIR=$DIR/d32o/tmp
3556         ln -s $DIR/$tfile $TMP_DIR/symlink12
3557         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3558         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3559                 error "symlink12 not a link"
3560         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3561         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3562                 error "$DIR/d32o/tmp/symlink12 not file type"
3563         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3564                 error "$DIR/d32o/symlink02 not file type"
3565 }
3566 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3567
3568 test_32p() {
3569         log 32p_1
3570         rm -fr $DIR/d32p
3571         log 32p_2
3572         rm -f $DIR/$tfile
3573         log 32p_3
3574         touch $DIR/$tfile
3575         log 32p_4
3576         test_mkdir -p $DIR/d32p/tmp
3577         log 32p_5
3578         TMP_DIR=$DIR/d32p/tmp
3579         log 32p_6
3580         ln -s $DIR/$tfile $TMP_DIR/symlink12
3581         log 32p_7
3582         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3583         log 32p_8
3584         cat $DIR/d32p/tmp/symlink12 ||
3585                 error "Can't open $DIR/d32p/tmp/symlink12"
3586         log 32p_9
3587         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3588         log 32p_10
3589 }
3590 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3591
3592 test_32q() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3602         cleanup_test32_mount
3603 }
3604 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3605
3606 test_32r() {
3607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3608
3609         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3610         trap cleanup_test32_mount EXIT
3611         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3612         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3613         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3614                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3615         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3616         cleanup_test32_mount
3617 }
3618 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3619
3620 test_33aa() {
3621         rm -f $DIR/$tfile
3622         touch $DIR/$tfile
3623         chmod 444 $DIR/$tfile
3624         chown $RUNAS_ID $DIR/$tfile
3625         log 33_1
3626         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3627         log 33_2
3628 }
3629 run_test 33aa "write file with mode 444 (should return error)"
3630
3631 test_33a() {
3632         rm -fr $DIR/$tdir
3633         test_mkdir $DIR/$tdir
3634         chown $RUNAS_ID $DIR/$tdir
3635         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3636                 error "$RUNAS create $tdir/$tfile failed"
3637         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3638                 error "open RDWR" || true
3639 }
3640 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3641
3642 test_33b() {
3643         rm -fr $DIR/$tdir
3644         test_mkdir $DIR/$tdir
3645         chown $RUNAS_ID $DIR/$tdir
3646         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3647 }
3648 run_test 33b "test open file with malformed flags (No panic)"
3649
3650 test_33c() {
3651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3652         remote_ost_nodsh && skip "remote OST with nodsh"
3653
3654         local ostnum
3655         local ostname
3656         local write_bytes
3657         local all_zeros
3658
3659         all_zeros=:
3660         rm -fr $DIR/$tdir
3661         test_mkdir $DIR/$tdir
3662         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3663
3664         sync
3665         for ostnum in $(seq $OSTCOUNT); do
3666                 # test-framework's OST numbering is one-based, while Lustre's
3667                 # is zero-based
3668                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3669                 # Parsing llobdstat's output sucks; we could grep the /proc
3670                 # path, but that's likely to not be as portable as using the
3671                 # llobdstat utility.  So we parse lctl output instead.
3672                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3673                         obdfilter/$ostname/stats |
3674                         awk '/^write_bytes/ {print $7}' )
3675                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3676                 if (( ${write_bytes:-0} > 0 ))
3677                 then
3678                         all_zeros=false
3679                         break;
3680                 fi
3681         done
3682
3683         $all_zeros || return 0
3684
3685         # Write four bytes
3686         echo foo > $DIR/$tdir/bar
3687         # Really write them
3688         sync
3689
3690         # Total up write_bytes after writing.  We'd better find non-zeros.
3691         for ostnum in $(seq $OSTCOUNT); do
3692                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3693                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3694                         obdfilter/$ostname/stats |
3695                         awk '/^write_bytes/ {print $7}' )
3696                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3697                 if (( ${write_bytes:-0} > 0 ))
3698                 then
3699                         all_zeros=false
3700                         break;
3701                 fi
3702         done
3703
3704         if $all_zeros
3705         then
3706                 for ostnum in $(seq $OSTCOUNT); do
3707                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3708                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3709                         do_facet ost$ostnum lctl get_param -n \
3710                                 obdfilter/$ostname/stats
3711                 done
3712                 error "OST not keeping write_bytes stats (b22312)"
3713         fi
3714 }
3715 run_test 33c "test llobdstat and write_bytes"
3716
3717 test_33d() {
3718         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3720
3721         local MDTIDX=1
3722         local remote_dir=$DIR/$tdir/remote_dir
3723
3724         test_mkdir $DIR/$tdir
3725         $LFS mkdir -i $MDTIDX $remote_dir ||
3726                 error "create remote directory failed"
3727
3728         touch $remote_dir/$tfile
3729         chmod 444 $remote_dir/$tfile
3730         chown $RUNAS_ID $remote_dir/$tfile
3731
3732         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3733
3734         chown $RUNAS_ID $remote_dir
3735         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3736                                         error "create" || true
3737         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3738                                     error "open RDWR" || true
3739         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3740 }
3741 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3742
3743 test_33e() {
3744         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3745
3746         mkdir $DIR/$tdir
3747
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir failed"
3760
3761         umask 777
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3772
3773         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3774
3775         umask 000
3776         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3777         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3778         mkdir $DIR/$tdir/local_dir
3779
3780         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3781         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3782         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3783
3784         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3785                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3786 }
3787 run_test 33e "mkdir and striped directory should have same mode"
3788
3789 cleanup_33f() {
3790         trap 0
3791         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3792 }
3793
3794 test_33f() {
3795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3796         remote_mds_nodsh && skip "remote MDS with nodsh"
3797
3798         mkdir $DIR/$tdir
3799         chmod go+rwx $DIR/$tdir
3800         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3801         trap cleanup_33f EXIT
3802
3803         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3804                 error "cannot create striped directory"
3805
3806         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3807                 error "cannot create files in striped directory"
3808
3809         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3810                 error "cannot remove files in striped directory"
3811
3812         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3813                 error "cannot remove striped directory"
3814
3815         cleanup_33f
3816 }
3817 run_test 33f "nonroot user can create, access, and remove a striped directory"
3818
3819 test_33g() {
3820         mkdir -p $DIR/$tdir/dir2
3821
3822         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3823         echo $err
3824         [[ $err =~ "exists" ]] || error "Not exists error"
3825 }
3826 run_test 33g "nonroot user create already existing root created file"
3827
3828 test_33h() {
3829         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3830         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3831                 skip "Need MDS version at least 2.13.50"
3832
3833         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3834                 error "mkdir $tdir failed"
3835         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3836
3837         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3838         local index2
3839
3840         for fname in $DIR/$tdir/$tfile.bak \
3841                      $DIR/$tdir/$tfile.SAV \
3842                      $DIR/$tdir/$tfile.orig \
3843                      $DIR/$tdir/$tfile~; do
3844                 touch $fname  || error "touch $fname failed"
3845                 index2=$($LFS getstripe -m $fname)
3846                 [ $index -eq $index2 ] ||
3847                         error "$fname MDT index mismatch $index != $index2"
3848         done
3849
3850         local failed=0
3851         for i in {1..250}; do
3852                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3853                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3854                         touch $fname  || error "touch $fname failed"
3855                         index2=$($LFS getstripe -m $fname)
3856                         if [[ $index != $index2 ]]; then
3857                                 failed=$((failed + 1))
3858                                 echo "$fname MDT index mismatch $index != $index2"
3859                         fi
3860                 done
3861         done
3862         echo "$failed MDT index mismatches"
3863         (( failed < 20 )) || error "MDT index mismatch $failed times"
3864
3865 }
3866 run_test 33h "temp file is located on the same MDT as target"
3867
3868 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3869 test_34a() {
3870         rm -f $DIR/f34
3871         $MCREATE $DIR/f34 || error "mcreate failed"
3872         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3873                 error "getstripe failed"
3874         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3875         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3876                 error "getstripe failed"
3877         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3878                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3879 }
3880 run_test 34a "truncate file that has not been opened ==========="
3881
3882 test_34b() {
3883         [ ! -f $DIR/f34 ] && test_34a
3884         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3885                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3886         $OPENFILE -f O_RDONLY $DIR/f34
3887         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3888                 error "getstripe failed"
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891 }
3892 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3893
3894 test_34c() {
3895         [ ! -f $DIR/f34 ] && test_34a
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         $OPENFILE -f O_RDWR $DIR/f34
3899         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3900                 error "$LFS getstripe failed"
3901         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3902                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3903 }
3904 run_test 34c "O_RDWR opening file-with-size works =============="
3905
3906 test_34d() {
3907         [ ! -f $DIR/f34 ] && test_34a
3908         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3909                 error "dd failed"
3910         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3911                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3912         rm $DIR/f34
3913 }
3914 run_test 34d "write to sparse file ============================="
3915
3916 test_34e() {
3917         rm -f $DIR/f34e
3918         $MCREATE $DIR/f34e || error "mcreate failed"
3919         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3920         $CHECKSTAT -s 1000 $DIR/f34e ||
3921                 error "Size of $DIR/f34e not equal to 1000 bytes"
3922         $OPENFILE -f O_RDWR $DIR/f34e
3923         $CHECKSTAT -s 1000 $DIR/f34e ||
3924                 error "Size of $DIR/f34e not equal to 1000 bytes"
3925 }
3926 run_test 34e "create objects, some with size and some without =="
3927
3928 test_34f() { # bug 6242, 6243
3929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3930
3931         SIZE34F=48000
3932         rm -f $DIR/f34f
3933         $MCREATE $DIR/f34f || error "mcreate failed"
3934         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3935         dd if=$DIR/f34f of=$TMP/f34f
3936         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3937         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3938         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3939         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3940         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3941 }
3942 run_test 34f "read from a file with no objects until EOF ======="
3943
3944 test_34g() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3948                 error "dd failed"
3949         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3950         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3951                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3952         cancel_lru_locks osc
3953         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3954                 error "wrong size after lock cancel"
3955
3956         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3957         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3958                 error "expanding truncate failed"
3959         cancel_lru_locks osc
3960         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3961                 error "wrong expanded size after lock cancel"
3962 }
3963 run_test 34g "truncate long file ==============================="
3964
3965 test_34h() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         local gid=10
3969         local sz=1000
3970
3971         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3972         sync # Flush the cache so that multiop below does not block on cache
3973              # flush when getting the group lock
3974         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3975         MULTIPID=$!
3976
3977         # Since just timed wait is not good enough, let's do a sync write
3978         # that way we are sure enough time for a roundtrip + processing
3979         # passed + 2 seconds of extra margin.
3980         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3981         rm $DIR/${tfile}-1
3982         sleep 2
3983
3984         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3985                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3986                 kill -9 $MULTIPID
3987         fi
3988         wait $MULTIPID
3989         local nsz=`stat -c %s $DIR/$tfile`
3990         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3991 }
3992 run_test 34h "ftruncate file under grouplock should not block"
3993
3994 test_35a() {
3995         cp /bin/sh $DIR/f35a
3996         chmod 444 $DIR/f35a
3997         chown $RUNAS_ID $DIR/f35a
3998         $RUNAS $DIR/f35a && error || true
3999         rm $DIR/f35a
4000 }
4001 run_test 35a "exec file with mode 444 (should return and not leak)"
4002
4003 test_36a() {
4004         rm -f $DIR/f36
4005         utime $DIR/f36 || error "utime failed for MDS"
4006 }
4007 run_test 36a "MDS utime check (mknod, utime)"
4008
4009 test_36b() {
4010         echo "" > $DIR/f36
4011         utime $DIR/f36 || error "utime failed for OST"
4012 }
4013 run_test 36b "OST utime check (open, utime)"
4014
4015 test_36c() {
4016         rm -f $DIR/d36/f36
4017         test_mkdir $DIR/d36
4018         chown $RUNAS_ID $DIR/d36
4019         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4020 }
4021 run_test 36c "non-root MDS utime check (mknod, utime)"
4022
4023 test_36d() {
4024         [ ! -d $DIR/d36 ] && test_36c
4025         echo "" > $DIR/d36/f36
4026         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4027 }
4028 run_test 36d "non-root OST utime check (open, utime)"
4029
4030 test_36e() {
4031         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4032
4033         test_mkdir $DIR/$tdir
4034         touch $DIR/$tdir/$tfile
4035         $RUNAS utime $DIR/$tdir/$tfile &&
4036                 error "utime worked, expected failure" || true
4037 }
4038 run_test 36e "utime on non-owned file (should return error)"
4039
4040 subr_36fh() {
4041         local fl="$1"
4042         local LANG_SAVE=$LANG
4043         local LC_LANG_SAVE=$LC_LANG
4044         export LANG=C LC_LANG=C # for date language
4045
4046         DATESTR="Dec 20  2000"
4047         test_mkdir $DIR/$tdir
4048         lctl set_param fail_loc=$fl
4049         date; date +%s
4050         cp /etc/hosts $DIR/$tdir/$tfile
4051         sync & # write RPC generated with "current" inode timestamp, but delayed
4052         sleep 1
4053         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4054         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4055         cancel_lru_locks $OSC
4056         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4057         date; date +%s
4058         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4059                 echo "BEFORE: $LS_BEFORE" && \
4060                 echo "AFTER : $LS_AFTER" && \
4061                 echo "WANT  : $DATESTR" && \
4062                 error "$DIR/$tdir/$tfile timestamps changed" || true
4063
4064         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4065 }
4066
4067 test_36f() {
4068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4069
4070         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4071         subr_36fh "0x80000214"
4072 }
4073 run_test 36f "utime on file racing with OST BRW write =========="
4074
4075 test_36g() {
4076         remote_ost_nodsh && skip "remote OST with nodsh"
4077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4078         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4079                 skip "Need MDS version at least 2.12.51"
4080
4081         local fmd_max_age
4082         local fmd
4083         local facet="ost1"
4084         local tgt="obdfilter"
4085
4086         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4087
4088         test_mkdir $DIR/$tdir
4089         fmd_max_age=$(do_facet $facet \
4090                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4091                 head -n 1")
4092
4093         echo "FMD max age: ${fmd_max_age}s"
4094         touch $DIR/$tdir/$tfile
4095         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4096                 gawk '{cnt=cnt+$1}  END{print cnt}')
4097         echo "FMD before: $fmd"
4098         [[ $fmd == 0 ]] &&
4099                 error "FMD wasn't create by touch"
4100         sleep $((fmd_max_age + 12))
4101         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4102                 gawk '{cnt=cnt+$1}  END{print cnt}')
4103         echo "FMD after: $fmd"
4104         [[ $fmd == 0 ]] ||
4105                 error "FMD wasn't expired by ping"
4106 }
4107 run_test 36g "FMD cache expiry ====================="
4108
4109 test_36h() {
4110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4111
4112         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4113         subr_36fh "0x80000227"
4114 }
4115 run_test 36h "utime on file racing with OST BRW write =========="
4116
4117 test_36i() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119
4120         test_mkdir $DIR/$tdir
4121         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4122
4123         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4124         local new_mtime=$((mtime + 200))
4125
4126         #change Modify time of striped dir
4127         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4128                         error "change mtime failed"
4129
4130         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4131
4132         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4133 }
4134 run_test 36i "change mtime on striped directory"
4135
4136 # test_37 - duplicate with tests 32q 32r
4137
4138 test_38() {
4139         local file=$DIR/$tfile
4140         touch $file
4141         openfile -f O_DIRECTORY $file
4142         local RC=$?
4143         local ENOTDIR=20
4144         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4145         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4146 }
4147 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4148
4149 test_39a() { # was test_39
4150         touch $DIR/$tfile
4151         touch $DIR/${tfile}2
4152 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4153 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4154 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4155         sleep 2
4156         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4157         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4158                 echo "mtime"
4159                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4160                 echo "atime"
4161                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4162                 echo "ctime"
4163                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4164                 error "O_TRUNC didn't change timestamps"
4165         fi
4166 }
4167 run_test 39a "mtime changed on create"
4168
4169 test_39b() {
4170         test_mkdir -c1 $DIR/$tdir
4171         cp -p /etc/passwd $DIR/$tdir/fopen
4172         cp -p /etc/passwd $DIR/$tdir/flink
4173         cp -p /etc/passwd $DIR/$tdir/funlink
4174         cp -p /etc/passwd $DIR/$tdir/frename
4175         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4176
4177         sleep 1
4178         echo "aaaaaa" >> $DIR/$tdir/fopen
4179         echo "aaaaaa" >> $DIR/$tdir/flink
4180         echo "aaaaaa" >> $DIR/$tdir/funlink
4181         echo "aaaaaa" >> $DIR/$tdir/frename
4182
4183         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4184         local link_new=`stat -c %Y $DIR/$tdir/flink`
4185         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4186         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4187
4188         cat $DIR/$tdir/fopen > /dev/null
4189         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4190         rm -f $DIR/$tdir/funlink2
4191         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4192
4193         for (( i=0; i < 2; i++ )) ; do
4194                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4195                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4196                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4197                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4198
4199                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4200                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4201                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4202                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4203
4204                 cancel_lru_locks $OSC
4205                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4206         done
4207 }
4208 run_test 39b "mtime change on open, link, unlink, rename  ======"
4209
4210 # this should be set to past
4211 TEST_39_MTIME=`date -d "1 year ago" +%s`
4212
4213 # bug 11063
4214 test_39c() {
4215         touch $DIR1/$tfile
4216         sleep 2
4217         local mtime0=`stat -c %Y $DIR1/$tfile`
4218
4219         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4220         local mtime1=`stat -c %Y $DIR1/$tfile`
4221         [ "$mtime1" = $TEST_39_MTIME ] || \
4222                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4223
4224         local d1=`date +%s`
4225         echo hello >> $DIR1/$tfile
4226         local d2=`date +%s`
4227         local mtime2=`stat -c %Y $DIR1/$tfile`
4228         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4229                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4230
4231         mv $DIR1/$tfile $DIR1/$tfile-1
4232
4233         for (( i=0; i < 2; i++ )) ; do
4234                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4235                 [ "$mtime2" = "$mtime3" ] || \
4236                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4237
4238                 cancel_lru_locks $OSC
4239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4240         done
4241 }
4242 run_test 39c "mtime change on rename ==========================="
4243
4244 # bug 21114
4245 test_39d() {
4246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4247
4248         touch $DIR1/$tfile
4249         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4250
4251         for (( i=0; i < 2; i++ )) ; do
4252                 local mtime=`stat -c %Y $DIR1/$tfile`
4253                 [ $mtime = $TEST_39_MTIME ] || \
4254                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4255
4256                 cancel_lru_locks $OSC
4257                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4258         done
4259 }
4260 run_test 39d "create, utime, stat =============================="
4261
4262 # bug 21114
4263 test_39e() {
4264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4265
4266         touch $DIR1/$tfile
4267         local mtime1=`stat -c %Y $DIR1/$tfile`
4268
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime2=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime2 = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39e "create, stat, utime, stat ========================"
4281
4282 # bug 21114
4283 test_39f() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         touch $DIR1/$tfile
4287         mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         sleep 2
4290         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294                 [ $mtime2 = $TEST_39_MTIME ] || \
4295                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4296
4297                 cancel_lru_locks $OSC
4298                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4299         done
4300 }
4301 run_test 39f "create, stat, sleep, utime, stat ================="
4302
4303 # bug 11063
4304 test_39g() {
4305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4306
4307         echo hello >> $DIR1/$tfile
4308         local mtime1=`stat -c %Y $DIR1/$tfile`
4309
4310         sleep 2
4311         chmod o+r $DIR1/$tfile
4312
4313         for (( i=0; i < 2; i++ )) ; do
4314                 local mtime2=`stat -c %Y $DIR1/$tfile`
4315                 [ "$mtime1" = "$mtime2" ] || \
4316                         error "lost mtime: $mtime2, should be $mtime1"
4317
4318                 cancel_lru_locks $OSC
4319                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4320         done
4321 }
4322 run_test 39g "write, chmod, stat ==============================="
4323
4324 # bug 11063
4325 test_39h() {
4326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4327
4328         touch $DIR1/$tfile
4329         sleep 1
4330
4331         local d1=`date`
4332         echo hello >> $DIR1/$tfile
4333         local mtime1=`stat -c %Y $DIR1/$tfile`
4334
4335         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4336         local d2=`date`
4337         if [ "$d1" != "$d2" ]; then
4338                 echo "write and touch not within one second"
4339         else
4340                 for (( i=0; i < 2; i++ )) ; do
4341                         local mtime2=`stat -c %Y $DIR1/$tfile`
4342                         [ "$mtime2" = $TEST_39_MTIME ] || \
4343                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4344
4345                         cancel_lru_locks $OSC
4346                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4347                 done
4348         fi
4349 }
4350 run_test 39h "write, utime within one second, stat ============="
4351
4352 test_39i() {
4353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4354
4355         touch $DIR1/$tfile
4356         sleep 1
4357
4358         echo hello >> $DIR1/$tfile
4359         local mtime1=`stat -c %Y $DIR1/$tfile`
4360
4361         mv $DIR1/$tfile $DIR1/$tfile-1
4362
4363         for (( i=0; i < 2; i++ )) ; do
4364                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4365
4366                 [ "$mtime1" = "$mtime2" ] || \
4367                         error "lost mtime: $mtime2, should be $mtime1"
4368
4369                 cancel_lru_locks $OSC
4370                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4371         done
4372 }
4373 run_test 39i "write, rename, stat =============================="
4374
4375 test_39j() {
4376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4377
4378         start_full_debug_logging
4379         touch $DIR1/$tfile
4380         sleep 1
4381
4382         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4383         lctl set_param fail_loc=0x80000412
4384         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4385                 error "multiop failed"
4386         local multipid=$!
4387         local mtime1=`stat -c %Y $DIR1/$tfile`
4388
4389         mv $DIR1/$tfile $DIR1/$tfile-1
4390
4391         kill -USR1 $multipid
4392         wait $multipid || error "multiop close failed"
4393
4394         for (( i=0; i < 2; i++ )) ; do
4395                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4396                 [ "$mtime1" = "$mtime2" ] ||
4397                         error "mtime is lost on close: $mtime2, " \
4398                               "should be $mtime1"
4399
4400                 cancel_lru_locks
4401                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4402         done
4403         lctl set_param fail_loc=0
4404         stop_full_debug_logging
4405 }
4406 run_test 39j "write, rename, close, stat ======================="
4407
4408 test_39k() {
4409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4410
4411         touch $DIR1/$tfile
4412         sleep 1
4413
4414         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4415         local multipid=$!
4416         local mtime1=`stat -c %Y $DIR1/$tfile`
4417
4418         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4419
4420         kill -USR1 $multipid
4421         wait $multipid || error "multiop close failed"
4422
4423         for (( i=0; i < 2; i++ )) ; do
4424                 local mtime2=`stat -c %Y $DIR1/$tfile`
4425
4426                 [ "$mtime2" = $TEST_39_MTIME ] || \
4427                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4428
4429                 cancel_lru_locks
4430                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4431         done
4432 }
4433 run_test 39k "write, utime, close, stat ========================"
4434
4435 # this should be set to future
4436 TEST_39_ATIME=`date -d "1 year" +%s`
4437
4438 test_39l() {
4439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4440         remote_mds_nodsh && skip "remote MDS with nodsh"
4441
4442         local atime_diff=$(do_facet $SINGLEMDS \
4443                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4444         rm -rf $DIR/$tdir
4445         mkdir -p $DIR/$tdir
4446
4447         # test setting directory atime to future
4448         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4449         local atime=$(stat -c %X $DIR/$tdir)
4450         [ "$atime" = $TEST_39_ATIME ] ||
4451                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4452
4453         # test setting directory atime from future to now
4454         local now=$(date +%s)
4455         touch -a -d @$now $DIR/$tdir
4456
4457         atime=$(stat -c %X $DIR/$tdir)
4458         [ "$atime" -eq "$now"  ] ||
4459                 error "atime is not updated from future: $atime, $now"
4460
4461         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4462         sleep 3
4463
4464         # test setting directory atime when now > dir atime + atime_diff
4465         local d1=$(date +%s)
4466         ls $DIR/$tdir
4467         local d2=$(date +%s)
4468         cancel_lru_locks mdc
4469         atime=$(stat -c %X $DIR/$tdir)
4470         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4471                 error "atime is not updated  : $atime, should be $d2"
4472
4473         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4474         sleep 3
4475
4476         # test not setting directory atime when now < dir atime + atime_diff
4477         ls $DIR/$tdir
4478         cancel_lru_locks mdc
4479         atime=$(stat -c %X $DIR/$tdir)
4480         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4481                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4482
4483         do_facet $SINGLEMDS \
4484                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4485 }
4486 run_test 39l "directory atime update ==========================="
4487
4488 test_39m() {
4489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4490
4491         touch $DIR1/$tfile
4492         sleep 2
4493         local far_past_mtime=$(date -d "May 29 1953" +%s)
4494         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4495
4496         touch -m -d @$far_past_mtime $DIR1/$tfile
4497         touch -a -d @$far_past_atime $DIR1/$tfile
4498
4499         for (( i=0; i < 2; i++ )) ; do
4500                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4501                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4502                         error "atime or mtime set incorrectly"
4503
4504                 cancel_lru_locks $OSC
4505                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4506         done
4507 }
4508 run_test 39m "test atime and mtime before 1970"
4509
4510 test_39n() { # LU-3832
4511         remote_mds_nodsh && skip "remote MDS with nodsh"
4512
4513         local atime_diff=$(do_facet $SINGLEMDS \
4514                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4515         local atime0
4516         local atime1
4517         local atime2
4518
4519         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4520
4521         rm -rf $DIR/$tfile
4522         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4523         atime0=$(stat -c %X $DIR/$tfile)
4524
4525         sleep 5
4526         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4527         atime1=$(stat -c %X $DIR/$tfile)
4528
4529         sleep 5
4530         cancel_lru_locks mdc
4531         cancel_lru_locks osc
4532         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4533         atime2=$(stat -c %X $DIR/$tfile)
4534
4535         do_facet $SINGLEMDS \
4536                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4537
4538         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4539         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4540 }
4541 run_test 39n "check that O_NOATIME is honored"
4542
4543 test_39o() {
4544         TESTDIR=$DIR/$tdir/$tfile
4545         [ -e $TESTDIR ] && rm -rf $TESTDIR
4546         mkdir -p $TESTDIR
4547         cd $TESTDIR
4548         links1=2
4549         ls
4550         mkdir a b
4551         ls
4552         links2=$(stat -c %h .)
4553         [ $(($links1 + 2)) != $links2 ] &&
4554                 error "wrong links count $(($links1 + 2)) != $links2"
4555         rmdir b
4556         links3=$(stat -c %h .)
4557         [ $(($links1 + 1)) != $links3 ] &&
4558                 error "wrong links count $links1 != $links3"
4559         return 0
4560 }
4561 run_test 39o "directory cached attributes updated after create"
4562
4563 test_39p() {
4564         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4565
4566         local MDTIDX=1
4567         TESTDIR=$DIR/$tdir/$tdir
4568         [ -e $TESTDIR ] && rm -rf $TESTDIR
4569         test_mkdir -p $TESTDIR
4570         cd $TESTDIR
4571         links1=2
4572         ls
4573         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4574         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4575         ls
4576         links2=$(stat -c %h .)
4577         [ $(($links1 + 2)) != $links2 ] &&
4578                 error "wrong links count $(($links1 + 2)) != $links2"
4579         rmdir remote_dir2
4580         links3=$(stat -c %h .)
4581         [ $(($links1 + 1)) != $links3 ] &&
4582                 error "wrong links count $links1 != $links3"
4583         return 0
4584 }
4585 run_test 39p "remote directory cached attributes updated after create ========"
4586
4587 test_39r() {
4588         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4589                 skip "no atime update on old OST"
4590         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4591                 skip_env "ldiskfs only test"
4592         fi
4593
4594         local saved_adiff
4595         saved_adiff=$(do_facet ost1 \
4596                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4597         stack_trap "do_facet ost1 \
4598                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4599
4600         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4601
4602         $LFS setstripe -i 0 $DIR/$tfile
4603         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4604                 error "can't write initial file"
4605         cancel_lru_locks osc
4606
4607         # exceed atime_diff and access file
4608         sleep 6
4609         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4610
4611         local atime_cli=$(stat -c %X $DIR/$tfile)
4612         echo "client atime: $atime_cli"
4613         # allow atime update to be written to device
4614         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4615         sleep 5
4616
4617         local ostdev=$(ostdevname 1)
4618         local fid=($(lfs getstripe -y $DIR/$tfile |
4619                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4620         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4621         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4622
4623         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4624         local atime_ost=$(do_facet ost1 "$cmd" |&
4625                           awk -F'[: ]' '/atime:/ { print $4 }')
4626         (( atime_cli == atime_ost )) ||
4627                 error "atime on client $atime_cli != ost $atime_ost"
4628 }
4629 run_test 39r "lazy atime update on OST"
4630
4631 test_39q() { # LU-8041
4632         local testdir=$DIR/$tdir
4633         mkdir -p $testdir
4634         multiop_bg_pause $testdir D_c || error "multiop failed"
4635         local multipid=$!
4636         cancel_lru_locks mdc
4637         kill -USR1 $multipid
4638         local atime=$(stat -c %X $testdir)
4639         [ "$atime" -ne 0 ] || error "atime is zero"
4640 }
4641 run_test 39q "close won't zero out atime"
4642
4643 test_40() {
4644         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4645         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4646                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4647         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4648                 error "$tfile is not 4096 bytes in size"
4649 }
4650 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4651
4652 test_41() {
4653         # bug 1553
4654         small_write $DIR/f41 18
4655 }
4656 run_test 41 "test small file write + fstat ====================="
4657
4658 count_ost_writes() {
4659         lctl get_param -n ${OSC}.*.stats |
4660                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4661                         END { printf("%0.0f", writes) }'
4662 }
4663
4664 # decent default
4665 WRITEBACK_SAVE=500
4666 DIRTY_RATIO_SAVE=40
4667 MAX_DIRTY_RATIO=50
4668 BG_DIRTY_RATIO_SAVE=10
4669 MAX_BG_DIRTY_RATIO=25
4670
4671 start_writeback() {
4672         trap 0
4673         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4674         # dirty_ratio, dirty_background_ratio
4675         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4676                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4677                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4678                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4679         else
4680                 # if file not here, we are a 2.4 kernel
4681                 kill -CONT `pidof kupdated`
4682         fi
4683 }
4684
4685 stop_writeback() {
4686         # setup the trap first, so someone cannot exit the test at the
4687         # exact wrong time and mess up a machine
4688         trap start_writeback EXIT
4689         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4690         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4691                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4692                 sysctl -w vm.dirty_writeback_centisecs=0
4693                 sysctl -w vm.dirty_writeback_centisecs=0
4694                 # save and increase /proc/sys/vm/dirty_ratio
4695                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4696                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4697                 # save and increase /proc/sys/vm/dirty_background_ratio
4698                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4699                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4700         else
4701                 # if file not here, we are a 2.4 kernel
4702                 kill -STOP `pidof kupdated`
4703         fi
4704 }
4705
4706 # ensure that all stripes have some grant before we test client-side cache
4707 setup_test42() {
4708         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4709                 dd if=/dev/zero of=$i bs=4k count=1
4710                 rm $i
4711         done
4712 }
4713
4714 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4715 # file truncation, and file removal.
4716 test_42a() {
4717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4718
4719         setup_test42
4720         cancel_lru_locks $OSC
4721         stop_writeback
4722         sync; sleep 1; sync # just to be safe
4723         BEFOREWRITES=`count_ost_writes`
4724         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4725         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4726         AFTERWRITES=`count_ost_writes`
4727         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4728                 error "$BEFOREWRITES < $AFTERWRITES"
4729         start_writeback
4730 }
4731 run_test 42a "ensure that we don't flush on close"
4732
4733 test_42b() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         setup_test42
4737         cancel_lru_locks $OSC
4738         stop_writeback
4739         sync
4740         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4741         BEFOREWRITES=$(count_ost_writes)
4742         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4743         AFTERWRITES=$(count_ost_writes)
4744         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4745                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4746         fi
4747         BEFOREWRITES=$(count_ost_writes)
4748         sync || error "sync: $?"
4749         AFTERWRITES=$(count_ost_writes)
4750         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4751                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4752         fi
4753         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4754         start_writeback
4755         return 0
4756 }
4757 run_test 42b "test destroy of file with cached dirty data ======"
4758
4759 # if these tests just want to test the effect of truncation,
4760 # they have to be very careful.  consider:
4761 # - the first open gets a {0,EOF}PR lock
4762 # - the first write conflicts and gets a {0, count-1}PW
4763 # - the rest of the writes are under {count,EOF}PW
4764 # - the open for truncate tries to match a {0,EOF}PR
4765 #   for the filesize and cancels the PWs.
4766 # any number of fixes (don't get {0,EOF} on open, match
4767 # composite locks, do smarter file size management) fix
4768 # this, but for now we want these tests to verify that
4769 # the cancellation with truncate intent works, so we
4770 # start the file with a full-file pw lock to match against
4771 # until the truncate.
4772 trunc_test() {
4773         test=$1
4774         file=$DIR/$test
4775         offset=$2
4776         cancel_lru_locks $OSC
4777         stop_writeback
4778         # prime the file with 0,EOF PW to match
4779         touch $file
4780         $TRUNCATE $file 0
4781         sync; sync
4782         # now the real test..
4783         dd if=/dev/zero of=$file bs=1024 count=100
4784         BEFOREWRITES=`count_ost_writes`
4785         $TRUNCATE $file $offset
4786         cancel_lru_locks $OSC
4787         AFTERWRITES=`count_ost_writes`
4788         start_writeback
4789 }
4790
4791 test_42c() {
4792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4793
4794         trunc_test 42c 1024
4795         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4796                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4797         rm $file
4798 }
4799 run_test 42c "test partial truncate of file with cached dirty data"
4800
4801 test_42d() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         trunc_test 42d 0
4805         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4806                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4807         rm $file
4808 }
4809 run_test 42d "test complete truncate of file with cached dirty data"
4810
4811 test_42e() { # bug22074
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         local TDIR=$DIR/${tdir}e
4815         local pages=16 # hardcoded 16 pages, don't change it.
4816         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4817         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4818         local max_dirty_mb
4819         local warmup_files
4820
4821         test_mkdir $DIR/${tdir}e
4822         $LFS setstripe -c 1 $TDIR
4823         createmany -o $TDIR/f $files
4824
4825         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4826
4827         # we assume that with $OSTCOUNT files, at least one of them will
4828         # be allocated on OST0.
4829         warmup_files=$((OSTCOUNT * max_dirty_mb))
4830         createmany -o $TDIR/w $warmup_files
4831
4832         # write a large amount of data into one file and sync, to get good
4833         # avail_grant number from OST.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4838                 break
4839         done
4840         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4841         sync
4842         $LCTL get_param $proc_osc0/cur_dirty_bytes
4843         $LCTL get_param $proc_osc0/cur_grant_bytes
4844
4845         # create as much dirty pages as we can while not to trigger the actual
4846         # RPCs directly. but depends on the env, VFS may trigger flush during this
4847         # period, hopefully we are good.
4848         for ((i=0; i<$warmup_files; i++)); do
4849                 idx=$($LFS getstripe -i $TDIR/w$i)
4850                 [ $idx -ne 0 ] && continue
4851                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4852         done
4853         $LCTL get_param $proc_osc0/cur_dirty_bytes
4854         $LCTL get_param $proc_osc0/cur_grant_bytes
4855
4856         # perform the real test
4857         $LCTL set_param $proc_osc0/rpc_stats 0
4858         for ((;i<$files; i++)); do
4859                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4860                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4861         done
4862         sync
4863         $LCTL get_param $proc_osc0/rpc_stats
4864
4865         local percent=0
4866         local have_ppr=false
4867         $LCTL get_param $proc_osc0/rpc_stats |
4868                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4869                         # skip lines until we are at the RPC histogram data
4870                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4871                         $have_ppr || continue
4872
4873                         # we only want the percent stat for < 16 pages
4874                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4875
4876                         percent=$((percent + WPCT))
4877                         if [[ $percent -gt 15 ]]; then
4878                                 error "less than 16-pages write RPCs" \
4879                                       "$percent% > 15%"
4880                                 break
4881                         fi
4882                 done
4883         rm -rf $TDIR
4884 }
4885 run_test 42e "verify sub-RPC writes are not done synchronously"
4886
4887 test_43A() { # was test_43
4888         test_mkdir $DIR/$tdir
4889         cp -p /bin/ls $DIR/$tdir/$tfile
4890         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4891         pid=$!
4892         # give multiop a chance to open
4893         sleep 1
4894
4895         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4896         kill -USR1 $pid
4897         # Wait for multiop to exit
4898         wait $pid
4899 }
4900 run_test 43A "execution of file opened for write should return -ETXTBSY"
4901
4902 test_43a() {
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4913
4914 test_43b() {
4915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4916
4917         test_mkdir $DIR/$tdir
4918         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4919         $DIR/$tdir/sleep 60 &
4920         SLEEP_PID=$!
4921         # Make sure exec of $tdir/sleep wins race with truncate
4922         sleep 1
4923         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4924         kill $SLEEP_PID
4925 }
4926 run_test 43b "truncate of file being executed should return -ETXTBSY"
4927
4928 test_43c() {
4929         local testdir="$DIR/$tdir"
4930         test_mkdir $testdir
4931         cp $SHELL $testdir/
4932         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4933                 ( cd $testdir && md5sum -c )
4934 }
4935 run_test 43c "md5sum of copy into lustre"
4936
4937 test_44A() { # was test_44
4938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4939
4940         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4941         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4942 }
4943 run_test 44A "zero length read from a sparse stripe"
4944
4945 test_44a() {
4946         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4947                 awk '{ print $2 }')
4948         [ -z "$nstripe" ] && skip "can't get stripe info"
4949         [[ $nstripe -gt $OSTCOUNT ]] &&
4950                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4951
4952         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4953                 awk '{ print $2 }')
4954         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4955                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4956                         awk '{ print $2 }')
4957         fi
4958
4959         OFFSETS="0 $((stride/2)) $((stride-1))"
4960         for offset in $OFFSETS; do
4961                 for i in $(seq 0 $((nstripe-1))); do
4962                         local GLOBALOFFSETS=""
4963                         # size in Bytes
4964                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4965                         local myfn=$DIR/d44a-$size
4966                         echo "--------writing $myfn at $size"
4967                         ll_sparseness_write $myfn $size ||
4968                                 error "ll_sparseness_write"
4969                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4970                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4971                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4972
4973                         for j in $(seq 0 $((nstripe-1))); do
4974                                 # size in Bytes
4975                                 size=$((((j + $nstripe )*$stride + $offset)))
4976                                 ll_sparseness_write $myfn $size ||
4977                                         error "ll_sparseness_write"
4978                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4979                         done
4980                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4981                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4982                         rm -f $myfn
4983                 done
4984         done
4985 }
4986 run_test 44a "test sparse pwrite ==============================="
4987
4988 dirty_osc_total() {
4989         tot=0
4990         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4991                 tot=$(($tot + $d))
4992         done
4993         echo $tot
4994 }
4995 do_dirty_record() {
4996         before=`dirty_osc_total`
4997         echo executing "\"$*\""
4998         eval $*
4999         after=`dirty_osc_total`
5000         echo before $before, after $after
5001 }
5002 test_45() {
5003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5004
5005         f="$DIR/f45"
5006         # Obtain grants from OST if it supports it
5007         echo blah > ${f}_grant
5008         stop_writeback
5009         sync
5010         do_dirty_record "echo blah > $f"
5011         [[ $before -eq $after ]] && error "write wasn't cached"
5012         do_dirty_record "> $f"
5013         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5014         do_dirty_record "echo blah > $f"
5015         [[ $before -eq $after ]] && error "write wasn't cached"
5016         do_dirty_record "sync"
5017         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5018         do_dirty_record "echo blah > $f"
5019         [[ $before -eq $after ]] && error "write wasn't cached"
5020         do_dirty_record "cancel_lru_locks osc"
5021         [[ $before -gt $after ]] ||
5022                 error "lock cancellation didn't lower dirty count"
5023         start_writeback
5024 }
5025 run_test 45 "osc io page accounting ============================"
5026
5027 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5028 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5029 # objects offset and an assert hit when an rpc was built with 1023's mapped
5030 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5031 test_46() {
5032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5033
5034         f="$DIR/f46"
5035         stop_writeback
5036         sync
5037         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5038         sync
5039         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5040         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5041         sync
5042         start_writeback
5043 }
5044 run_test 46 "dirtying a previously written page ================"
5045
5046 # test_47 is removed "Device nodes check" is moved to test_28
5047
5048 test_48a() { # bug 2399
5049         [ "$mds1_FSTYPE" = "zfs" ] &&
5050         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5051                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5052
5053         test_mkdir $DIR/$tdir
5054         cd $DIR/$tdir
5055         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5056         test_mkdir $DIR/$tdir
5057         touch foo || error "'touch foo' failed after recreating cwd"
5058         test_mkdir bar
5059         touch .foo || error "'touch .foo' failed after recreating cwd"
5060         test_mkdir .bar
5061         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5062         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5063         cd . || error "'cd .' failed after recreating cwd"
5064         mkdir . && error "'mkdir .' worked after recreating cwd"
5065         rmdir . && error "'rmdir .' worked after recreating cwd"
5066         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5067         cd .. || error "'cd ..' failed after recreating cwd"
5068 }
5069 run_test 48a "Access renamed working dir (should return errors)="
5070
5071 test_48b() { # bug 2399
5072         rm -rf $DIR/$tdir
5073         test_mkdir $DIR/$tdir
5074         cd $DIR/$tdir
5075         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5076         touch foo && error "'touch foo' worked after removing cwd"
5077         mkdir foo && error "'mkdir foo' worked after removing cwd"
5078         touch .foo && error "'touch .foo' worked after removing cwd"
5079         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5080         ls . > /dev/null && error "'ls .' worked after removing cwd"
5081         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5082         mkdir . && error "'mkdir .' worked after removing cwd"
5083         rmdir . && error "'rmdir .' worked after removing cwd"
5084         ln -s . foo && error "'ln -s .' worked after removing cwd"
5085         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5086 }
5087 run_test 48b "Access removed working dir (should return errors)="
5088
5089 test_48c() { # bug 2350
5090         #lctl set_param debug=-1
5091         #set -vx
5092         rm -rf $DIR/$tdir
5093         test_mkdir -p $DIR/$tdir/dir
5094         cd $DIR/$tdir/dir
5095         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5096         $TRACE touch foo && error "touch foo worked after removing cwd"
5097         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5098         touch .foo && error "touch .foo worked after removing cwd"
5099         mkdir .foo && error "mkdir .foo worked after removing cwd"
5100         $TRACE ls . && error "'ls .' worked after removing cwd"
5101         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5102         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5103         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5104         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5105         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5106 }
5107 run_test 48c "Access removed working subdir (should return errors)"
5108
5109 test_48d() { # bug 2350
5110         #lctl set_param debug=-1
5111         #set -vx
5112         rm -rf $DIR/$tdir
5113         test_mkdir -p $DIR/$tdir/dir
5114         cd $DIR/$tdir/dir
5115         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5116         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5117         $TRACE touch foo && error "'touch foo' worked after removing parent"
5118         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5119         touch .foo && error "'touch .foo' worked after removing parent"
5120         mkdir .foo && error "mkdir .foo worked after removing parent"
5121         $TRACE ls . && error "'ls .' worked after removing parent"
5122         $TRACE ls .. && error "'ls ..' worked after removing parent"
5123         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5124         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5125         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5126         true
5127 }
5128 run_test 48d "Access removed parent subdir (should return errors)"
5129
5130 test_48e() { # bug 4134
5131         #lctl set_param debug=-1
5132         #set -vx
5133         rm -rf $DIR/$tdir
5134         test_mkdir -p $DIR/$tdir/dir
5135         cd $DIR/$tdir/dir
5136         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5137         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5138         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5139         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5140         # On a buggy kernel addition of "touch foo" after cd .. will
5141         # produce kernel oops in lookup_hash_it
5142         touch ../foo && error "'cd ..' worked after recreate parent"
5143         cd $DIR
5144         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5145 }
5146 run_test 48e "Access to recreated parent subdir (should return errors)"
5147
5148 test_48f() {
5149         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5150                 skip "need MDS >= 2.13.55"
5151         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5152         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5153                 skip "needs different host for mdt1 mdt2"
5154         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5155
5156         $LFS mkdir -i0 $DIR/$tdir
5157         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5158
5159         for d in sub1 sub2 sub3; do
5160                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5161                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5162                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5163         done
5164
5165         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5166 }
5167 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5168
5169 test_49() { # LU-1030
5170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5171         remote_ost_nodsh && skip "remote OST with nodsh"
5172
5173         # get ost1 size - $FSNAME-OST0000
5174         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5175                 awk '{ print $4 }')
5176         # write 800M at maximum
5177         [[ $ost1_size -lt 2 ]] && ost1_size=2
5178         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5179
5180         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5181         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5182         local dd_pid=$!
5183
5184         # change max_pages_per_rpc while writing the file
5185         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5186         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5187         # loop until dd process exits
5188         while ps ax -opid | grep -wq $dd_pid; do
5189                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5190                 sleep $((RANDOM % 5 + 1))
5191         done
5192         # restore original max_pages_per_rpc
5193         $LCTL set_param $osc1_mppc=$orig_mppc
5194         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5195 }
5196 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5197
5198 test_50() {
5199         # bug 1485
5200         test_mkdir $DIR/$tdir
5201         cd $DIR/$tdir
5202         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5203 }
5204 run_test 50 "special situations: /proc symlinks  ==============="
5205
5206 test_51a() {    # was test_51
5207         # bug 1516 - create an empty entry right after ".." then split dir
5208         test_mkdir -c1 $DIR/$tdir
5209         touch $DIR/$tdir/foo
5210         $MCREATE $DIR/$tdir/bar
5211         rm $DIR/$tdir/foo
5212         createmany -m $DIR/$tdir/longfile 201
5213         FNUM=202
5214         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5215                 $MCREATE $DIR/$tdir/longfile$FNUM
5216                 FNUM=$(($FNUM + 1))
5217                 echo -n "+"
5218         done
5219         echo
5220         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5221 }
5222 run_test 51a "special situations: split htree with empty entry =="
5223
5224 cleanup_print_lfs_df () {
5225         trap 0
5226         $LFS df
5227         $LFS df -i
5228 }
5229
5230 test_51b() {
5231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5232
5233         local dir=$DIR/$tdir
5234         local nrdirs=$((65536 + 100))
5235
5236         # cleanup the directory
5237         rm -fr $dir
5238
5239         test_mkdir -c1 $dir
5240
5241         $LFS df
5242         $LFS df -i
5243         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5244         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5245         [[ $numfree -lt $nrdirs ]] &&
5246                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5247
5248         # need to check free space for the directories as well
5249         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5250         numfree=$(( blkfree / $(fs_inode_ksize) ))
5251         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5252
5253         trap cleanup_print_lfs_df EXIT
5254
5255         # create files
5256         createmany -d $dir/d $nrdirs || {
5257                 unlinkmany $dir/d $nrdirs
5258                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5259         }
5260
5261         # really created :
5262         nrdirs=$(ls -U $dir | wc -l)
5263
5264         # unlink all but 100 subdirectories, then check it still works
5265         local left=100
5266         local delete=$((nrdirs - left))
5267
5268         $LFS df
5269         $LFS df -i
5270
5271         # for ldiskfs the nlink count should be 1, but this is OSD specific
5272         # and so this is listed for informational purposes only
5273         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5274         unlinkmany -d $dir/d $delete ||
5275                 error "unlink of first $delete subdirs failed"
5276
5277         echo "nlink between: $(stat -c %h $dir)"
5278         local found=$(ls -U $dir | wc -l)
5279         [ $found -ne $left ] &&
5280                 error "can't find subdirs: found only $found, expected $left"
5281
5282         unlinkmany -d $dir/d $delete $left ||
5283                 error "unlink of second $left subdirs failed"
5284         # regardless of whether the backing filesystem tracks nlink accurately
5285         # or not, the nlink count shouldn't be more than "." and ".." here
5286         local after=$(stat -c %h $dir)
5287         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5288                 echo "nlink after: $after"
5289
5290         cleanup_print_lfs_df
5291 }
5292 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5293
5294 test_51d() {
5295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5296         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5297
5298         test_mkdir $DIR/$tdir
5299         createmany -o $DIR/$tdir/t- 1000
5300         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5301         for N in $(seq 0 $((OSTCOUNT - 1))); do
5302                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5303                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5304                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5305                         '($1 == '$N') { objs += 1 } \
5306                         END { printf("%0.0f", objs) }')
5307                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5308         done
5309         unlinkmany $DIR/$tdir/t- 1000
5310
5311         NLAST=0
5312         for N in $(seq 1 $((OSTCOUNT - 1))); do
5313                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5314                         error "OST $N has less objects vs OST $NLAST" \
5315                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5316                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5317                         error "OST $N has less objects vs OST $NLAST" \
5318                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5319
5320                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5321                         error "OST $N has less #0 objects vs OST $NLAST" \
5322                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5323                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5324                         error "OST $N has less #0 objects vs OST $NLAST" \
5325                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5326                 NLAST=$N
5327         done
5328         rm -f $TMP/$tfile
5329 }
5330 run_test 51d "check object distribution"
5331
5332 test_51e() {
5333         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5334                 skip_env "ldiskfs only test"
5335         fi
5336
5337         test_mkdir -c1 $DIR/$tdir
5338         test_mkdir -c1 $DIR/$tdir/d0
5339
5340         touch $DIR/$tdir/d0/foo
5341         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5342                 error "file exceed 65000 nlink limit!"
5343         unlinkmany $DIR/$tdir/d0/f- 65001
5344         return 0
5345 }
5346 run_test 51e "check file nlink limit"
5347
5348 test_51f() {
5349         test_mkdir $DIR/$tdir
5350
5351         local max=100000
5352         local ulimit_old=$(ulimit -n)
5353         local spare=20 # number of spare fd's for scripts/libraries, etc.
5354         local mdt=$($LFS getstripe -m $DIR/$tdir)
5355         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5356
5357         echo "MDT$mdt numfree=$numfree, max=$max"
5358         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5359         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5360                 while ! ulimit -n $((numfree + spare)); do
5361                         numfree=$((numfree * 3 / 4))
5362                 done
5363                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5364         else
5365                 echo "left ulimit at $ulimit_old"
5366         fi
5367
5368         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5369                 unlinkmany $DIR/$tdir/f $numfree
5370                 error "create+open $numfree files in $DIR/$tdir failed"
5371         }
5372         ulimit -n $ulimit_old
5373
5374         # if createmany exits at 120s there will be fewer than $numfree files
5375         unlinkmany $DIR/$tdir/f $numfree || true
5376 }
5377 run_test 51f "check many open files limit"
5378
5379 test_52a() {
5380         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5381         test_mkdir $DIR/$tdir
5382         touch $DIR/$tdir/foo
5383         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5384         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5385         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5386         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5387         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5388                                         error "link worked"
5389         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5390         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5391         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5392                                                      error "lsattr"
5393         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5394         cp -r $DIR/$tdir $TMP/
5395         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5396 }
5397 run_test 52a "append-only flag test (should return errors)"
5398
5399 test_52b() {
5400         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5401         test_mkdir $DIR/$tdir
5402         touch $DIR/$tdir/foo
5403         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5404         cat test > $DIR/$tdir/foo && error "cat test worked"
5405         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5406         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5407         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5408                                         error "link worked"
5409         echo foo >> $DIR/$tdir/foo && error "echo worked"
5410         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5411         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5412         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5413         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5414                                                         error "lsattr"
5415         chattr -i $DIR/$tdir/foo || error "chattr failed"
5416
5417         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5418 }
5419 run_test 52b "immutable flag test (should return errors) ======="
5420
5421 test_53() {
5422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5423         remote_mds_nodsh && skip "remote MDS with nodsh"
5424         remote_ost_nodsh && skip "remote OST with nodsh"
5425
5426         local param
5427         local param_seq
5428         local ostname
5429         local mds_last
5430         local mds_last_seq
5431         local ost_last
5432         local ost_last_seq
5433         local ost_last_id
5434         local ostnum
5435         local node
5436         local found=false
5437         local support_last_seq=true
5438
5439         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5440                 support_last_seq=false
5441
5442         # only test MDT0000
5443         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5444         local value
5445         for value in $(do_facet $SINGLEMDS \
5446                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5447                 param=$(echo ${value[0]} | cut -d "=" -f1)
5448                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5449
5450                 if $support_last_seq; then
5451                         param_seq=$(echo $param |
5452                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5453                         mds_last_seq=$(do_facet $SINGLEMDS \
5454                                        $LCTL get_param -n $param_seq)
5455                 fi
5456                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5457
5458                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5459                 node=$(facet_active_host ost$((ostnum+1)))
5460                 param="obdfilter.$ostname.last_id"
5461                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5462                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5463                         ost_last_id=$ost_last
5464
5465                         if $support_last_seq; then
5466                                 ost_last_id=$(echo $ost_last |
5467                                               awk -F':' '{print $2}' |
5468                                               sed -e "s/^0x//g")
5469                                 ost_last_seq=$(echo $ost_last |
5470                                                awk -F':' '{print $1}')
5471                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5472                         fi
5473
5474                         if [[ $ost_last_id != $mds_last ]]; then
5475                                 error "$ost_last_id != $mds_last"
5476                         else
5477                                 found=true
5478                                 break
5479                         fi
5480                 done
5481         done
5482         $found || error "can not match last_seq/last_id for $mdtosc"
5483         return 0
5484 }
5485 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5486
5487 test_54a() {
5488         perl -MSocket -e ';' || skip "no Socket perl module installed"
5489
5490         $SOCKETSERVER $DIR/socket ||
5491                 error "$SOCKETSERVER $DIR/socket failed: $?"
5492         $SOCKETCLIENT $DIR/socket ||
5493                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5494         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5495 }
5496 run_test 54a "unix domain socket test =========================="
5497
5498 test_54b() {
5499         f="$DIR/f54b"
5500         mknod $f c 1 3
5501         chmod 0666 $f
5502         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5503 }
5504 run_test 54b "char device works in lustre ======================"
5505
5506 find_loop_dev() {
5507         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5508         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5509         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5510
5511         for i in $(seq 3 7); do
5512                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5513                 LOOPDEV=$LOOPBASE$i
5514                 LOOPNUM=$i
5515                 break
5516         done
5517 }
5518
5519 cleanup_54c() {
5520         local rc=0
5521         loopdev="$DIR/loop54c"
5522
5523         trap 0
5524         $UMOUNT $DIR/$tdir || rc=$?
5525         losetup -d $loopdev || true
5526         losetup -d $LOOPDEV || true
5527         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5528         return $rc
5529 }
5530
5531 test_54c() {
5532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5533
5534         loopdev="$DIR/loop54c"
5535
5536         find_loop_dev
5537         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5538         trap cleanup_54c EXIT
5539         mknod $loopdev b 7 $LOOPNUM
5540         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5541         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5542         losetup $loopdev $DIR/$tfile ||
5543                 error "can't set up $loopdev for $DIR/$tfile"
5544         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5545         test_mkdir $DIR/$tdir
5546         mount -t ext2 $loopdev $DIR/$tdir ||
5547                 error "error mounting $loopdev on $DIR/$tdir"
5548         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5549                 error "dd write"
5550         df $DIR/$tdir
5551         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5552                 error "dd read"
5553         cleanup_54c
5554 }
5555 run_test 54c "block device works in lustre ====================="
5556
5557 test_54d() {
5558         f="$DIR/f54d"
5559         string="aaaaaa"
5560         mknod $f p
5561         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5562 }
5563 run_test 54d "fifo device works in lustre ======================"
5564
5565 test_54e() {
5566         f="$DIR/f54e"
5567         string="aaaaaa"
5568         cp -aL /dev/console $f
5569         echo $string > $f || error "echo $string to $f failed"
5570 }
5571 run_test 54e "console/tty device works in lustre ======================"
5572
5573 test_56a() {
5574         local numfiles=3
5575         local dir=$DIR/$tdir
5576
5577         rm -rf $dir
5578         test_mkdir -p $dir/dir
5579         for i in $(seq $numfiles); do
5580                 touch $dir/file$i
5581                 touch $dir/dir/file$i
5582         done
5583
5584         local numcomp=$($LFS getstripe --component-count $dir)
5585
5586         [[ $numcomp == 0 ]] && numcomp=1
5587
5588         # test lfs getstripe with --recursive
5589         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5590
5591         [[ $filenum -eq $((numfiles * 2)) ]] ||
5592                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5593         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5594         [[ $filenum -eq $numfiles ]] ||
5595                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5596         echo "$LFS getstripe showed obdidx or l_ost_idx"
5597
5598         # test lfs getstripe with file instead of dir
5599         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5600         [[ $filenum -eq 1 ]] ||
5601                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5602         echo "$LFS getstripe file1 passed"
5603
5604         #test lfs getstripe with --verbose
5605         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5606         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5607                 error "$LFS getstripe --verbose $dir: "\
5608                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5609         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5610                 error "$LFS getstripe $dir: showed lmm_magic"
5611
5612         #test lfs getstripe with -v prints lmm_fid
5613         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5614         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5615                 error "$LFS getstripe -v $dir: "\
5616                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5617         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5618                 error "$LFS getstripe $dir: showed lmm_fid by default"
5619         echo "$LFS getstripe --verbose passed"
5620
5621         #check for FID information
5622         local fid1=$($LFS getstripe --fid $dir/file1)
5623         local fid2=$($LFS getstripe --verbose $dir/file1 |
5624                      awk '/lmm_fid: / { print $2; exit; }')
5625         local fid3=$($LFS path2fid $dir/file1)
5626
5627         [ "$fid1" != "$fid2" ] &&
5628                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5629         [ "$fid1" != "$fid3" ] &&
5630                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5631         echo "$LFS getstripe --fid passed"
5632
5633         #test lfs getstripe with --obd
5634         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5635                 error "$LFS getstripe --obd wrong_uuid: should return error"
5636
5637         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5638
5639         local ostidx=1
5640         local obduuid=$(ostuuid_from_index $ostidx)
5641         local found=$($LFS getstripe -r --obd $obduuid $dir |
5642                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5643
5644         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5645         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5646                 ((filenum--))
5647         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5648                 ((filenum--))
5649
5650         [[ $found -eq $filenum ]] ||
5651                 error "$LFS getstripe --obd: found $found expect $filenum"
5652         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5653                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5654                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5655                 error "$LFS getstripe --obd: should not show file on other obd"
5656         echo "$LFS getstripe --obd passed"
5657 }
5658 run_test 56a "check $LFS getstripe"
5659
5660 test_56b() {
5661         local dir=$DIR/$tdir
5662         local numdirs=3
5663
5664         test_mkdir $dir
5665         for i in $(seq $numdirs); do
5666                 test_mkdir $dir/dir$i
5667         done
5668
5669         # test lfs getdirstripe default mode is non-recursion, which is
5670         # different from lfs getstripe
5671         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5672
5673         [[ $dircnt -eq 1 ]] ||
5674                 error "$LFS getdirstripe: found $dircnt, not 1"
5675         dircnt=$($LFS getdirstripe --recursive $dir |
5676                 grep -c lmv_stripe_count)
5677         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5678                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5679 }
5680 run_test 56b "check $LFS getdirstripe"
5681
5682 test_56c() {
5683         remote_ost_nodsh && skip "remote OST with nodsh"
5684
5685         local ost_idx=0
5686         local ost_name=$(ostname_from_index $ost_idx)
5687         local old_status=$(ost_dev_status $ost_idx)
5688         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5689
5690         [[ -z "$old_status" ]] ||
5691                 skip_env "OST $ost_name is in $old_status status"
5692
5693         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5694         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5695                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5696         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5697                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5698                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5699         fi
5700
5701         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5702                 error "$LFS df -v showing inactive devices"
5703         sleep_maxage
5704
5705         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5706
5707         [[ "$new_status" =~ "D" ]] ||
5708                 error "$ost_name status is '$new_status', missing 'D'"
5709         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5710                 [[ "$new_status" =~ "N" ]] ||
5711                         error "$ost_name status is '$new_status', missing 'N'"
5712         fi
5713         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5714                 [[ "$new_status" =~ "f" ]] ||
5715                         error "$ost_name status is '$new_status', missing 'f'"
5716         fi
5717
5718         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5719         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5720                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5721         [[ -z "$p" ]] && restore_lustre_params < $p || true
5722         sleep_maxage
5723
5724         new_status=$(ost_dev_status $ost_idx)
5725         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5726                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5727         # can't check 'f' as devices may actually be on flash
5728 }
5729 run_test 56c "check 'lfs df' showing device status"
5730
5731 test_56d() {
5732         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5733         local osts=$($LFS df -v $MOUNT | grep -c OST)
5734
5735         $LFS df $MOUNT
5736
5737         (( mdts == MDSCOUNT )) ||
5738                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5739         (( osts == OSTCOUNT )) ||
5740                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5741 }
5742 run_test 56d "'lfs df -v' prints only configured devices"
5743
5744 NUMFILES=3
5745 NUMDIRS=3
5746 setup_56() {
5747         local local_tdir="$1"
5748         local local_numfiles="$2"
5749         local local_numdirs="$3"
5750         local dir_params="$4"
5751         local dir_stripe_params="$5"
5752
5753         if [ ! -d "$local_tdir" ] ; then
5754                 test_mkdir -p $dir_stripe_params $local_tdir
5755                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5756                 for i in $(seq $local_numfiles) ; do
5757                         touch $local_tdir/file$i
5758                 done
5759                 for i in $(seq $local_numdirs) ; do
5760                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5761                         for j in $(seq $local_numfiles) ; do
5762                                 touch $local_tdir/dir$i/file$j
5763                         done
5764                 done
5765         fi
5766 }
5767
5768 setup_56_special() {
5769         local local_tdir=$1
5770         local local_numfiles=$2
5771         local local_numdirs=$3
5772
5773         setup_56 $local_tdir $local_numfiles $local_numdirs
5774
5775         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5776                 for i in $(seq $local_numfiles) ; do
5777                         mknod $local_tdir/loop${i}b b 7 $i
5778                         mknod $local_tdir/null${i}c c 1 3
5779                         ln -s $local_tdir/file1 $local_tdir/link${i}
5780                 done
5781                 for i in $(seq $local_numdirs) ; do
5782                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5783                         mknod $local_tdir/dir$i/null${i}c c 1 3
5784                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5785                 done
5786         fi
5787 }
5788
5789 test_56g() {
5790         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5791         local expected=$(($NUMDIRS + 2))
5792
5793         setup_56 $dir $NUMFILES $NUMDIRS
5794
5795         # test lfs find with -name
5796         for i in $(seq $NUMFILES) ; do
5797                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5798
5799                 [ $nums -eq $expected ] ||
5800                         error "lfs find -name '*$i' $dir wrong: "\
5801                               "found $nums, expected $expected"
5802         done
5803 }
5804 run_test 56g "check lfs find -name"
5805
5806 test_56h() {
5807         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5808         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5809
5810         setup_56 $dir $NUMFILES $NUMDIRS
5811
5812         # test lfs find with ! -name
5813         for i in $(seq $NUMFILES) ; do
5814                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5815
5816                 [ $nums -eq $expected ] ||
5817                         error "lfs find ! -name '*$i' $dir wrong: "\
5818                               "found $nums, expected $expected"
5819         done
5820 }
5821 run_test 56h "check lfs find ! -name"
5822
5823 test_56i() {
5824         local dir=$DIR/$tdir
5825
5826         test_mkdir $dir
5827
5828         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5829         local out=$($cmd)
5830
5831         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5832 }
5833 run_test 56i "check 'lfs find -ost UUID' skips directories"
5834
5835 test_56j() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$((NUMDIRS + 1))
5841         local cmd="$LFS find -type d $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56j "check lfs find -type d"
5848
5849 test_56k() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$(((NUMDIRS + 1) * NUMFILES))
5855         local cmd="$LFS find -type f $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56k "check lfs find -type f"
5862
5863 test_56l() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type b $dir"
5870         local nums=$($cmd | wc -l)
5871
5872         [ $nums -eq $expected ] ||
5873                 error "'$cmd' wrong: found $nums, expected $expected"
5874 }
5875 run_test 56l "check lfs find -type b"
5876
5877 test_56m() {
5878         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5879
5880         setup_56_special $dir $NUMFILES $NUMDIRS
5881
5882         local expected=$((NUMDIRS + NUMFILES))
5883         local cmd="$LFS find -type c $dir"
5884         local nums=$($cmd | wc -l)
5885         [ $nums -eq $expected ] ||
5886                 error "'$cmd' wrong: found $nums, expected $expected"
5887 }
5888 run_test 56m "check lfs find -type c"
5889
5890 test_56n() {
5891         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5892         setup_56_special $dir $NUMFILES $NUMDIRS
5893
5894         local expected=$((NUMDIRS + NUMFILES))
5895         local cmd="$LFS find -type l $dir"
5896         local nums=$($cmd | wc -l)
5897
5898         [ $nums -eq $expected ] ||
5899                 error "'$cmd' wrong: found $nums, expected $expected"
5900 }
5901 run_test 56n "check lfs find -type l"
5902
5903 test_56o() {
5904         local dir=$DIR/$tdir
5905
5906         setup_56 $dir $NUMFILES $NUMDIRS
5907         utime $dir/file1 > /dev/null || error "utime (1)"
5908         utime $dir/file2 > /dev/null || error "utime (2)"
5909         utime $dir/dir1 > /dev/null || error "utime (3)"
5910         utime $dir/dir2 > /dev/null || error "utime (4)"
5911         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5912         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5913
5914         local expected=4
5915         local nums=$($LFS find -mtime +0 $dir | wc -l)
5916
5917         [ $nums -eq $expected ] ||
5918                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5919
5920         expected=12
5921         cmd="$LFS find -mtime 0 $dir"
5922         nums=$($cmd | wc -l)
5923         [ $nums -eq $expected ] ||
5924                 error "'$cmd' wrong: found $nums, expected $expected"
5925 }
5926 run_test 56o "check lfs find -mtime for old files"
5927
5928 test_56ob() {
5929         local dir=$DIR/$tdir
5930         local expected=1
5931         local count=0
5932
5933         # just to make sure there is something that won't be found
5934         test_mkdir $dir
5935         touch $dir/$tfile.now
5936
5937         for age in year week day hour min; do
5938                 count=$((count + 1))
5939
5940                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5941                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5942                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5943
5944                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5945                 local nums=$($cmd | wc -l)
5946                 [ $nums -eq $expected ] ||
5947                         error "'$cmd' wrong: found $nums, expected $expected"
5948
5949                 cmd="$LFS find $dir -atime $count${age:0:1}"
5950                 nums=$($cmd | wc -l)
5951                 [ $nums -eq $expected ] ||
5952                         error "'$cmd' wrong: found $nums, expected $expected"
5953         done
5954
5955         sleep 2
5956         cmd="$LFS find $dir -ctime +1s -type f"
5957         nums=$($cmd | wc -l)
5958         (( $nums == $count * 2 + 1)) ||
5959                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5960 }
5961 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5962
5963 test_newerXY_base() {
5964         local x=$1
5965         local y=$2
5966         local dir=$DIR/$tdir
5967         local ref
5968         local negref
5969
5970         if [ $y == "t" ]; then
5971                 if [ $x == "b" ]; then
5972                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5973                 else
5974                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5975                 fi
5976         else
5977                 ref=$DIR/$tfile.newer.$x$y
5978                 touch $ref || error "touch $ref failed"
5979         fi
5980
5981         echo "before = $ref"
5982         sleep 2
5983         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5984         sleep 2
5985         if [ $y == "t" ]; then
5986                 if [ $x == "b" ]; then
5987                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5988                 else
5989                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5990                 fi
5991         else
5992                 negref=$DIR/$tfile.negnewer.$x$y
5993                 touch $negref || error "touch $negref failed"
5994         fi
5995
5996         echo "after = $negref"
5997         local cmd="$LFS find $dir -newer$x$y $ref"
5998         local nums=$(eval $cmd | wc -l)
5999         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6000
6001         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6002                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6003
6004         cmd="$LFS find $dir ! -newer$x$y $negref"
6005         nums=$(eval $cmd | wc -l)
6006         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6007                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6008
6009         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6010         nums=$(eval $cmd | wc -l)
6011         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6012                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6013
6014         rm -rf $DIR/*
6015 }
6016
6017 test_56oc() {
6018         test_newerXY_base "a" "a"
6019         test_newerXY_base "a" "m"
6020         test_newerXY_base "a" "c"
6021         test_newerXY_base "m" "a"
6022         test_newerXY_base "m" "m"
6023         test_newerXY_base "m" "c"
6024         test_newerXY_base "c" "a"
6025         test_newerXY_base "c" "m"
6026         test_newerXY_base "c" "c"
6027
6028         [[ -n "$sles_version" ]] &&
6029                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6030
6031         test_newerXY_base "a" "t"
6032         test_newerXY_base "m" "t"
6033         test_newerXY_base "c" "t"
6034
6035         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6036            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6037                 ! btime_supported && echo "btime unsupported" && return 0
6038
6039         test_newerXY_base "b" "b"
6040         test_newerXY_base "b" "t"
6041 }
6042 run_test 56oc "check lfs find -newerXY work"
6043
6044 btime_supported() {
6045         local dir=$DIR/$tdir
6046         local rc
6047
6048         mkdir -p $dir
6049         touch $dir/$tfile
6050         $LFS find $dir -btime -1d -type f
6051         rc=$?
6052         rm -rf $dir
6053         return $rc
6054 }
6055
6056 test_56od() {
6057         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6058                 ! btime_supported && skip "btime unsupported on MDS"
6059
6060         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6061                 ! btime_supported && skip "btime unsupported on clients"
6062
6063         local dir=$DIR/$tdir
6064         local ref=$DIR/$tfile.ref
6065         local negref=$DIR/$tfile.negref
6066
6067         mkdir $dir || error "mkdir $dir failed"
6068         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6069         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6070         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6071         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6072         touch $ref || error "touch $ref failed"
6073         # sleep 3 seconds at least
6074         sleep 3
6075
6076         local before=$(do_facet mds1 date +%s)
6077         local skew=$(($(date +%s) - before + 1))
6078
6079         if (( skew < 0 && skew > -5 )); then
6080                 sleep $((0 - skew + 1))
6081                 skew=0
6082         fi
6083
6084         # Set the dir stripe params to limit files all on MDT0,
6085         # otherwise we need to calc the max clock skew between
6086         # the client and MDTs.
6087         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6088         sleep 2
6089         touch $negref || error "touch $negref failed"
6090
6091         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6092         local nums=$($cmd | wc -l)
6093         local expected=$(((NUMFILES + 1) * NUMDIRS))
6094
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097
6098         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6099         nums=$($cmd | wc -l)
6100         expected=$((NUMFILES + 1))
6101         [ $nums -eq $expected ] ||
6102                 error "'$cmd' wrong: found $nums, expected $expected"
6103
6104         [ $skew -lt 0 ] && return
6105
6106         local after=$(do_facet mds1 date +%s)
6107         local age=$((after - before + 1 + skew))
6108
6109         cmd="$LFS find $dir -btime -${age}s -type f"
6110         nums=$($cmd | wc -l)
6111         expected=$(((NUMFILES + 1) * NUMDIRS))
6112
6113         echo "Clock skew between client and server: $skew, age:$age"
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(($NUMDIRS + 1))
6118         cmd="$LFS find $dir -btime -${age}s -type d"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122         rm -f $ref $negref || error "Failed to remove $ref $negref"
6123 }
6124 run_test 56od "check lfs find -btime with units"
6125
6126 test_56p() {
6127         [ $RUNAS_ID -eq $UID ] &&
6128                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6129
6130         local dir=$DIR/$tdir
6131
6132         setup_56 $dir $NUMFILES $NUMDIRS
6133         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6134
6135         local expected=$NUMFILES
6136         local cmd="$LFS find -uid $RUNAS_ID $dir"
6137         local nums=$($cmd | wc -l)
6138
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141
6142         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6143         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6144         nums=$($cmd | wc -l)
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147 }
6148 run_test 56p "check lfs find -uid and ! -uid"
6149
6150 test_56q() {
6151         [ $RUNAS_ID -eq $UID ] &&
6152                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6153
6154         local dir=$DIR/$tdir
6155
6156         setup_56 $dir $NUMFILES $NUMDIRS
6157         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6158
6159         local expected=$NUMFILES
6160         local cmd="$LFS find -gid $RUNAS_GID $dir"
6161         local nums=$($cmd | wc -l)
6162
6163         [ $nums -eq $expected ] ||
6164                 error "'$cmd' wrong: found $nums, expected $expected"
6165
6166         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6167         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6168         nums=$($cmd | wc -l)
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171 }
6172 run_test 56q "check lfs find -gid and ! -gid"
6173
6174 test_56r() {
6175         local dir=$DIR/$tdir
6176
6177         setup_56 $dir $NUMFILES $NUMDIRS
6178
6179         local expected=12
6180         local cmd="$LFS find -size 0 -type f -lazy $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185         cmd="$LFS find -size 0 -type f $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189
6190         expected=0
6191         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6192         nums=$($cmd | wc -l)
6193         [ $nums -eq $expected ] ||
6194                 error "'$cmd' wrong: found $nums, expected $expected"
6195         cmd="$LFS find ! -size 0 -type f $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199
6200         echo "test" > $dir/$tfile
6201         echo "test2" > $dir/$tfile.2 && sync
6202         expected=1
6203         cmd="$LFS find -size 5 -type f -lazy $dir"
6204         nums=$($cmd | wc -l)
6205         [ $nums -eq $expected ] ||
6206                 error "'$cmd' wrong: found $nums, expected $expected"
6207         cmd="$LFS find -size 5 -type f $dir"
6208         nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211
6212         expected=1
6213         cmd="$LFS find -size +5 -type f -lazy $dir"
6214         nums=$($cmd | wc -l)
6215         [ $nums -eq $expected ] ||
6216                 error "'$cmd' wrong: found $nums, expected $expected"
6217         cmd="$LFS find -size +5 -type f $dir"
6218         nums=$($cmd | wc -l)
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221
6222         expected=2
6223         cmd="$LFS find -size +0 -type f -lazy $dir"
6224         nums=$($cmd | wc -l)
6225         [ $nums -eq $expected ] ||
6226                 error "'$cmd' wrong: found $nums, expected $expected"
6227         cmd="$LFS find -size +0 -type f $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231
6232         expected=2
6233         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6234         nums=$($cmd | wc -l)
6235         [ $nums -eq $expected ] ||
6236                 error "'$cmd' wrong: found $nums, expected $expected"
6237         cmd="$LFS find ! -size -5 -type f $dir"
6238         nums=$($cmd | wc -l)
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         expected=12
6243         cmd="$LFS find -size -5 -type f -lazy $dir"
6244         nums=$($cmd | wc -l)
6245         [ $nums -eq $expected ] ||
6246                 error "'$cmd' wrong: found $nums, expected $expected"
6247         cmd="$LFS find -size -5 -type f $dir"
6248         nums=$($cmd | wc -l)
6249         [ $nums -eq $expected ] ||
6250                 error "'$cmd' wrong: found $nums, expected $expected"
6251 }
6252 run_test 56r "check lfs find -size works"
6253
6254 test_56ra_sub() {
6255         local expected=$1
6256         local glimpses=$2
6257         local cmd="$3"
6258
6259         cancel_lru_locks $OSC
6260
6261         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6262         local nums=$($cmd | wc -l)
6263
6264         [ $nums -eq $expected ] ||
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266
6267         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6268
6269         if (( rpcs_before + glimpses != rpcs_after )); then
6270                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6271                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6272
6273                 if [[ $glimpses == 0 ]]; then
6274                         error "'$cmd' should not send glimpse RPCs to OST"
6275                 else
6276                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6277                 fi
6278         fi
6279 }
6280
6281 test_56ra() {
6282         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6283                 skip "MDS < 2.12.58 doesn't return LSOM data"
6284         local dir=$DIR/$tdir
6285         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6286
6287         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6288
6289         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6290         $LCTL set_param -n llite.*.statahead_agl=0
6291         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6292
6293         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6294         # open and close all files to ensure LSOM is updated
6295         cancel_lru_locks $OSC
6296         find $dir -type f | xargs cat > /dev/null
6297
6298         #   expect_found  glimpse_rpcs  command_to_run
6299         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6300         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6301         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6302         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6303
6304         echo "test" > $dir/$tfile
6305         echo "test2" > $dir/$tfile.2 && sync
6306         cancel_lru_locks $OSC
6307         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6308
6309         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6310         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6311         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6312         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6313
6314         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6315         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6316         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6317         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6318         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6319         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6320 }
6321 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6322
6323 test_56rb() {
6324         local dir=$DIR/$tdir
6325         local tmp=$TMP/$tfile.log
6326         local mdt_idx;
6327
6328         test_mkdir -p $dir || error "failed to mkdir $dir"
6329         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6330                 error "failed to setstripe $dir/$tfile"
6331         mdt_idx=$($LFS getdirstripe -i $dir)
6332         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6333
6334         stack_trap "rm -f $tmp" EXIT
6335         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6336         ! grep -q obd_uuid $tmp ||
6337                 error "failed to find --size +100K --ost 0 $dir"
6338         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6339         ! grep -q obd_uuid $tmp ||
6340                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6341 }
6342 run_test 56rb "check lfs find --size --ost/--mdt works"
6343
6344 test_56s() { # LU-611 #LU-9369
6345         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6346
6347         local dir=$DIR/$tdir
6348         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6349
6350         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6351         for i in $(seq $NUMDIRS); do
6352                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6353         done
6354
6355         local expected=$NUMDIRS
6356         local cmd="$LFS find -c $OSTCOUNT $dir"
6357         local nums=$($cmd | wc -l)
6358
6359         [ $nums -eq $expected ] || {
6360                 $LFS getstripe -R $dir
6361                 error "'$cmd' wrong: found $nums, expected $expected"
6362         }
6363
6364         expected=$((NUMDIRS + onestripe))
6365         cmd="$LFS find -stripe-count +0 -type f $dir"
6366         nums=$($cmd | wc -l)
6367         [ $nums -eq $expected ] || {
6368                 $LFS getstripe -R $dir
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370         }
6371
6372         expected=$onestripe
6373         cmd="$LFS find -stripe-count 1 -type f $dir"
6374         nums=$($cmd | wc -l)
6375         [ $nums -eq $expected ] || {
6376                 $LFS getstripe -R $dir
6377                 error "'$cmd' wrong: found $nums, expected $expected"
6378         }
6379
6380         cmd="$LFS find -stripe-count -2 -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=0
6388         cmd="$LFS find -stripe-count $((OSTCOUNT + 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 run_test 56s "check lfs find -stripe-count works"
6396
6397 test_56t() { # LU-611 #LU-9369
6398         local dir=$DIR/$tdir
6399
6400         setup_56 $dir 0 $NUMDIRS
6401         for i in $(seq $NUMDIRS); do
6402                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6403         done
6404
6405         local expected=$NUMDIRS
6406         local cmd="$LFS find -S 8M $dir"
6407         local nums=$($cmd | wc -l)
6408
6409         [ $nums -eq $expected ] || {
6410                 $LFS getstripe -R $dir
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         }
6413         rm -rf $dir
6414
6415         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6416
6417         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6418
6419         expected=$(((NUMDIRS + 1) * NUMFILES))
6420         cmd="$LFS find -stripe-size 512k -type f $dir"
6421         nums=$($cmd | wc -l)
6422         [ $nums -eq $expected ] ||
6423                 error "'$cmd' wrong: found $nums, expected $expected"
6424
6425         cmd="$LFS find -stripe-size +320k -type f $dir"
6426         nums=$($cmd | wc -l)
6427         [ $nums -eq $expected ] ||
6428                 error "'$cmd' wrong: found $nums, expected $expected"
6429
6430         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6431         cmd="$LFS find -stripe-size +200k -type f $dir"
6432         nums=$($cmd | wc -l)
6433         [ $nums -eq $expected ] ||
6434                 error "'$cmd' wrong: found $nums, expected $expected"
6435
6436         cmd="$LFS find -stripe-size -640k -type f $dir"
6437         nums=$($cmd | wc -l)
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         expected=4
6442         cmd="$LFS find -stripe-size 256k -type f $dir"
6443         nums=$($cmd | wc -l)
6444         [ $nums -eq $expected ] ||
6445                 error "'$cmd' wrong: found $nums, expected $expected"
6446
6447         cmd="$LFS find -stripe-size -320k -type f $dir"
6448         nums=$($cmd | wc -l)
6449         [ $nums -eq $expected ] ||
6450                 error "'$cmd' wrong: found $nums, expected $expected"
6451
6452         expected=0
6453         cmd="$LFS find -stripe-size 1024k -type f $dir"
6454         nums=$($cmd | wc -l)
6455         [ $nums -eq $expected ] ||
6456                 error "'$cmd' wrong: found $nums, expected $expected"
6457 }
6458 run_test 56t "check lfs find -stripe-size works"
6459
6460 test_56u() { # LU-611
6461         local dir=$DIR/$tdir
6462
6463         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6464
6465         if [[ $OSTCOUNT -gt 1 ]]; then
6466                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6467                 onestripe=4
6468         else
6469                 onestripe=0
6470         fi
6471
6472         local expected=$(((NUMDIRS + 1) * NUMFILES))
6473         local cmd="$LFS find -stripe-index 0 -type f $dir"
6474         local nums=$($cmd | wc -l)
6475
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478
6479         expected=$onestripe
6480         cmd="$LFS find -stripe-index 1 -type f $dir"
6481         nums=$($cmd | wc -l)
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484
6485         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=0
6491         # This should produce an error and not return any files
6492         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6493         nums=$($cmd 2>/dev/null | wc -l)
6494         [ $nums -eq $expected ] ||
6495                 error "'$cmd' wrong: found $nums, expected $expected"
6496
6497         if [[ $OSTCOUNT -gt 1 ]]; then
6498                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6499                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6500                 nums=$($cmd | wc -l)
6501                 [ $nums -eq $expected ] ||
6502                         error "'$cmd' wrong: found $nums, expected $expected"
6503         fi
6504 }
6505 run_test 56u "check lfs find -stripe-index works"
6506
6507 test_56v() {
6508         local mdt_idx=0
6509         local dir=$DIR/$tdir
6510
6511         setup_56 $dir $NUMFILES $NUMDIRS
6512
6513         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6514         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6515
6516         for file in $($LFS find -m $UUID $dir); do
6517                 file_midx=$($LFS getstripe -m $file)
6518                 [ $file_midx -eq $mdt_idx ] ||
6519                         error "lfs find -m $UUID != getstripe -m $file_midx"
6520         done
6521 }
6522 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6523
6524 test_56w() {
6525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6527
6528         local dir=$DIR/$tdir
6529
6530         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6531
6532         local stripe_size=$($LFS getstripe -S -d $dir) ||
6533                 error "$LFS getstripe -S -d $dir failed"
6534         stripe_size=${stripe_size%% *}
6535
6536         local file_size=$((stripe_size * OSTCOUNT))
6537         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6538         local required_space=$((file_num * file_size))
6539         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6540                            head -n1)
6541         [[ $free_space -le $((required_space / 1024)) ]] &&
6542                 skip_env "need $required_space, have $free_space kbytes"
6543
6544         local dd_bs=65536
6545         local dd_count=$((file_size / dd_bs))
6546
6547         # write data into the files
6548         local i
6549         local j
6550         local file
6551
6552         for i in $(seq $NUMFILES); do
6553                 file=$dir/file$i
6554                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6555                         error "write data into $file failed"
6556         done
6557         for i in $(seq $NUMDIRS); do
6558                 for j in $(seq $NUMFILES); do
6559                         file=$dir/dir$i/file$j
6560                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6561                                 error "write data into $file failed"
6562                 done
6563         done
6564
6565         # $LFS_MIGRATE will fail if hard link migration is unsupported
6566         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6567                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6568                         error "creating links to $dir/dir1/file1 failed"
6569         fi
6570
6571         local expected=-1
6572
6573         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6574
6575         # lfs_migrate file
6576         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6577
6578         echo "$cmd"
6579         eval $cmd || error "$cmd failed"
6580
6581         check_stripe_count $dir/file1 $expected
6582
6583         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6584         then
6585                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6586                 # OST 1 if it is on OST 0. This file is small enough to
6587                 # be on only one stripe.
6588                 file=$dir/migr_1_ost
6589                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6590                         error "write data into $file failed"
6591                 local obdidx=$($LFS getstripe -i $file)
6592                 local oldmd5=$(md5sum $file)
6593                 local newobdidx=0
6594
6595                 [[ $obdidx -eq 0 ]] && newobdidx=1
6596                 cmd="$LFS migrate -i $newobdidx $file"
6597                 echo $cmd
6598                 eval $cmd || error "$cmd failed"
6599
6600                 local realobdix=$($LFS getstripe -i $file)
6601                 local newmd5=$(md5sum $file)
6602
6603                 [[ $newobdidx -ne $realobdix ]] &&
6604                         error "new OST is different (was=$obdidx, "\
6605                               "wanted=$newobdidx, got=$realobdix)"
6606                 [[ "$oldmd5" != "$newmd5" ]] &&
6607                         error "md5sum differ: $oldmd5, $newmd5"
6608         fi
6609
6610         # lfs_migrate dir
6611         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6612         echo "$cmd"
6613         eval $cmd || error "$cmd failed"
6614
6615         for j in $(seq $NUMFILES); do
6616                 check_stripe_count $dir/dir1/file$j $expected
6617         done
6618
6619         # lfs_migrate works with lfs find
6620         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6621              $LFS_MIGRATE -y -c $expected"
6622         echo "$cmd"
6623         eval $cmd || error "$cmd failed"
6624
6625         for i in $(seq 2 $NUMFILES); do
6626                 check_stripe_count $dir/file$i $expected
6627         done
6628         for i in $(seq 2 $NUMDIRS); do
6629                 for j in $(seq $NUMFILES); do
6630                 check_stripe_count $dir/dir$i/file$j $expected
6631                 done
6632         done
6633 }
6634 run_test 56w "check lfs_migrate -c stripe_count works"
6635
6636 test_56wb() {
6637         local file1=$DIR/$tdir/file1
6638         local create_pool=false
6639         local initial_pool=$($LFS getstripe -p $DIR)
6640         local pool_list=()
6641         local pool=""
6642
6643         echo -n "Creating test dir..."
6644         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6645         echo "done."
6646
6647         echo -n "Creating test file..."
6648         touch $file1 || error "cannot create file"
6649         echo "done."
6650
6651         echo -n "Detecting existing pools..."
6652         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6653
6654         if [ ${#pool_list[@]} -gt 0 ]; then
6655                 echo "${pool_list[@]}"
6656                 for thispool in "${pool_list[@]}"; do
6657                         if [[ -z "$initial_pool" ||
6658                               "$initial_pool" != "$thispool" ]]; then
6659                                 pool="$thispool"
6660                                 echo "Using existing pool '$pool'"
6661                                 break
6662                         fi
6663                 done
6664         else
6665                 echo "none detected."
6666         fi
6667         if [ -z "$pool" ]; then
6668                 pool=${POOL:-testpool}
6669                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6670                 echo -n "Creating pool '$pool'..."
6671                 create_pool=true
6672                 pool_add $pool &> /dev/null ||
6673                         error "pool_add failed"
6674                 echo "done."
6675
6676                 echo -n "Adding target to pool..."
6677                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6678                         error "pool_add_targets failed"
6679                 echo "done."
6680         fi
6681
6682         echo -n "Setting pool using -p option..."
6683         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6684                 error "migrate failed rc = $?"
6685         echo "done."
6686
6687         echo -n "Verifying test file is in pool after migrating..."
6688         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6689                 error "file was not migrated to pool $pool"
6690         echo "done."
6691
6692         echo -n "Removing test file from pool '$pool'..."
6693         # "lfs migrate $file" won't remove the file from the pool
6694         # until some striping information is changed.
6695         $LFS migrate -c 1 $file1 &> /dev/null ||
6696                 error "cannot remove from pool"
6697         [ "$($LFS getstripe -p $file1)" ] &&
6698                 error "pool still set"
6699         echo "done."
6700
6701         echo -n "Setting pool using --pool option..."
6702         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6703                 error "migrate failed rc = $?"
6704         echo "done."
6705
6706         # Clean up
6707         rm -f $file1
6708         if $create_pool; then
6709                 destroy_test_pools 2> /dev/null ||
6710                         error "destroy test pools failed"
6711         fi
6712 }
6713 run_test 56wb "check lfs_migrate pool support"
6714
6715 test_56wc() {
6716         local file1="$DIR/$tdir/file1"
6717         local parent_ssize
6718         local parent_scount
6719         local cur_ssize
6720         local cur_scount
6721         local orig_ssize
6722
6723         echo -n "Creating test dir..."
6724         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6725         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6726                 error "cannot set stripe by '-S 1M -c 1'"
6727         echo "done"
6728
6729         echo -n "Setting initial stripe for test file..."
6730         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6731                 error "cannot set stripe"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6734         echo "done."
6735
6736         # File currently set to -S 512K -c 1
6737
6738         # Ensure -c and -S options are rejected when -R is set
6739         echo -n "Verifying incompatible options are detected..."
6740         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6741                 error "incompatible -c and -R options not detected"
6742         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6743                 error "incompatible -S and -R options not detected"
6744         echo "done."
6745
6746         # Ensure unrecognized options are passed through to 'lfs migrate'
6747         echo -n "Verifying -S option is passed through to lfs migrate..."
6748         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6749                 error "migration failed"
6750         cur_ssize=$($LFS getstripe -S "$file1")
6751         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6752         echo "done."
6753
6754         # File currently set to -S 1M -c 1
6755
6756         # Ensure long options are supported
6757         echo -n "Verifying long options supported..."
6758         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6759                 error "long option without argument not supported"
6760         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6761                 error "long option with argument not supported"
6762         cur_ssize=$($LFS getstripe -S "$file1")
6763         [ $cur_ssize -eq 524288 ] ||
6764                 error "migrate --stripe-size $cur_ssize != 524288"
6765         echo "done."
6766
6767         # File currently set to -S 512K -c 1
6768
6769         if [ "$OSTCOUNT" -gt 1 ]; then
6770                 echo -n "Verifying explicit stripe count can be set..."
6771                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6772                         error "migrate failed"
6773                 cur_scount=$($LFS getstripe -c "$file1")
6774                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6775                 echo "done."
6776         fi
6777
6778         # File currently set to -S 512K -c 1 or -S 512K -c 2
6779
6780         # Ensure parent striping is used if -R is set, and no stripe
6781         # count or size is specified
6782         echo -n "Setting stripe for parent directory..."
6783         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6784                 error "cannot set stripe '-S 2M -c 1'"
6785         echo "done."
6786
6787         echo -n "Verifying restripe option uses parent stripe settings..."
6788         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6789         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6790         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6791                 error "migrate failed"
6792         cur_ssize=$($LFS getstripe -S "$file1")
6793         [ $cur_ssize -eq $parent_ssize ] ||
6794                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6795         cur_scount=$($LFS getstripe -c "$file1")
6796         [ $cur_scount -eq $parent_scount ] ||
6797                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6798         echo "done."
6799
6800         # File currently set to -S 1M -c 1
6801
6802         # Ensure striping is preserved if -R is not set, and no stripe
6803         # count or size is specified
6804         echo -n "Verifying striping size preserved when not specified..."
6805         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6806         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6807                 error "cannot set stripe on parent directory"
6808         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6809                 error "migrate failed"
6810         cur_ssize=$($LFS getstripe -S "$file1")
6811         [ $cur_ssize -eq $orig_ssize ] ||
6812                 error "migrate by default $cur_ssize != $orig_ssize"
6813         echo "done."
6814
6815         # Ensure file name properly detected when final option has no argument
6816         echo -n "Verifying file name properly detected..."
6817         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6818                 error "file name interpreted as option argument"
6819         echo "done."
6820
6821         # Clean up
6822         rm -f "$file1"
6823 }
6824 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6825
6826 test_56wd() {
6827         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6828
6829         local file1=$DIR/$tdir/file1
6830
6831         echo -n "Creating test dir..."
6832         test_mkdir $DIR/$tdir || error "cannot create dir"
6833         echo "done."
6834
6835         echo -n "Creating test file..."
6836         touch $file1
6837         echo "done."
6838
6839         # Ensure 'lfs migrate' will fail by using a non-existent option,
6840         # and make sure rsync is not called to recover
6841         echo -n "Make sure --no-rsync option works..."
6842         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6843                 grep -q 'refusing to fall back to rsync' ||
6844                 error "rsync was called with --no-rsync set"
6845         echo "done."
6846
6847         # Ensure rsync is called without trying 'lfs migrate' first
6848         echo -n "Make sure --rsync option works..."
6849         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6850                 grep -q 'falling back to rsync' &&
6851                 error "lfs migrate was called with --rsync set"
6852         echo "done."
6853
6854         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6855         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6856                 grep -q 'at the same time' ||
6857                 error "--rsync and --no-rsync accepted concurrently"
6858         echo "done."
6859
6860         # Clean up
6861         rm -f $file1
6862 }
6863 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6864
6865 test_56we() {
6866         local td=$DIR/$tdir
6867         local tf=$td/$tfile
6868
6869         test_mkdir $td || error "cannot create $td"
6870         touch $tf || error "cannot touch $tf"
6871
6872         echo -n "Make sure --non-direct|-D works..."
6873         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6874                 grep -q "lfs migrate --non-direct" ||
6875                 error "--non-direct option cannot work correctly"
6876         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6877                 grep -q "lfs migrate -D" ||
6878                 error "-D option cannot work correctly"
6879         echo "done."
6880 }
6881 run_test 56we "check lfs_migrate --non-direct|-D support"
6882
6883 test_56x() {
6884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6885         check_swap_layouts_support
6886
6887         local dir=$DIR/$tdir
6888         local ref1=/etc/passwd
6889         local file1=$dir/file1
6890
6891         test_mkdir $dir || error "creating dir $dir"
6892         $LFS setstripe -c 2 $file1
6893         cp $ref1 $file1
6894         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6895         stripe=$($LFS getstripe -c $file1)
6896         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6897         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6898
6899         # clean up
6900         rm -f $file1
6901 }
6902 run_test 56x "lfs migration support"
6903
6904 test_56xa() {
6905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6906         check_swap_layouts_support
6907
6908         local dir=$DIR/$tdir/$testnum
6909
6910         test_mkdir -p $dir
6911
6912         local ref1=/etc/passwd
6913         local file1=$dir/file1
6914
6915         $LFS setstripe -c 2 $file1
6916         cp $ref1 $file1
6917         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6918
6919         local stripe=$($LFS getstripe -c $file1)
6920
6921         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6922         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6923
6924         # clean up
6925         rm -f $file1
6926 }
6927 run_test 56xa "lfs migration --block support"
6928
6929 check_migrate_links() {
6930         local dir="$1"
6931         local file1="$dir/file1"
6932         local begin="$2"
6933         local count="$3"
6934         local runas="$4"
6935         local total_count=$(($begin + $count - 1))
6936         local symlink_count=10
6937         local uniq_count=10
6938
6939         if [ ! -f "$file1" ]; then
6940                 echo -n "creating initial file..."
6941                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6942                         error "cannot setstripe initial file"
6943                 echo "done"
6944
6945                 echo -n "creating symlinks..."
6946                 for s in $(seq 1 $symlink_count); do
6947                         ln -s "$file1" "$dir/slink$s" ||
6948                                 error "cannot create symlinks"
6949                 done
6950                 echo "done"
6951
6952                 echo -n "creating nonlinked files..."
6953                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6954                         error "cannot create nonlinked files"
6955                 echo "done"
6956         fi
6957
6958         # create hard links
6959         if [ ! -f "$dir/file$total_count" ]; then
6960                 echo -n "creating hard links $begin:$total_count..."
6961                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6962                         /dev/null || error "cannot create hard links"
6963                 echo "done"
6964         fi
6965
6966         echo -n "checking number of hard links listed in xattrs..."
6967         local fid=$($LFS getstripe -F "$file1")
6968         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6969
6970         echo "${#paths[*]}"
6971         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6972                         skip "hard link list has unexpected size, skipping test"
6973         fi
6974         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6975                         error "link names should exceed xattrs size"
6976         fi
6977
6978         echo -n "migrating files..."
6979         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6980         local rc=$?
6981         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6982         echo "done"
6983
6984         # make sure all links have been properly migrated
6985         echo -n "verifying files..."
6986         fid=$($LFS getstripe -F "$file1") ||
6987                 error "cannot get fid for file $file1"
6988         for i in $(seq 2 $total_count); do
6989                 local fid2=$($LFS getstripe -F $dir/file$i)
6990
6991                 [ "$fid2" == "$fid" ] ||
6992                         error "migrated hard link has mismatched FID"
6993         done
6994
6995         # make sure hard links were properly detected, and migration was
6996         # performed only once for the entire link set; nonlinked files should
6997         # also be migrated
6998         local actual=$(grep -c 'done' <<< "$migrate_out")
6999         local expected=$(($uniq_count + 1))
7000
7001         [ "$actual" -eq  "$expected" ] ||
7002                 error "hard links individually migrated ($actual != $expected)"
7003
7004         # make sure the correct number of hard links are present
7005         local hardlinks=$(stat -c '%h' "$file1")
7006
7007         [ $hardlinks -eq $total_count ] ||
7008                 error "num hard links $hardlinks != $total_count"
7009         echo "done"
7010
7011         return 0
7012 }
7013
7014 test_56xb() {
7015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7016                 skip "Need MDS version at least 2.10.55"
7017
7018         local dir="$DIR/$tdir"
7019
7020         test_mkdir "$dir" || error "cannot create dir $dir"
7021
7022         echo "testing lfs migrate mode when all links fit within xattrs"
7023         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7024
7025         echo "testing rsync mode when all links fit within xattrs"
7026         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7027
7028         echo "testing lfs migrate mode when all links do not fit within xattrs"
7029         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7030
7031         echo "testing rsync mode when all links do not fit within xattrs"
7032         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7033
7034         chown -R $RUNAS_ID $dir
7035         echo "testing non-root lfs migrate mode when not all links are in xattr"
7036         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7037
7038         # clean up
7039         rm -rf $dir
7040 }
7041 run_test 56xb "lfs migration hard link support"
7042
7043 test_56xc() {
7044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7045
7046         local dir="$DIR/$tdir"
7047
7048         test_mkdir "$dir" || error "cannot create dir $dir"
7049
7050         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7051         echo -n "Setting initial stripe for 20MB test file..."
7052         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7053                 error "cannot setstripe 20MB file"
7054         echo "done"
7055         echo -n "Sizing 20MB test file..."
7056         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7057         echo "done"
7058         echo -n "Verifying small file autostripe count is 1..."
7059         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7060                 error "cannot migrate 20MB file"
7061         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7062                 error "cannot get stripe for $dir/20mb"
7063         [ $stripe_count -eq 1 ] ||
7064                 error "unexpected stripe count $stripe_count for 20MB file"
7065         rm -f "$dir/20mb"
7066         echo "done"
7067
7068         # Test 2: File is small enough to fit within the available space on
7069         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7070         # have at least an additional 1KB for each desired stripe for test 3
7071         echo -n "Setting stripe for 1GB test file..."
7072         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7073         echo "done"
7074         echo -n "Sizing 1GB test file..."
7075         # File size is 1GB + 3KB
7076         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7077         echo "done"
7078
7079         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7080         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7081         if (( avail > 524288 * OSTCOUNT )); then
7082                 echo -n "Migrating 1GB file..."
7083                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7084                         error "cannot migrate 1GB file"
7085                 echo "done"
7086                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7087                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7088                         error "cannot getstripe for 1GB file"
7089                 [ $stripe_count -eq 2 ] ||
7090                         error "unexpected stripe count $stripe_count != 2"
7091                 echo "done"
7092         fi
7093
7094         # Test 3: File is too large to fit within the available space on
7095         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7096         if [ $OSTCOUNT -ge 3 ]; then
7097                 # The required available space is calculated as
7098                 # file size (1GB + 3KB) / OST count (3).
7099                 local kb_per_ost=349526
7100
7101                 echo -n "Migrating 1GB file with limit..."
7102                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7103                         error "cannot migrate 1GB file with limit"
7104                 echo "done"
7105
7106                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7107                 echo -n "Verifying 1GB autostripe count with limited space..."
7108                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7109                         error "unexpected stripe count $stripe_count (min 3)"
7110                 echo "done"
7111         fi
7112
7113         # clean up
7114         rm -rf $dir
7115 }
7116 run_test 56xc "lfs migration autostripe"
7117
7118 test_56xd() {
7119         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7120
7121         local dir=$DIR/$tdir
7122         local f_mgrt=$dir/$tfile.mgrt
7123         local f_yaml=$dir/$tfile.yaml
7124         local f_copy=$dir/$tfile.copy
7125         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7126         local layout_copy="-c 2 -S 2M -i 1"
7127         local yamlfile=$dir/yamlfile
7128         local layout_before;
7129         local layout_after;
7130
7131         test_mkdir "$dir" || error "cannot create dir $dir"
7132         $LFS setstripe $layout_yaml $f_yaml ||
7133                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7134         $LFS getstripe --yaml $f_yaml > $yamlfile
7135         $LFS setstripe $layout_copy $f_copy ||
7136                 error "cannot setstripe $f_copy with layout $layout_copy"
7137         touch $f_mgrt
7138         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7139
7140         # 1. test option --yaml
7141         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7142                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7143         layout_before=$(get_layout_param $f_yaml)
7144         layout_after=$(get_layout_param $f_mgrt)
7145         [ "$layout_after" == "$layout_before" ] ||
7146                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7147
7148         # 2. test option --copy
7149         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7150                 error "cannot migrate $f_mgrt with --copy $f_copy"
7151         layout_before=$(get_layout_param $f_copy)
7152         layout_after=$(get_layout_param $f_mgrt)
7153         [ "$layout_after" == "$layout_before" ] ||
7154                 error "lfs_migrate --copy: $layout_after != $layout_before"
7155 }
7156 run_test 56xd "check lfs_migrate --yaml and --copy support"
7157
7158 test_56xe() {
7159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7160
7161         local dir=$DIR/$tdir
7162         local f_comp=$dir/$tfile
7163         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7164         local layout_before=""
7165         local layout_after=""
7166
7167         test_mkdir "$dir" || error "cannot create dir $dir"
7168         $LFS setstripe $layout $f_comp ||
7169                 error "cannot setstripe $f_comp with layout $layout"
7170         layout_before=$(get_layout_param $f_comp)
7171         dd if=/dev/zero of=$f_comp bs=1M count=4
7172
7173         # 1. migrate a comp layout file by lfs_migrate
7174         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7175         layout_after=$(get_layout_param $f_comp)
7176         [ "$layout_before" == "$layout_after" ] ||
7177                 error "lfs_migrate: $layout_before != $layout_after"
7178
7179         # 2. migrate a comp layout file by lfs migrate
7180         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7181         layout_after=$(get_layout_param $f_comp)
7182         [ "$layout_before" == "$layout_after" ] ||
7183                 error "lfs migrate: $layout_before != $layout_after"
7184 }
7185 run_test 56xe "migrate a composite layout file"
7186
7187 test_56xf() {
7188         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7189
7190         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7191                 skip "Need server version at least 2.13.53"
7192
7193         local dir=$DIR/$tdir
7194         local f_comp=$dir/$tfile
7195         local layout="-E 1M -c1 -E -1 -c2"
7196         local fid_before=""
7197         local fid_after=""
7198
7199         test_mkdir "$dir" || error "cannot create dir $dir"
7200         $LFS setstripe $layout $f_comp ||
7201                 error "cannot setstripe $f_comp with layout $layout"
7202         fid_before=$($LFS getstripe --fid $f_comp)
7203         dd if=/dev/zero of=$f_comp bs=1M count=4
7204
7205         # 1. migrate a comp layout file to a comp layout
7206         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7207         fid_after=$($LFS getstripe --fid $f_comp)
7208         [ "$fid_before" == "$fid_after" ] ||
7209                 error "comp-to-comp migrate: $fid_before != $fid_after"
7210
7211         # 2. migrate a comp layout file to a plain layout
7212         $LFS migrate -c2 $f_comp ||
7213                 error "cannot migrate $f_comp by lfs migrate"
7214         fid_after=$($LFS getstripe --fid $f_comp)
7215         [ "$fid_before" == "$fid_after" ] ||
7216                 error "comp-to-plain migrate: $fid_before != $fid_after"
7217
7218         # 3. migrate a plain layout file to a comp layout
7219         $LFS migrate $layout $f_comp ||
7220                 error "cannot migrate $f_comp by lfs migrate"
7221         fid_after=$($LFS getstripe --fid $f_comp)
7222         [ "$fid_before" == "$fid_after" ] ||
7223                 error "plain-to-comp migrate: $fid_before != $fid_after"
7224 }
7225 run_test 56xf "FID is not lost during migration of a composite layout file"
7226
7227 test_56y() {
7228         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7229                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7230
7231         local res=""
7232         local dir=$DIR/$tdir
7233         local f1=$dir/file1
7234         local f2=$dir/file2
7235
7236         test_mkdir -p $dir || error "creating dir $dir"
7237         touch $f1 || error "creating std file $f1"
7238         $MULTIOP $f2 H2c || error "creating released file $f2"
7239
7240         # a directory can be raid0, so ask only for files
7241         res=$($LFS find $dir -L raid0 -type f | wc -l)
7242         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7243
7244         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7245         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7246
7247         # only files can be released, so no need to force file search
7248         res=$($LFS find $dir -L released)
7249         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7250
7251         res=$($LFS find $dir -type f \! -L released)
7252         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7253 }
7254 run_test 56y "lfs find -L raid0|released"
7255
7256 test_56z() { # LU-4824
7257         # This checks to make sure 'lfs find' continues after errors
7258         # There are two classes of errors that should be caught:
7259         # - If multiple paths are provided, all should be searched even if one
7260         #   errors out
7261         # - If errors are encountered during the search, it should not terminate
7262         #   early
7263         local dir=$DIR/$tdir
7264         local i
7265
7266         test_mkdir $dir
7267         for i in d{0..9}; do
7268                 test_mkdir $dir/$i
7269                 touch $dir/$i/$tfile
7270         done
7271         $LFS find $DIR/non_existent_dir $dir &&
7272                 error "$LFS find did not return an error"
7273         # Make a directory unsearchable. This should NOT be the last entry in
7274         # directory order.  Arbitrarily pick the 6th entry
7275         chmod 700 $($LFS find $dir -type d | sed '6!d')
7276
7277         $RUNAS $LFS find $DIR/non_existent $dir
7278         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7279
7280         # The user should be able to see 10 directories and 9 files
7281         (( count == 19 )) ||
7282                 error "$LFS find found $count != 19 entries after error"
7283 }
7284 run_test 56z "lfs find should continue after an error"
7285
7286 test_56aa() { # LU-5937
7287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7288
7289         local dir=$DIR/$tdir
7290
7291         mkdir $dir
7292         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7293
7294         createmany -o $dir/striped_dir/${tfile}- 1024
7295         local dirs=$($LFS find --size +8k $dir/)
7296
7297         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7298 }
7299 run_test 56aa "lfs find --size under striped dir"
7300
7301 test_56ab() { # LU-10705
7302         test_mkdir $DIR/$tdir
7303         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7304         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7305         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7306         # Flush writes to ensure valid blocks.  Need to be more thorough for
7307         # ZFS, since blocks are not allocated/returned to client immediately.
7308         sync_all_data
7309         wait_zfs_commit ost1 2
7310         cancel_lru_locks osc
7311         ls -ls $DIR/$tdir
7312
7313         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7314
7315         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7316
7317         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7318         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7319
7320         rm -f $DIR/$tdir/$tfile.[123]
7321 }
7322 run_test 56ab "lfs find --blocks"
7323
7324 test_56ba() {
7325         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7326                 skip "Need MDS version at least 2.10.50"
7327
7328         # Create composite files with one component
7329         local dir=$DIR/$tdir
7330
7331         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7332         # Create composite files with three components
7333         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7334         # Create non-composite files
7335         createmany -o $dir/${tfile}- 10
7336
7337         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7338
7339         [[ $nfiles == 10 ]] ||
7340                 error "lfs find -E 1M found $nfiles != 10 files"
7341
7342         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7343         [[ $nfiles == 25 ]] ||
7344                 error "lfs find ! -E 1M found $nfiles != 25 files"
7345
7346         # All files have a component that starts at 0
7347         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7348         [[ $nfiles == 35 ]] ||
7349                 error "lfs find --component-start 0 - $nfiles != 35 files"
7350
7351         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7352         [[ $nfiles == 15 ]] ||
7353                 error "lfs find --component-start 2M - $nfiles != 15 files"
7354
7355         # All files created here have a componenet that does not starts at 2M
7356         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7357         [[ $nfiles == 35 ]] ||
7358                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7359
7360         # Find files with a specified number of components
7361         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7362         [[ $nfiles == 15 ]] ||
7363                 error "lfs find --component-count 3 - $nfiles != 15 files"
7364
7365         # Remember non-composite files have a component count of zero
7366         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7367         [[ $nfiles == 10 ]] ||
7368                 error "lfs find --component-count 0 - $nfiles != 10 files"
7369
7370         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7371         [[ $nfiles == 20 ]] ||
7372                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7373
7374         # All files have a flag called "init"
7375         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7376         [[ $nfiles == 35 ]] ||
7377                 error "lfs find --component-flags init - $nfiles != 35 files"
7378
7379         # Multi-component files will have a component not initialized
7380         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7381         [[ $nfiles == 15 ]] ||
7382                 error "lfs find !--component-flags init - $nfiles != 15 files"
7383
7384         rm -rf $dir
7385
7386 }
7387 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7388
7389 test_56ca() {
7390         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7391                 skip "Need MDS version at least 2.10.57"
7392
7393         local td=$DIR/$tdir
7394         local tf=$td/$tfile
7395         local dir
7396         local nfiles
7397         local cmd
7398         local i
7399         local j
7400
7401         # create mirrored directories and mirrored files
7402         mkdir $td || error "mkdir $td failed"
7403         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7404         createmany -o $tf- 10 || error "create $tf- failed"
7405
7406         for i in $(seq 2); do
7407                 dir=$td/dir$i
7408                 mkdir $dir || error "mkdir $dir failed"
7409                 $LFS mirror create -N$((3 + i)) $dir ||
7410                         error "create mirrored dir $dir failed"
7411                 createmany -o $dir/$tfile- 10 ||
7412                         error "create $dir/$tfile- failed"
7413         done
7414
7415         # change the states of some mirrored files
7416         echo foo > $tf-6
7417         for i in $(seq 2); do
7418                 dir=$td/dir$i
7419                 for j in $(seq 4 9); do
7420                         echo foo > $dir/$tfile-$j
7421                 done
7422         done
7423
7424         # find mirrored files with specific mirror count
7425         cmd="$LFS find --mirror-count 3 --type f $td"
7426         nfiles=$($cmd | wc -l)
7427         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7428
7429         cmd="$LFS find ! --mirror-count 3 --type f $td"
7430         nfiles=$($cmd | wc -l)
7431         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7432
7433         cmd="$LFS find --mirror-count +2 --type f $td"
7434         nfiles=$($cmd | wc -l)
7435         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7436
7437         cmd="$LFS find --mirror-count -6 --type f $td"
7438         nfiles=$($cmd | wc -l)
7439         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7440
7441         # find mirrored files with specific file state
7442         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7443         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7444
7445         cmd="$LFS find --mirror-state=ro --type f $td"
7446         nfiles=$($cmd | wc -l)
7447         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7448
7449         cmd="$LFS find ! --mirror-state=ro --type f $td"
7450         nfiles=$($cmd | wc -l)
7451         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7452
7453         cmd="$LFS find --mirror-state=wp --type f $td"
7454         nfiles=$($cmd | wc -l)
7455         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7456
7457         cmd="$LFS find ! --mirror-state=sp --type f $td"
7458         nfiles=$($cmd | wc -l)
7459         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7460 }
7461 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7462
7463 test_57a() {
7464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7465         # note test will not do anything if MDS is not local
7466         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7467                 skip_env "ldiskfs only test"
7468         fi
7469         remote_mds_nodsh && skip "remote MDS with nodsh"
7470
7471         local MNTDEV="osd*.*MDT*.mntdev"
7472         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7473         [ -z "$DEV" ] && error "can't access $MNTDEV"
7474         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7475                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7476                         error "can't access $DEV"
7477                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7478                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7479                 rm $TMP/t57a.dump
7480         done
7481 }
7482 run_test 57a "verify MDS filesystem created with large inodes =="
7483
7484 test_57b() {
7485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7486         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7487                 skip_env "ldiskfs only test"
7488         fi
7489         remote_mds_nodsh && skip "remote MDS with nodsh"
7490
7491         local dir=$DIR/$tdir
7492         local filecount=100
7493         local file1=$dir/f1
7494         local fileN=$dir/f$filecount
7495
7496         rm -rf $dir || error "removing $dir"
7497         test_mkdir -c1 $dir
7498         local mdtidx=$($LFS getstripe -m $dir)
7499         local mdtname=MDT$(printf %04x $mdtidx)
7500         local facet=mds$((mdtidx + 1))
7501
7502         echo "mcreating $filecount files"
7503         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7504
7505         # verify that files do not have EAs yet
7506         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7507                 error "$file1 has an EA"
7508         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7509                 error "$fileN has an EA"
7510
7511         sync
7512         sleep 1
7513         df $dir  #make sure we get new statfs data
7514         local mdsfree=$(do_facet $facet \
7515                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7516         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7517         local file
7518
7519         echo "opening files to create objects/EAs"
7520         for file in $(seq -f $dir/f%g 1 $filecount); do
7521                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7522                         error "opening $file"
7523         done
7524
7525         # verify that files have EAs now
7526         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7527         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7528
7529         sleep 1  #make sure we get new statfs data
7530         df $dir
7531         local mdsfree2=$(do_facet $facet \
7532                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7533         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7534
7535         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7536                 if [ "$mdsfree" != "$mdsfree2" ]; then
7537                         error "MDC before $mdcfree != after $mdcfree2"
7538                 else
7539                         echo "MDC before $mdcfree != after $mdcfree2"
7540                         echo "unable to confirm if MDS has large inodes"
7541                 fi
7542         fi
7543         rm -rf $dir
7544 }
7545 run_test 57b "default LOV EAs are stored inside large inodes ==="
7546
7547 test_58() {
7548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7549         [ -z "$(which wiretest 2>/dev/null)" ] &&
7550                         skip_env "could not find wiretest"
7551
7552         wiretest
7553 }
7554 run_test 58 "verify cross-platform wire constants =============="
7555
7556 test_59() {
7557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7558
7559         echo "touch 130 files"
7560         createmany -o $DIR/f59- 130
7561         echo "rm 130 files"
7562         unlinkmany $DIR/f59- 130
7563         sync
7564         # wait for commitment of removal
7565         wait_delete_completed
7566 }
7567 run_test 59 "verify cancellation of llog records async ========="
7568
7569 TEST60_HEAD="test_60 run $RANDOM"
7570 test_60a() {
7571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7572         remote_mgs_nodsh && skip "remote MGS with nodsh"
7573         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7574                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7575                         skip_env "missing subtest run-llog.sh"
7576
7577         log "$TEST60_HEAD - from kernel mode"
7578         do_facet mgs "$LCTL dk > /dev/null"
7579         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7580         do_facet mgs $LCTL dk > $TMP/$tfile
7581
7582         # LU-6388: test llog_reader
7583         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7584         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7585         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7586                         skip_env "missing llog_reader"
7587         local fstype=$(facet_fstype mgs)
7588         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7589                 skip_env "Only for ldiskfs or zfs type mgs"
7590
7591         local mntpt=$(facet_mntpt mgs)
7592         local mgsdev=$(mgsdevname 1)
7593         local fid_list
7594         local fid
7595         local rec_list
7596         local rec
7597         local rec_type
7598         local obj_file
7599         local path
7600         local seq
7601         local oid
7602         local pass=true
7603
7604         #get fid and record list
7605         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7606                 tail -n 4))
7607         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7608                 tail -n 4))
7609         #remount mgs as ldiskfs or zfs type
7610         stop mgs || error "stop mgs failed"
7611         mount_fstype mgs || error "remount mgs failed"
7612         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7613                 fid=${fid_list[i]}
7614                 rec=${rec_list[i]}
7615                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7616                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7617                 oid=$((16#$oid))
7618
7619                 case $fstype in
7620                         ldiskfs )
7621                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7622                         zfs )
7623                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7624                 esac
7625                 echo "obj_file is $obj_file"
7626                 do_facet mgs $llog_reader $obj_file
7627
7628                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7629                         awk '{ print $3 }' | sed -e "s/^type=//g")
7630                 if [ $rec_type != $rec ]; then
7631                         echo "FAILED test_60a wrong record type $rec_type," \
7632                               "should be $rec"
7633                         pass=false
7634                         break
7635                 fi
7636
7637                 #check obj path if record type is LLOG_LOGID_MAGIC
7638                 if [ "$rec" == "1064553b" ]; then
7639                         path=$(do_facet mgs $llog_reader $obj_file |
7640                                 grep "path=" | awk '{ print $NF }' |
7641                                 sed -e "s/^path=//g")
7642                         if [ $obj_file != $mntpt/$path ]; then
7643                                 echo "FAILED test_60a wrong obj path" \
7644                                       "$montpt/$path, should be $obj_file"
7645                                 pass=false
7646                                 break
7647                         fi
7648                 fi
7649         done
7650         rm -f $TMP/$tfile
7651         #restart mgs before "error", otherwise it will block the next test
7652         stop mgs || error "stop mgs failed"
7653         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7654         $pass || error "test failed, see FAILED test_60a messages for specifics"
7655 }
7656 run_test 60a "llog_test run from kernel module and test llog_reader"
7657
7658 test_60b() { # bug 6411
7659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7660
7661         dmesg > $DIR/$tfile
7662         LLOG_COUNT=$(do_facet mgs dmesg |
7663                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7664                           /llog_[a-z]*.c:[0-9]/ {
7665                                 if (marker)
7666                                         from_marker++
7667                                 from_begin++
7668                           }
7669                           END {
7670                                 if (marker)
7671                                         print from_marker
7672                                 else
7673                                         print from_begin
7674                           }")
7675
7676         [[ $LLOG_COUNT -gt 120 ]] &&
7677                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7678 }
7679 run_test 60b "limit repeated messages from CERROR/CWARN"
7680
7681 test_60c() {
7682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7683
7684         echo "create 5000 files"
7685         createmany -o $DIR/f60c- 5000
7686 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7687         lctl set_param fail_loc=0x80000137
7688         unlinkmany $DIR/f60c- 5000
7689         lctl set_param fail_loc=0
7690 }
7691 run_test 60c "unlink file when mds full"
7692
7693 test_60d() {
7694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7695
7696         SAVEPRINTK=$(lctl get_param -n printk)
7697         # verify "lctl mark" is even working"
7698         MESSAGE="test message ID $RANDOM $$"
7699         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7700         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7701
7702         lctl set_param printk=0 || error "set lnet.printk failed"
7703         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7704         MESSAGE="new test message ID $RANDOM $$"
7705         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7706         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7707         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7708
7709         lctl set_param -n printk="$SAVEPRINTK"
7710 }
7711 run_test 60d "test printk console message masking"
7712
7713 test_60e() {
7714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7715         remote_mds_nodsh && skip "remote MDS with nodsh"
7716
7717         touch $DIR/$tfile
7718 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7719         do_facet mds1 lctl set_param fail_loc=0x15b
7720         rm $DIR/$tfile
7721 }
7722 run_test 60e "no space while new llog is being created"
7723
7724 test_60g() {
7725         local pid
7726         local i
7727
7728         test_mkdir -c $MDSCOUNT $DIR/$tdir
7729
7730         (
7731                 local index=0
7732                 while true; do
7733                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7734                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7735                                 2>/dev/null
7736                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7737                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7738                         index=$((index + 1))
7739                 done
7740         ) &
7741
7742         pid=$!
7743
7744         for i in {0..100}; do
7745                 # define OBD_FAIL_OSD_TXN_START    0x19a
7746                 local index=$((i % MDSCOUNT + 1))
7747
7748                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7749                         > /dev/null
7750                 sleep 0.01
7751         done
7752
7753         kill -9 $pid
7754
7755         for i in $(seq $MDSCOUNT); do
7756                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7757         done
7758
7759         mkdir $DIR/$tdir/new || error "mkdir failed"
7760         rmdir $DIR/$tdir/new || error "rmdir failed"
7761
7762         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7763                 -t namespace
7764         for i in $(seq $MDSCOUNT); do
7765                 wait_update_facet mds$i "$LCTL get_param -n \
7766                         mdd.$(facet_svc mds$i).lfsck_namespace |
7767                         awk '/^status/ { print \\\$2 }'" "completed"
7768         done
7769
7770         ls -R $DIR/$tdir || error "ls failed"
7771         rm -rf $DIR/$tdir || error "rmdir failed"
7772 }
7773 run_test 60g "transaction abort won't cause MDT hung"
7774
7775 test_60h() {
7776         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7777                 skip "Need MDS version at least 2.12.52"
7778         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7779
7780         local f
7781
7782         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7783         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7784         for fail_loc in 0x80000188 0x80000189; do
7785                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7786                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7787                         error "mkdir $dir-$fail_loc failed"
7788                 for i in {0..10}; do
7789                         # create may fail on missing stripe
7790                         echo $i > $DIR/$tdir-$fail_loc/$i
7791                 done
7792                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7793                         error "getdirstripe $tdir-$fail_loc failed"
7794                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7795                         error "migrate $tdir-$fail_loc failed"
7796                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7797                         error "getdirstripe $tdir-$fail_loc failed"
7798                 pushd $DIR/$tdir-$fail_loc
7799                 for f in *; do
7800                         echo $f | cmp $f - || error "$f data mismatch"
7801                 done
7802                 popd
7803                 rm -rf $DIR/$tdir-$fail_loc
7804         done
7805 }
7806 run_test 60h "striped directory with missing stripes can be accessed"
7807
7808 test_61a() {
7809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7810
7811         f="$DIR/f61"
7812         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7813         cancel_lru_locks osc
7814         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7815         sync
7816 }
7817 run_test 61a "mmap() writes don't make sync hang ================"
7818
7819 test_61b() {
7820         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7821 }
7822 run_test 61b "mmap() of unstriped file is successful"
7823
7824 # bug 2330 - insufficient obd_match error checking causes LBUG
7825 test_62() {
7826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7827
7828         f="$DIR/f62"
7829         echo foo > $f
7830         cancel_lru_locks osc
7831         lctl set_param fail_loc=0x405
7832         cat $f && error "cat succeeded, expect -EIO"
7833         lctl set_param fail_loc=0
7834 }
7835 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7836 # match every page all of the time.
7837 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7838
7839 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7840 # Though this test is irrelevant anymore, it helped to reveal some
7841 # other grant bugs (LU-4482), let's keep it.
7842 test_63a() {   # was test_63
7843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7844
7845         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7846
7847         for i in `seq 10` ; do
7848                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7849                 sleep 5
7850                 kill $!
7851                 sleep 1
7852         done
7853
7854         rm -f $DIR/f63 || true
7855 }
7856 run_test 63a "Verify oig_wait interruption does not crash ======="
7857
7858 # bug 2248 - async write errors didn't return to application on sync
7859 # bug 3677 - async write errors left page locked
7860 test_63b() {
7861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7862
7863         debugsave
7864         lctl set_param debug=-1
7865
7866         # ensure we have a grant to do async writes
7867         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7868         rm $DIR/$tfile
7869
7870         sync    # sync lest earlier test intercept the fail_loc
7871
7872         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7873         lctl set_param fail_loc=0x80000406
7874         $MULTIOP $DIR/$tfile Owy && \
7875                 error "sync didn't return ENOMEM"
7876         sync; sleep 2; sync     # do a real sync this time to flush page
7877         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7878                 error "locked page left in cache after async error" || true
7879         debugrestore
7880 }
7881 run_test 63b "async write errors should be returned to fsync ==="
7882
7883 test_64a () {
7884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7885
7886         lfs df $DIR
7887         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7888 }
7889 run_test 64a "verify filter grant calculations (in kernel) ====="
7890
7891 test_64b () {
7892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7893
7894         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7895 }
7896 run_test 64b "check out-of-space detection on client"
7897
7898 test_64c() {
7899         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7900 }
7901 run_test 64c "verify grant shrink"
7902
7903 import_param() {
7904         local tgt=$1
7905         local param=$2
7906
7907         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7908 }
7909
7910 # this does exactly what osc_request.c:osc_announce_cached() does in
7911 # order to calculate max amount of grants to ask from server
7912 want_grant() {
7913         local tgt=$1
7914
7915         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7916         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7917
7918         ((rpc_in_flight++));
7919         nrpages=$((nrpages * rpc_in_flight))
7920
7921         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7922
7923         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7924
7925         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7926         local undirty=$((nrpages * PAGE_SIZE))
7927
7928         local max_extent_pages
7929         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7930         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7931         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7932         local grant_extent_tax
7933         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7934
7935         undirty=$((undirty + nrextents * grant_extent_tax))
7936
7937         echo $undirty
7938 }
7939
7940 # this is size of unit for grant allocation. It should be equal to
7941 # what tgt_grant.c:tgt_grant_chunk() calculates
7942 grant_chunk() {
7943         local tgt=$1
7944         local max_brw_size
7945         local grant_extent_tax
7946
7947         max_brw_size=$(import_param $tgt max_brw_size)
7948
7949         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7950
7951         echo $(((max_brw_size + grant_extent_tax) * 2))
7952 }
7953
7954 test_64d() {
7955         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7956                 skip "OST < 2.10.55 doesn't limit grants enough"
7957
7958         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7959
7960         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7961                 skip "no grant_param connect flag"
7962
7963         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7964
7965         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7966         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7967
7968
7969         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7970         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7971
7972         $LFS setstripe $DIR/$tfile -i 0 -c 1
7973         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7974         ddpid=$!
7975
7976         while kill -0 $ddpid; do
7977                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7978
7979                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7980                         kill $ddpid
7981                         error "cur_grant $cur_grant > $max_cur_granted"
7982                 fi
7983
7984                 sleep 1
7985         done
7986 }
7987 run_test 64d "check grant limit exceed"
7988
7989 check_grants() {
7990         local tgt=$1
7991         local expected=$2
7992         local msg=$3
7993         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7994
7995         ((cur_grants == expected)) ||
7996                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7997 }
7998
7999 round_up_p2() {
8000         echo $((($1 + $2 - 1) & ~($2 - 1)))
8001 }
8002
8003 test_64e() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8006                 skip "Need OSS version at least 2.11.56"
8007
8008         # Remount client to reset grant
8009         remount_client $MOUNT || error "failed to remount client"
8010         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8011
8012         local init_grants=$(import_param $osc_tgt initial_grant)
8013
8014         check_grants $osc_tgt $init_grants "init grants"
8015
8016         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8017         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8018         local gbs=$(import_param $osc_tgt grant_block_size)
8019
8020         # write random number of bytes from max_brw_size / 4 to max_brw_size
8021         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8022         # align for direct io
8023         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8024         # round to grant consumption unit
8025         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8026
8027         local grants=$((wb_round_up + extent_tax))
8028
8029         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8030
8031         # define OBD_FAIL_TGT_NO_GRANT 0x725
8032         # make the server not grant more back
8033         do_facet ost1 $LCTL set_param fail_loc=0x725
8034         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8035
8036         do_facet ost1 $LCTL set_param fail_loc=0
8037
8038         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8039
8040         rm -f $DIR/$tfile || error "rm failed"
8041
8042         # Remount client to reset grant
8043         remount_client $MOUNT || error "failed to remount client"
8044         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8045
8046         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8047
8048         # define OBD_FAIL_TGT_NO_GRANT 0x725
8049         # make the server not grant more back
8050         do_facet ost1 $LCTL set_param fail_loc=0x725
8051         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8052         do_facet ost1 $LCTL set_param fail_loc=0
8053
8054         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8055 }
8056 run_test 64e "check grant consumption (no grant allocation)"
8057
8058 test_64f() {
8059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8060
8061         # Remount client to reset grant
8062         remount_client $MOUNT || error "failed to remount client"
8063         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8064
8065         local init_grants=$(import_param $osc_tgt initial_grant)
8066         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8067         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8068         local gbs=$(import_param $osc_tgt grant_block_size)
8069         local chunk=$(grant_chunk $osc_tgt)
8070
8071         # write random number of bytes from max_brw_size / 4 to max_brw_size
8072         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8073         # align for direct io
8074         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8075         # round to grant consumption unit
8076         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8077
8078         local grants=$((wb_round_up + extent_tax))
8079
8080         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8081         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8082                 error "error writing to $DIR/$tfile"
8083
8084         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8085                 "direct io with grant allocation"
8086
8087         rm -f $DIR/$tfile || error "rm failed"
8088
8089         # Remount client to reset grant
8090         remount_client $MOUNT || error "failed to remount client"
8091         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8092
8093         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8094
8095         local cmd="oO_WRONLY:w${write_bytes}_yc"
8096
8097         $MULTIOP $DIR/$tfile $cmd &
8098         MULTIPID=$!
8099         sleep 1
8100
8101         check_grants $osc_tgt $((init_grants - grants)) \
8102                 "buffered io, not write rpc"
8103
8104         kill -USR1 $MULTIPID
8105         wait
8106
8107         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8108                 "buffered io, one RPC"
8109 }
8110 run_test 64f "check grant consumption (with grant allocation)"
8111
8112 # bug 1414 - set/get directories' stripe info
8113 test_65a() {
8114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8115
8116         test_mkdir $DIR/$tdir
8117         touch $DIR/$tdir/f1
8118         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8119 }
8120 run_test 65a "directory with no stripe info"
8121
8122 test_65b() {
8123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8124
8125         test_mkdir $DIR/$tdir
8126         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8127
8128         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8129                                                 error "setstripe"
8130         touch $DIR/$tdir/f2
8131         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8132 }
8133 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8134
8135 test_65c() {
8136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8137         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8138
8139         test_mkdir $DIR/$tdir
8140         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8141
8142         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8143                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8144         touch $DIR/$tdir/f3
8145         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8146 }
8147 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8148
8149 test_65d() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         test_mkdir $DIR/$tdir
8153         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8154         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8155
8156         if [[ $STRIPECOUNT -le 0 ]]; then
8157                 sc=1
8158         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8159                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8160                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8161         else
8162                 sc=$(($STRIPECOUNT - 1))
8163         fi
8164         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8165         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8166         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8167                 error "lverify failed"
8168 }
8169 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8170
8171 test_65e() {
8172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8173
8174         test_mkdir $DIR/$tdir
8175
8176         $LFS setstripe $DIR/$tdir || error "setstripe"
8177         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8178                                         error "no stripe info failed"
8179         touch $DIR/$tdir/f6
8180         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8181 }
8182 run_test 65e "directory setstripe defaults"
8183
8184 test_65f() {
8185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8186
8187         test_mkdir $DIR/${tdir}f
8188         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8189                 error "setstripe succeeded" || true
8190 }
8191 run_test 65f "dir setstripe permission (should return error) ==="
8192
8193 test_65g() {
8194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8195
8196         test_mkdir $DIR/$tdir
8197         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8198
8199         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8200                 error "setstripe -S failed"
8201         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8202         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8203                 error "delete default stripe failed"
8204 }
8205 run_test 65g "directory setstripe -d"
8206
8207 test_65h() {
8208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8209
8210         test_mkdir $DIR/$tdir
8211         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8212
8213         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8214                 error "setstripe -S failed"
8215         test_mkdir $DIR/$tdir/dd1
8216         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8217                 error "stripe info inherit failed"
8218 }
8219 run_test 65h "directory stripe info inherit ===================="
8220
8221 test_65i() {
8222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8223
8224         save_layout_restore_at_exit $MOUNT
8225
8226         # bug6367: set non-default striping on root directory
8227         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8228
8229         # bug12836: getstripe on -1 default directory striping
8230         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8231
8232         # bug12836: getstripe -v on -1 default directory striping
8233         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8234
8235         # bug12836: new find on -1 default directory striping
8236         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8237 }
8238 run_test 65i "various tests to set root directory striping"
8239
8240 test_65j() { # bug6367
8241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8242
8243         sync; sleep 1
8244
8245         # if we aren't already remounting for each test, do so for this test
8246         if [ "$I_MOUNTED" = "yes" ]; then
8247                 cleanup || error "failed to unmount"
8248                 setup
8249         fi
8250
8251         save_layout_restore_at_exit $MOUNT
8252
8253         $LFS setstripe -d $MOUNT || error "setstripe failed"
8254 }
8255 run_test 65j "set default striping on root directory (bug 6367)="
8256
8257 cleanup_65k() {
8258         rm -rf $DIR/$tdir
8259         wait_delete_completed
8260         do_facet $SINGLEMDS "lctl set_param -n \
8261                 osp.$ost*MDT0000.max_create_count=$max_count"
8262         do_facet $SINGLEMDS "lctl set_param -n \
8263                 osp.$ost*MDT0000.create_count=$count"
8264         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8265         echo $INACTIVE_OSC "is Activate"
8266
8267         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8268 }
8269
8270 test_65k() { # bug11679
8271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8272         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8273         remote_mds_nodsh && skip "remote MDS with nodsh"
8274
8275         local disable_precreate=true
8276         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8277                 disable_precreate=false
8278
8279         echo "Check OST status: "
8280         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8281                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8282
8283         for OSC in $MDS_OSCS; do
8284                 echo $OSC "is active"
8285                 do_facet $SINGLEMDS lctl --device %$OSC activate
8286         done
8287
8288         for INACTIVE_OSC in $MDS_OSCS; do
8289                 local ost=$(osc_to_ost $INACTIVE_OSC)
8290                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8291                                lov.*md*.target_obd |
8292                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8293
8294                 mkdir -p $DIR/$tdir
8295                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8296                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8297
8298                 echo "Deactivate: " $INACTIVE_OSC
8299                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8300
8301                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8302                               osp.$ost*MDT0000.create_count")
8303                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8304                                   osp.$ost*MDT0000.max_create_count")
8305                 $disable_precreate &&
8306                         do_facet $SINGLEMDS "lctl set_param -n \
8307                                 osp.$ost*MDT0000.max_create_count=0"
8308
8309                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8310                         [ -f $DIR/$tdir/$idx ] && continue
8311                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8312                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8313                                 { cleanup_65k;
8314                                   error "setstripe $idx should succeed"; }
8315                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8316                 done
8317                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8318                 rmdir $DIR/$tdir
8319
8320                 do_facet $SINGLEMDS "lctl set_param -n \
8321                         osp.$ost*MDT0000.max_create_count=$max_count"
8322                 do_facet $SINGLEMDS "lctl set_param -n \
8323                         osp.$ost*MDT0000.create_count=$count"
8324                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8325                 echo $INACTIVE_OSC "is Activate"
8326
8327                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8328         done
8329 }
8330 run_test 65k "validate manual striping works properly with deactivated OSCs"
8331
8332 test_65l() { # bug 12836
8333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8334
8335         test_mkdir -p $DIR/$tdir/test_dir
8336         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8337         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8338 }
8339 run_test 65l "lfs find on -1 stripe dir ========================"
8340
8341 test_65m() {
8342         local layout=$(save_layout $MOUNT)
8343         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8344                 restore_layout $MOUNT $layout
8345                 error "setstripe should fail by non-root users"
8346         }
8347         true
8348 }
8349 run_test 65m "normal user can't set filesystem default stripe"
8350
8351 test_65n() {
8352         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8353         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8354                 skip "Need MDS version at least 2.12.50"
8355         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8356
8357         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8358         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8359         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8360
8361         local root_layout=$(save_layout $MOUNT)
8362         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8363
8364         # new subdirectory under root directory should not inherit
8365         # the default layout from root
8366         local dir1=$MOUNT/$tdir-1
8367         mkdir $dir1 || error "mkdir $dir1 failed"
8368         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8369                 error "$dir1 shouldn't have LOV EA"
8370
8371         # delete the default layout on root directory
8372         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8373
8374         local dir2=$MOUNT/$tdir-2
8375         mkdir $dir2 || error "mkdir $dir2 failed"
8376         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8377                 error "$dir2 shouldn't have LOV EA"
8378
8379         # set a new striping pattern on root directory
8380         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8381         local new_def_stripe_size=$((def_stripe_size * 2))
8382         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8383                 error "set stripe size on $MOUNT failed"
8384
8385         # new file created in $dir2 should inherit the new stripe size from
8386         # the filesystem default
8387         local file2=$dir2/$tfile-2
8388         touch $file2 || error "touch $file2 failed"
8389
8390         local file2_stripe_size=$($LFS getstripe -S $file2)
8391         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8392                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8393
8394         local dir3=$MOUNT/$tdir-3
8395         mkdir $dir3 || error "mkdir $dir3 failed"
8396         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8397         # the root layout, which is the actual default layout that will be used
8398         # when new files are created in $dir3.
8399         local dir3_layout=$(get_layout_param $dir3)
8400         local root_dir_layout=$(get_layout_param $MOUNT)
8401         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8402                 error "$dir3 should show the default layout from $MOUNT"
8403
8404         # set OST pool on root directory
8405         local pool=$TESTNAME
8406         pool_add $pool || error "add $pool failed"
8407         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8408                 error "add targets to $pool failed"
8409
8410         $LFS setstripe -p $pool $MOUNT ||
8411                 error "set OST pool on $MOUNT failed"
8412
8413         # new file created in $dir3 should inherit the pool from
8414         # the filesystem default
8415         local file3=$dir3/$tfile-3
8416         touch $file3 || error "touch $file3 failed"
8417
8418         local file3_pool=$($LFS getstripe -p $file3)
8419         [[ "$file3_pool" = "$pool" ]] ||
8420                 error "$file3 didn't inherit OST pool $pool"
8421
8422         local dir4=$MOUNT/$tdir-4
8423         mkdir $dir4 || error "mkdir $dir4 failed"
8424         local dir4_layout=$(get_layout_param $dir4)
8425         root_dir_layout=$(get_layout_param $MOUNT)
8426         echo "$LFS getstripe -d $dir4"
8427         $LFS getstripe -d $dir4
8428         echo "$LFS getstripe -d $MOUNT"
8429         $LFS getstripe -d $MOUNT
8430         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8431                 error "$dir4 should show the default layout from $MOUNT"
8432
8433         # new file created in $dir4 should inherit the pool from
8434         # the filesystem default
8435         local file4=$dir4/$tfile-4
8436         touch $file4 || error "touch $file4 failed"
8437
8438         local file4_pool=$($LFS getstripe -p $file4)
8439         [[ "$file4_pool" = "$pool" ]] ||
8440                 error "$file4 didn't inherit OST pool $pool"
8441
8442         # new subdirectory under non-root directory should inherit
8443         # the default layout from its parent directory
8444         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8445                 error "set directory layout on $dir4 failed"
8446
8447         local dir5=$dir4/$tdir-5
8448         mkdir $dir5 || error "mkdir $dir5 failed"
8449
8450         dir4_layout=$(get_layout_param $dir4)
8451         local dir5_layout=$(get_layout_param $dir5)
8452         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8453                 error "$dir5 should inherit the default layout from $dir4"
8454
8455         # though subdir under ROOT doesn't inherit default layout, but
8456         # its sub dir/file should be created with default layout.
8457         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8458         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8459                 skip "Need MDS version at least 2.12.59"
8460
8461         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8462         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8463         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8464
8465         if [ $default_lmv_hash == "none" ]; then
8466                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8467         else
8468                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8469                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8470         fi
8471
8472         $LFS setdirstripe -D -c 2 $MOUNT ||
8473                 error "setdirstripe -D -c 2 failed"
8474         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8475         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8476         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8477 }
8478 run_test 65n "don't inherit default layout from root for new subdirectories"
8479
8480 # bug 2543 - update blocks count on client
8481 test_66() {
8482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8483
8484         COUNT=${COUNT:-8}
8485         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8486         sync; sync_all_data; sync; sync_all_data
8487         cancel_lru_locks osc
8488         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8489         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8490 }
8491 run_test 66 "update inode blocks count on client ==============="
8492
8493 meminfo() {
8494         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8495 }
8496
8497 swap_used() {
8498         swapon -s | awk '($1 == "'$1'") { print $4 }'
8499 }
8500
8501 # bug5265, obdfilter oa2dentry return -ENOENT
8502 # #define OBD_FAIL_SRV_ENOENT 0x217
8503 test_69() {
8504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8505         remote_ost_nodsh && skip "remote OST with nodsh"
8506
8507         f="$DIR/$tfile"
8508         $LFS setstripe -c 1 -i 0 $f
8509
8510         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8511
8512         do_facet ost1 lctl set_param fail_loc=0x217
8513         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8514         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8515
8516         do_facet ost1 lctl set_param fail_loc=0
8517         $DIRECTIO write $f 0 2 || error "write error"
8518
8519         cancel_lru_locks osc
8520         $DIRECTIO read $f 0 1 || error "read error"
8521
8522         do_facet ost1 lctl set_param fail_loc=0x217
8523         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8524
8525         do_facet ost1 lctl set_param fail_loc=0
8526         rm -f $f
8527 }
8528 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8529
8530 test_71() {
8531         test_mkdir $DIR/$tdir
8532         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8533         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8534 }
8535 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8536
8537 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539         [ "$RUNAS_ID" = "$UID" ] &&
8540                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8541         # Check that testing environment is properly set up. Skip if not
8542         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8543                 skip_env "User $RUNAS_ID does not exist - skipping"
8544
8545         touch $DIR/$tfile
8546         chmod 777 $DIR/$tfile
8547         chmod ug+s $DIR/$tfile
8548         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8549                 error "$RUNAS dd $DIR/$tfile failed"
8550         # See if we are still setuid/sgid
8551         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8552                 error "S/gid is not dropped on write"
8553         # Now test that MDS is updated too
8554         cancel_lru_locks mdc
8555         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8556                 error "S/gid is not dropped on MDS"
8557         rm -f $DIR/$tfile
8558 }
8559 run_test 72a "Test that remove suid works properly (bug5695) ===="
8560
8561 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8562         local perm
8563
8564         [ "$RUNAS_ID" = "$UID" ] &&
8565                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8566         [ "$RUNAS_ID" -eq 0 ] &&
8567                 skip_env "RUNAS_ID = 0 -- skipping"
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569         # Check that testing environment is properly set up. Skip if not
8570         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8571                 skip_env "User $RUNAS_ID does not exist - skipping"
8572
8573         touch $DIR/${tfile}-f{g,u}
8574         test_mkdir $DIR/${tfile}-dg
8575         test_mkdir $DIR/${tfile}-du
8576         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8577         chmod g+s $DIR/${tfile}-{f,d}g
8578         chmod u+s $DIR/${tfile}-{f,d}u
8579         for perm in 777 2777 4777; do
8580                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8581                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8582                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8583                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8584         done
8585         true
8586 }
8587 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8588
8589 # bug 3462 - multiple simultaneous MDC requests
8590 test_73() {
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592
8593         test_mkdir $DIR/d73-1
8594         test_mkdir $DIR/d73-2
8595         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8596         pid1=$!
8597
8598         lctl set_param fail_loc=0x80000129
8599         $MULTIOP $DIR/d73-1/f73-2 Oc &
8600         sleep 1
8601         lctl set_param fail_loc=0
8602
8603         $MULTIOP $DIR/d73-2/f73-3 Oc &
8604         pid3=$!
8605
8606         kill -USR1 $pid1
8607         wait $pid1 || return 1
8608
8609         sleep 25
8610
8611         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8612         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8613         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8614
8615         rm -rf $DIR/d73-*
8616 }
8617 run_test 73 "multiple MDC requests (should not deadlock)"
8618
8619 test_74a() { # bug 6149, 6184
8620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8621
8622         touch $DIR/f74a
8623         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8624         #
8625         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8626         # will spin in a tight reconnection loop
8627         $LCTL set_param fail_loc=0x8000030e
8628         # get any lock that won't be difficult - lookup works.
8629         ls $DIR/f74a
8630         $LCTL set_param fail_loc=0
8631         rm -f $DIR/f74a
8632         true
8633 }
8634 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8635
8636 test_74b() { # bug 13310
8637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8638
8639         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8640         #
8641         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8642         # will spin in a tight reconnection loop
8643         $LCTL set_param fail_loc=0x8000030e
8644         # get a "difficult" lock
8645         touch $DIR/f74b
8646         $LCTL set_param fail_loc=0
8647         rm -f $DIR/f74b
8648         true
8649 }
8650 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8651
8652 test_74c() {
8653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8654
8655         #define OBD_FAIL_LDLM_NEW_LOCK
8656         $LCTL set_param fail_loc=0x319
8657         touch $DIR/$tfile && error "touch successful"
8658         $LCTL set_param fail_loc=0
8659         true
8660 }
8661 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8662
8663 slab_lic=/sys/kernel/slab/lustre_inode_cache
8664 num_objects() {
8665         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8666         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8667                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8668 }
8669
8670 test_76a() { # Now for b=20433, added originally in b=1443
8671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8672
8673         cancel_lru_locks osc
8674         # there may be some slab objects cached per core
8675         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8676         local before=$(num_objects)
8677         local count=$((512 * cpus))
8678         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8679         local margin=$((count / 10))
8680         if [[ -f $slab_lic/aliases ]]; then
8681                 local aliases=$(cat $slab_lic/aliases)
8682                 (( aliases > 0 )) && margin=$((margin * aliases))
8683         fi
8684
8685         echo "before slab objects: $before"
8686         for i in $(seq $count); do
8687                 touch $DIR/$tfile
8688                 rm -f $DIR/$tfile
8689         done
8690         cancel_lru_locks osc
8691         local after=$(num_objects)
8692         echo "created: $count, after slab objects: $after"
8693         # shared slab counts are not very accurate, allow significant margin
8694         # the main goal is that the cache growth is not permanently > $count
8695         while (( after > before + margin )); do
8696                 sleep 1
8697                 after=$(num_objects)
8698                 wait=$((wait + 1))
8699                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8700                 if (( wait > 60 )); then
8701                         error "inode slab grew from $before+$margin to $after"
8702                 fi
8703         done
8704 }
8705 run_test 76a "confirm clients recycle inodes properly ===="
8706
8707 test_76b() {
8708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8709         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8710
8711         local count=512
8712         local before=$(num_objects)
8713
8714         for i in $(seq $count); do
8715                 mkdir $DIR/$tdir
8716                 rmdir $DIR/$tdir
8717         done
8718
8719         local after=$(num_objects)
8720         local wait=0
8721
8722         while (( after > before )); do
8723                 sleep 1
8724                 after=$(num_objects)
8725                 wait=$((wait + 1))
8726                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8727                 if (( wait > 60 )); then
8728                         error "inode slab grew from $before to $after"
8729                 fi
8730         done
8731
8732         echo "slab objects before: $before, after: $after"
8733 }
8734 run_test 76b "confirm clients recycle directory inodes properly ===="
8735
8736 export ORIG_CSUM=""
8737 set_checksums()
8738 {
8739         # Note: in sptlrpc modes which enable its own bulk checksum, the
8740         # original crc32_le bulk checksum will be automatically disabled,
8741         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8742         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8743         # In this case set_checksums() will not be no-op, because sptlrpc
8744         # bulk checksum will be enabled all through the test.
8745
8746         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8747         lctl set_param -n osc.*.checksums $1
8748         return 0
8749 }
8750
8751 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8752                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8753 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8754                              tr -d [] | head -n1)}
8755 set_checksum_type()
8756 {
8757         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8758         rc=$?
8759         log "set checksum type to $1, rc = $rc"
8760         return $rc
8761 }
8762
8763 get_osc_checksum_type()
8764 {
8765         # arugment 1: OST name, like OST0000
8766         ost=$1
8767         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8768                         sed 's/.*\[\(.*\)\].*/\1/g')
8769         rc=$?
8770         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8771         echo $checksum_type
8772 }
8773
8774 F77_TMP=$TMP/f77-temp
8775 F77SZ=8
8776 setup_f77() {
8777         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8778                 error "error writing to $F77_TMP"
8779 }
8780
8781 test_77a() { # bug 10889
8782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8783         $GSS && skip_env "could not run with gss"
8784
8785         [ ! -f $F77_TMP ] && setup_f77
8786         set_checksums 1
8787         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8788         set_checksums 0
8789         rm -f $DIR/$tfile
8790 }
8791 run_test 77a "normal checksum read/write operation"
8792
8793 test_77b() { # bug 10889
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795         $GSS && skip_env "could not run with gss"
8796
8797         [ ! -f $F77_TMP ] && setup_f77
8798         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8799         $LCTL set_param fail_loc=0x80000409
8800         set_checksums 1
8801
8802         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8803                 error "dd error: $?"
8804         $LCTL set_param fail_loc=0
8805
8806         for algo in $CKSUM_TYPES; do
8807                 cancel_lru_locks osc
8808                 set_checksum_type $algo
8809                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8810                 $LCTL set_param fail_loc=0x80000408
8811                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8812                 $LCTL set_param fail_loc=0
8813         done
8814         set_checksums 0
8815         set_checksum_type $ORIG_CSUM_TYPE
8816         rm -f $DIR/$tfile
8817 }
8818 run_test 77b "checksum error on client write, read"
8819
8820 cleanup_77c() {
8821         trap 0
8822         set_checksums 0
8823         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8824         $check_ost &&
8825                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8826         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8827         $check_ost && [ -n "$ost_file_prefix" ] &&
8828                 do_facet ost1 rm -f ${ost_file_prefix}\*
8829 }
8830
8831 test_77c() {
8832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8833         $GSS && skip_env "could not run with gss"
8834         remote_ost_nodsh && skip "remote OST with nodsh"
8835
8836         local bad1
8837         local osc_file_prefix
8838         local osc_file
8839         local check_ost=false
8840         local ost_file_prefix
8841         local ost_file
8842         local orig_cksum
8843         local dump_cksum
8844         local fid
8845
8846         # ensure corruption will occur on first OSS/OST
8847         $LFS setstripe -i 0 $DIR/$tfile
8848
8849         [ ! -f $F77_TMP ] && setup_f77
8850         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8851                 error "dd write error: $?"
8852         fid=$($LFS path2fid $DIR/$tfile)
8853
8854         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8855         then
8856                 check_ost=true
8857                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8858                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8859         else
8860                 echo "OSS do not support bulk pages dump upon error"
8861         fi
8862
8863         osc_file_prefix=$($LCTL get_param -n debug_path)
8864         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8865
8866         trap cleanup_77c EXIT
8867
8868         set_checksums 1
8869         # enable bulk pages dump upon error on Client
8870         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8871         # enable bulk pages dump upon error on OSS
8872         $check_ost &&
8873                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8874
8875         # flush Client cache to allow next read to reach OSS
8876         cancel_lru_locks osc
8877
8878         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8879         $LCTL set_param fail_loc=0x80000408
8880         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8881         $LCTL set_param fail_loc=0
8882
8883         rm -f $DIR/$tfile
8884
8885         # check cksum dump on Client
8886         osc_file=$(ls ${osc_file_prefix}*)
8887         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8888         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8889         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8890         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8891         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8892                      cksum)
8893         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8894         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8895                 error "dump content does not match on Client"
8896
8897         $check_ost || skip "No need to check cksum dump on OSS"
8898
8899         # check cksum dump on OSS
8900         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8901         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8902         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8903         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8904         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8905                 error "dump content does not match on OSS"
8906
8907         cleanup_77c
8908 }
8909 run_test 77c "checksum error on client read with debug"
8910
8911 test_77d() { # bug 10889
8912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8913         $GSS && skip_env "could not run with gss"
8914
8915         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8916         $LCTL set_param fail_loc=0x80000409
8917         set_checksums 1
8918         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8919                 error "direct write: rc=$?"
8920         $LCTL set_param fail_loc=0
8921         set_checksums 0
8922
8923         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8924         $LCTL set_param fail_loc=0x80000408
8925         set_checksums 1
8926         cancel_lru_locks osc
8927         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8928                 error "direct read: rc=$?"
8929         $LCTL set_param fail_loc=0
8930         set_checksums 0
8931 }
8932 run_test 77d "checksum error on OST direct write, read"
8933
8934 test_77f() { # bug 10889
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936         $GSS && skip_env "could not run with gss"
8937
8938         set_checksums 1
8939         for algo in $CKSUM_TYPES; do
8940                 cancel_lru_locks osc
8941                 set_checksum_type $algo
8942                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8943                 $LCTL set_param fail_loc=0x409
8944                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8945                         error "direct write succeeded"
8946                 $LCTL set_param fail_loc=0
8947         done
8948         set_checksum_type $ORIG_CSUM_TYPE
8949         set_checksums 0
8950 }
8951 run_test 77f "repeat checksum error on write (expect error)"
8952
8953 test_77g() { # bug 10889
8954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8955         $GSS && skip_env "could not run with gss"
8956         remote_ost_nodsh && skip "remote OST with nodsh"
8957
8958         [ ! -f $F77_TMP ] && setup_f77
8959
8960         local file=$DIR/$tfile
8961         stack_trap "rm -f $file" EXIT
8962
8963         $LFS setstripe -c 1 -i 0 $file
8964         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8965         do_facet ost1 lctl set_param fail_loc=0x8000021a
8966         set_checksums 1
8967         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8968                 error "write error: rc=$?"
8969         do_facet ost1 lctl set_param fail_loc=0
8970         set_checksums 0
8971
8972         cancel_lru_locks osc
8973         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8974         do_facet ost1 lctl set_param fail_loc=0x8000021b
8975         set_checksums 1
8976         cmp $F77_TMP $file || error "file compare failed"
8977         do_facet ost1 lctl set_param fail_loc=0
8978         set_checksums 0
8979 }
8980 run_test 77g "checksum error on OST write, read"
8981
8982 test_77k() { # LU-10906
8983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8984         $GSS && skip_env "could not run with gss"
8985
8986         local cksum_param="osc.$FSNAME*.checksums"
8987         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8988         local checksum
8989         local i
8990
8991         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8992         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8993         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8994
8995         for i in 0 1; do
8996                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8997                         error "failed to set checksum=$i on MGS"
8998                 wait_update $HOSTNAME "$get_checksum" $i
8999                 #remount
9000                 echo "remount client, checksum should be $i"
9001                 remount_client $MOUNT || error "failed to remount client"
9002                 checksum=$(eval $get_checksum)
9003                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9004         done
9005         # remove persistent param to avoid races with checksum mountopt below
9006         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9007                 error "failed to delete checksum on MGS"
9008
9009         for opt in "checksum" "nochecksum"; do
9010                 #remount with mount option
9011                 echo "remount client with option $opt, checksum should be $i"
9012                 umount_client $MOUNT || error "failed to umount client"
9013                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9014                         error "failed to mount client with option '$opt'"
9015                 checksum=$(eval $get_checksum)
9016                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9017                 i=$((i - 1))
9018         done
9019
9020         remount_client $MOUNT || error "failed to remount client"
9021 }
9022 run_test 77k "enable/disable checksum correctly"
9023
9024 test_77l() {
9025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9026         $GSS && skip_env "could not run with gss"
9027
9028         set_checksums 1
9029         stack_trap "set_checksums $ORIG_CSUM" EXIT
9030         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9031
9032         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9033
9034         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9035         for algo in $CKSUM_TYPES; do
9036                 set_checksum_type $algo || error "fail to set checksum type $algo"
9037                 osc_algo=$(get_osc_checksum_type OST0000)
9038                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9039
9040                 # no locks, no reqs to let the connection idle
9041                 cancel_lru_locks osc
9042                 lru_resize_disable osc
9043                 wait_osc_import_state client ost1 IDLE
9044
9045                 # ensure ost1 is connected
9046                 stat $DIR/$tfile >/dev/null || error "can't stat"
9047                 wait_osc_import_state client ost1 FULL
9048
9049                 osc_algo=$(get_osc_checksum_type OST0000)
9050                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9051         done
9052         return 0
9053 }
9054 run_test 77l "preferred checksum type is remembered after reconnected"
9055
9056 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9057 rm -f $F77_TMP
9058 unset F77_TMP
9059
9060 cleanup_test_78() {
9061         trap 0
9062         rm -f $DIR/$tfile
9063 }
9064
9065 test_78() { # bug 10901
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         remote_ost || skip_env "local OST"
9068
9069         NSEQ=5
9070         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9071         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9072         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9073         echo "MemTotal: $MEMTOTAL"
9074
9075         # reserve 256MB of memory for the kernel and other running processes,
9076         # and then take 1/2 of the remaining memory for the read/write buffers.
9077         if [ $MEMTOTAL -gt 512 ] ;then
9078                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9079         else
9080                 # for those poor memory-starved high-end clusters...
9081                 MEMTOTAL=$((MEMTOTAL / 2))
9082         fi
9083         echo "Mem to use for directio: $MEMTOTAL"
9084
9085         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9086         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9087         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9088         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9089                 head -n1)
9090         echo "Smallest OST: $SMALLESTOST"
9091         [[ $SMALLESTOST -lt 10240 ]] &&
9092                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9093
9094         trap cleanup_test_78 EXIT
9095
9096         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9097                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9098
9099         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9100         echo "File size: $F78SIZE"
9101         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9102         for i in $(seq 1 $NSEQ); do
9103                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9104                 echo directIO rdwr round $i of $NSEQ
9105                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9106         done
9107
9108         cleanup_test_78
9109 }
9110 run_test 78 "handle large O_DIRECT writes correctly ============"
9111
9112 test_79() { # bug 12743
9113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9114
9115         wait_delete_completed
9116
9117         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9118         BKFREE=$(calc_osc_kbytes kbytesfree)
9119         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9120
9121         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9122         DFTOTAL=`echo $STRING | cut -d, -f1`
9123         DFUSED=`echo $STRING  | cut -d, -f2`
9124         DFAVAIL=`echo $STRING | cut -d, -f3`
9125         DFFREE=$(($DFTOTAL - $DFUSED))
9126
9127         ALLOWANCE=$((64 * $OSTCOUNT))
9128
9129         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9130            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9131                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9132         fi
9133         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9134            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9135                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9136         fi
9137         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9138            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9139                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9140         fi
9141 }
9142 run_test 79 "df report consistency check ======================="
9143
9144 test_80() { # bug 10718
9145         remote_ost_nodsh && skip "remote OST with nodsh"
9146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9147
9148         # relax strong synchronous semantics for slow backends like ZFS
9149         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9150                 local soc="obdfilter.*.sync_lock_cancel"
9151                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9152
9153                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9154                 if [ -z "$save" ]; then
9155                         soc="obdfilter.*.sync_on_lock_cancel"
9156                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9157                 fi
9158
9159                 if [ "$save" != "never" ]; then
9160                         local hosts=$(comma_list $(osts_nodes))
9161
9162                         do_nodes $hosts $LCTL set_param $soc=never
9163                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9164                 fi
9165         fi
9166
9167         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9168         sync; sleep 1; sync
9169         local before=$(date +%s)
9170         cancel_lru_locks osc
9171         local after=$(date +%s)
9172         local diff=$((after - before))
9173         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9174
9175         rm -f $DIR/$tfile
9176 }
9177 run_test 80 "Page eviction is equally fast at high offsets too"
9178
9179 test_81a() { # LU-456
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181         remote_ost_nodsh && skip "remote OST with nodsh"
9182
9183         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9184         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9185         do_facet ost1 lctl set_param fail_loc=0x80000228
9186
9187         # write should trigger a retry and success
9188         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9189         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9190         RC=$?
9191         if [ $RC -ne 0 ] ; then
9192                 error "write should success, but failed for $RC"
9193         fi
9194 }
9195 run_test 81a "OST should retry write when get -ENOSPC ==============="
9196
9197 test_81b() { # LU-456
9198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9199         remote_ost_nodsh && skip "remote OST with nodsh"
9200
9201         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9202         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9203         do_facet ost1 lctl set_param fail_loc=0x228
9204
9205         # write should retry several times and return -ENOSPC finally
9206         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9207         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9208         RC=$?
9209         ENOSPC=28
9210         if [ $RC -ne $ENOSPC ] ; then
9211                 error "dd should fail for -ENOSPC, but succeed."
9212         fi
9213 }
9214 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9215
9216 test_99() {
9217         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9218
9219         test_mkdir $DIR/$tdir.cvsroot
9220         chown $RUNAS_ID $DIR/$tdir.cvsroot
9221
9222         cd $TMP
9223         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9224
9225         cd /etc/init.d
9226         # some versions of cvs import exit(1) when asked to import links or
9227         # files they can't read.  ignore those files.
9228         local toignore=$(find . -type l -printf '-I %f\n' -o \
9229                          ! -perm /4 -printf '-I %f\n')
9230         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9231                 $tdir.reposname vtag rtag
9232
9233         cd $DIR
9234         test_mkdir $DIR/$tdir.reposname
9235         chown $RUNAS_ID $DIR/$tdir.reposname
9236         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9237
9238         cd $DIR/$tdir.reposname
9239         $RUNAS touch foo99
9240         $RUNAS cvs add -m 'addmsg' foo99
9241         $RUNAS cvs update
9242         $RUNAS cvs commit -m 'nomsg' foo99
9243         rm -fr $DIR/$tdir.cvsroot
9244 }
9245 run_test 99 "cvs strange file/directory operations"
9246
9247 test_100() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249         [[ "$NETTYPE" =~ tcp ]] ||
9250                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9251         remote_ost_nodsh && skip "remote OST with nodsh"
9252         remote_mds_nodsh && skip "remote MDS with nodsh"
9253         remote_servers ||
9254                 skip "useless for local single node setup"
9255
9256         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9257                 [ "$PROT" != "tcp" ] && continue
9258                 RPORT=$(echo $REMOTE | cut -d: -f2)
9259                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9260
9261                 rc=0
9262                 LPORT=`echo $LOCAL | cut -d: -f2`
9263                 if [ $LPORT -ge 1024 ]; then
9264                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9265                         netstat -tna
9266                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9267                 fi
9268         done
9269         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9270 }
9271 run_test 100 "check local port using privileged port ==========="
9272
9273 function get_named_value()
9274 {
9275     local tag
9276
9277     tag=$1
9278     while read ;do
9279         line=$REPLY
9280         case $line in
9281         $tag*)
9282             echo $line | sed "s/^$tag[ ]*//"
9283             break
9284             ;;
9285         esac
9286     done
9287 }
9288
9289 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9290                    awk '/^max_cached_mb/ { print $2 }')
9291
9292 cleanup_101a() {
9293         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9294         trap 0
9295 }
9296
9297 test_101a() {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299
9300         local s
9301         local discard
9302         local nreads=10000
9303         local cache_limit=32
9304
9305         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9306         trap cleanup_101a EXIT
9307         $LCTL set_param -n llite.*.read_ahead_stats 0
9308         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9309
9310         #
9311         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9312         #
9313         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9314         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9315
9316         discard=0
9317         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9318                 get_named_value 'read but discarded' | cut -d" " -f1); do
9319                         discard=$(($discard + $s))
9320         done
9321         cleanup_101a
9322
9323         $LCTL get_param osc.*-osc*.rpc_stats
9324         $LCTL get_param llite.*.read_ahead_stats
9325
9326         # Discard is generally zero, but sometimes a few random reads line up
9327         # and trigger larger readahead, which is wasted & leads to discards.
9328         if [[ $(($discard)) -gt $nreads ]]; then
9329                 error "too many ($discard) discarded pages"
9330         fi
9331         rm -f $DIR/$tfile || true
9332 }
9333 run_test 101a "check read-ahead for random reads"
9334
9335 setup_test101bc() {
9336         test_mkdir $DIR/$tdir
9337         local ssize=$1
9338         local FILE_LENGTH=$2
9339         STRIPE_OFFSET=0
9340
9341         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9342
9343         local list=$(comma_list $(osts_nodes))
9344         set_osd_param $list '' read_cache_enable 0
9345         set_osd_param $list '' writethrough_cache_enable 0
9346
9347         trap cleanup_test101bc EXIT
9348         # prepare the read-ahead file
9349         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9350
9351         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9352                                 count=$FILE_SIZE_MB 2> /dev/null
9353
9354 }
9355
9356 cleanup_test101bc() {
9357         trap 0
9358         rm -rf $DIR/$tdir
9359         rm -f $DIR/$tfile
9360
9361         local list=$(comma_list $(osts_nodes))
9362         set_osd_param $list '' read_cache_enable 1
9363         set_osd_param $list '' writethrough_cache_enable 1
9364 }
9365
9366 calc_total() {
9367         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9368 }
9369
9370 ra_check_101() {
9371         local READ_SIZE=$1
9372         local STRIPE_SIZE=$2
9373         local FILE_LENGTH=$3
9374         local RA_INC=1048576
9375         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9376         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9377                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9378         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9379                         get_named_value 'read but discarded' |
9380                         cut -d" " -f1 | calc_total)
9381         if [[ $DISCARD -gt $discard_limit ]]; then
9382                 $LCTL get_param llite.*.read_ahead_stats
9383                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9384         else
9385                 echo "Read-ahead success for size ${READ_SIZE}"
9386         fi
9387 }
9388
9389 test_101b() {
9390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9391         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9392
9393         local STRIPE_SIZE=1048576
9394         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9395
9396         if [ $SLOW == "yes" ]; then
9397                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9398         else
9399                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9400         fi
9401
9402         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9403
9404         # prepare the read-ahead file
9405         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9406         cancel_lru_locks osc
9407         for BIDX in 2 4 8 16 32 64 128 256
9408         do
9409                 local BSIZE=$((BIDX*4096))
9410                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9411                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9412                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9413                 $LCTL set_param -n llite.*.read_ahead_stats 0
9414                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9415                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9416                 cancel_lru_locks osc
9417                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9418         done
9419         cleanup_test101bc
9420         true
9421 }
9422 run_test 101b "check stride-io mode read-ahead ================="
9423
9424 test_101c() {
9425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9426
9427         local STRIPE_SIZE=1048576
9428         local FILE_LENGTH=$((STRIPE_SIZE*100))
9429         local nreads=10000
9430         local rsize=65536
9431         local osc_rpc_stats
9432
9433         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9434
9435         cancel_lru_locks osc
9436         $LCTL set_param osc.*.rpc_stats 0
9437         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9438         $LCTL get_param osc.*.rpc_stats
9439         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9440                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9441                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9442                 local size
9443
9444                 if [ $lines -le 20 ]; then
9445                         echo "continue debug"
9446                         continue
9447                 fi
9448                 for size in 1 2 4 8; do
9449                         local rpc=$(echo "$stats" |
9450                                     awk '($1 == "'$size':") {print $2; exit; }')
9451                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9452                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9453                 done
9454                 echo "$osc_rpc_stats check passed!"
9455         done
9456         cleanup_test101bc
9457         true
9458 }
9459 run_test 101c "check stripe_size aligned read-ahead ================="
9460
9461 test_101d() {
9462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9463
9464         local file=$DIR/$tfile
9465         local sz_MB=${FILESIZE_101d:-80}
9466         local ra_MB=${READAHEAD_MB:-40}
9467
9468         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9469         [ $free_MB -lt $sz_MB ] &&
9470                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9471
9472         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9473         $LFS setstripe -c -1 $file || error "setstripe failed"
9474
9475         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9476         echo Cancel LRU locks on lustre client to flush the client cache
9477         cancel_lru_locks osc
9478
9479         echo Disable read-ahead
9480         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9481         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9482         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9483         $LCTL get_param -n llite.*.max_read_ahead_mb
9484
9485         echo "Reading the test file $file with read-ahead disabled"
9486         local sz_KB=$((sz_MB * 1024 / 4))
9487         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9488         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9489         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9490                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9491
9492         echo "Cancel LRU locks on lustre client to flush the client cache"
9493         cancel_lru_locks osc
9494         echo Enable read-ahead with ${ra_MB}MB
9495         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9496
9497         echo "Reading the test file $file with read-ahead enabled"
9498         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9499                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9500
9501         echo "read-ahead disabled time read $raOFF"
9502         echo "read-ahead enabled time read $raON"
9503
9504         rm -f $file
9505         wait_delete_completed
9506
9507         # use awk for this check instead of bash because it handles decimals
9508         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9509                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9510 }
9511 run_test 101d "file read with and without read-ahead enabled"
9512
9513 test_101e() {
9514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9515
9516         local file=$DIR/$tfile
9517         local size_KB=500  #KB
9518         local count=100
9519         local bsize=1024
9520
9521         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9522         local need_KB=$((count * size_KB))
9523         [[ $free_KB -le $need_KB ]] &&
9524                 skip_env "Need free space $need_KB, have $free_KB"
9525
9526         echo "Creating $count ${size_KB}K test files"
9527         for ((i = 0; i < $count; i++)); do
9528                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9529         done
9530
9531         echo "Cancel LRU locks on lustre client to flush the client cache"
9532         cancel_lru_locks $OSC
9533
9534         echo "Reset readahead stats"
9535         $LCTL set_param -n llite.*.read_ahead_stats 0
9536
9537         for ((i = 0; i < $count; i++)); do
9538                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9539         done
9540
9541         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9542                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9543
9544         for ((i = 0; i < $count; i++)); do
9545                 rm -rf $file.$i 2>/dev/null
9546         done
9547
9548         #10000 means 20% reads are missing in readahead
9549         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9550 }
9551 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9552
9553 test_101f() {
9554         which iozone || skip_env "no iozone installed"
9555
9556         local old_debug=$($LCTL get_param debug)
9557         old_debug=${old_debug#*=}
9558         $LCTL set_param debug="reada mmap"
9559
9560         # create a test file
9561         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9562
9563         echo Cancel LRU locks on lustre client to flush the client cache
9564         cancel_lru_locks osc
9565
9566         echo Reset readahead stats
9567         $LCTL set_param -n llite.*.read_ahead_stats 0
9568
9569         echo mmap read the file with small block size
9570         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9571                 > /dev/null 2>&1
9572
9573         echo checking missing pages
9574         $LCTL get_param llite.*.read_ahead_stats
9575         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9576                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9577
9578         $LCTL set_param debug="$old_debug"
9579         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9580         rm -f $DIR/$tfile
9581 }
9582 run_test 101f "check mmap read performance"
9583
9584 test_101g_brw_size_test() {
9585         local mb=$1
9586         local pages=$((mb * 1048576 / PAGE_SIZE))
9587         local file=$DIR/$tfile
9588
9589         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9590                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9591         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9592                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9593                         return 2
9594         done
9595
9596         stack_trap "rm -f $file" EXIT
9597         $LCTL set_param -n osc.*.rpc_stats=0
9598
9599         # 10 RPCs should be enough for the test
9600         local count=10
9601         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9602                 { error "dd write ${mb} MB blocks failed"; return 3; }
9603         cancel_lru_locks osc
9604         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9605                 { error "dd write ${mb} MB blocks failed"; return 4; }
9606
9607         # calculate number of full-sized read and write RPCs
9608         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9609                 sed -n '/pages per rpc/,/^$/p' |
9610                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9611                 END { print reads,writes }'))
9612         # allow one extra full-sized read RPC for async readahead
9613         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9614                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9615         [[ ${rpcs[1]} == $count ]] ||
9616                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9617 }
9618
9619 test_101g() {
9620         remote_ost_nodsh && skip "remote OST with nodsh"
9621
9622         local rpcs
9623         local osts=$(get_facets OST)
9624         local list=$(comma_list $(osts_nodes))
9625         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9626         local brw_size="obdfilter.*.brw_size"
9627
9628         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9629
9630         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9631
9632         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9633                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9634                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9635            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9636                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9637                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9638
9639                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9640                         suffix="M"
9641
9642                 if [[ $orig_mb -lt 16 ]]; then
9643                         save_lustre_params $osts "$brw_size" > $p
9644                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9645                                 error "set 16MB RPC size failed"
9646
9647                         echo "remount client to enable new RPC size"
9648                         remount_client $MOUNT || error "remount_client failed"
9649                 fi
9650
9651                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9652                 # should be able to set brw_size=12, but no rpc_stats for that
9653                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9654         fi
9655
9656         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9657
9658         if [[ $orig_mb -lt 16 ]]; then
9659                 restore_lustre_params < $p
9660                 remount_client $MOUNT || error "remount_client restore failed"
9661         fi
9662
9663         rm -f $p $DIR/$tfile
9664 }
9665 run_test 101g "Big bulk(4/16 MiB) readahead"
9666
9667 test_101h() {
9668         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9669
9670         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9671                 error "dd 70M file failed"
9672         echo Cancel LRU locks on lustre client to flush the client cache
9673         cancel_lru_locks osc
9674
9675         echo "Reset readahead stats"
9676         $LCTL set_param -n llite.*.read_ahead_stats 0
9677
9678         echo "Read 10M of data but cross 64M bundary"
9679         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9680         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9681                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9682         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9683         rm -f $p $DIR/$tfile
9684 }
9685 run_test 101h "Readahead should cover current read window"
9686
9687 test_101i() {
9688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9689                 error "dd 10M file failed"
9690
9691         local max_per_file_mb=$($LCTL get_param -n \
9692                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9693         cancel_lru_locks osc
9694         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9695         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9696                 error "set max_read_ahead_per_file_mb to 1 failed"
9697
9698         echo "Reset readahead stats"
9699         $LCTL set_param llite.*.read_ahead_stats=0
9700
9701         dd if=$DIR/$tfile of=/dev/null bs=2M
9702
9703         $LCTL get_param llite.*.read_ahead_stats
9704         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9705                      awk '/misses/ { print $2 }')
9706         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9707         rm -f $DIR/$tfile
9708 }
9709 run_test 101i "allow current readahead to exceed reservation"
9710
9711 test_101j() {
9712         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9713                 error "setstripe $DIR/$tfile failed"
9714         local file_size=$((1048576 * 16))
9715         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9716         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9717
9718         echo Disable read-ahead
9719         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9720
9721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9722         for blk in $PAGE_SIZE 1048576 $file_size; do
9723                 cancel_lru_locks osc
9724                 echo "Reset readahead stats"
9725                 $LCTL set_param -n llite.*.read_ahead_stats=0
9726                 local count=$(($file_size / $blk))
9727                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9728                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9729                              get_named_value 'failed to fast read' |
9730                              cut -d" " -f1 | calc_total)
9731                 $LCTL get_param -n llite.*.read_ahead_stats
9732                 [ $miss -eq $count ] || error "expected $count got $miss"
9733         done
9734
9735         rm -f $p $DIR/$tfile
9736 }
9737 run_test 101j "A complete read block should be submitted when no RA"
9738
9739 setup_test102() {
9740         test_mkdir $DIR/$tdir
9741         chown $RUNAS_ID $DIR/$tdir
9742         STRIPE_SIZE=65536
9743         STRIPE_OFFSET=1
9744         STRIPE_COUNT=$OSTCOUNT
9745         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9746
9747         trap cleanup_test102 EXIT
9748         cd $DIR
9749         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9750         cd $DIR/$tdir
9751         for num in 1 2 3 4; do
9752                 for count in $(seq 1 $STRIPE_COUNT); do
9753                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9754                                 local size=`expr $STRIPE_SIZE \* $num`
9755                                 local file=file"$num-$idx-$count"
9756                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9757                         done
9758                 done
9759         done
9760
9761         cd $DIR
9762         $1 tar cf $TMP/f102.tar $tdir --xattrs
9763 }
9764
9765 cleanup_test102() {
9766         trap 0
9767         rm -f $TMP/f102.tar
9768         rm -rf $DIR/d0.sanity/d102
9769 }
9770
9771 test_102a() {
9772         [ "$UID" != 0 ] && skip "must run as root"
9773         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9774                 skip_env "must have user_xattr"
9775
9776         [ -z "$(which setfattr 2>/dev/null)" ] &&
9777                 skip_env "could not find setfattr"
9778
9779         local testfile=$DIR/$tfile
9780
9781         touch $testfile
9782         echo "set/get xattr..."
9783         setfattr -n trusted.name1 -v value1 $testfile ||
9784                 error "setfattr -n trusted.name1=value1 $testfile failed"
9785         getfattr -n trusted.name1 $testfile 2> /dev/null |
9786           grep "trusted.name1=.value1" ||
9787                 error "$testfile missing trusted.name1=value1"
9788
9789         setfattr -n user.author1 -v author1 $testfile ||
9790                 error "setfattr -n user.author1=author1 $testfile failed"
9791         getfattr -n user.author1 $testfile 2> /dev/null |
9792           grep "user.author1=.author1" ||
9793                 error "$testfile missing trusted.author1=author1"
9794
9795         echo "listxattr..."
9796         setfattr -n trusted.name2 -v value2 $testfile ||
9797                 error "$testfile unable to set trusted.name2"
9798         setfattr -n trusted.name3 -v value3 $testfile ||
9799                 error "$testfile unable to set trusted.name3"
9800         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9801             grep "trusted.name" | wc -l) -eq 3 ] ||
9802                 error "$testfile missing 3 trusted.name xattrs"
9803
9804         setfattr -n user.author2 -v author2 $testfile ||
9805                 error "$testfile unable to set user.author2"
9806         setfattr -n user.author3 -v author3 $testfile ||
9807                 error "$testfile unable to set user.author3"
9808         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9809             grep "user.author" | wc -l) -eq 3 ] ||
9810                 error "$testfile missing 3 user.author xattrs"
9811
9812         echo "remove xattr..."
9813         setfattr -x trusted.name1 $testfile ||
9814                 error "$testfile error deleting trusted.name1"
9815         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9816                 error "$testfile did not delete trusted.name1 xattr"
9817
9818         setfattr -x user.author1 $testfile ||
9819                 error "$testfile error deleting user.author1"
9820         echo "set lustre special xattr ..."
9821         $LFS setstripe -c1 $testfile
9822         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9823                 awk -F "=" '/trusted.lov/ { print $2 }' )
9824         setfattr -n "trusted.lov" -v $lovea $testfile ||
9825                 error "$testfile doesn't ignore setting trusted.lov again"
9826         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9827                 error "$testfile allow setting invalid trusted.lov"
9828         rm -f $testfile
9829 }
9830 run_test 102a "user xattr test =================================="
9831
9832 check_102b_layout() {
9833         local layout="$*"
9834         local testfile=$DIR/$tfile
9835
9836         echo "test layout '$layout'"
9837         $LFS setstripe $layout $testfile || error "setstripe failed"
9838         $LFS getstripe -y $testfile
9839
9840         echo "get/set/list trusted.lov xattr ..." # b=10930
9841         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9842         [[ "$value" =~ "trusted.lov" ]] ||
9843                 error "can't get trusted.lov from $testfile"
9844         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9845                 error "getstripe failed"
9846
9847         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9848
9849         value=$(cut -d= -f2 <<<$value)
9850         # LU-13168: truncated xattr should fail if short lov_user_md header
9851         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9852                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9853         for len in $lens; do
9854                 echo "setfattr $len $testfile.2"
9855                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9856                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9857         done
9858         local stripe_size=$($LFS getstripe -S $testfile.2)
9859         local stripe_count=$($LFS getstripe -c $testfile.2)
9860         [[ $stripe_size -eq 65536 ]] ||
9861                 error "stripe size $stripe_size != 65536"
9862         [[ $stripe_count -eq $stripe_count_orig ]] ||
9863                 error "stripe count $stripe_count != $stripe_count_orig"
9864         rm $testfile $testfile.2
9865 }
9866
9867 test_102b() {
9868         [ -z "$(which setfattr 2>/dev/null)" ] &&
9869                 skip_env "could not find setfattr"
9870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9871
9872         # check plain layout
9873         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9874
9875         # and also check composite layout
9876         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9877
9878 }
9879 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9880
9881 test_102c() {
9882         [ -z "$(which setfattr 2>/dev/null)" ] &&
9883                 skip_env "could not find setfattr"
9884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9885
9886         # b10930: get/set/list lustre.lov xattr
9887         echo "get/set/list lustre.lov xattr ..."
9888         test_mkdir $DIR/$tdir
9889         chown $RUNAS_ID $DIR/$tdir
9890         local testfile=$DIR/$tdir/$tfile
9891         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9892                 error "setstripe failed"
9893         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9894                 error "getstripe failed"
9895         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9896         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9897
9898         local testfile2=${testfile}2
9899         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9900                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9901
9902         $RUNAS $MCREATE $testfile2
9903         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9904         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9905         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9906         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9907         [ $stripe_count -eq $STRIPECOUNT ] ||
9908                 error "stripe count $stripe_count != $STRIPECOUNT"
9909 }
9910 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9911
9912 compare_stripe_info1() {
9913         local stripe_index_all_zero=true
9914
9915         for num in 1 2 3 4; do
9916                 for count in $(seq 1 $STRIPE_COUNT); do
9917                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9918                                 local size=$((STRIPE_SIZE * num))
9919                                 local file=file"$num-$offset-$count"
9920                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9921                                 [[ $stripe_size -ne $size ]] &&
9922                                     error "$file: size $stripe_size != $size"
9923                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9924                                 # allow fewer stripes to be created, ORI-601
9925                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9926                                     error "$file: count $stripe_count != $count"
9927                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9928                                 [[ $stripe_index -ne 0 ]] &&
9929                                         stripe_index_all_zero=false
9930                         done
9931                 done
9932         done
9933         $stripe_index_all_zero &&
9934                 error "all files are being extracted starting from OST index 0"
9935         return 0
9936 }
9937
9938 have_xattrs_include() {
9939         tar --help | grep -q xattrs-include &&
9940                 echo --xattrs-include="lustre.*"
9941 }
9942
9943 test_102d() {
9944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9945         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9946
9947         XINC=$(have_xattrs_include)
9948         setup_test102
9949         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9950         cd $DIR/$tdir/$tdir
9951         compare_stripe_info1
9952 }
9953 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9954
9955 test_102f() {
9956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9958
9959         XINC=$(have_xattrs_include)
9960         setup_test102
9961         test_mkdir $DIR/$tdir.restore
9962         cd $DIR
9963         tar cf - --xattrs $tdir | tar xf - \
9964                 -C $DIR/$tdir.restore --xattrs $XINC
9965         cd $DIR/$tdir.restore/$tdir
9966         compare_stripe_info1
9967 }
9968 run_test 102f "tar copy files, not keep osts"
9969
9970 grow_xattr() {
9971         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9972                 skip "must have user_xattr"
9973         [ -z "$(which setfattr 2>/dev/null)" ] &&
9974                 skip_env "could not find setfattr"
9975         [ -z "$(which getfattr 2>/dev/null)" ] &&
9976                 skip_env "could not find getfattr"
9977
9978         local xsize=${1:-1024}  # in bytes
9979         local file=$DIR/$tfile
9980         local value="$(generate_string $xsize)"
9981         local xbig=trusted.big
9982         local toobig=$2
9983
9984         touch $file
9985         log "save $xbig on $file"
9986         if [ -z "$toobig" ]
9987         then
9988                 setfattr -n $xbig -v $value $file ||
9989                         error "saving $xbig on $file failed"
9990         else
9991                 setfattr -n $xbig -v $value $file &&
9992                         error "saving $xbig on $file succeeded"
9993                 return 0
9994         fi
9995
9996         local orig=$(get_xattr_value $xbig $file)
9997         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9998
9999         local xsml=trusted.sml
10000         log "save $xsml on $file"
10001         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10002
10003         local new=$(get_xattr_value $xbig $file)
10004         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10005
10006         log "grow $xsml on $file"
10007         setfattr -n $xsml -v "$value" $file ||
10008                 error "growing $xsml on $file failed"
10009
10010         new=$(get_xattr_value $xbig $file)
10011         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10012         log "$xbig still valid after growing $xsml"
10013
10014         rm -f $file
10015 }
10016
10017 test_102h() { # bug 15777
10018         grow_xattr 1024
10019 }
10020 run_test 102h "grow xattr from inside inode to external block"
10021
10022 test_102ha() {
10023         large_xattr_enabled || skip_env "ea_inode feature disabled"
10024
10025         echo "setting xattr of max xattr size: $(max_xattr_size)"
10026         grow_xattr $(max_xattr_size)
10027
10028         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10029         echo "This should fail:"
10030         grow_xattr $(($(max_xattr_size) + 10)) 1
10031 }
10032 run_test 102ha "grow xattr from inside inode to external inode"
10033
10034 test_102i() { # bug 17038
10035         [ -z "$(which getfattr 2>/dev/null)" ] &&
10036                 skip "could not find getfattr"
10037
10038         touch $DIR/$tfile
10039         ln -s $DIR/$tfile $DIR/${tfile}link
10040         getfattr -n trusted.lov $DIR/$tfile ||
10041                 error "lgetxattr on $DIR/$tfile failed"
10042         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10043                 grep -i "no such attr" ||
10044                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10045         rm -f $DIR/$tfile $DIR/${tfile}link
10046 }
10047 run_test 102i "lgetxattr test on symbolic link ============"
10048
10049 test_102j() {
10050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10052
10053         XINC=$(have_xattrs_include)
10054         setup_test102 "$RUNAS"
10055         chown $RUNAS_ID $DIR/$tdir
10056         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10057         cd $DIR/$tdir/$tdir
10058         compare_stripe_info1 "$RUNAS"
10059 }
10060 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10061
10062 test_102k() {
10063         [ -z "$(which setfattr 2>/dev/null)" ] &&
10064                 skip "could not find setfattr"
10065
10066         touch $DIR/$tfile
10067         # b22187 just check that does not crash for regular file.
10068         setfattr -n trusted.lov $DIR/$tfile
10069         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10070         local test_kdir=$DIR/$tdir
10071         test_mkdir $test_kdir
10072         local default_size=$($LFS getstripe -S $test_kdir)
10073         local default_count=$($LFS getstripe -c $test_kdir)
10074         local default_offset=$($LFS getstripe -i $test_kdir)
10075         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10076                 error 'dir setstripe failed'
10077         setfattr -n trusted.lov $test_kdir
10078         local stripe_size=$($LFS getstripe -S $test_kdir)
10079         local stripe_count=$($LFS getstripe -c $test_kdir)
10080         local stripe_offset=$($LFS getstripe -i $test_kdir)
10081         [ $stripe_size -eq $default_size ] ||
10082                 error "stripe size $stripe_size != $default_size"
10083         [ $stripe_count -eq $default_count ] ||
10084                 error "stripe count $stripe_count != $default_count"
10085         [ $stripe_offset -eq $default_offset ] ||
10086                 error "stripe offset $stripe_offset != $default_offset"
10087         rm -rf $DIR/$tfile $test_kdir
10088 }
10089 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10090
10091 test_102l() {
10092         [ -z "$(which getfattr 2>/dev/null)" ] &&
10093                 skip "could not find getfattr"
10094
10095         # LU-532 trusted. xattr is invisible to non-root
10096         local testfile=$DIR/$tfile
10097
10098         touch $testfile
10099
10100         echo "listxattr as user..."
10101         chown $RUNAS_ID $testfile
10102         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10103             grep -q "trusted" &&
10104                 error "$testfile trusted xattrs are user visible"
10105
10106         return 0;
10107 }
10108 run_test 102l "listxattr size test =================================="
10109
10110 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10111         local path=$DIR/$tfile
10112         touch $path
10113
10114         listxattr_size_check $path || error "listattr_size_check $path failed"
10115 }
10116 run_test 102m "Ensure listxattr fails on small bufffer ========"
10117
10118 cleanup_test102
10119
10120 getxattr() { # getxattr path name
10121         # Return the base64 encoding of the value of xattr name on path.
10122         local path=$1
10123         local name=$2
10124
10125         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10126         # file: $path
10127         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10128         #
10129         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10130
10131         getfattr --absolute-names --encoding=base64 --name=$name $path |
10132                 awk -F= -v name=$name '$1 == name {
10133                         print substr($0, index($0, "=") + 1);
10134         }'
10135 }
10136
10137 test_102n() { # LU-4101 mdt: protect internal xattrs
10138         [ -z "$(which setfattr 2>/dev/null)" ] &&
10139                 skip "could not find setfattr"
10140         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10141         then
10142                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10143         fi
10144
10145         local file0=$DIR/$tfile.0
10146         local file1=$DIR/$tfile.1
10147         local xattr0=$TMP/$tfile.0
10148         local xattr1=$TMP/$tfile.1
10149         local namelist="lov lma lmv link fid version som hsm"
10150         local name
10151         local value
10152
10153         rm -rf $file0 $file1 $xattr0 $xattr1
10154         touch $file0 $file1
10155
10156         # Get 'before' xattrs of $file1.
10157         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10158
10159         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10160                 namelist+=" lfsck_namespace"
10161         for name in $namelist; do
10162                 # Try to copy xattr from $file0 to $file1.
10163                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10164
10165                 setfattr --name=trusted.$name --value="$value" $file1 ||
10166                         error "setxattr 'trusted.$name' failed"
10167
10168                 # Try to set a garbage xattr.
10169                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10170
10171                 if [[ x$name == "xlov" ]]; then
10172                         setfattr --name=trusted.lov --value="$value" $file1 &&
10173                         error "setxattr invalid 'trusted.lov' success"
10174                 else
10175                         setfattr --name=trusted.$name --value="$value" $file1 ||
10176                                 error "setxattr invalid 'trusted.$name' failed"
10177                 fi
10178
10179                 # Try to remove the xattr from $file1. We don't care if this
10180                 # appears to succeed or fail, we just don't want there to be
10181                 # any changes or crashes.
10182                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10183         done
10184
10185         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10186         then
10187                 name="lfsck_ns"
10188                 # Try to copy xattr from $file0 to $file1.
10189                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10190
10191                 setfattr --name=trusted.$name --value="$value" $file1 ||
10192                         error "setxattr 'trusted.$name' failed"
10193
10194                 # Try to set a garbage xattr.
10195                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10196
10197                 setfattr --name=trusted.$name --value="$value" $file1 ||
10198                         error "setxattr 'trusted.$name' failed"
10199
10200                 # Try to remove the xattr from $file1. We don't care if this
10201                 # appears to succeed or fail, we just don't want there to be
10202                 # any changes or crashes.
10203                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10204         fi
10205
10206         # Get 'after' xattrs of file1.
10207         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10208
10209         if ! diff $xattr0 $xattr1; then
10210                 error "before and after xattrs of '$file1' differ"
10211         fi
10212
10213         rm -rf $file0 $file1 $xattr0 $xattr1
10214
10215         return 0
10216 }
10217 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10218
10219 test_102p() { # LU-4703 setxattr did not check ownership
10220         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10221                 skip "MDS needs to be at least 2.5.56"
10222
10223         local testfile=$DIR/$tfile
10224
10225         touch $testfile
10226
10227         echo "setfacl as user..."
10228         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10229         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10230
10231         echo "setfattr as user..."
10232         setfacl -m "u:$RUNAS_ID:---" $testfile
10233         $RUNAS setfattr -x system.posix_acl_access $testfile
10234         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10235 }
10236 run_test 102p "check setxattr(2) correctly fails without permission"
10237
10238 test_102q() {
10239         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10240                 skip "MDS needs to be at least 2.6.92"
10241
10242         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10243 }
10244 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10245
10246 test_102r() {
10247         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10248                 skip "MDS needs to be at least 2.6.93"
10249
10250         touch $DIR/$tfile || error "touch"
10251         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10252         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10253         rm $DIR/$tfile || error "rm"
10254
10255         #normal directory
10256         mkdir -p $DIR/$tdir || error "mkdir"
10257         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10258         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10259         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10260                 error "$testfile error deleting user.author1"
10261         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10262                 grep "user.$(basename $tdir)" &&
10263                 error "$tdir did not delete user.$(basename $tdir)"
10264         rmdir $DIR/$tdir || error "rmdir"
10265
10266         #striped directory
10267         test_mkdir $DIR/$tdir
10268         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10269         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10270         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10271                 error "$testfile error deleting user.author1"
10272         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10273                 grep "user.$(basename $tdir)" &&
10274                 error "$tdir did not delete user.$(basename $tdir)"
10275         rmdir $DIR/$tdir || error "rm striped dir"
10276 }
10277 run_test 102r "set EAs with empty values"
10278
10279 test_102s() {
10280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10281                 skip "MDS needs to be at least 2.11.52"
10282
10283         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10284
10285         save_lustre_params client "llite.*.xattr_cache" > $save
10286
10287         for cache in 0 1; do
10288                 lctl set_param llite.*.xattr_cache=$cache
10289
10290                 rm -f $DIR/$tfile
10291                 touch $DIR/$tfile || error "touch"
10292                 for prefix in lustre security system trusted user; do
10293                         # Note getxattr() may fail with 'Operation not
10294                         # supported' or 'No such attribute' depending
10295                         # on prefix and cache.
10296                         getfattr -n $prefix.n102s $DIR/$tfile &&
10297                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10298                 done
10299         done
10300
10301         restore_lustre_params < $save
10302 }
10303 run_test 102s "getting nonexistent xattrs should fail"
10304
10305 test_102t() {
10306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10307                 skip "MDS needs to be at least 2.11.52"
10308
10309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10310
10311         save_lustre_params client "llite.*.xattr_cache" > $save
10312
10313         for cache in 0 1; do
10314                 lctl set_param llite.*.xattr_cache=$cache
10315
10316                 for buf_size in 0 256; do
10317                         rm -f $DIR/$tfile
10318                         touch $DIR/$tfile || error "touch"
10319                         setfattr -n user.multiop $DIR/$tfile
10320                         $MULTIOP $DIR/$tfile oa$buf_size ||
10321                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10322                 done
10323         done
10324
10325         restore_lustre_params < $save
10326 }
10327 run_test 102t "zero length xattr values handled correctly"
10328
10329 run_acl_subtest()
10330 {
10331     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10332     return $?
10333 }
10334
10335 test_103a() {
10336         [ "$UID" != 0 ] && skip "must run as root"
10337         $GSS && skip_env "could not run under gss"
10338         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10339                 skip_env "must have acl enabled"
10340         [ -z "$(which setfacl 2>/dev/null)" ] &&
10341                 skip_env "could not find setfacl"
10342         remote_mds_nodsh && skip "remote MDS with nodsh"
10343
10344         gpasswd -a daemon bin                           # LU-5641
10345         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10346
10347         declare -a identity_old
10348
10349         for num in $(seq $MDSCOUNT); do
10350                 switch_identity $num true || identity_old[$num]=$?
10351         done
10352
10353         SAVE_UMASK=$(umask)
10354         umask 0022
10355         mkdir -p $DIR/$tdir
10356         cd $DIR/$tdir
10357
10358         echo "performing cp ..."
10359         run_acl_subtest cp || error "run_acl_subtest cp failed"
10360         echo "performing getfacl-noacl..."
10361         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10362         echo "performing misc..."
10363         run_acl_subtest misc || error  "misc test failed"
10364         echo "performing permissions..."
10365         run_acl_subtest permissions || error "permissions failed"
10366         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10367         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10368                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10369                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10370         then
10371                 echo "performing permissions xattr..."
10372                 run_acl_subtest permissions_xattr ||
10373                         error "permissions_xattr failed"
10374         fi
10375         echo "performing setfacl..."
10376         run_acl_subtest setfacl || error  "setfacl test failed"
10377
10378         # inheritance test got from HP
10379         echo "performing inheritance..."
10380         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10381         chmod +x make-tree || error "chmod +x failed"
10382         run_acl_subtest inheritance || error "inheritance test failed"
10383         rm -f make-tree
10384
10385         echo "LU-974 ignore umask when acl is enabled..."
10386         run_acl_subtest 974 || error "LU-974 umask test failed"
10387         if [ $MDSCOUNT -ge 2 ]; then
10388                 run_acl_subtest 974_remote ||
10389                         error "LU-974 umask test failed under remote dir"
10390         fi
10391
10392         echo "LU-2561 newly created file is same size as directory..."
10393         if [ "$mds1_FSTYPE" != "zfs" ]; then
10394                 run_acl_subtest 2561 || error "LU-2561 test failed"
10395         else
10396                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10397         fi
10398
10399         run_acl_subtest 4924 || error "LU-4924 test failed"
10400
10401         cd $SAVE_PWD
10402         umask $SAVE_UMASK
10403
10404         for num in $(seq $MDSCOUNT); do
10405                 if [ "${identity_old[$num]}" = 1 ]; then
10406                         switch_identity $num false || identity_old[$num]=$?
10407                 fi
10408         done
10409 }
10410 run_test 103a "acl test"
10411
10412 test_103b() {
10413         declare -a pids
10414         local U
10415
10416         for U in {0..511}; do
10417                 {
10418                 local O=$(printf "%04o" $U)
10419
10420                 umask $(printf "%04o" $((511 ^ $O)))
10421                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10422                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10423
10424                 (( $S == ($O & 0666) )) ||
10425                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10426
10427                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10428                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10429                 (( $S == ($O & 0666) )) ||
10430                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10431
10432                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10433                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10434                 (( $S == ($O & 0666) )) ||
10435                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10436                 rm -f $DIR/$tfile.[smp]$0
10437                 } &
10438                 local pid=$!
10439
10440                 # limit the concurrently running threads to 64. LU-11878
10441                 local idx=$((U % 64))
10442                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10443                 pids[idx]=$pid
10444         done
10445         wait
10446 }
10447 run_test 103b "umask lfs setstripe"
10448
10449 test_103c() {
10450         mkdir -p $DIR/$tdir
10451         cp -rp $DIR/$tdir $DIR/$tdir.bak
10452
10453         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10454                 error "$DIR/$tdir shouldn't contain default ACL"
10455         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10456                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10457         true
10458 }
10459 run_test 103c "'cp -rp' won't set empty acl"
10460
10461 test_104a() {
10462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10463
10464         touch $DIR/$tfile
10465         lfs df || error "lfs df failed"
10466         lfs df -ih || error "lfs df -ih failed"
10467         lfs df -h $DIR || error "lfs df -h $DIR failed"
10468         lfs df -i $DIR || error "lfs df -i $DIR failed"
10469         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10470         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10471
10472         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10473         lctl --device %$OSC deactivate
10474         lfs df || error "lfs df with deactivated OSC failed"
10475         lctl --device %$OSC activate
10476         # wait the osc back to normal
10477         wait_osc_import_ready client ost
10478
10479         lfs df || error "lfs df with reactivated OSC failed"
10480         rm -f $DIR/$tfile
10481 }
10482 run_test 104a "lfs df [-ih] [path] test ========================="
10483
10484 test_104b() {
10485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10486         [ $RUNAS_ID -eq $UID ] &&
10487                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10488
10489         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10490                         grep "Permission denied" | wc -l)))
10491         if [ $denied_cnt -ne 0 ]; then
10492                 error "lfs check servers test failed"
10493         fi
10494 }
10495 run_test 104b "$RUNAS lfs check servers test ===================="
10496
10497 test_105a() {
10498         # doesn't work on 2.4 kernels
10499         touch $DIR/$tfile
10500         if $(flock_is_enabled); then
10501                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10502         else
10503                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10504         fi
10505         rm -f $DIR/$tfile
10506 }
10507 run_test 105a "flock when mounted without -o flock test ========"
10508
10509 test_105b() {
10510         touch $DIR/$tfile
10511         if $(flock_is_enabled); then
10512                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10513         else
10514                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10515         fi
10516         rm -f $DIR/$tfile
10517 }
10518 run_test 105b "fcntl when mounted without -o flock test ========"
10519
10520 test_105c() {
10521         touch $DIR/$tfile
10522         if $(flock_is_enabled); then
10523                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10524         else
10525                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10526         fi
10527         rm -f $DIR/$tfile
10528 }
10529 run_test 105c "lockf when mounted without -o flock test"
10530
10531 test_105d() { # bug 15924
10532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10533
10534         test_mkdir $DIR/$tdir
10535         flock_is_enabled || skip_env "mount w/o flock enabled"
10536         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10537         $LCTL set_param fail_loc=0x80000315
10538         flocks_test 2 $DIR/$tdir
10539 }
10540 run_test 105d "flock race (should not freeze) ========"
10541
10542 test_105e() { # bug 22660 && 22040
10543         flock_is_enabled || skip_env "mount w/o flock enabled"
10544
10545         touch $DIR/$tfile
10546         flocks_test 3 $DIR/$tfile
10547 }
10548 run_test 105e "Two conflicting flocks from same process"
10549
10550 test_106() { #bug 10921
10551         test_mkdir $DIR/$tdir
10552         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10553         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10554 }
10555 run_test 106 "attempt exec of dir followed by chown of that dir"
10556
10557 test_107() {
10558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10559
10560         CDIR=`pwd`
10561         local file=core
10562
10563         cd $DIR
10564         rm -f $file
10565
10566         local save_pattern=$(sysctl -n kernel.core_pattern)
10567         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10568         sysctl -w kernel.core_pattern=$file
10569         sysctl -w kernel.core_uses_pid=0
10570
10571         ulimit -c unlimited
10572         sleep 60 &
10573         SLEEPPID=$!
10574
10575         sleep 1
10576
10577         kill -s 11 $SLEEPPID
10578         wait $SLEEPPID
10579         if [ -e $file ]; then
10580                 size=`stat -c%s $file`
10581                 [ $size -eq 0 ] && error "Fail to create core file $file"
10582         else
10583                 error "Fail to create core file $file"
10584         fi
10585         rm -f $file
10586         sysctl -w kernel.core_pattern=$save_pattern
10587         sysctl -w kernel.core_uses_pid=$save_uses_pid
10588         cd $CDIR
10589 }
10590 run_test 107 "Coredump on SIG"
10591
10592 test_110() {
10593         test_mkdir $DIR/$tdir
10594         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10595         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10596                 error "mkdir with 256 char should fail, but did not"
10597         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10598                 error "create with 255 char failed"
10599         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10600                 error "create with 256 char should fail, but did not"
10601
10602         ls -l $DIR/$tdir
10603         rm -rf $DIR/$tdir
10604 }
10605 run_test 110 "filename length checking"
10606
10607 #
10608 # Purpose: To verify dynamic thread (OSS) creation.
10609 #
10610 test_115() {
10611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10612         remote_ost_nodsh && skip "remote OST with nodsh"
10613
10614         # Lustre does not stop service threads once they are started.
10615         # Reset number of running threads to default.
10616         stopall
10617         setupall
10618
10619         local OSTIO_pre
10620         local save_params="$TMP/sanity-$TESTNAME.parameters"
10621
10622         # Get ll_ost_io count before I/O
10623         OSTIO_pre=$(do_facet ost1 \
10624                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10625         # Exit if lustre is not running (ll_ost_io not running).
10626         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10627
10628         echo "Starting with $OSTIO_pre threads"
10629         local thread_max=$((OSTIO_pre * 2))
10630         local rpc_in_flight=$((thread_max * 2))
10631         # Number of I/O Process proposed to be started.
10632         local nfiles
10633         local facets=$(get_facets OST)
10634
10635         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10636         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10637
10638         # Set in_flight to $rpc_in_flight
10639         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10640                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10641         nfiles=${rpc_in_flight}
10642         # Set ost thread_max to $thread_max
10643         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10644
10645         # 5 Minutes should be sufficient for max number of OSS
10646         # threads(thread_max) to be created.
10647         local timeout=300
10648
10649         # Start I/O.
10650         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10651         test_mkdir $DIR/$tdir
10652         for i in $(seq $nfiles); do
10653                 local file=$DIR/$tdir/${tfile}-$i
10654                 $LFS setstripe -c -1 -i 0 $file
10655                 ($WTL $file $timeout)&
10656         done
10657
10658         # I/O Started - Wait for thread_started to reach thread_max or report
10659         # error if thread_started is more than thread_max.
10660         echo "Waiting for thread_started to reach thread_max"
10661         local thread_started=0
10662         local end_time=$((SECONDS + timeout))
10663
10664         while [ $SECONDS -le $end_time ] ; do
10665                 echo -n "."
10666                 # Get ost i/o thread_started count.
10667                 thread_started=$(do_facet ost1 \
10668                         "$LCTL get_param \
10669                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10670                 # Break out if thread_started is equal/greater than thread_max
10671                 if [[ $thread_started -ge $thread_max ]]; then
10672                         echo ll_ost_io thread_started $thread_started, \
10673                                 equal/greater than thread_max $thread_max
10674                         break
10675                 fi
10676                 sleep 1
10677         done
10678
10679         # Cleanup - We have the numbers, Kill i/o jobs if running.
10680         jobcount=($(jobs -p))
10681         for i in $(seq 0 $((${#jobcount[@]}-1)))
10682         do
10683                 kill -9 ${jobcount[$i]}
10684                 if [ $? -ne 0 ] ; then
10685                         echo Warning: \
10686                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10687                 fi
10688         done
10689
10690         # Cleanup files left by WTL binary.
10691         for i in $(seq $nfiles); do
10692                 local file=$DIR/$tdir/${tfile}-$i
10693                 rm -rf $file
10694                 if [ $? -ne 0 ] ; then
10695                         echo "Warning: Failed to delete file $file"
10696                 fi
10697         done
10698
10699         restore_lustre_params <$save_params
10700         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10701
10702         # Error out if no new thread has started or Thread started is greater
10703         # than thread max.
10704         if [[ $thread_started -le $OSTIO_pre ||
10705                         $thread_started -gt $thread_max ]]; then
10706                 error "ll_ost_io: thread_started $thread_started" \
10707                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10708                       "No new thread started or thread started greater " \
10709                       "than thread_max."
10710         fi
10711 }
10712 run_test 115 "verify dynamic thread creation===================="
10713
10714 free_min_max () {
10715         wait_delete_completed
10716         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10717         echo "OST kbytes available: ${AVAIL[@]}"
10718         MAXV=${AVAIL[0]}
10719         MAXI=0
10720         MINV=${AVAIL[0]}
10721         MINI=0
10722         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10723                 #echo OST $i: ${AVAIL[i]}kb
10724                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10725                         MAXV=${AVAIL[i]}
10726                         MAXI=$i
10727                 fi
10728                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10729                         MINV=${AVAIL[i]}
10730                         MINI=$i
10731                 fi
10732         done
10733         echo "Min free space: OST $MINI: $MINV"
10734         echo "Max free space: OST $MAXI: $MAXV"
10735 }
10736
10737 test_116a() { # was previously test_116()
10738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10740         remote_mds_nodsh && skip "remote MDS with nodsh"
10741
10742         echo -n "Free space priority "
10743         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10744                 head -n1
10745         declare -a AVAIL
10746         free_min_max
10747
10748         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10749         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10750         trap simple_cleanup_common EXIT
10751
10752         # Check if we need to generate uneven OSTs
10753         test_mkdir -p $DIR/$tdir/OST${MINI}
10754         local FILL=$((MINV / 4))
10755         local DIFF=$((MAXV - MINV))
10756         local DIFF2=$((DIFF * 100 / MINV))
10757
10758         local threshold=$(do_facet $SINGLEMDS \
10759                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10760         threshold=${threshold%%%}
10761         echo -n "Check for uneven OSTs: "
10762         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10763
10764         if [[ $DIFF2 -gt $threshold ]]; then
10765                 echo "ok"
10766                 echo "Don't need to fill OST$MINI"
10767         else
10768                 # generate uneven OSTs. Write 2% over the QOS threshold value
10769                 echo "no"
10770                 DIFF=$((threshold - DIFF2 + 2))
10771                 DIFF2=$((MINV * DIFF / 100))
10772                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10773                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10774                         error "setstripe failed"
10775                 DIFF=$((DIFF2 / 2048))
10776                 i=0
10777                 while [ $i -lt $DIFF ]; do
10778                         i=$((i + 1))
10779                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10780                                 bs=2M count=1 2>/dev/null
10781                         echo -n .
10782                 done
10783                 echo .
10784                 sync
10785                 sleep_maxage
10786                 free_min_max
10787         fi
10788
10789         DIFF=$((MAXV - MINV))
10790         DIFF2=$((DIFF * 100 / MINV))
10791         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10792         if [ $DIFF2 -gt $threshold ]; then
10793                 echo "ok"
10794         else
10795                 echo "failed - QOS mode won't be used"
10796                 simple_cleanup_common
10797                 skip "QOS imbalance criteria not met"
10798         fi
10799
10800         MINI1=$MINI
10801         MINV1=$MINV
10802         MAXI1=$MAXI
10803         MAXV1=$MAXV
10804
10805         # now fill using QOS
10806         $LFS setstripe -c 1 $DIR/$tdir
10807         FILL=$((FILL / 200))
10808         if [ $FILL -gt 600 ]; then
10809                 FILL=600
10810         fi
10811         echo "writing $FILL files to QOS-assigned OSTs"
10812         i=0
10813         while [ $i -lt $FILL ]; do
10814                 i=$((i + 1))
10815                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10816                         count=1 2>/dev/null
10817                 echo -n .
10818         done
10819         echo "wrote $i 200k files"
10820         sync
10821         sleep_maxage
10822
10823         echo "Note: free space may not be updated, so measurements might be off"
10824         free_min_max
10825         DIFF2=$((MAXV - MINV))
10826         echo "free space delta: orig $DIFF final $DIFF2"
10827         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10828         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10829         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10830         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10831         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10832         if [[ $DIFF -gt 0 ]]; then
10833                 FILL=$((DIFF2 * 100 / DIFF - 100))
10834                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10835         fi
10836
10837         # Figure out which files were written where
10838         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10839                awk '/'$MINI1': / {print $2; exit}')
10840         echo $UUID
10841         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10842         echo "$MINC files created on smaller OST $MINI1"
10843         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10844                awk '/'$MAXI1': / {print $2; exit}')
10845         echo $UUID
10846         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10847         echo "$MAXC files created on larger OST $MAXI1"
10848         if [[ $MINC -gt 0 ]]; then
10849                 FILL=$((MAXC * 100 / MINC - 100))
10850                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10851         fi
10852         [[ $MAXC -gt $MINC ]] ||
10853                 error_ignore LU-9 "stripe QOS didn't balance free space"
10854         simple_cleanup_common
10855 }
10856 run_test 116a "stripe QOS: free space balance ==================="
10857
10858 test_116b() { # LU-2093
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860         remote_mds_nodsh && skip "remote MDS with nodsh"
10861
10862 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10863         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10864                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10865         [ -z "$old_rr" ] && skip "no QOS"
10866         do_facet $SINGLEMDS lctl set_param \
10867                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10868         mkdir -p $DIR/$tdir
10869         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10870         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10871         do_facet $SINGLEMDS lctl set_param fail_loc=0
10872         rm -rf $DIR/$tdir
10873         do_facet $SINGLEMDS lctl set_param \
10874                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10875 }
10876 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10877
10878 test_117() # bug 10891
10879 {
10880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10881
10882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10883         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10884         lctl set_param fail_loc=0x21e
10885         > $DIR/$tfile || error "truncate failed"
10886         lctl set_param fail_loc=0
10887         echo "Truncate succeeded."
10888         rm -f $DIR/$tfile
10889 }
10890 run_test 117 "verify osd extend =========="
10891
10892 NO_SLOW_RESENDCOUNT=4
10893 export OLD_RESENDCOUNT=""
10894 set_resend_count () {
10895         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10896         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10897         lctl set_param -n $PROC_RESENDCOUNT $1
10898         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10899 }
10900
10901 # for reduce test_118* time (b=14842)
10902 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10903
10904 # Reset async IO behavior after error case
10905 reset_async() {
10906         FILE=$DIR/reset_async
10907
10908         # Ensure all OSCs are cleared
10909         $LFS setstripe -c -1 $FILE
10910         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10911         sync
10912         rm $FILE
10913 }
10914
10915 test_118a() #bug 11710
10916 {
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918
10919         reset_async
10920
10921         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10922         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10923         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10924
10925         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10926                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10927                 return 1;
10928         fi
10929         rm -f $DIR/$tfile
10930 }
10931 run_test 118a "verify O_SYNC works =========="
10932
10933 test_118b()
10934 {
10935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10936         remote_ost_nodsh && skip "remote OST with nodsh"
10937
10938         reset_async
10939
10940         #define OBD_FAIL_SRV_ENOENT 0x217
10941         set_nodes_failloc "$(osts_nodes)" 0x217
10942         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10943         RC=$?
10944         set_nodes_failloc "$(osts_nodes)" 0
10945         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10946         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10947                     grep -c writeback)
10948
10949         if [[ $RC -eq 0 ]]; then
10950                 error "Must return error due to dropped pages, rc=$RC"
10951                 return 1;
10952         fi
10953
10954         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10955                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10956                 return 1;
10957         fi
10958
10959         echo "Dirty pages not leaked on ENOENT"
10960
10961         # Due to the above error the OSC will issue all RPCs syncronously
10962         # until a subsequent RPC completes successfully without error.
10963         $MULTIOP $DIR/$tfile Ow4096yc
10964         rm -f $DIR/$tfile
10965
10966         return 0
10967 }
10968 run_test 118b "Reclaim dirty pages on fatal error =========="
10969
10970 test_118c()
10971 {
10972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10973
10974         # for 118c, restore the original resend count, LU-1940
10975         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10976                                 set_resend_count $OLD_RESENDCOUNT
10977         remote_ost_nodsh && skip "remote OST with nodsh"
10978
10979         reset_async
10980
10981         #define OBD_FAIL_OST_EROFS               0x216
10982         set_nodes_failloc "$(osts_nodes)" 0x216
10983
10984         # multiop should block due to fsync until pages are written
10985         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10986         MULTIPID=$!
10987         sleep 1
10988
10989         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10990                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10991         fi
10992
10993         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10994                     grep -c writeback)
10995         if [[ $WRITEBACK -eq 0 ]]; then
10996                 error "No page in writeback, writeback=$WRITEBACK"
10997         fi
10998
10999         set_nodes_failloc "$(osts_nodes)" 0
11000         wait $MULTIPID
11001         RC=$?
11002         if [[ $RC -ne 0 ]]; then
11003                 error "Multiop fsync failed, rc=$RC"
11004         fi
11005
11006         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11007         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11008                     grep -c writeback)
11009         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11010                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11011         fi
11012
11013         rm -f $DIR/$tfile
11014         echo "Dirty pages flushed via fsync on EROFS"
11015         return 0
11016 }
11017 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11018
11019 # continue to use small resend count to reduce test_118* time (b=14842)
11020 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11021
11022 test_118d()
11023 {
11024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11025         remote_ost_nodsh && skip "remote OST with nodsh"
11026
11027         reset_async
11028
11029         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11030         set_nodes_failloc "$(osts_nodes)" 0x214
11031         # multiop should block due to fsync until pages are written
11032         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11033         MULTIPID=$!
11034         sleep 1
11035
11036         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11037                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11038         fi
11039
11040         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11041                     grep -c writeback)
11042         if [[ $WRITEBACK -eq 0 ]]; then
11043                 error "No page in writeback, writeback=$WRITEBACK"
11044         fi
11045
11046         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11047         set_nodes_failloc "$(osts_nodes)" 0
11048
11049         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11050         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11051                     grep -c writeback)
11052         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11053                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11054         fi
11055
11056         rm -f $DIR/$tfile
11057         echo "Dirty pages gaurenteed flushed via fsync"
11058         return 0
11059 }
11060 run_test 118d "Fsync validation inject a delay of the bulk =========="
11061
11062 test_118f() {
11063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11064
11065         reset_async
11066
11067         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11068         lctl set_param fail_loc=0x8000040a
11069
11070         # Should simulate EINVAL error which is fatal
11071         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11072         RC=$?
11073         if [[ $RC -eq 0 ]]; then
11074                 error "Must return error due to dropped pages, rc=$RC"
11075         fi
11076
11077         lctl set_param fail_loc=0x0
11078
11079         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
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 [[ $LOCKED -ne 0 ]]; then
11084                 error "Locked pages remain in cache, locked=$LOCKED"
11085         fi
11086
11087         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11088                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11089         fi
11090
11091         rm -f $DIR/$tfile
11092         echo "No pages locked after fsync"
11093
11094         reset_async
11095         return 0
11096 }
11097 run_test 118f "Simulate unrecoverable OSC side error =========="
11098
11099 test_118g() {
11100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11101
11102         reset_async
11103
11104         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11105         lctl set_param fail_loc=0x406
11106
11107         # simulate local -ENOMEM
11108         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11109         RC=$?
11110
11111         lctl set_param fail_loc=0
11112         if [[ $RC -eq 0 ]]; then
11113                 error "Must return error due to dropped pages, rc=$RC"
11114         fi
11115
11116         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11117         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11118         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11119                         grep -c writeback)
11120         if [[ $LOCKED -ne 0 ]]; then
11121                 error "Locked pages remain in cache, locked=$LOCKED"
11122         fi
11123
11124         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11125                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11126         fi
11127
11128         rm -f $DIR/$tfile
11129         echo "No pages locked after fsync"
11130
11131         reset_async
11132         return 0
11133 }
11134 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11135
11136 test_118h() {
11137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11138         remote_ost_nodsh && skip "remote OST with nodsh"
11139
11140         reset_async
11141
11142         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11143         set_nodes_failloc "$(osts_nodes)" 0x20e
11144         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11145         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11146         RC=$?
11147
11148         set_nodes_failloc "$(osts_nodes)" 0
11149         if [[ $RC -eq 0 ]]; then
11150                 error "Must return error due to dropped pages, rc=$RC"
11151         fi
11152
11153         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11154         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11156                     grep -c writeback)
11157         if [[ $LOCKED -ne 0 ]]; then
11158                 error "Locked pages remain in cache, locked=$LOCKED"
11159         fi
11160
11161         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11162                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11163         fi
11164
11165         rm -f $DIR/$tfile
11166         echo "No pages locked after fsync"
11167
11168         return 0
11169 }
11170 run_test 118h "Verify timeout in handling recoverables errors  =========="
11171
11172 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11173
11174 test_118i() {
11175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11176         remote_ost_nodsh && skip "remote OST with nodsh"
11177
11178         reset_async
11179
11180         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11181         set_nodes_failloc "$(osts_nodes)" 0x20e
11182
11183         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11184         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11185         PID=$!
11186         sleep 5
11187         set_nodes_failloc "$(osts_nodes)" 0
11188
11189         wait $PID
11190         RC=$?
11191         if [[ $RC -ne 0 ]]; then
11192                 error "got error, but should be not, rc=$RC"
11193         fi
11194
11195         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11196         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11197         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11198         if [[ $LOCKED -ne 0 ]]; then
11199                 error "Locked pages remain in cache, locked=$LOCKED"
11200         fi
11201
11202         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11203                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11204         fi
11205
11206         rm -f $DIR/$tfile
11207         echo "No pages locked after fsync"
11208
11209         return 0
11210 }
11211 run_test 118i "Fix error before timeout in recoverable error  =========="
11212
11213 [ "$SLOW" = "no" ] && set_resend_count 4
11214
11215 test_118j() {
11216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11217         remote_ost_nodsh && skip "remote OST with nodsh"
11218
11219         reset_async
11220
11221         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11222         set_nodes_failloc "$(osts_nodes)" 0x220
11223
11224         # return -EIO from OST
11225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11226         RC=$?
11227         set_nodes_failloc "$(osts_nodes)" 0x0
11228         if [[ $RC -eq 0 ]]; then
11229                 error "Must return error due to dropped pages, rc=$RC"
11230         fi
11231
11232         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11233         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11234         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11235         if [[ $LOCKED -ne 0 ]]; then
11236                 error "Locked pages remain in cache, locked=$LOCKED"
11237         fi
11238
11239         # in recoverable error on OST we want resend and stay until it finished
11240         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11241                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11242         fi
11243
11244         rm -f $DIR/$tfile
11245         echo "No pages locked after fsync"
11246
11247         return 0
11248 }
11249 run_test 118j "Simulate unrecoverable OST side error =========="
11250
11251 test_118k()
11252 {
11253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11254         remote_ost_nodsh && skip "remote OSTs with nodsh"
11255
11256         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11257         set_nodes_failloc "$(osts_nodes)" 0x20e
11258         test_mkdir $DIR/$tdir
11259
11260         for ((i=0;i<10;i++)); do
11261                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11262                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11263                 SLEEPPID=$!
11264                 sleep 0.500s
11265                 kill $SLEEPPID
11266                 wait $SLEEPPID
11267         done
11268
11269         set_nodes_failloc "$(osts_nodes)" 0
11270         rm -rf $DIR/$tdir
11271 }
11272 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11273
11274 test_118l() # LU-646
11275 {
11276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11277
11278         test_mkdir $DIR/$tdir
11279         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11280         rm -rf $DIR/$tdir
11281 }
11282 run_test 118l "fsync dir"
11283
11284 test_118m() # LU-3066
11285 {
11286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11287
11288         test_mkdir $DIR/$tdir
11289         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11290         rm -rf $DIR/$tdir
11291 }
11292 run_test 118m "fdatasync dir ========="
11293
11294 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11295
11296 test_118n()
11297 {
11298         local begin
11299         local end
11300
11301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11302         remote_ost_nodsh && skip "remote OSTs with nodsh"
11303
11304         # Sleep to avoid a cached response.
11305         #define OBD_STATFS_CACHE_SECONDS 1
11306         sleep 2
11307
11308         # Inject a 10 second delay in the OST_STATFS handler.
11309         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11310         set_nodes_failloc "$(osts_nodes)" 0x242
11311
11312         begin=$SECONDS
11313         stat --file-system $MOUNT > /dev/null
11314         end=$SECONDS
11315
11316         set_nodes_failloc "$(osts_nodes)" 0
11317
11318         if ((end - begin > 20)); then
11319             error "statfs took $((end - begin)) seconds, expected 10"
11320         fi
11321 }
11322 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11323
11324 test_119a() # bug 11737
11325 {
11326         BSIZE=$((512 * 1024))
11327         directio write $DIR/$tfile 0 1 $BSIZE
11328         # We ask to read two blocks, which is more than a file size.
11329         # directio will indicate an error when requested and actual
11330         # sizes aren't equeal (a normal situation in this case) and
11331         # print actual read amount.
11332         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11333         if [ "$NOB" != "$BSIZE" ]; then
11334                 error "read $NOB bytes instead of $BSIZE"
11335         fi
11336         rm -f $DIR/$tfile
11337 }
11338 run_test 119a "Short directIO read must return actual read amount"
11339
11340 test_119b() # bug 11737
11341 {
11342         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11343
11344         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11346         sync
11347         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11348                 error "direct read failed"
11349         rm -f $DIR/$tfile
11350 }
11351 run_test 119b "Sparse directIO read must return actual read amount"
11352
11353 test_119c() # bug 13099
11354 {
11355         BSIZE=1048576
11356         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11357         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11358         rm -f $DIR/$tfile
11359 }
11360 run_test 119c "Testing for direct read hitting hole"
11361
11362 test_119d() # bug 15950
11363 {
11364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11365
11366         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11367         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11368         BSIZE=1048576
11369         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11370         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11371         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11372         lctl set_param fail_loc=0x40d
11373         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11374         pid_dio=$!
11375         sleep 1
11376         cat $DIR/$tfile > /dev/null &
11377         lctl set_param fail_loc=0
11378         pid_reads=$!
11379         wait $pid_dio
11380         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11381         sleep 2
11382         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11383         error "the read rpcs have not completed in 2s"
11384         rm -f $DIR/$tfile
11385         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11386 }
11387 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11388
11389 test_120a() {
11390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11391         remote_mds_nodsh && skip "remote MDS with nodsh"
11392         test_mkdir -i0 -c1 $DIR/$tdir
11393         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11394                 skip_env "no early lock cancel on server"
11395
11396         lru_resize_disable mdc
11397         lru_resize_disable osc
11398         cancel_lru_locks mdc
11399         # asynchronous object destroy at MDT could cause bl ast to client
11400         cancel_lru_locks osc
11401
11402         stat $DIR/$tdir > /dev/null
11403         can1=$(do_facet mds1 \
11404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11405                awk '/ldlm_cancel/ {print $2}')
11406         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11407                awk '/ldlm_bl_callback/ {print $2}')
11408         test_mkdir -i0 -c1 $DIR/$tdir/d1
11409         can2=$(do_facet mds1 \
11410                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11411                awk '/ldlm_cancel/ {print $2}')
11412         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11413                awk '/ldlm_bl_callback/ {print $2}')
11414         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11415         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11416         lru_resize_enable mdc
11417         lru_resize_enable osc
11418 }
11419 run_test 120a "Early Lock Cancel: mkdir test"
11420
11421 test_120b() {
11422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11423         remote_mds_nodsh && skip "remote MDS with nodsh"
11424         test_mkdir $DIR/$tdir
11425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11426                 skip_env "no early lock cancel on server"
11427
11428         lru_resize_disable mdc
11429         lru_resize_disable osc
11430         cancel_lru_locks mdc
11431         stat $DIR/$tdir > /dev/null
11432         can1=$(do_facet $SINGLEMDS \
11433                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11434                awk '/ldlm_cancel/ {print $2}')
11435         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11436                awk '/ldlm_bl_callback/ {print $2}')
11437         touch $DIR/$tdir/f1
11438         can2=$(do_facet $SINGLEMDS \
11439                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11440                awk '/ldlm_cancel/ {print $2}')
11441         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11442                awk '/ldlm_bl_callback/ {print $2}')
11443         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11444         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11445         lru_resize_enable mdc
11446         lru_resize_enable osc
11447 }
11448 run_test 120b "Early Lock Cancel: create test"
11449
11450 test_120c() {
11451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11452         remote_mds_nodsh && skip "remote MDS with nodsh"
11453         test_mkdir -i0 -c1 $DIR/$tdir
11454         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11455                 skip "no early lock cancel on server"
11456
11457         lru_resize_disable mdc
11458         lru_resize_disable osc
11459         test_mkdir -i0 -c1 $DIR/$tdir/d1
11460         test_mkdir -i0 -c1 $DIR/$tdir/d2
11461         touch $DIR/$tdir/d1/f1
11462         cancel_lru_locks mdc
11463         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11464         can1=$(do_facet mds1 \
11465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11466                awk '/ldlm_cancel/ {print $2}')
11467         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11468                awk '/ldlm_bl_callback/ {print $2}')
11469         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11470         can2=$(do_facet mds1 \
11471                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11472                awk '/ldlm_cancel/ {print $2}')
11473         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11474                awk '/ldlm_bl_callback/ {print $2}')
11475         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11476         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11477         lru_resize_enable mdc
11478         lru_resize_enable osc
11479 }
11480 run_test 120c "Early Lock Cancel: link test"
11481
11482 test_120d() {
11483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11484         remote_mds_nodsh && skip "remote MDS with nodsh"
11485         test_mkdir -i0 -c1 $DIR/$tdir
11486         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11487                 skip_env "no early lock cancel on server"
11488
11489         lru_resize_disable mdc
11490         lru_resize_disable osc
11491         touch $DIR/$tdir
11492         cancel_lru_locks mdc
11493         stat $DIR/$tdir > /dev/null
11494         can1=$(do_facet mds1 \
11495                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11496                awk '/ldlm_cancel/ {print $2}')
11497         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11498                awk '/ldlm_bl_callback/ {print $2}')
11499         chmod a+x $DIR/$tdir
11500         can2=$(do_facet mds1 \
11501                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11502                awk '/ldlm_cancel/ {print $2}')
11503         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11504                awk '/ldlm_bl_callback/ {print $2}')
11505         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11506         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11507         lru_resize_enable mdc
11508         lru_resize_enable osc
11509 }
11510 run_test 120d "Early Lock Cancel: setattr test"
11511
11512 test_120e() {
11513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11514         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11515                 skip_env "no early lock cancel on server"
11516         remote_mds_nodsh && skip "remote MDS with nodsh"
11517
11518         local dlmtrace_set=false
11519
11520         test_mkdir -i0 -c1 $DIR/$tdir
11521         lru_resize_disable mdc
11522         lru_resize_disable osc
11523         ! $LCTL get_param debug | grep -q dlmtrace &&
11524                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11525         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11526         cancel_lru_locks mdc
11527         cancel_lru_locks osc
11528         dd if=$DIR/$tdir/f1 of=/dev/null
11529         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11530         # XXX client can not do early lock cancel of OST lock
11531         # during unlink (LU-4206), so cancel osc lock now.
11532         sleep 2
11533         cancel_lru_locks osc
11534         can1=$(do_facet mds1 \
11535                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11536                awk '/ldlm_cancel/ {print $2}')
11537         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11538                awk '/ldlm_bl_callback/ {print $2}')
11539         unlink $DIR/$tdir/f1
11540         sleep 5
11541         can2=$(do_facet mds1 \
11542                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11543                awk '/ldlm_cancel/ {print $2}')
11544         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11545                awk '/ldlm_bl_callback/ {print $2}')
11546         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11547                 $LCTL dk $TMP/cancel.debug.txt
11548         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11549                 $LCTL dk $TMP/blocking.debug.txt
11550         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11551         lru_resize_enable mdc
11552         lru_resize_enable osc
11553 }
11554 run_test 120e "Early Lock Cancel: unlink test"
11555
11556 test_120f() {
11557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11558         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11559                 skip_env "no early lock cancel on server"
11560         remote_mds_nodsh && skip "remote MDS with nodsh"
11561
11562         test_mkdir -i0 -c1 $DIR/$tdir
11563         lru_resize_disable mdc
11564         lru_resize_disable osc
11565         test_mkdir -i0 -c1 $DIR/$tdir/d1
11566         test_mkdir -i0 -c1 $DIR/$tdir/d2
11567         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11568         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11569         cancel_lru_locks mdc
11570         cancel_lru_locks osc
11571         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11572         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11573         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11574         # XXX client can not do early lock cancel of OST lock
11575         # during rename (LU-4206), so cancel osc lock now.
11576         sleep 2
11577         cancel_lru_locks osc
11578         can1=$(do_facet mds1 \
11579                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11580                awk '/ldlm_cancel/ {print $2}')
11581         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11582                awk '/ldlm_bl_callback/ {print $2}')
11583         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11584         sleep 5
11585         can2=$(do_facet mds1 \
11586                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11587                awk '/ldlm_cancel/ {print $2}')
11588         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11589                awk '/ldlm_bl_callback/ {print $2}')
11590         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11591         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11592         lru_resize_enable mdc
11593         lru_resize_enable osc
11594 }
11595 run_test 120f "Early Lock Cancel: rename test"
11596
11597 test_120g() {
11598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11599         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11600                 skip_env "no early lock cancel on server"
11601         remote_mds_nodsh && skip "remote MDS with nodsh"
11602
11603         lru_resize_disable mdc
11604         lru_resize_disable osc
11605         count=10000
11606         echo create $count files
11607         test_mkdir $DIR/$tdir
11608         cancel_lru_locks mdc
11609         cancel_lru_locks osc
11610         t0=$(date +%s)
11611
11612         can0=$(do_facet $SINGLEMDS \
11613                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11614                awk '/ldlm_cancel/ {print $2}')
11615         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11616                awk '/ldlm_bl_callback/ {print $2}')
11617         createmany -o $DIR/$tdir/f $count
11618         sync
11619         can1=$(do_facet $SINGLEMDS \
11620                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11621                awk '/ldlm_cancel/ {print $2}')
11622         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11623                awk '/ldlm_bl_callback/ {print $2}')
11624         t1=$(date +%s)
11625         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11626         echo rm $count files
11627         rm -r $DIR/$tdir
11628         sync
11629         can2=$(do_facet $SINGLEMDS \
11630                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11631                awk '/ldlm_cancel/ {print $2}')
11632         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11633                awk '/ldlm_bl_callback/ {print $2}')
11634         t2=$(date +%s)
11635         echo total: $count removes in $((t2-t1))
11636         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11637         sleep 2
11638         # wait for commitment of removal
11639         lru_resize_enable mdc
11640         lru_resize_enable osc
11641 }
11642 run_test 120g "Early Lock Cancel: performance test"
11643
11644 test_121() { #bug #10589
11645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11646
11647         rm -rf $DIR/$tfile
11648         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11649 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11650         lctl set_param fail_loc=0x310
11651         cancel_lru_locks osc > /dev/null
11652         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11653         lctl set_param fail_loc=0
11654         [[ $reads -eq $writes ]] ||
11655                 error "read $reads blocks, must be $writes blocks"
11656 }
11657 run_test 121 "read cancel race ========="
11658
11659 test_123a_base() { # was test 123, statahead(bug 11401)
11660         local lsx="$1"
11661
11662         SLOWOK=0
11663         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11664                 log "testing UP system. Performance may be lower than expected."
11665                 SLOWOK=1
11666         fi
11667
11668         rm -rf $DIR/$tdir
11669         test_mkdir $DIR/$tdir
11670         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11671         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11672         MULT=10
11673         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11674                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11675
11676                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11677                 lctl set_param -n llite.*.statahead_max 0
11678                 lctl get_param llite.*.statahead_max
11679                 cancel_lru_locks mdc
11680                 cancel_lru_locks osc
11681                 stime=$(date +%s)
11682                 time $lsx $DIR/$tdir | wc -l
11683                 etime=$(date +%s)
11684                 delta=$((etime - stime))
11685                 log "$lsx $i files without statahead: $delta sec"
11686                 lctl set_param llite.*.statahead_max=$max
11687
11688                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11689                         grep "statahead wrong:" | awk '{print $3}')
11690                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11691                 cancel_lru_locks mdc
11692                 cancel_lru_locks osc
11693                 stime=$(date +%s)
11694                 time $lsx $DIR/$tdir | wc -l
11695                 etime=$(date +%s)
11696                 delta_sa=$((etime - stime))
11697                 log "$lsx $i files with statahead: $delta_sa sec"
11698                 lctl get_param -n llite.*.statahead_stats
11699                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11700                         grep "statahead wrong:" | awk '{print $3}')
11701
11702                 [[ $swrong -lt $ewrong ]] &&
11703                         log "statahead was stopped, maybe too many locks held!"
11704                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11705
11706                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11707                         max=$(lctl get_param -n llite.*.statahead_max |
11708                                 head -n 1)
11709                         lctl set_param -n llite.*.statahead_max 0
11710                         lctl get_param llite.*.statahead_max
11711                         cancel_lru_locks mdc
11712                         cancel_lru_locks osc
11713                         stime=$(date +%s)
11714                         time $lsx $DIR/$tdir | wc -l
11715                         etime=$(date +%s)
11716                         delta=$((etime - stime))
11717                         log "$lsx $i files again without statahead: $delta sec"
11718                         lctl set_param llite.*.statahead_max=$max
11719                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11720                                 if [  $SLOWOK -eq 0 ]; then
11721                                         error "$lsx $i files is slower with statahead!"
11722                                 else
11723                                         log "$lsx $i files is slower with statahead!"
11724                                 fi
11725                                 break
11726                         fi
11727                 fi
11728
11729                 [ $delta -gt 20 ] && break
11730                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11731                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11732         done
11733         log "$lsx done"
11734
11735         stime=$(date +%s)
11736         rm -r $DIR/$tdir
11737         sync
11738         etime=$(date +%s)
11739         delta=$((etime - stime))
11740         log "rm -r $DIR/$tdir/: $delta seconds"
11741         log "rm done"
11742         lctl get_param -n llite.*.statahead_stats
11743 }
11744
11745 test_123aa() {
11746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11747
11748         test_123a_base "ls -l"
11749 }
11750 run_test 123aa "verify statahead work"
11751
11752 test_123ab() {
11753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11754
11755         statx_supported || skip_env "Test must be statx() syscall supported"
11756
11757         test_123a_base "$STATX -l"
11758 }
11759 run_test 123ab "verify statahead work by using statx"
11760
11761 test_123ac() {
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763
11764         statx_supported || skip_env "Test must be statx() syscall supported"
11765
11766         local rpcs_before
11767         local rpcs_after
11768         local agl_before
11769         local agl_after
11770
11771         cancel_lru_locks $OSC
11772         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11773         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11774                 awk '/agl.total:/ {print $3}')
11775         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11776         test_123a_base "$STATX --cached=always -D"
11777         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11778                 awk '/agl.total:/ {print $3}')
11779         [ $agl_before -eq $agl_after ] ||
11780                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11781         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11782         [ $rpcs_after -eq $rpcs_before ] ||
11783                 error "$STATX should not send glimpse RPCs to $OSC"
11784 }
11785 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11786
11787 test_123b () { # statahead(bug 15027)
11788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11789
11790         test_mkdir $DIR/$tdir
11791         createmany -o $DIR/$tdir/$tfile-%d 1000
11792
11793         cancel_lru_locks mdc
11794         cancel_lru_locks osc
11795
11796 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11797         lctl set_param fail_loc=0x80000803
11798         ls -lR $DIR/$tdir > /dev/null
11799         log "ls done"
11800         lctl set_param fail_loc=0x0
11801         lctl get_param -n llite.*.statahead_stats
11802         rm -r $DIR/$tdir
11803         sync
11804
11805 }
11806 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11807
11808 test_123c() {
11809         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11810
11811         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11812         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11813         touch $DIR/$tdir.1/{1..3}
11814         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11815
11816         remount_client $MOUNT
11817
11818         $MULTIOP $DIR/$tdir.0 Q
11819
11820         # let statahead to complete
11821         ls -l $DIR/$tdir.0 > /dev/null
11822
11823         testid=$(echo $TESTNAME | tr '_' ' ')
11824         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11825                 error "statahead warning" || true
11826 }
11827 run_test 123c "Can not initialize inode warning on DNE statahead"
11828
11829 test_124a() {
11830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11831         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11832                 skip_env "no lru resize on server"
11833
11834         local NR=2000
11835
11836         test_mkdir $DIR/$tdir
11837
11838         log "create $NR files at $DIR/$tdir"
11839         createmany -o $DIR/$tdir/f $NR ||
11840                 error "failed to create $NR files in $DIR/$tdir"
11841
11842         cancel_lru_locks mdc
11843         ls -l $DIR/$tdir > /dev/null
11844
11845         local NSDIR=""
11846         local LRU_SIZE=0
11847         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11848                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11849                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11850                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11851                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11852                         log "NSDIR=$NSDIR"
11853                         log "NS=$(basename $NSDIR)"
11854                         break
11855                 fi
11856         done
11857
11858         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11859                 skip "Not enough cached locks created!"
11860         fi
11861         log "LRU=$LRU_SIZE"
11862
11863         local SLEEP=30
11864
11865         # We know that lru resize allows one client to hold $LIMIT locks
11866         # for 10h. After that locks begin to be killed by client.
11867         local MAX_HRS=10
11868         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11869         log "LIMIT=$LIMIT"
11870         if [ $LIMIT -lt $LRU_SIZE ]; then
11871                 skip "Limit is too small $LIMIT"
11872         fi
11873
11874         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11875         # killing locks. Some time was spent for creating locks. This means
11876         # that up to the moment of sleep finish we must have killed some of
11877         # them (10-100 locks). This depends on how fast ther were created.
11878         # Many of them were touched in almost the same moment and thus will
11879         # be killed in groups.
11880         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11881
11882         # Use $LRU_SIZE_B here to take into account real number of locks
11883         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11884         local LRU_SIZE_B=$LRU_SIZE
11885         log "LVF=$LVF"
11886         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11887         log "OLD_LVF=$OLD_LVF"
11888         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11889
11890         # Let's make sure that we really have some margin. Client checks
11891         # cached locks every 10 sec.
11892         SLEEP=$((SLEEP+20))
11893         log "Sleep ${SLEEP} sec"
11894         local SEC=0
11895         while ((SEC<$SLEEP)); do
11896                 echo -n "..."
11897                 sleep 5
11898                 SEC=$((SEC+5))
11899                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11900                 echo -n "$LRU_SIZE"
11901         done
11902         echo ""
11903         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11904         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11905
11906         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11907                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11908                 unlinkmany $DIR/$tdir/f $NR
11909                 return
11910         }
11911
11912         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11913         log "unlink $NR files at $DIR/$tdir"
11914         unlinkmany $DIR/$tdir/f $NR
11915 }
11916 run_test 124a "lru resize ======================================="
11917
11918 get_max_pool_limit()
11919 {
11920         local limit=$($LCTL get_param \
11921                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11922         local max=0
11923         for l in $limit; do
11924                 if [[ $l -gt $max ]]; then
11925                         max=$l
11926                 fi
11927         done
11928         echo $max
11929 }
11930
11931 test_124b() {
11932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11933         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11934                 skip_env "no lru resize on server"
11935
11936         LIMIT=$(get_max_pool_limit)
11937
11938         NR=$(($(default_lru_size)*20))
11939         if [[ $NR -gt $LIMIT ]]; then
11940                 log "Limit lock number by $LIMIT locks"
11941                 NR=$LIMIT
11942         fi
11943
11944         IFree=$(mdsrate_inodes_available)
11945         if [ $IFree -lt $NR ]; then
11946                 log "Limit lock number by $IFree inodes"
11947                 NR=$IFree
11948         fi
11949
11950         lru_resize_disable mdc
11951         test_mkdir -p $DIR/$tdir/disable_lru_resize
11952
11953         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11954         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11955         cancel_lru_locks mdc
11956         stime=`date +%s`
11957         PID=""
11958         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11959         PID="$PID $!"
11960         sleep 2
11961         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11962         PID="$PID $!"
11963         sleep 2
11964         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11965         PID="$PID $!"
11966         wait $PID
11967         etime=`date +%s`
11968         nolruresize_delta=$((etime-stime))
11969         log "ls -la time: $nolruresize_delta seconds"
11970         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11971         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11972
11973         lru_resize_enable mdc
11974         test_mkdir -p $DIR/$tdir/enable_lru_resize
11975
11976         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11977         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11978         cancel_lru_locks mdc
11979         stime=`date +%s`
11980         PID=""
11981         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11982         PID="$PID $!"
11983         sleep 2
11984         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11985         PID="$PID $!"
11986         sleep 2
11987         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11988         PID="$PID $!"
11989         wait $PID
11990         etime=`date +%s`
11991         lruresize_delta=$((etime-stime))
11992         log "ls -la time: $lruresize_delta seconds"
11993         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11994
11995         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11996                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11997         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11998                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11999         else
12000                 log "lru resize performs the same with no lru resize"
12001         fi
12002         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12003 }
12004 run_test 124b "lru resize (performance test) ======================="
12005
12006 test_124c() {
12007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12008         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12009                 skip_env "no lru resize on server"
12010
12011         # cache ununsed locks on client
12012         local nr=100
12013         cancel_lru_locks mdc
12014         test_mkdir $DIR/$tdir
12015         createmany -o $DIR/$tdir/f $nr ||
12016                 error "failed to create $nr files in $DIR/$tdir"
12017         ls -l $DIR/$tdir > /dev/null
12018
12019         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12020         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12021         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12022         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12023         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12024
12025         # set lru_max_age to 1 sec
12026         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12027         echo "sleep $((recalc_p * 2)) seconds..."
12028         sleep $((recalc_p * 2))
12029
12030         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12031         # restore lru_max_age
12032         $LCTL set_param -n $nsdir.lru_max_age $max_age
12033         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12034         unlinkmany $DIR/$tdir/f $nr
12035 }
12036 run_test 124c "LRUR cancel very aged locks"
12037
12038 test_124d() {
12039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12040         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12041                 skip_env "no lru resize on server"
12042
12043         # cache ununsed locks on client
12044         local nr=100
12045
12046         lru_resize_disable mdc
12047         stack_trap "lru_resize_enable mdc" EXIT
12048
12049         cancel_lru_locks mdc
12050
12051         # asynchronous object destroy at MDT could cause bl ast to client
12052         test_mkdir $DIR/$tdir
12053         createmany -o $DIR/$tdir/f $nr ||
12054                 error "failed to create $nr files in $DIR/$tdir"
12055         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12056
12057         ls -l $DIR/$tdir > /dev/null
12058
12059         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12060         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12061         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12062         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12063
12064         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12065
12066         # set lru_max_age to 1 sec
12067         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12068         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12069
12070         echo "sleep $((recalc_p * 2)) seconds..."
12071         sleep $((recalc_p * 2))
12072
12073         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12074
12075         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12076 }
12077 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12078
12079 test_125() { # 13358
12080         $LCTL get_param -n llite.*.client_type | grep -q local ||
12081                 skip "must run as local client"
12082         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12083                 skip_env "must have acl enabled"
12084         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12085
12086         test_mkdir $DIR/$tdir
12087         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12088         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12089         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12090 }
12091 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12092
12093 test_126() { # bug 12829/13455
12094         $GSS && skip_env "must run as gss disabled"
12095         $LCTL get_param -n llite.*.client_type | grep -q local ||
12096                 skip "must run as local client"
12097         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12098
12099         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12100         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12101         rm -f $DIR/$tfile
12102         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12103 }
12104 run_test 126 "check that the fsgid provided by the client is taken into account"
12105
12106 test_127a() { # bug 15521
12107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12108         local name count samp unit min max sum sumsq
12109
12110         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12111         echo "stats before reset"
12112         $LCTL get_param osc.*.stats
12113         $LCTL set_param osc.*.stats=0
12114         local fsize=$((2048 * 1024))
12115
12116         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12117         cancel_lru_locks osc
12118         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12119
12120         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12121         stack_trap "rm -f $TMP/$tfile.tmp"
12122         while read name count samp unit min max sum sumsq; do
12123                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12124                 [ ! $min ] && error "Missing min value for $name proc entry"
12125                 eval $name=$count || error "Wrong proc format"
12126
12127                 case $name in
12128                 read_bytes|write_bytes)
12129                         [[ "$unit" =~ "bytes" ]] ||
12130                                 error "unit is not 'bytes': $unit"
12131                         (( $min >= 4096 )) || error "min is too small: $min"
12132                         (( $min <= $fsize )) || error "min is too big: $min"
12133                         (( $max >= 4096 )) || error "max is too small: $max"
12134                         (( $max <= $fsize )) || error "max is too big: $max"
12135                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12136                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12137                                 error "sumsquare is too small: $sumsq"
12138                         (( $sumsq <= $fsize * $fsize )) ||
12139                                 error "sumsquare is too big: $sumsq"
12140                         ;;
12141                 ost_read|ost_write)
12142                         [[ "$unit" =~ "usec" ]] ||
12143                                 error "unit is not 'usec': $unit"
12144                         ;;
12145                 *)      ;;
12146                 esac
12147         done < $DIR/$tfile.tmp
12148
12149         #check that we actually got some stats
12150         [ "$read_bytes" ] || error "Missing read_bytes stats"
12151         [ "$write_bytes" ] || error "Missing write_bytes stats"
12152         [ "$read_bytes" != 0 ] || error "no read done"
12153         [ "$write_bytes" != 0 ] || error "no write done"
12154 }
12155 run_test 127a "verify the client stats are sane"
12156
12157 test_127b() { # bug LU-333
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         local name count samp unit min max sum sumsq
12160
12161         echo "stats before reset"
12162         $LCTL get_param llite.*.stats
12163         $LCTL set_param llite.*.stats=0
12164
12165         # perform 2 reads and writes so MAX is different from SUM.
12166         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12167         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12168         cancel_lru_locks osc
12169         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12170         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12171
12172         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12173         stack_trap "rm -f $TMP/$tfile.tmp"
12174         while read name count samp unit min max sum sumsq; do
12175                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12176                 eval $name=$count || error "Wrong proc format"
12177
12178                 case $name in
12179                 read_bytes|write_bytes)
12180                         [[ "$unit" =~ "bytes" ]] ||
12181                                 error "unit is not 'bytes': $unit"
12182                         (( $count == 2 )) || error "count is not 2: $count"
12183                         (( $min == $PAGE_SIZE )) ||
12184                                 error "min is not $PAGE_SIZE: $min"
12185                         (( $max == $PAGE_SIZE )) ||
12186                                 error "max is not $PAGE_SIZE: $max"
12187                         (( $sum == $PAGE_SIZE * 2 )) ||
12188                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12189                         ;;
12190                 read|write)
12191                         [[ "$unit" =~ "usec" ]] ||
12192                                 error "unit is not 'usec': $unit"
12193                         ;;
12194                 *)      ;;
12195                 esac
12196         done < $TMP/$tfile.tmp
12197
12198         #check that we actually got some stats
12199         [ "$read_bytes" ] || error "Missing read_bytes stats"
12200         [ "$write_bytes" ] || error "Missing write_bytes stats"
12201         [ "$read_bytes" != 0 ] || error "no read done"
12202         [ "$write_bytes" != 0 ] || error "no write done"
12203 }
12204 run_test 127b "verify the llite client stats are sane"
12205
12206 test_127c() { # LU-12394
12207         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12208         local size
12209         local bsize
12210         local reads
12211         local writes
12212         local count
12213
12214         $LCTL set_param llite.*.extents_stats=1
12215         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12216
12217         # Use two stripes so there is enough space in default config
12218         $LFS setstripe -c 2 $DIR/$tfile
12219
12220         # Extent stats start at 0-4K and go in power of two buckets
12221         # LL_HIST_START = 12 --> 2^12 = 4K
12222         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12223         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12224         # small configs
12225         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12226                 do
12227                 # Write and read, 2x each, second time at a non-zero offset
12228                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12229                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12230                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12231                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12232                 rm -f $DIR/$tfile
12233         done
12234
12235         $LCTL get_param llite.*.extents_stats
12236
12237         count=2
12238         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12239                 do
12240                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12241                                 grep -m 1 $bsize)
12242                 reads=$(echo $bucket | awk '{print $5}')
12243                 writes=$(echo $bucket | awk '{print $9}')
12244                 [ "$reads" -eq $count ] ||
12245                         error "$reads reads in < $bsize bucket, expect $count"
12246                 [ "$writes" -eq $count ] ||
12247                         error "$writes writes in < $bsize bucket, expect $count"
12248         done
12249
12250         # Test mmap write and read
12251         $LCTL set_param llite.*.extents_stats=c
12252         size=512
12253         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12254         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12255         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12256
12257         $LCTL get_param llite.*.extents_stats
12258
12259         count=$(((size*1024) / PAGE_SIZE))
12260
12261         bsize=$((2 * PAGE_SIZE / 1024))K
12262
12263         bucket=$($LCTL get_param -n llite.*.extents_stats |
12264                         grep -m 1 $bsize)
12265         reads=$(echo $bucket | awk '{print $5}')
12266         writes=$(echo $bucket | awk '{print $9}')
12267         # mmap writes fault in the page first, creating an additonal read
12268         [ "$reads" -eq $((2 * count)) ] ||
12269                 error "$reads reads in < $bsize bucket, expect $count"
12270         [ "$writes" -eq $count ] ||
12271                 error "$writes writes in < $bsize bucket, expect $count"
12272 }
12273 run_test 127c "test llite extent stats with regular & mmap i/o"
12274
12275 test_128() { # bug 15212
12276         touch $DIR/$tfile
12277         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12278                 find $DIR/$tfile
12279                 find $DIR/$tfile
12280         EOF
12281
12282         result=$(grep error $TMP/$tfile.log)
12283         rm -f $DIR/$tfile $TMP/$tfile.log
12284         [ -z "$result" ] ||
12285                 error "consecutive find's under interactive lfs failed"
12286 }
12287 run_test 128 "interactive lfs for 2 consecutive find's"
12288
12289 set_dir_limits () {
12290         local mntdev
12291         local canondev
12292         local node
12293
12294         local ldproc=/proc/fs/ldiskfs
12295         local facets=$(get_facets MDS)
12296
12297         for facet in ${facets//,/ }; do
12298                 canondev=$(ldiskfs_canon \
12299                            *.$(convert_facet2label $facet).mntdev $facet)
12300                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12301                         ldproc=/sys/fs/ldiskfs
12302                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12303                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12304         done
12305 }
12306
12307 check_mds_dmesg() {
12308         local facets=$(get_facets MDS)
12309         for facet in ${facets//,/ }; do
12310                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12311         done
12312         return 1
12313 }
12314
12315 test_129() {
12316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12317         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12318                 skip "Need MDS version with at least 2.5.56"
12319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12320                 skip_env "ldiskfs only test"
12321         fi
12322         remote_mds_nodsh && skip "remote MDS with nodsh"
12323
12324         local ENOSPC=28
12325         local has_warning=false
12326
12327         rm -rf $DIR/$tdir
12328         mkdir -p $DIR/$tdir
12329
12330         # block size of mds1
12331         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12332         set_dir_limits $maxsize $((maxsize * 6 / 8))
12333         stack_trap "set_dir_limits 0 0"
12334         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12335         local dirsize=$(stat -c%s "$DIR/$tdir")
12336         local nfiles=0
12337         while (( $dirsize <= $maxsize )); do
12338                 $MCREATE $DIR/$tdir/file_base_$nfiles
12339                 rc=$?
12340                 # check two errors:
12341                 # ENOSPC for ext4 max_dir_size, which has been used since
12342                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12343                 if (( rc == ENOSPC )); then
12344                         set_dir_limits 0 0
12345                         echo "rc=$rc returned as expected after $nfiles files"
12346
12347                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12348                                 error "create failed w/o dir size limit"
12349
12350                         # messages may be rate limited if test is run repeatedly
12351                         check_mds_dmesg '"is approaching max"' ||
12352                                 echo "warning message should be output"
12353                         check_mds_dmesg '"has reached max"' ||
12354                                 echo "reached message should be output"
12355
12356                         dirsize=$(stat -c%s "$DIR/$tdir")
12357
12358                         [[ $dirsize -ge $maxsize ]] && return 0
12359                         error "dirsize $dirsize < $maxsize after $nfiles files"
12360                 elif (( rc != 0 )); then
12361                         break
12362                 fi
12363                 nfiles=$((nfiles + 1))
12364                 dirsize=$(stat -c%s "$DIR/$tdir")
12365         done
12366
12367         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12368 }
12369 run_test 129 "test directory size limit ========================"
12370
12371 OLDIFS="$IFS"
12372 cleanup_130() {
12373         trap 0
12374         IFS="$OLDIFS"
12375 }
12376
12377 test_130a() {
12378         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12379         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12380
12381         trap cleanup_130 EXIT RETURN
12382
12383         local fm_file=$DIR/$tfile
12384         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12385         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12386                 error "dd failed for $fm_file"
12387
12388         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12389         filefrag -ves $fm_file
12390         RC=$?
12391         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12392                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12393         [ $RC != 0 ] && error "filefrag $fm_file failed"
12394
12395         filefrag_op=$(filefrag -ve -k $fm_file |
12396                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12397         lun=$($LFS getstripe -i $fm_file)
12398
12399         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12400         IFS=$'\n'
12401         tot_len=0
12402         for line in $filefrag_op
12403         do
12404                 frag_lun=`echo $line | cut -d: -f5`
12405                 ext_len=`echo $line | cut -d: -f4`
12406                 if (( $frag_lun != $lun )); then
12407                         cleanup_130
12408                         error "FIEMAP on 1-stripe file($fm_file) failed"
12409                         return
12410                 fi
12411                 (( tot_len += ext_len ))
12412         done
12413
12414         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12415                 cleanup_130
12416                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12417                 return
12418         fi
12419
12420         cleanup_130
12421
12422         echo "FIEMAP on single striped file succeeded"
12423 }
12424 run_test 130a "FIEMAP (1-stripe file)"
12425
12426 test_130b() {
12427         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12428
12429         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12430         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12431
12432         trap cleanup_130 EXIT RETURN
12433
12434         local fm_file=$DIR/$tfile
12435         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12436                         error "setstripe on $fm_file"
12437         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12438                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12439
12440         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12441                 error "dd failed on $fm_file"
12442
12443         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12444         filefrag_op=$(filefrag -ve -k $fm_file |
12445                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12446
12447         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12448                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12449
12450         IFS=$'\n'
12451         tot_len=0
12452         num_luns=1
12453         for line in $filefrag_op
12454         do
12455                 frag_lun=$(echo $line | cut -d: -f5 |
12456                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12457                 ext_len=$(echo $line | cut -d: -f4)
12458                 if (( $frag_lun != $last_lun )); then
12459                         if (( tot_len != 1024 )); then
12460                                 cleanup_130
12461                                 error "FIEMAP on $fm_file failed; returned " \
12462                                 "len $tot_len for OST $last_lun instead of 1024"
12463                                 return
12464                         else
12465                                 (( num_luns += 1 ))
12466                                 tot_len=0
12467                         fi
12468                 fi
12469                 (( tot_len += ext_len ))
12470                 last_lun=$frag_lun
12471         done
12472         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12473                 cleanup_130
12474                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12475                         "luns or wrong len for OST $last_lun"
12476                 return
12477         fi
12478
12479         cleanup_130
12480
12481         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12482 }
12483 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12484
12485 test_130c() {
12486         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12487
12488         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12489         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12490
12491         trap cleanup_130 EXIT RETURN
12492
12493         local fm_file=$DIR/$tfile
12494         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12495         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12496                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12497
12498         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12499                         error "dd failed on $fm_file"
12500
12501         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12502         filefrag_op=$(filefrag -ve -k $fm_file |
12503                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12504
12505         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12506                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12507
12508         IFS=$'\n'
12509         tot_len=0
12510         num_luns=1
12511         for line in $filefrag_op
12512         do
12513                 frag_lun=$(echo $line | cut -d: -f5 |
12514                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12515                 ext_len=$(echo $line | cut -d: -f4)
12516                 if (( $frag_lun != $last_lun )); then
12517                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12518                         if (( logical != 512 )); then
12519                                 cleanup_130
12520                                 error "FIEMAP on $fm_file failed; returned " \
12521                                 "logical start for lun $logical instead of 512"
12522                                 return
12523                         fi
12524                         if (( tot_len != 512 )); then
12525                                 cleanup_130
12526                                 error "FIEMAP on $fm_file failed; returned " \
12527                                 "len $tot_len for OST $last_lun instead of 1024"
12528                                 return
12529                         else
12530                                 (( num_luns += 1 ))
12531                                 tot_len=0
12532                         fi
12533                 fi
12534                 (( tot_len += ext_len ))
12535                 last_lun=$frag_lun
12536         done
12537         if (( num_luns != 2 || tot_len != 512 )); then
12538                 cleanup_130
12539                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12540                         "luns or wrong len for OST $last_lun"
12541                 return
12542         fi
12543
12544         cleanup_130
12545
12546         echo "FIEMAP on 2-stripe file with hole succeeded"
12547 }
12548 run_test 130c "FIEMAP (2-stripe file with hole)"
12549
12550 test_130d() {
12551         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12552
12553         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12554         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12555
12556         trap cleanup_130 EXIT RETURN
12557
12558         local fm_file=$DIR/$tfile
12559         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12560                         error "setstripe on $fm_file"
12561         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12562                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12563
12564         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12565         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12566                 error "dd failed on $fm_file"
12567
12568         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12569         filefrag_op=$(filefrag -ve -k $fm_file |
12570                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12571
12572         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12573                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12574
12575         IFS=$'\n'
12576         tot_len=0
12577         num_luns=1
12578         for line in $filefrag_op
12579         do
12580                 frag_lun=$(echo $line | cut -d: -f5 |
12581                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12582                 ext_len=$(echo $line | cut -d: -f4)
12583                 if (( $frag_lun != $last_lun )); then
12584                         if (( tot_len != 1024 )); then
12585                                 cleanup_130
12586                                 error "FIEMAP on $fm_file failed; returned " \
12587                                 "len $tot_len for OST $last_lun instead of 1024"
12588                                 return
12589                         else
12590                                 (( num_luns += 1 ))
12591                                 tot_len=0
12592                         fi
12593                 fi
12594                 (( tot_len += ext_len ))
12595                 last_lun=$frag_lun
12596         done
12597         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12598                 cleanup_130
12599                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12600                         "luns or wrong len for OST $last_lun"
12601                 return
12602         fi
12603
12604         cleanup_130
12605
12606         echo "FIEMAP on N-stripe file succeeded"
12607 }
12608 run_test 130d "FIEMAP (N-stripe file)"
12609
12610 test_130e() {
12611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12612
12613         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12614         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12615
12616         trap cleanup_130 EXIT RETURN
12617
12618         local fm_file=$DIR/$tfile
12619         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12620         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12621                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12622
12623         NUM_BLKS=512
12624         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12625         for ((i = 0; i < $NUM_BLKS; i++))
12626         do
12627                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12628         done
12629
12630         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12631         filefrag_op=$(filefrag -ve -k $fm_file |
12632                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12633
12634         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12635                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12636
12637         IFS=$'\n'
12638         tot_len=0
12639         num_luns=1
12640         for line in $filefrag_op
12641         do
12642                 frag_lun=$(echo $line | cut -d: -f5 |
12643                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12644                 ext_len=$(echo $line | cut -d: -f4)
12645                 if (( $frag_lun != $last_lun )); then
12646                         if (( tot_len != $EXPECTED_LEN )); then
12647                                 cleanup_130
12648                                 error "FIEMAP on $fm_file failed; returned " \
12649                                 "len $tot_len for OST $last_lun instead " \
12650                                 "of $EXPECTED_LEN"
12651                                 return
12652                         else
12653                                 (( num_luns += 1 ))
12654                                 tot_len=0
12655                         fi
12656                 fi
12657                 (( tot_len += ext_len ))
12658                 last_lun=$frag_lun
12659         done
12660         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12661                 cleanup_130
12662                 error "FIEMAP on $fm_file failed; returned wrong number " \
12663                         "of luns or wrong len for OST $last_lun"
12664                 return
12665         fi
12666
12667         cleanup_130
12668
12669         echo "FIEMAP with continuation calls succeeded"
12670 }
12671 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12672
12673 test_130f() {
12674         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12675         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12676
12677         local fm_file=$DIR/$tfile
12678         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12679                 error "multiop create with lov_delay_create on $fm_file"
12680
12681         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12682         filefrag_extents=$(filefrag -vek $fm_file |
12683                            awk '/extents? found/ { print $2 }')
12684         if [[ "$filefrag_extents" != "0" ]]; then
12685                 error "FIEMAP on $fm_file failed; " \
12686                       "returned $filefrag_extents expected 0"
12687         fi
12688
12689         rm -f $fm_file
12690 }
12691 run_test 130f "FIEMAP (unstriped file)"
12692
12693 # Test for writev/readv
12694 test_131a() {
12695         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12696                 error "writev test failed"
12697         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12698                 error "readv failed"
12699         rm -f $DIR/$tfile
12700 }
12701 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12702
12703 test_131b() {
12704         local fsize=$((524288 + 1048576 + 1572864))
12705         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12706                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12707                         error "append writev test failed"
12708
12709         ((fsize += 1572864 + 1048576))
12710         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12711                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12712                         error "append writev test failed"
12713         rm -f $DIR/$tfile
12714 }
12715 run_test 131b "test append writev"
12716
12717 test_131c() {
12718         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12719         error "NOT PASS"
12720 }
12721 run_test 131c "test read/write on file w/o objects"
12722
12723 test_131d() {
12724         rwv -f $DIR/$tfile -w -n 1 1572864
12725         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12726         if [ "$NOB" != 1572864 ]; then
12727                 error "Short read filed: read $NOB bytes instead of 1572864"
12728         fi
12729         rm -f $DIR/$tfile
12730 }
12731 run_test 131d "test short read"
12732
12733 test_131e() {
12734         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12735         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12736         error "read hitting hole failed"
12737         rm -f $DIR/$tfile
12738 }
12739 run_test 131e "test read hitting hole"
12740
12741 check_stats() {
12742         local facet=$1
12743         local op=$2
12744         local want=${3:-0}
12745         local res
12746
12747         case $facet in
12748         mds*) res=$(do_facet $facet \
12749                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12750                  ;;
12751         ost*) res=$(do_facet $facet \
12752                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12753                  ;;
12754         *) error "Wrong facet '$facet'" ;;
12755         esac
12756         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12757         # if the argument $3 is zero, it means any stat increment is ok.
12758         if [[ $want -gt 0 ]]; then
12759                 local count=$(echo $res | awk '{ print $2 }')
12760                 [[ $count -ne $want ]] &&
12761                         error "The $op counter on $facet is $count, not $want"
12762         fi
12763 }
12764
12765 test_133a() {
12766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12767         remote_ost_nodsh && skip "remote OST with nodsh"
12768         remote_mds_nodsh && skip "remote MDS with nodsh"
12769         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12770                 skip_env "MDS doesn't support rename stats"
12771
12772         local testdir=$DIR/${tdir}/stats_testdir
12773
12774         mkdir -p $DIR/${tdir}
12775
12776         # clear stats.
12777         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12778         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12779
12780         # verify mdt stats first.
12781         mkdir ${testdir} || error "mkdir failed"
12782         check_stats $SINGLEMDS "mkdir" 1
12783         touch ${testdir}/${tfile} || error "touch failed"
12784         check_stats $SINGLEMDS "open" 1
12785         check_stats $SINGLEMDS "close" 1
12786         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12787                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12788                 check_stats $SINGLEMDS "mknod" 2
12789         }
12790         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12791         check_stats $SINGLEMDS "unlink" 1
12792         rm -f ${testdir}/${tfile} || error "file remove failed"
12793         check_stats $SINGLEMDS "unlink" 2
12794
12795         # remove working dir and check mdt stats again.
12796         rmdir ${testdir} || error "rmdir failed"
12797         check_stats $SINGLEMDS "rmdir" 1
12798
12799         local testdir1=$DIR/${tdir}/stats_testdir1
12800         mkdir -p ${testdir}
12801         mkdir -p ${testdir1}
12802         touch ${testdir1}/test1
12803         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12804         check_stats $SINGLEMDS "crossdir_rename" 1
12805
12806         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12807         check_stats $SINGLEMDS "samedir_rename" 1
12808
12809         rm -rf $DIR/${tdir}
12810 }
12811 run_test 133a "Verifying MDT stats ========================================"
12812
12813 test_133b() {
12814         local res
12815
12816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12817         remote_ost_nodsh && skip "remote OST with nodsh"
12818         remote_mds_nodsh && skip "remote MDS with nodsh"
12819
12820         local testdir=$DIR/${tdir}/stats_testdir
12821
12822         mkdir -p ${testdir} || error "mkdir failed"
12823         touch ${testdir}/${tfile} || error "touch failed"
12824         cancel_lru_locks mdc
12825
12826         # clear stats.
12827         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12828         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12829
12830         # extra mdt stats verification.
12831         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12832         check_stats $SINGLEMDS "setattr" 1
12833         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12834         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12835         then            # LU-1740
12836                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12837                 check_stats $SINGLEMDS "getattr" 1
12838         fi
12839         rm -rf $DIR/${tdir}
12840
12841         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12842         # so the check below is not reliable
12843         [ $MDSCOUNT -eq 1 ] || return 0
12844
12845         # Sleep to avoid a cached response.
12846         #define OBD_STATFS_CACHE_SECONDS 1
12847         sleep 2
12848         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12849         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12850         $LFS df || error "lfs failed"
12851         check_stats $SINGLEMDS "statfs" 1
12852
12853         # check aggregated statfs (LU-10018)
12854         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12855                 return 0
12856         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12857                 return 0
12858         sleep 2
12859         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12860         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12861         df $DIR
12862         check_stats $SINGLEMDS "statfs" 1
12863
12864         # We want to check that the client didn't send OST_STATFS to
12865         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12866         # extra care is needed here.
12867         if remote_mds; then
12868                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12869                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12870
12871                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12872                 [ "$res" ] && error "OST got STATFS"
12873         fi
12874
12875         return 0
12876 }
12877 run_test 133b "Verifying extra MDT stats =================================="
12878
12879 test_133c() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_ost_nodsh && skip "remote OST with nodsh"
12882         remote_mds_nodsh && skip "remote MDS with nodsh"
12883
12884         local testdir=$DIR/$tdir/stats_testdir
12885
12886         test_mkdir -p $testdir
12887
12888         # verify obdfilter stats.
12889         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12890         sync
12891         cancel_lru_locks osc
12892         wait_delete_completed
12893
12894         # clear stats.
12895         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12896         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12897
12898         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12899                 error "dd failed"
12900         sync
12901         cancel_lru_locks osc
12902         check_stats ost1 "write" 1
12903
12904         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12905         check_stats ost1 "read" 1
12906
12907         > $testdir/$tfile || error "truncate failed"
12908         check_stats ost1 "punch" 1
12909
12910         rm -f $testdir/$tfile || error "file remove failed"
12911         wait_delete_completed
12912         check_stats ost1 "destroy" 1
12913
12914         rm -rf $DIR/$tdir
12915 }
12916 run_test 133c "Verifying OST stats ========================================"
12917
12918 order_2() {
12919         local value=$1
12920         local orig=$value
12921         local order=1
12922
12923         while [ $value -ge 2 ]; do
12924                 order=$((order*2))
12925                 value=$((value/2))
12926         done
12927
12928         if [ $orig -gt $order ]; then
12929                 order=$((order*2))
12930         fi
12931         echo $order
12932 }
12933
12934 size_in_KMGT() {
12935     local value=$1
12936     local size=('K' 'M' 'G' 'T');
12937     local i=0
12938     local size_string=$value
12939
12940     while [ $value -ge 1024 ]; do
12941         if [ $i -gt 3 ]; then
12942             #T is the biggest unit we get here, if that is bigger,
12943             #just return XXXT
12944             size_string=${value}T
12945             break
12946         fi
12947         value=$((value >> 10))
12948         if [ $value -lt 1024 ]; then
12949             size_string=${value}${size[$i]}
12950             break
12951         fi
12952         i=$((i + 1))
12953     done
12954
12955     echo $size_string
12956 }
12957
12958 get_rename_size() {
12959         local size=$1
12960         local context=${2:-.}
12961         local sample=$(do_facet $SINGLEMDS $LCTL \
12962                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12963                 grep -A1 $context |
12964                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12965         echo $sample
12966 }
12967
12968 test_133d() {
12969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12970         remote_ost_nodsh && skip "remote OST with nodsh"
12971         remote_mds_nodsh && skip "remote MDS with nodsh"
12972         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12973                 skip_env "MDS doesn't support rename stats"
12974
12975         local testdir1=$DIR/${tdir}/stats_testdir1
12976         local testdir2=$DIR/${tdir}/stats_testdir2
12977         mkdir -p $DIR/${tdir}
12978
12979         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12980
12981         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12982         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12983
12984         createmany -o $testdir1/test 512 || error "createmany failed"
12985
12986         # check samedir rename size
12987         mv ${testdir1}/test0 ${testdir1}/test_0
12988
12989         local testdir1_size=$(ls -l $DIR/${tdir} |
12990                 awk '/stats_testdir1/ {print $5}')
12991         local testdir2_size=$(ls -l $DIR/${tdir} |
12992                 awk '/stats_testdir2/ {print $5}')
12993
12994         testdir1_size=$(order_2 $testdir1_size)
12995         testdir2_size=$(order_2 $testdir2_size)
12996
12997         testdir1_size=$(size_in_KMGT $testdir1_size)
12998         testdir2_size=$(size_in_KMGT $testdir2_size)
12999
13000         echo "source rename dir size: ${testdir1_size}"
13001         echo "target rename dir size: ${testdir2_size}"
13002
13003         local cmd="do_facet $SINGLEMDS $LCTL "
13004         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13005
13006         eval $cmd || error "$cmd failed"
13007         local samedir=$($cmd | grep 'same_dir')
13008         local same_sample=$(get_rename_size $testdir1_size)
13009         [ -z "$samedir" ] && error "samedir_rename_size count error"
13010         [[ $same_sample -eq 1 ]] ||
13011                 error "samedir_rename_size error $same_sample"
13012         echo "Check same dir rename stats success"
13013
13014         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13015
13016         # check crossdir rename size
13017         mv ${testdir1}/test_0 ${testdir2}/test_0
13018
13019         testdir1_size=$(ls -l $DIR/${tdir} |
13020                 awk '/stats_testdir1/ {print $5}')
13021         testdir2_size=$(ls -l $DIR/${tdir} |
13022                 awk '/stats_testdir2/ {print $5}')
13023
13024         testdir1_size=$(order_2 $testdir1_size)
13025         testdir2_size=$(order_2 $testdir2_size)
13026
13027         testdir1_size=$(size_in_KMGT $testdir1_size)
13028         testdir2_size=$(size_in_KMGT $testdir2_size)
13029
13030         echo "source rename dir size: ${testdir1_size}"
13031         echo "target rename dir size: ${testdir2_size}"
13032
13033         eval $cmd || error "$cmd failed"
13034         local crossdir=$($cmd | grep 'crossdir')
13035         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13036         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13037         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13038         [[ $src_sample -eq 1 ]] ||
13039                 error "crossdir_rename_size error $src_sample"
13040         [[ $tgt_sample -eq 1 ]] ||
13041                 error "crossdir_rename_size error $tgt_sample"
13042         echo "Check cross dir rename stats success"
13043         rm -rf $DIR/${tdir}
13044 }
13045 run_test 133d "Verifying rename_stats ========================================"
13046
13047 test_133e() {
13048         remote_mds_nodsh && skip "remote MDS with nodsh"
13049         remote_ost_nodsh && skip "remote OST with nodsh"
13050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13051
13052         local testdir=$DIR/${tdir}/stats_testdir
13053         local ctr f0 f1 bs=32768 count=42 sum
13054
13055         mkdir -p ${testdir} || error "mkdir failed"
13056
13057         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13058
13059         for ctr in {write,read}_bytes; do
13060                 sync
13061                 cancel_lru_locks osc
13062
13063                 do_facet ost1 $LCTL set_param -n \
13064                         "obdfilter.*.exports.clear=clear"
13065
13066                 if [ $ctr = write_bytes ]; then
13067                         f0=/dev/zero
13068                         f1=${testdir}/${tfile}
13069                 else
13070                         f0=${testdir}/${tfile}
13071                         f1=/dev/null
13072                 fi
13073
13074                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13075                         error "dd failed"
13076                 sync
13077                 cancel_lru_locks osc
13078
13079                 sum=$(do_facet ost1 $LCTL get_param \
13080                         "obdfilter.*.exports.*.stats" |
13081                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13082                                 $1 == ctr { sum += $7 }
13083                                 END { printf("%0.0f", sum) }')
13084
13085                 if ((sum != bs * count)); then
13086                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13087                 fi
13088         done
13089
13090         rm -rf $DIR/${tdir}
13091 }
13092 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13093
13094 test_133f() {
13095         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13096                 skip "too old lustre for get_param -R ($facet_ver)"
13097
13098         # verifying readability.
13099         $LCTL get_param -R '*' &> /dev/null
13100
13101         # Verifing writability with badarea_io.
13102         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13103                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13104                 error "client badarea_io failed"
13105
13106         # remount the FS in case writes/reads /proc break the FS
13107         cleanup || error "failed to unmount"
13108         setup || error "failed to setup"
13109 }
13110 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13111
13112 test_133g() {
13113         remote_mds_nodsh && skip "remote MDS with nodsh"
13114         remote_ost_nodsh && skip "remote OST with nodsh"
13115
13116         local facet
13117         for facet in mds1 ost1; do
13118                 local facet_ver=$(lustre_version_code $facet)
13119                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13120                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13121                 else
13122                         log "$facet: too old lustre for get_param -R"
13123                 fi
13124                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13125                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13126                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13127                                 xargs badarea_io" ||
13128                                         error "$facet badarea_io failed"
13129                 else
13130                         skip_noexit "$facet: too old lustre for get_param -R"
13131                 fi
13132         done
13133
13134         # remount the FS in case writes/reads /proc break the FS
13135         cleanup || error "failed to unmount"
13136         setup || error "failed to setup"
13137 }
13138 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13139
13140 test_133h() {
13141         remote_mds_nodsh && skip "remote MDS with nodsh"
13142         remote_ost_nodsh && skip "remote OST with nodsh"
13143         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13144                 skip "Need MDS version at least 2.9.54"
13145
13146         local facet
13147         for facet in client mds1 ost1; do
13148                 # Get the list of files that are missing the terminating newline
13149                 local plist=$(do_facet $facet
13150                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13151                 local ent
13152                 for ent in $plist; do
13153                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13154                                 awk -v FS='\v' -v RS='\v\v' \
13155                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13156                                         print FILENAME}'" 2>/dev/null)
13157                         [ -z $missing ] || {
13158                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13159                                 error "file does not end with newline: $facet-$ent"
13160                         }
13161                 done
13162         done
13163 }
13164 run_test 133h "Proc files should end with newlines"
13165
13166 test_134a() {
13167         remote_mds_nodsh && skip "remote MDS with nodsh"
13168         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13169                 skip "Need MDS version at least 2.7.54"
13170
13171         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13172         cancel_lru_locks mdc
13173
13174         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13175         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13176         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13177
13178         local nr=1000
13179         createmany -o $DIR/$tdir/f $nr ||
13180                 error "failed to create $nr files in $DIR/$tdir"
13181         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13182
13183         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13184         do_facet mds1 $LCTL set_param fail_loc=0x327
13185         do_facet mds1 $LCTL set_param fail_val=500
13186         touch $DIR/$tdir/m
13187
13188         echo "sleep 10 seconds ..."
13189         sleep 10
13190         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13191
13192         do_facet mds1 $LCTL set_param fail_loc=0
13193         do_facet mds1 $LCTL set_param fail_val=0
13194         [ $lck_cnt -lt $unused ] ||
13195                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13196
13197         rm $DIR/$tdir/m
13198         unlinkmany $DIR/$tdir/f $nr
13199 }
13200 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13201
13202 test_134b() {
13203         remote_mds_nodsh && skip "remote MDS with nodsh"
13204         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13205                 skip "Need MDS version at least 2.7.54"
13206
13207         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13208         cancel_lru_locks mdc
13209
13210         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13211                         ldlm.lock_reclaim_threshold_mb)
13212         # disable reclaim temporarily
13213         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13214
13215         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13216         do_facet mds1 $LCTL set_param fail_loc=0x328
13217         do_facet mds1 $LCTL set_param fail_val=500
13218
13219         $LCTL set_param debug=+trace
13220
13221         local nr=600
13222         createmany -o $DIR/$tdir/f $nr &
13223         local create_pid=$!
13224
13225         echo "Sleep $TIMEOUT seconds ..."
13226         sleep $TIMEOUT
13227         if ! ps -p $create_pid  > /dev/null 2>&1; then
13228                 do_facet mds1 $LCTL set_param fail_loc=0
13229                 do_facet mds1 $LCTL set_param fail_val=0
13230                 do_facet mds1 $LCTL set_param \
13231                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13232                 error "createmany finished incorrectly!"
13233         fi
13234         do_facet mds1 $LCTL set_param fail_loc=0
13235         do_facet mds1 $LCTL set_param fail_val=0
13236         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13237         wait $create_pid || return 1
13238
13239         unlinkmany $DIR/$tdir/f $nr
13240 }
13241 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13242
13243 test_135() {
13244         remote_mds_nodsh && skip "remote MDS with nodsh"
13245         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13246                 skip "Need MDS version at least 2.13.50"
13247         local fname
13248
13249         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13250
13251 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13252         #set only one record at plain llog
13253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13254
13255         #fill already existed plain llog each 64767
13256         #wrapping whole catalog
13257         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13258
13259         createmany -o $DIR/$tdir/$tfile_ 64700
13260         for (( i = 0; i < 64700; i = i + 2 ))
13261         do
13262                 rm $DIR/$tdir/$tfile_$i &
13263                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13264                 local pid=$!
13265                 wait $pid
13266         done
13267
13268         #waiting osp synchronization
13269         wait_delete_completed
13270 }
13271 run_test 135 "Race catalog processing"
13272
13273 test_136() {
13274         remote_mds_nodsh && skip "remote MDS with nodsh"
13275         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13276                 skip "Need MDS version at least 2.13.50"
13277         local fname
13278
13279         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13280         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13281         #set only one record at plain llog
13282 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13283         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13284
13285         #fill already existed 2 plain llogs each 64767
13286         #wrapping whole catalog
13287         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13288         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13289         wait_delete_completed
13290
13291         createmany -o $DIR/$tdir/$tfile_ 10
13292         sleep 25
13293
13294         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13295         for (( i = 0; i < 10; i = i + 3 ))
13296         do
13297                 rm $DIR/$tdir/$tfile_$i &
13298                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13299                 local pid=$!
13300                 wait $pid
13301                 sleep 7
13302                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13303         done
13304
13305         #waiting osp synchronization
13306         wait_delete_completed
13307 }
13308 run_test 136 "Race catalog processing 2"
13309
13310 test_140() { #bug-17379
13311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13312
13313         test_mkdir $DIR/$tdir
13314         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13315         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13316
13317         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13318         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13319         local i=0
13320         while i=$((i + 1)); do
13321                 test_mkdir $i
13322                 cd $i || error "Changing to $i"
13323                 ln -s ../stat stat || error "Creating stat symlink"
13324                 # Read the symlink until ELOOP present,
13325                 # not LBUGing the system is considered success,
13326                 # we didn't overrun the stack.
13327                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13328                 if [ $ret -ne 0 ]; then
13329                         if [ $ret -eq 40 ]; then
13330                                 break  # -ELOOP
13331                         else
13332                                 error "Open stat symlink"
13333                                         return
13334                         fi
13335                 fi
13336         done
13337         i=$((i - 1))
13338         echo "The symlink depth = $i"
13339         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13340                 error "Invalid symlink depth"
13341
13342         # Test recursive symlink
13343         ln -s symlink_self symlink_self
13344         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13345         echo "open symlink_self returns $ret"
13346         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13347 }
13348 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13349
13350 test_150a() {
13351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13352
13353         local TF="$TMP/$tfile"
13354
13355         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13356         cp $TF $DIR/$tfile
13357         cancel_lru_locks $OSC
13358         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13359         remount_client $MOUNT
13360         df -P $MOUNT
13361         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13362
13363         $TRUNCATE $TF 6000
13364         $TRUNCATE $DIR/$tfile 6000
13365         cancel_lru_locks $OSC
13366         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13367
13368         echo "12345" >>$TF
13369         echo "12345" >>$DIR/$tfile
13370         cancel_lru_locks $OSC
13371         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13372
13373         echo "12345" >>$TF
13374         echo "12345" >>$DIR/$tfile
13375         cancel_lru_locks $OSC
13376         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13377
13378         rm -f $TF
13379         true
13380 }
13381 run_test 150a "truncate/append tests"
13382
13383 test_150b() {
13384         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13385         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13386                 skip "Need OST version at least 2.13.53"
13387         touch $DIR/$tfile
13388         check_fallocate $DIR/$tfile || error "fallocate failed"
13389 }
13390 run_test 150b "Verify fallocate (prealloc) functionality"
13391
13392 test_150c() {
13393         local bytes
13394         local want
13395
13396         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13397         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13398                 skip "Need OST version at least 2.13.53"
13399
13400         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13401         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13402         sync; sync_all_data
13403         cancel_lru_locks $OSC
13404         sleep 5
13405         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13406         want=$((OSTCOUNT * 1048576))
13407
13408         # Must allocate all requested space, not more than 5% extra
13409         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13410                 error "bytes $bytes is not $want"
13411 }
13412 run_test 150c "Verify fallocate Size and Blocks"
13413
13414 test_150d() {
13415         local bytes
13416         local want
13417
13418         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13419         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13420                 skip "Need OST version at least 2.13.53"
13421
13422         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13423         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13424         sync; sync_all_data
13425         cancel_lru_locks $OSC
13426         sleep 5
13427         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13428         want=$((OSTCOUNT * 1048576))
13429
13430         # Must allocate all requested space, not more than 5% extra
13431         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13432                 error "bytes $bytes is not $want"
13433 }
13434 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13435
13436 test_150e() {
13437         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13438         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13439                 skip "Need OST version at least 2.13.55"
13440
13441         echo "df before:"
13442         $LFS df
13443         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13444                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13445
13446         # Find OST with Minimum Size
13447         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13448                        sort -un | head -1)
13449
13450         # Get 90% of the available space
13451         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13452
13453         fallocate -l${space}k $DIR/$tfile ||
13454                 error "fallocate ${space}k $DIR/$tfile failed"
13455         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13456
13457         # get size immediately after fallocate. This should be correctly
13458         # updated
13459         local size=$(stat -c '%s' $DIR/$tfile)
13460         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13461
13462         # Sleep for a while for statfs to get updated. And not pull from cache.
13463         sleep 2
13464
13465         echo "df after fallocate:"
13466         $LFS df
13467
13468         (( size / 1024 == space )) || error "size $size != requested $space"
13469         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13470                 error "used $used < space $space"
13471
13472         rm $DIR/$tfile || error "rm failed"
13473         sync
13474         wait_delete_completed
13475
13476         echo "df after unlink:"
13477         $LFS df
13478 }
13479 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13480
13481 #LU-2902 roc_hit was not able to read all values from lproc
13482 function roc_hit_init() {
13483         local list=$(comma_list $(osts_nodes))
13484         local dir=$DIR/$tdir-check
13485         local file=$dir/$tfile
13486         local BEFORE
13487         local AFTER
13488         local idx
13489
13490         test_mkdir $dir
13491         #use setstripe to do a write to every ost
13492         for i in $(seq 0 $((OSTCOUNT-1))); do
13493                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13494                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13495                 idx=$(printf %04x $i)
13496                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13497                         awk '$1 == "cache_access" {sum += $7}
13498                                 END { printf("%0.0f", sum) }')
13499
13500                 cancel_lru_locks osc
13501                 cat $file >/dev/null
13502
13503                 AFTER=$(get_osd_param $list *OST*$idx stats |
13504                         awk '$1 == "cache_access" {sum += $7}
13505                                 END { printf("%0.0f", sum) }')
13506
13507                 echo BEFORE:$BEFORE AFTER:$AFTER
13508                 if ! let "AFTER - BEFORE == 4"; then
13509                         rm -rf $dir
13510                         error "roc_hit is not safe to use"
13511                 fi
13512                 rm $file
13513         done
13514
13515         rm -rf $dir
13516 }
13517
13518 function roc_hit() {
13519         local list=$(comma_list $(osts_nodes))
13520         echo $(get_osd_param $list '' stats |
13521                 awk '$1 == "cache_hit" {sum += $7}
13522                         END { printf("%0.0f", sum) }')
13523 }
13524
13525 function set_cache() {
13526         local on=1
13527
13528         if [ "$2" == "off" ]; then
13529                 on=0;
13530         fi
13531         local list=$(comma_list $(osts_nodes))
13532         set_osd_param $list '' $1_cache_enable $on
13533
13534         cancel_lru_locks osc
13535 }
13536
13537 test_151() {
13538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13539         remote_ost_nodsh && skip "remote OST with nodsh"
13540
13541         local CPAGES=3
13542         local list=$(comma_list $(osts_nodes))
13543
13544         # check whether obdfilter is cache capable at all
13545         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13546                 skip "not cache-capable obdfilter"
13547         fi
13548
13549         # check cache is enabled on all obdfilters
13550         if get_osd_param $list '' read_cache_enable | grep 0; then
13551                 skip "oss cache is disabled"
13552         fi
13553
13554         set_osd_param $list '' writethrough_cache_enable 1
13555
13556         # check write cache is enabled on all obdfilters
13557         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13558                 skip "oss write cache is NOT enabled"
13559         fi
13560
13561         roc_hit_init
13562
13563         #define OBD_FAIL_OBD_NO_LRU  0x609
13564         do_nodes $list $LCTL set_param fail_loc=0x609
13565
13566         # pages should be in the case right after write
13567         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13568                 error "dd failed"
13569
13570         local BEFORE=$(roc_hit)
13571         cancel_lru_locks osc
13572         cat $DIR/$tfile >/dev/null
13573         local AFTER=$(roc_hit)
13574
13575         do_nodes $list $LCTL set_param fail_loc=0
13576
13577         if ! let "AFTER - BEFORE == CPAGES"; then
13578                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13579         fi
13580
13581         cancel_lru_locks osc
13582         # invalidates OST cache
13583         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13584         set_osd_param $list '' read_cache_enable 0
13585         cat $DIR/$tfile >/dev/null
13586
13587         # now data shouldn't be found in the cache
13588         BEFORE=$(roc_hit)
13589         cancel_lru_locks osc
13590         cat $DIR/$tfile >/dev/null
13591         AFTER=$(roc_hit)
13592         if let "AFTER - BEFORE != 0"; then
13593                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13594         fi
13595
13596         set_osd_param $list '' read_cache_enable 1
13597         rm -f $DIR/$tfile
13598 }
13599 run_test 151 "test cache on oss and controls ==============================="
13600
13601 test_152() {
13602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13603
13604         local TF="$TMP/$tfile"
13605
13606         # simulate ENOMEM during write
13607 #define OBD_FAIL_OST_NOMEM      0x226
13608         lctl set_param fail_loc=0x80000226
13609         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13610         cp $TF $DIR/$tfile
13611         sync || error "sync failed"
13612         lctl set_param fail_loc=0
13613
13614         # discard client's cache
13615         cancel_lru_locks osc
13616
13617         # simulate ENOMEM during read
13618         lctl set_param fail_loc=0x80000226
13619         cmp $TF $DIR/$tfile || error "cmp failed"
13620         lctl set_param fail_loc=0
13621
13622         rm -f $TF
13623 }
13624 run_test 152 "test read/write with enomem ============================"
13625
13626 test_153() {
13627         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13628 }
13629 run_test 153 "test if fdatasync does not crash ======================="
13630
13631 dot_lustre_fid_permission_check() {
13632         local fid=$1
13633         local ffid=$MOUNT/.lustre/fid/$fid
13634         local test_dir=$2
13635
13636         echo "stat fid $fid"
13637         stat $ffid > /dev/null || error "stat $ffid failed."
13638         echo "touch fid $fid"
13639         touch $ffid || error "touch $ffid failed."
13640         echo "write to fid $fid"
13641         cat /etc/hosts > $ffid || error "write $ffid failed."
13642         echo "read fid $fid"
13643         diff /etc/hosts $ffid || error "read $ffid failed."
13644         echo "append write to fid $fid"
13645         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13646         echo "rename fid $fid"
13647         mv $ffid $test_dir/$tfile.1 &&
13648                 error "rename $ffid to $tfile.1 should fail."
13649         touch $test_dir/$tfile.1
13650         mv $test_dir/$tfile.1 $ffid &&
13651                 error "rename $tfile.1 to $ffid should fail."
13652         rm -f $test_dir/$tfile.1
13653         echo "truncate fid $fid"
13654         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13655         echo "link fid $fid"
13656         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13657         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13658                 echo "setfacl fid $fid"
13659                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13660                 echo "getfacl fid $fid"
13661                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13662         fi
13663         echo "unlink fid $fid"
13664         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13665         echo "mknod fid $fid"
13666         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13667
13668         fid=[0xf00000400:0x1:0x0]
13669         ffid=$MOUNT/.lustre/fid/$fid
13670
13671         echo "stat non-exist fid $fid"
13672         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13673         echo "write to non-exist fid $fid"
13674         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13675         echo "link new fid $fid"
13676         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13677
13678         mkdir -p $test_dir/$tdir
13679         touch $test_dir/$tdir/$tfile
13680         fid=$($LFS path2fid $test_dir/$tdir)
13681         rc=$?
13682         [ $rc -ne 0 ] &&
13683                 error "error: could not get fid for $test_dir/$dir/$tfile."
13684
13685         ffid=$MOUNT/.lustre/fid/$fid
13686
13687         echo "ls $fid"
13688         ls $ffid > /dev/null || error "ls $ffid failed."
13689         echo "touch $fid/$tfile.1"
13690         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13691
13692         echo "touch $MOUNT/.lustre/fid/$tfile"
13693         touch $MOUNT/.lustre/fid/$tfile && \
13694                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13695
13696         echo "setxattr to $MOUNT/.lustre/fid"
13697         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13698
13699         echo "listxattr for $MOUNT/.lustre/fid"
13700         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13701
13702         echo "delxattr from $MOUNT/.lustre/fid"
13703         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13704
13705         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13706         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13707                 error "touch invalid fid should fail."
13708
13709         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13710         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13711                 error "touch non-normal fid should fail."
13712
13713         echo "rename $tdir to $MOUNT/.lustre/fid"
13714         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13715                 error "rename to $MOUNT/.lustre/fid should fail."
13716
13717         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13718         then            # LU-3547
13719                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13720                 local new_obf_mode=777
13721
13722                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13723                 chmod $new_obf_mode $DIR/.lustre/fid ||
13724                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13725
13726                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13727                 [ $obf_mode -eq $new_obf_mode ] ||
13728                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13729
13730                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13731                 chmod $old_obf_mode $DIR/.lustre/fid ||
13732                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13733         fi
13734
13735         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13736         fid=$($LFS path2fid $test_dir/$tfile-2)
13737
13738         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13739         then # LU-5424
13740                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13741                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13742                         error "create lov data thru .lustre failed"
13743         fi
13744         echo "cp /etc/passwd $test_dir/$tfile-2"
13745         cp /etc/passwd $test_dir/$tfile-2 ||
13746                 error "copy to $test_dir/$tfile-2 failed."
13747         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13748         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13749                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13750
13751         rm -rf $test_dir/tfile.lnk
13752         rm -rf $test_dir/$tfile-2
13753 }
13754
13755 test_154A() {
13756         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13757                 skip "Need MDS version at least 2.4.1"
13758
13759         local tf=$DIR/$tfile
13760         touch $tf
13761
13762         local fid=$($LFS path2fid $tf)
13763         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13764
13765         # check that we get the same pathname back
13766         local rootpath
13767         local found
13768         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13769                 echo "$rootpath $fid"
13770                 found=$($LFS fid2path $rootpath "$fid")
13771                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13772                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13773         done
13774
13775         # check wrong root path format
13776         rootpath=$MOUNT"_wrong"
13777         found=$($LFS fid2path $rootpath "$fid")
13778         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13779 }
13780 run_test 154A "lfs path2fid and fid2path basic checks"
13781
13782 test_154B() {
13783         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13784                 skip "Need MDS version at least 2.4.1"
13785
13786         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13787         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13788         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13789         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13790
13791         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13792         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13793
13794         # check that we get the same pathname
13795         echo "PFID: $PFID, name: $name"
13796         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13797         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13798         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13799                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13800
13801         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13802 }
13803 run_test 154B "verify the ll_decode_linkea tool"
13804
13805 test_154a() {
13806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13807         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13808         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13809                 skip "Need MDS version at least 2.2.51"
13810         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13811
13812         cp /etc/hosts $DIR/$tfile
13813
13814         fid=$($LFS path2fid $DIR/$tfile)
13815         rc=$?
13816         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13817
13818         dot_lustre_fid_permission_check "$fid" $DIR ||
13819                 error "dot lustre permission check $fid failed"
13820
13821         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13822
13823         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13824
13825         touch $MOUNT/.lustre/file &&
13826                 error "creation is not allowed under .lustre"
13827
13828         mkdir $MOUNT/.lustre/dir &&
13829                 error "mkdir is not allowed under .lustre"
13830
13831         rm -rf $DIR/$tfile
13832 }
13833 run_test 154a "Open-by-FID"
13834
13835 test_154b() {
13836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13837         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13838         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13839         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13840                 skip "Need MDS version at least 2.2.51"
13841
13842         local remote_dir=$DIR/$tdir/remote_dir
13843         local MDTIDX=1
13844         local rc=0
13845
13846         mkdir -p $DIR/$tdir
13847         $LFS mkdir -i $MDTIDX $remote_dir ||
13848                 error "create remote directory failed"
13849
13850         cp /etc/hosts $remote_dir/$tfile
13851
13852         fid=$($LFS path2fid $remote_dir/$tfile)
13853         rc=$?
13854         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13855
13856         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13857                 error "dot lustre permission check $fid failed"
13858         rm -rf $DIR/$tdir
13859 }
13860 run_test 154b "Open-by-FID for remote directory"
13861
13862 test_154c() {
13863         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13864                 skip "Need MDS version at least 2.4.1"
13865
13866         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13867         local FID1=$($LFS path2fid $DIR/$tfile.1)
13868         local FID2=$($LFS path2fid $DIR/$tfile.2)
13869         local FID3=$($LFS path2fid $DIR/$tfile.3)
13870
13871         local N=1
13872         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13873                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13874                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13875                 local want=FID$N
13876                 [ "$FID" = "${!want}" ] ||
13877                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13878                 N=$((N + 1))
13879         done
13880
13881         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13882         do
13883                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13884                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13885                 N=$((N + 1))
13886         done
13887 }
13888 run_test 154c "lfs path2fid and fid2path multiple arguments"
13889
13890 test_154d() {
13891         remote_mds_nodsh && skip "remote MDS with nodsh"
13892         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13893                 skip "Need MDS version at least 2.5.53"
13894
13895         if remote_mds; then
13896                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13897         else
13898                 nid="0@lo"
13899         fi
13900         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13901         local fd
13902         local cmd
13903
13904         rm -f $DIR/$tfile
13905         touch $DIR/$tfile
13906
13907         local fid=$($LFS path2fid $DIR/$tfile)
13908         # Open the file
13909         fd=$(free_fd)
13910         cmd="exec $fd<$DIR/$tfile"
13911         eval $cmd
13912         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13913         echo "$fid_list" | grep "$fid"
13914         rc=$?
13915
13916         cmd="exec $fd>/dev/null"
13917         eval $cmd
13918         if [ $rc -ne 0 ]; then
13919                 error "FID $fid not found in open files list $fid_list"
13920         fi
13921 }
13922 run_test 154d "Verify open file fid"
13923
13924 test_154e()
13925 {
13926         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13927                 skip "Need MDS version at least 2.6.50"
13928
13929         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13930                 error ".lustre returned by readdir"
13931         fi
13932 }
13933 run_test 154e ".lustre is not returned by readdir"
13934
13935 test_154f() {
13936         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13937
13938         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13939         test_mkdir -p -c1 $DIR/$tdir/d
13940         # test dirs inherit from its stripe
13941         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13942         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13943         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13944         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13945         touch $DIR/f
13946
13947         # get fid of parents
13948         local FID0=$($LFS path2fid $DIR/$tdir/d)
13949         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13950         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13951         local FID3=$($LFS path2fid $DIR)
13952
13953         # check that path2fid --parents returns expected <parent_fid>/name
13954         # 1) test for a directory (single parent)
13955         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13956         [ "$parent" == "$FID0/foo1" ] ||
13957                 error "expected parent: $FID0/foo1, got: $parent"
13958
13959         # 2) test for a file with nlink > 1 (multiple parents)
13960         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13961         echo "$parent" | grep -F "$FID1/$tfile" ||
13962                 error "$FID1/$tfile not returned in parent list"
13963         echo "$parent" | grep -F "$FID2/link" ||
13964                 error "$FID2/link not returned in parent list"
13965
13966         # 3) get parent by fid
13967         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13968         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13969         echo "$parent" | grep -F "$FID1/$tfile" ||
13970                 error "$FID1/$tfile not returned in parent list (by fid)"
13971         echo "$parent" | grep -F "$FID2/link" ||
13972                 error "$FID2/link not returned in parent list (by fid)"
13973
13974         # 4) test for entry in root directory
13975         parent=$($LFS path2fid --parents $DIR/f)
13976         echo "$parent" | grep -F "$FID3/f" ||
13977                 error "$FID3/f not returned in parent list"
13978
13979         # 5) test it on root directory
13980         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13981                 error "$MOUNT should not have parents"
13982
13983         # enable xattr caching and check that linkea is correctly updated
13984         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13985         save_lustre_params client "llite.*.xattr_cache" > $save
13986         lctl set_param llite.*.xattr_cache 1
13987
13988         # 6.1) linkea update on rename
13989         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13990
13991         # get parents by fid
13992         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13993         # foo1 should no longer be returned in parent list
13994         echo "$parent" | grep -F "$FID1" &&
13995                 error "$FID1 should no longer be in parent list"
13996         # the new path should appear
13997         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13998                 error "$FID2/$tfile.moved is not in parent list"
13999
14000         # 6.2) linkea update on unlink
14001         rm -f $DIR/$tdir/d/foo2/link
14002         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14003         # foo2/link should no longer be returned in parent list
14004         echo "$parent" | grep -F "$FID2/link" &&
14005                 error "$FID2/link should no longer be in parent list"
14006         true
14007
14008         rm -f $DIR/f
14009         restore_lustre_params < $save
14010         rm -f $save
14011 }
14012 run_test 154f "get parent fids by reading link ea"
14013
14014 test_154g()
14015 {
14016         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14017         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14018            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14019                 skip "Need MDS version at least 2.6.92"
14020
14021         mkdir -p $DIR/$tdir
14022         llapi_fid_test -d $DIR/$tdir
14023 }
14024 run_test 154g "various llapi FID tests"
14025
14026 test_155_small_load() {
14027     local temp=$TMP/$tfile
14028     local file=$DIR/$tfile
14029
14030     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14031         error "dd of=$temp bs=6096 count=1 failed"
14032     cp $temp $file
14033     cancel_lru_locks $OSC
14034     cmp $temp $file || error "$temp $file differ"
14035
14036     $TRUNCATE $temp 6000
14037     $TRUNCATE $file 6000
14038     cmp $temp $file || error "$temp $file differ (truncate1)"
14039
14040     echo "12345" >>$temp
14041     echo "12345" >>$file
14042     cmp $temp $file || error "$temp $file differ (append1)"
14043
14044     echo "12345" >>$temp
14045     echo "12345" >>$file
14046     cmp $temp $file || error "$temp $file differ (append2)"
14047
14048     rm -f $temp $file
14049     true
14050 }
14051
14052 test_155_big_load() {
14053         remote_ost_nodsh && skip "remote OST with nodsh"
14054
14055         local temp=$TMP/$tfile
14056         local file=$DIR/$tfile
14057
14058         free_min_max
14059         local cache_size=$(do_facet ost$((MAXI+1)) \
14060                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14061         local large_file_size=$((cache_size * 2))
14062
14063         echo "OSS cache size: $cache_size KB"
14064         echo "Large file size: $large_file_size KB"
14065
14066         [ $MAXV -le $large_file_size ] &&
14067                 skip_env "max available OST size needs > $large_file_size KB"
14068
14069         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14070
14071         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14072                 error "dd of=$temp bs=$large_file_size count=1k failed"
14073         cp $temp $file
14074         ls -lh $temp $file
14075         cancel_lru_locks osc
14076         cmp $temp $file || error "$temp $file differ"
14077
14078         rm -f $temp $file
14079         true
14080 }
14081
14082 save_writethrough() {
14083         local facets=$(get_facets OST)
14084
14085         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14086 }
14087
14088 test_155a() {
14089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14090
14091         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14092
14093         save_writethrough $p
14094
14095         set_cache read on
14096         set_cache writethrough on
14097         test_155_small_load
14098         restore_lustre_params < $p
14099         rm -f $p
14100 }
14101 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14102
14103 test_155b() {
14104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14105
14106         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14107
14108         save_writethrough $p
14109
14110         set_cache read on
14111         set_cache writethrough off
14112         test_155_small_load
14113         restore_lustre_params < $p
14114         rm -f $p
14115 }
14116 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14117
14118 test_155c() {
14119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14120
14121         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14122
14123         save_writethrough $p
14124
14125         set_cache read off
14126         set_cache writethrough on
14127         test_155_small_load
14128         restore_lustre_params < $p
14129         rm -f $p
14130 }
14131 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14132
14133 test_155d() {
14134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14135
14136         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14137
14138         save_writethrough $p
14139
14140         set_cache read off
14141         set_cache writethrough off
14142         test_155_small_load
14143         restore_lustre_params < $p
14144         rm -f $p
14145 }
14146 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14147
14148 test_155e() {
14149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14150
14151         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14152
14153         save_writethrough $p
14154
14155         set_cache read on
14156         set_cache writethrough on
14157         test_155_big_load
14158         restore_lustre_params < $p
14159         rm -f $p
14160 }
14161 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14162
14163 test_155f() {
14164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14165
14166         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14167
14168         save_writethrough $p
14169
14170         set_cache read on
14171         set_cache writethrough off
14172         test_155_big_load
14173         restore_lustre_params < $p
14174         rm -f $p
14175 }
14176 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14177
14178 test_155g() {
14179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14180
14181         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14182
14183         save_writethrough $p
14184
14185         set_cache read off
14186         set_cache writethrough on
14187         test_155_big_load
14188         restore_lustre_params < $p
14189         rm -f $p
14190 }
14191 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14192
14193 test_155h() {
14194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14195
14196         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14197
14198         save_writethrough $p
14199
14200         set_cache read off
14201         set_cache writethrough off
14202         test_155_big_load
14203         restore_lustre_params < $p
14204         rm -f $p
14205 }
14206 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14207
14208 test_156() {
14209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14210         remote_ost_nodsh && skip "remote OST with nodsh"
14211         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14212                 skip "stats not implemented on old servers"
14213         [ "$ost1_FSTYPE" = "zfs" ] &&
14214                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14215
14216         local CPAGES=3
14217         local BEFORE
14218         local AFTER
14219         local file="$DIR/$tfile"
14220         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14221
14222         save_writethrough $p
14223         roc_hit_init
14224
14225         log "Turn on read and write cache"
14226         set_cache read on
14227         set_cache writethrough on
14228
14229         log "Write data and read it back."
14230         log "Read should be satisfied from the cache."
14231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14232         BEFORE=$(roc_hit)
14233         cancel_lru_locks osc
14234         cat $file >/dev/null
14235         AFTER=$(roc_hit)
14236         if ! let "AFTER - BEFORE == CPAGES"; then
14237                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14238         else
14239                 log "cache hits: before: $BEFORE, after: $AFTER"
14240         fi
14241
14242         log "Read again; it should be satisfied from the cache."
14243         BEFORE=$AFTER
14244         cancel_lru_locks osc
14245         cat $file >/dev/null
14246         AFTER=$(roc_hit)
14247         if ! let "AFTER - BEFORE == CPAGES"; then
14248                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14249         else
14250                 log "cache hits:: before: $BEFORE, after: $AFTER"
14251         fi
14252
14253         log "Turn off the read cache and turn on the write cache"
14254         set_cache read off
14255         set_cache writethrough on
14256
14257         log "Read again; it should be satisfied from the cache."
14258         BEFORE=$(roc_hit)
14259         cancel_lru_locks osc
14260         cat $file >/dev/null
14261         AFTER=$(roc_hit)
14262         if ! let "AFTER - BEFORE == CPAGES"; then
14263                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14264         else
14265                 log "cache hits:: before: $BEFORE, after: $AFTER"
14266         fi
14267
14268         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14269                 # > 2.12.56 uses pagecache if cached
14270                 log "Read again; it should not be satisfied from the cache."
14271                 BEFORE=$AFTER
14272                 cancel_lru_locks osc
14273                 cat $file >/dev/null
14274                 AFTER=$(roc_hit)
14275                 if ! let "AFTER - BEFORE == 0"; then
14276                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14277                 else
14278                         log "cache hits:: before: $BEFORE, after: $AFTER"
14279                 fi
14280         fi
14281
14282         log "Write data and read it back."
14283         log "Read should be satisfied from the cache."
14284         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14285         BEFORE=$(roc_hit)
14286         cancel_lru_locks osc
14287         cat $file >/dev/null
14288         AFTER=$(roc_hit)
14289         if ! let "AFTER - BEFORE == CPAGES"; then
14290                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14291         else
14292                 log "cache hits:: before: $BEFORE, after: $AFTER"
14293         fi
14294
14295         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14296                 # > 2.12.56 uses pagecache if cached
14297                 log "Read again; it should not be satisfied from the cache."
14298                 BEFORE=$AFTER
14299                 cancel_lru_locks osc
14300                 cat $file >/dev/null
14301                 AFTER=$(roc_hit)
14302                 if ! let "AFTER - BEFORE == 0"; then
14303                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14304                 else
14305                         log "cache hits:: before: $BEFORE, after: $AFTER"
14306                 fi
14307         fi
14308
14309         log "Turn off read and write cache"
14310         set_cache read off
14311         set_cache writethrough off
14312
14313         log "Write data and read it back"
14314         log "It should not be satisfied from the cache."
14315         rm -f $file
14316         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14317         cancel_lru_locks osc
14318         BEFORE=$(roc_hit)
14319         cat $file >/dev/null
14320         AFTER=$(roc_hit)
14321         if ! let "AFTER - BEFORE == 0"; then
14322                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14323         else
14324                 log "cache hits:: before: $BEFORE, after: $AFTER"
14325         fi
14326
14327         log "Turn on the read cache and turn off the write cache"
14328         set_cache read on
14329         set_cache writethrough off
14330
14331         log "Write data and read it back"
14332         log "It should not be satisfied from the cache."
14333         rm -f $file
14334         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14335         BEFORE=$(roc_hit)
14336         cancel_lru_locks osc
14337         cat $file >/dev/null
14338         AFTER=$(roc_hit)
14339         if ! let "AFTER - BEFORE == 0"; then
14340                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14341         else
14342                 log "cache hits:: before: $BEFORE, after: $AFTER"
14343         fi
14344
14345         log "Read again; it should be satisfied from the cache."
14346         BEFORE=$(roc_hit)
14347         cancel_lru_locks osc
14348         cat $file >/dev/null
14349         AFTER=$(roc_hit)
14350         if ! let "AFTER - BEFORE == CPAGES"; then
14351                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14352         else
14353                 log "cache hits:: before: $BEFORE, after: $AFTER"
14354         fi
14355
14356         restore_lustre_params < $p
14357         rm -f $p $file
14358 }
14359 run_test 156 "Verification of tunables"
14360
14361 test_160a() {
14362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14363         remote_mds_nodsh && skip "remote MDS with nodsh"
14364         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14365                 skip "Need MDS version at least 2.2.0"
14366
14367         changelog_register || error "changelog_register failed"
14368         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14369         changelog_users $SINGLEMDS | grep -q $cl_user ||
14370                 error "User $cl_user not found in changelog_users"
14371
14372         # change something
14373         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14374         changelog_clear 0 || error "changelog_clear failed"
14375         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14376         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14377         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14378         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14379         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14380         rm $DIR/$tdir/pics/desktop.jpg
14381
14382         changelog_dump | tail -10
14383
14384         echo "verifying changelog mask"
14385         changelog_chmask "-MKDIR"
14386         changelog_chmask "-CLOSE"
14387
14388         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14389         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14390
14391         changelog_chmask "+MKDIR"
14392         changelog_chmask "+CLOSE"
14393
14394         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14395         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14396
14397         changelog_dump | tail -10
14398         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14399         CLOSES=$(changelog_dump | grep -c "CLOSE")
14400         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14401         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14402
14403         # verify contents
14404         echo "verifying target fid"
14405         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14406         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14407         [ "$fidc" == "$fidf" ] ||
14408                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14409         echo "verifying parent fid"
14410         # The FID returned from the Changelog may be the directory shard on
14411         # a different MDT, and not the FID returned by path2fid on the parent.
14412         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14413         # since this is what will matter when recreating this file in the tree.
14414         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14415         local pathp=$($LFS fid2path $MOUNT "$fidp")
14416         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14417                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14418
14419         echo "getting records for $cl_user"
14420         changelog_users $SINGLEMDS
14421         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14422         local nclr=3
14423         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14424                 error "changelog_clear failed"
14425         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14426         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14427         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14428                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14429
14430         local min0_rec=$(changelog_users $SINGLEMDS |
14431                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14432         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14433                           awk '{ print $1; exit; }')
14434
14435         changelog_dump | tail -n 5
14436         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14437         [ $first_rec == $((min0_rec + 1)) ] ||
14438                 error "first index should be $min0_rec + 1 not $first_rec"
14439
14440         # LU-3446 changelog index reset on MDT restart
14441         local cur_rec1=$(changelog_users $SINGLEMDS |
14442                          awk '/^current.index:/ { print $NF }')
14443         changelog_clear 0 ||
14444                 error "clear all changelog records for $cl_user failed"
14445         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14446         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14447                 error "Fail to start $SINGLEMDS"
14448         local cur_rec2=$(changelog_users $SINGLEMDS |
14449                          awk '/^current.index:/ { print $NF }')
14450         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14451         [ $cur_rec1 == $cur_rec2 ] ||
14452                 error "current index should be $cur_rec1 not $cur_rec2"
14453
14454         echo "verifying users from this test are deregistered"
14455         changelog_deregister || error "changelog_deregister failed"
14456         changelog_users $SINGLEMDS | grep -q $cl_user &&
14457                 error "User '$cl_user' still in changelog_users"
14458
14459         # lctl get_param -n mdd.*.changelog_users
14460         # current index: 144
14461         # ID    index (idle seconds)
14462         # cl3   144 (2)
14463         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14464                 # this is the normal case where all users were deregistered
14465                 # make sure no new records are added when no users are present
14466                 local last_rec1=$(changelog_users $SINGLEMDS |
14467                                   awk '/^current.index:/ { print $NF }')
14468                 touch $DIR/$tdir/chloe
14469                 local last_rec2=$(changelog_users $SINGLEMDS |
14470                                   awk '/^current.index:/ { print $NF }')
14471                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14472                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14473         else
14474                 # any changelog users must be leftovers from a previous test
14475                 changelog_users $SINGLEMDS
14476                 echo "other changelog users; can't verify off"
14477         fi
14478 }
14479 run_test 160a "changelog sanity"
14480
14481 test_160b() { # LU-3587
14482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14483         remote_mds_nodsh && skip "remote MDS with nodsh"
14484         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14485                 skip "Need MDS version at least 2.2.0"
14486
14487         changelog_register || error "changelog_register failed"
14488         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14489         changelog_users $SINGLEMDS | grep -q $cl_user ||
14490                 error "User '$cl_user' not found in changelog_users"
14491
14492         local longname1=$(str_repeat a 255)
14493         local longname2=$(str_repeat b 255)
14494
14495         cd $DIR
14496         echo "creating very long named file"
14497         touch $longname1 || error "create of '$longname1' failed"
14498         echo "renaming very long named file"
14499         mv $longname1 $longname2
14500
14501         changelog_dump | grep RENME | tail -n 5
14502         rm -f $longname2
14503 }
14504 run_test 160b "Verify that very long rename doesn't crash in changelog"
14505
14506 test_160c() {
14507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14508         remote_mds_nodsh && skip "remote MDS with nodsh"
14509
14510         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14511                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14512                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14513                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14514
14515         local rc=0
14516
14517         # Registration step
14518         changelog_register || error "changelog_register failed"
14519
14520         rm -rf $DIR/$tdir
14521         mkdir -p $DIR/$tdir
14522         $MCREATE $DIR/$tdir/foo_160c
14523         changelog_chmask "-TRUNC"
14524         $TRUNCATE $DIR/$tdir/foo_160c 200
14525         changelog_chmask "+TRUNC"
14526         $TRUNCATE $DIR/$tdir/foo_160c 199
14527         changelog_dump | tail -n 5
14528         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14529         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14530 }
14531 run_test 160c "verify that changelog log catch the truncate event"
14532
14533 test_160d() {
14534         remote_mds_nodsh && skip "remote MDS with nodsh"
14535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14537         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14538                 skip "Need MDS version at least 2.7.60"
14539
14540         # Registration step
14541         changelog_register || error "changelog_register failed"
14542
14543         mkdir -p $DIR/$tdir/migrate_dir
14544         changelog_clear 0 || error "changelog_clear failed"
14545
14546         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14547         changelog_dump | tail -n 5
14548         local migrates=$(changelog_dump | grep -c "MIGRT")
14549         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14550 }
14551 run_test 160d "verify that changelog log catch the migrate event"
14552
14553 test_160e() {
14554         remote_mds_nodsh && skip "remote MDS with nodsh"
14555
14556         # Create a user
14557         changelog_register || error "changelog_register failed"
14558
14559         # Delete a future user (expect fail)
14560         local MDT0=$(facet_svc $SINGLEMDS)
14561         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14562         local rc=$?
14563
14564         if [ $rc -eq 0 ]; then
14565                 error "Deleted non-existant user cl77"
14566         elif [ $rc -ne 2 ]; then
14567                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14568         fi
14569
14570         # Clear to a bad index (1 billion should be safe)
14571         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14572         rc=$?
14573
14574         if [ $rc -eq 0 ]; then
14575                 error "Successfully cleared to invalid CL index"
14576         elif [ $rc -ne 22 ]; then
14577                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14578         fi
14579 }
14580 run_test 160e "changelog negative testing (should return errors)"
14581
14582 test_160f() {
14583         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14584         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14585                 skip "Need MDS version at least 2.10.56"
14586
14587         local mdts=$(comma_list $(mdts_nodes))
14588
14589         # Create a user
14590         changelog_register || error "first changelog_register failed"
14591         changelog_register || error "second changelog_register failed"
14592         local cl_users
14593         declare -A cl_user1
14594         declare -A cl_user2
14595         local user_rec1
14596         local user_rec2
14597         local i
14598
14599         # generate some changelog records to accumulate on each MDT
14600         # use fnv1a because created files should be evenly distributed
14601         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14602                 error "test_mkdir $tdir failed"
14603         log "$(date +%s): creating first files"
14604         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14605                 error "create $DIR/$tdir/$tfile failed"
14606
14607         # check changelogs have been generated
14608         local start=$SECONDS
14609         local idle_time=$((MDSCOUNT * 5 + 5))
14610         local nbcl=$(changelog_dump | wc -l)
14611         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14612
14613         for param in "changelog_max_idle_time=$idle_time" \
14614                      "changelog_gc=1" \
14615                      "changelog_min_gc_interval=2" \
14616                      "changelog_min_free_cat_entries=3"; do
14617                 local MDT0=$(facet_svc $SINGLEMDS)
14618                 local var="${param%=*}"
14619                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14620
14621                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14622                 do_nodes $mdts $LCTL set_param mdd.*.$param
14623         done
14624
14625         # force cl_user2 to be idle (1st part), but also cancel the
14626         # cl_user1 records so that it is not evicted later in the test.
14627         local sleep1=$((idle_time / 2))
14628         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14629         sleep $sleep1
14630
14631         # simulate changelog catalog almost full
14632         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14633         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14634
14635         for i in $(seq $MDSCOUNT); do
14636                 cl_users=(${CL_USERS[mds$i]})
14637                 cl_user1[mds$i]="${cl_users[0]}"
14638                 cl_user2[mds$i]="${cl_users[1]}"
14639
14640                 [ -n "${cl_user1[mds$i]}" ] ||
14641                         error "mds$i: no user registered"
14642                 [ -n "${cl_user2[mds$i]}" ] ||
14643                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14644
14645                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14646                 [ -n "$user_rec1" ] ||
14647                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14648                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14649                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14650                 [ -n "$user_rec2" ] ||
14651                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14652                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14653                      "$user_rec1 + 2 == $user_rec2"
14654                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14655                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14656                               "$user_rec1 + 2, but is $user_rec2"
14657                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14658                 [ -n "$user_rec2" ] ||
14659                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14660                 [ $user_rec1 == $user_rec2 ] ||
14661                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14662                               "$user_rec1, but is $user_rec2"
14663         done
14664
14665         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14666         local sleep2=$((idle_time - (SECONDS - start) + 1))
14667         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14668         sleep $sleep2
14669
14670         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14671         # cl_user1 should be OK because it recently processed records.
14672         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14673         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14674                 error "create $DIR/$tdir/${tfile}b failed"
14675
14676         # ensure gc thread is done
14677         for i in $(mdts_nodes); do
14678                 wait_update $i \
14679                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14680                         error "$i: GC-thread not done"
14681         done
14682
14683         local first_rec
14684         for i in $(seq $MDSCOUNT); do
14685                 # check cl_user1 still registered
14686                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14687                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14688                 # check cl_user2 unregistered
14689                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14690                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14691
14692                 # check changelogs are present and starting at $user_rec1 + 1
14693                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14694                 [ -n "$user_rec1" ] ||
14695                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14696                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14697                             awk '{ print $1; exit; }')
14698
14699                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14700                 [ $((user_rec1 + 1)) == $first_rec ] ||
14701                         error "mds$i: first index should be $user_rec1 + 1, " \
14702                               "but is $first_rec"
14703         done
14704 }
14705 run_test 160f "changelog garbage collect (timestamped users)"
14706
14707 test_160g() {
14708         remote_mds_nodsh && skip "remote MDS with nodsh"
14709         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14710                 skip "Need MDS version at least 2.10.56"
14711
14712         local mdts=$(comma_list $(mdts_nodes))
14713
14714         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14715         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14716
14717         # Create a user
14718         changelog_register || error "first changelog_register failed"
14719         changelog_register || error "second changelog_register failed"
14720         local cl_users
14721         declare -A cl_user1
14722         declare -A cl_user2
14723         local user_rec1
14724         local user_rec2
14725         local i
14726
14727         # generate some changelog records to accumulate on each MDT
14728         # use fnv1a because created files should be evenly distributed
14729         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14730                 error "mkdir $tdir failed"
14731         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14732                 error "create $DIR/$tdir/$tfile failed"
14733
14734         # check changelogs have been generated
14735         local nbcl=$(changelog_dump | wc -l)
14736         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14737
14738         # reduce the max_idle_indexes value to make sure we exceed it
14739         max_ndx=$((nbcl / 2 - 1))
14740
14741         for param in "changelog_max_idle_indexes=$max_ndx" \
14742                      "changelog_gc=1" \
14743                      "changelog_min_gc_interval=2" \
14744                      "changelog_min_free_cat_entries=3"; do
14745                 local MDT0=$(facet_svc $SINGLEMDS)
14746                 local var="${param%=*}"
14747                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14748
14749                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14750                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14751                         error "unable to set mdd.*.$param"
14752         done
14753
14754         # simulate changelog catalog almost full
14755         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14756         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14757
14758         for i in $(seq $MDSCOUNT); do
14759                 cl_users=(${CL_USERS[mds$i]})
14760                 cl_user1[mds$i]="${cl_users[0]}"
14761                 cl_user2[mds$i]="${cl_users[1]}"
14762
14763                 [ -n "${cl_user1[mds$i]}" ] ||
14764                         error "mds$i: no user registered"
14765                 [ -n "${cl_user2[mds$i]}" ] ||
14766                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14767
14768                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14769                 [ -n "$user_rec1" ] ||
14770                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14771                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14772                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14773                 [ -n "$user_rec2" ] ||
14774                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14775                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14776                      "$user_rec1 + 2 == $user_rec2"
14777                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14778                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14779                               "$user_rec1 + 2, but is $user_rec2"
14780                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14781                 [ -n "$user_rec2" ] ||
14782                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14783                 [ $user_rec1 == $user_rec2 ] ||
14784                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14785                               "$user_rec1, but is $user_rec2"
14786         done
14787
14788         # ensure we are past the previous changelog_min_gc_interval set above
14789         sleep 2
14790
14791         # generate one more changelog to trigger fail_loc
14792         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14793                 error "create $DIR/$tdir/${tfile}bis failed"
14794
14795         # ensure gc thread is done
14796         for i in $(mdts_nodes); do
14797                 wait_update $i \
14798                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14799                         error "$i: GC-thread not done"
14800         done
14801
14802         local first_rec
14803         for i in $(seq $MDSCOUNT); do
14804                 # check cl_user1 still registered
14805                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14806                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14807                 # check cl_user2 unregistered
14808                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14809                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14810
14811                 # check changelogs are present and starting at $user_rec1 + 1
14812                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14813                 [ -n "$user_rec1" ] ||
14814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14815                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14816                             awk '{ print $1; exit; }')
14817
14818                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14819                 [ $((user_rec1 + 1)) == $first_rec ] ||
14820                         error "mds$i: first index should be $user_rec1 + 1, " \
14821                               "but is $first_rec"
14822         done
14823 }
14824 run_test 160g "changelog garbage collect (old users)"
14825
14826 test_160h() {
14827         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14828         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14829                 skip "Need MDS version at least 2.10.56"
14830
14831         local mdts=$(comma_list $(mdts_nodes))
14832
14833         # Create a user
14834         changelog_register || error "first changelog_register failed"
14835         changelog_register || error "second changelog_register failed"
14836         local cl_users
14837         declare -A cl_user1
14838         declare -A cl_user2
14839         local user_rec1
14840         local user_rec2
14841         local i
14842
14843         # generate some changelog records to accumulate on each MDT
14844         # use fnv1a because created files should be evenly distributed
14845         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14846                 error "test_mkdir $tdir failed"
14847         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14848                 error "create $DIR/$tdir/$tfile failed"
14849
14850         # check changelogs have been generated
14851         local nbcl=$(changelog_dump | wc -l)
14852         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14853
14854         for param in "changelog_max_idle_time=10" \
14855                      "changelog_gc=1" \
14856                      "changelog_min_gc_interval=2"; do
14857                 local MDT0=$(facet_svc $SINGLEMDS)
14858                 local var="${param%=*}"
14859                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14860
14861                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14862                 do_nodes $mdts $LCTL set_param mdd.*.$param
14863         done
14864
14865         # force cl_user2 to be idle (1st part)
14866         sleep 9
14867
14868         for i in $(seq $MDSCOUNT); do
14869                 cl_users=(${CL_USERS[mds$i]})
14870                 cl_user1[mds$i]="${cl_users[0]}"
14871                 cl_user2[mds$i]="${cl_users[1]}"
14872
14873                 [ -n "${cl_user1[mds$i]}" ] ||
14874                         error "mds$i: no user registered"
14875                 [ -n "${cl_user2[mds$i]}" ] ||
14876                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14877
14878                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14879                 [ -n "$user_rec1" ] ||
14880                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14881                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14882                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14883                 [ -n "$user_rec2" ] ||
14884                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14885                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14886                      "$user_rec1 + 2 == $user_rec2"
14887                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14888                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14889                               "$user_rec1 + 2, but is $user_rec2"
14890                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14891                 [ -n "$user_rec2" ] ||
14892                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14893                 [ $user_rec1 == $user_rec2 ] ||
14894                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14895                               "$user_rec1, but is $user_rec2"
14896         done
14897
14898         # force cl_user2 to be idle (2nd part) and to reach
14899         # changelog_max_idle_time
14900         sleep 2
14901
14902         # force each GC-thread start and block then
14903         # one per MDT/MDD, set fail_val accordingly
14904         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14905         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14906
14907         # generate more changelogs to trigger fail_loc
14908         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14909                 error "create $DIR/$tdir/${tfile}bis failed"
14910
14911         # stop MDT to stop GC-thread, should be done in back-ground as it will
14912         # block waiting for the thread to be released and exit
14913         declare -A stop_pids
14914         for i in $(seq $MDSCOUNT); do
14915                 stop mds$i &
14916                 stop_pids[mds$i]=$!
14917         done
14918
14919         for i in $(mdts_nodes); do
14920                 local facet
14921                 local nb=0
14922                 local facets=$(facets_up_on_host $i)
14923
14924                 for facet in ${facets//,/ }; do
14925                         if [[ $facet == mds* ]]; then
14926                                 nb=$((nb + 1))
14927                         fi
14928                 done
14929                 # ensure each MDS's gc threads are still present and all in "R"
14930                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14931                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14932                         error "$i: expected $nb GC-thread"
14933                 wait_update $i \
14934                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14935                         "R" 20 ||
14936                         error "$i: GC-thread not found in R-state"
14937                 # check umounts of each MDT on MDS have reached kthread_stop()
14938                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14939                         error "$i: expected $nb umount"
14940                 wait_update $i \
14941                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14942                         error "$i: umount not found in D-state"
14943         done
14944
14945         # release all GC-threads
14946         do_nodes $mdts $LCTL set_param fail_loc=0
14947
14948         # wait for MDT stop to complete
14949         for i in $(seq $MDSCOUNT); do
14950                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14951         done
14952
14953         # XXX
14954         # may try to check if any orphan changelog records are present
14955         # via ldiskfs/zfs and llog_reader...
14956
14957         # re-start/mount MDTs
14958         for i in $(seq $MDSCOUNT); do
14959                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14960                         error "Fail to start mds$i"
14961         done
14962
14963         local first_rec
14964         for i in $(seq $MDSCOUNT); do
14965                 # check cl_user1 still registered
14966                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14967                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14968                 # check cl_user2 unregistered
14969                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14970                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14971
14972                 # check changelogs are present and starting at $user_rec1 + 1
14973                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14974                 [ -n "$user_rec1" ] ||
14975                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14976                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14977                             awk '{ print $1; exit; }')
14978
14979                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14980                 [ $((user_rec1 + 1)) == $first_rec ] ||
14981                         error "mds$i: first index should be $user_rec1 + 1, " \
14982                               "but is $first_rec"
14983         done
14984 }
14985 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14986               "during mount"
14987
14988 test_160i() {
14989
14990         local mdts=$(comma_list $(mdts_nodes))
14991
14992         changelog_register || error "first changelog_register failed"
14993
14994         # generate some changelog records to accumulate on each MDT
14995         # use fnv1a because created files should be evenly distributed
14996         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14997                 error "mkdir $tdir failed"
14998         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14999                 error "create $DIR/$tdir/$tfile failed"
15000
15001         # check changelogs have been generated
15002         local nbcl=$(changelog_dump | wc -l)
15003         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15004
15005         # simulate race between register and unregister
15006         # XXX as fail_loc is set per-MDS, with DNE configs the race
15007         # simulation will only occur for one MDT per MDS and for the
15008         # others the normal race scenario will take place
15009         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15010         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15011         do_nodes $mdts $LCTL set_param fail_val=1
15012
15013         # unregister 1st user
15014         changelog_deregister &
15015         local pid1=$!
15016         # wait some time for deregister work to reach race rdv
15017         sleep 2
15018         # register 2nd user
15019         changelog_register || error "2nd user register failed"
15020
15021         wait $pid1 || error "1st user deregister failed"
15022
15023         local i
15024         local last_rec
15025         declare -A LAST_REC
15026         for i in $(seq $MDSCOUNT); do
15027                 if changelog_users mds$i | grep "^cl"; then
15028                         # make sure new records are added with one user present
15029                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15030                                           awk '/^current.index:/ { print $NF }')
15031                 else
15032                         error "mds$i has no user registered"
15033                 fi
15034         done
15035
15036         # generate more changelog records to accumulate on each MDT
15037         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15038                 error "create $DIR/$tdir/${tfile}bis failed"
15039
15040         for i in $(seq $MDSCOUNT); do
15041                 last_rec=$(changelog_users $SINGLEMDS |
15042                            awk '/^current.index:/ { print $NF }')
15043                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15044                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15045                         error "changelogs are off on mds$i"
15046         done
15047 }
15048 run_test 160i "changelog user register/unregister race"
15049
15050 test_160j() {
15051         remote_mds_nodsh && skip "remote MDS with nodsh"
15052         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15053                 skip "Need MDS version at least 2.12.56"
15054
15055         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15056         stack_trap "umount $MOUNT2" EXIT
15057
15058         changelog_register || error "first changelog_register failed"
15059         stack_trap "changelog_deregister" EXIT
15060
15061         # generate some changelog
15062         # use fnv1a because created files should be evenly distributed
15063         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15064                 error "mkdir $tdir failed"
15065         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15066                 error "create $DIR/$tdir/${tfile}bis failed"
15067
15068         # open the changelog device
15069         exec 3>/dev/changelog-$FSNAME-MDT0000
15070         stack_trap "exec 3>&-" EXIT
15071         exec 4</dev/changelog-$FSNAME-MDT0000
15072         stack_trap "exec 4<&-" EXIT
15073
15074         # umount the first lustre mount
15075         umount $MOUNT
15076         stack_trap "mount_client $MOUNT" EXIT
15077
15078         # read changelog
15079         cat <&4 >/dev/null || error "read changelog failed"
15080
15081         # clear changelog
15082         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15083         changelog_users $SINGLEMDS | grep -q $cl_user ||
15084                 error "User $cl_user not found in changelog_users"
15085
15086         printf 'clear:'$cl_user':0' >&3
15087 }
15088 run_test 160j "client can be umounted  while its chanangelog is being used"
15089
15090 test_160k() {
15091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15092         remote_mds_nodsh && skip "remote MDS with nodsh"
15093
15094         mkdir -p $DIR/$tdir/1/1
15095
15096         changelog_register || error "changelog_register failed"
15097         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15098
15099         changelog_users $SINGLEMDS | grep -q $cl_user ||
15100                 error "User '$cl_user' not found in changelog_users"
15101 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15102         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15103         rmdir $DIR/$tdir/1/1 & sleep 1
15104         mkdir $DIR/$tdir/2
15105         touch $DIR/$tdir/2/2
15106         rm -rf $DIR/$tdir/2
15107
15108         wait
15109         sleep 4
15110
15111         changelog_dump | grep rmdir || error "rmdir not recorded"
15112
15113         rm -rf $DIR/$tdir
15114         changelog_deregister
15115 }
15116 run_test 160k "Verify that changelog records are not lost"
15117
15118 # Verifies that a file passed as a parameter has recently had an operation
15119 # performed on it that has generated an MTIME changelog which contains the
15120 # correct parent FID. As files might reside on a different MDT from the
15121 # parent directory in DNE configurations, the FIDs are translated to paths
15122 # before being compared, which should be identical
15123 compare_mtime_changelog() {
15124         local file="${1}"
15125         local mdtidx
15126         local mtime
15127         local cl_fid
15128         local pdir
15129         local dir
15130
15131         mdtidx=$($LFS getstripe --mdt-index $file)
15132         mdtidx=$(printf "%04x" $mdtidx)
15133
15134         # Obtain the parent FID from the MTIME changelog
15135         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15136         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15137
15138         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15139         [ -z "$cl_fid" ] && error "parent FID not present"
15140
15141         # Verify that the path for the parent FID is the same as the path for
15142         # the test directory
15143         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15144
15145         dir=$(dirname $1)
15146
15147         [[ "${pdir%/}" == "$dir" ]] ||
15148                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15149 }
15150
15151 test_160l() {
15152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15153
15154         remote_mds_nodsh && skip "remote MDS with nodsh"
15155         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15156                 skip "Need MDS version at least 2.13.55"
15157
15158         local cl_user
15159
15160         changelog_register || error "changelog_register failed"
15161         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15162
15163         changelog_users $SINGLEMDS | grep -q $cl_user ||
15164                 error "User '$cl_user' not found in changelog_users"
15165
15166         # Clear some types so that MTIME changelogs are generated
15167         changelog_chmask "-CREAT"
15168         changelog_chmask "-CLOSE"
15169
15170         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15171
15172         # Test CL_MTIME during setattr
15173         touch $DIR/$tdir/$tfile
15174         compare_mtime_changelog $DIR/$tdir/$tfile
15175
15176         # Test CL_MTIME during close
15177         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15178                 error "cannot create file $DIR/$tdir/${tfile}_2"
15179         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15180 }
15181 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15182
15183 test_161a() {
15184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15185
15186         test_mkdir -c1 $DIR/$tdir
15187         cp /etc/hosts $DIR/$tdir/$tfile
15188         test_mkdir -c1 $DIR/$tdir/foo1
15189         test_mkdir -c1 $DIR/$tdir/foo2
15190         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15191         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15192         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15193         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15194         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15195         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15196                 $LFS fid2path $DIR $FID
15197                 error "bad link ea"
15198         fi
15199         # middle
15200         rm $DIR/$tdir/foo2/zachary
15201         # last
15202         rm $DIR/$tdir/foo2/thor
15203         # first
15204         rm $DIR/$tdir/$tfile
15205         # rename
15206         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15207         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15208                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15209         rm $DIR/$tdir/foo2/maggie
15210
15211         # overflow the EA
15212         local longname=$tfile.avg_len_is_thirty_two_
15213         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15214                 error_noexit 'failed to unlink many hardlinks'" EXIT
15215         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15216                 error "failed to hardlink many files"
15217         links=$($LFS fid2path $DIR $FID | wc -l)
15218         echo -n "${links}/1000 links in link EA"
15219         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15220 }
15221 run_test 161a "link ea sanity"
15222
15223 test_161b() {
15224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15225         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15226
15227         local MDTIDX=1
15228         local remote_dir=$DIR/$tdir/remote_dir
15229
15230         mkdir -p $DIR/$tdir
15231         $LFS mkdir -i $MDTIDX $remote_dir ||
15232                 error "create remote directory failed"
15233
15234         cp /etc/hosts $remote_dir/$tfile
15235         mkdir -p $remote_dir/foo1
15236         mkdir -p $remote_dir/foo2
15237         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15238         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15239         ln $remote_dir/$tfile $remote_dir/foo1/luna
15240         ln $remote_dir/$tfile $remote_dir/foo2/thor
15241
15242         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15243                      tr -d ']')
15244         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15245                 $LFS fid2path $DIR $FID
15246                 error "bad link ea"
15247         fi
15248         # middle
15249         rm $remote_dir/foo2/zachary
15250         # last
15251         rm $remote_dir/foo2/thor
15252         # first
15253         rm $remote_dir/$tfile
15254         # rename
15255         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15256         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15257         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15258                 $LFS fid2path $DIR $FID
15259                 error "bad link rename"
15260         fi
15261         rm $remote_dir/foo2/maggie
15262
15263         # overflow the EA
15264         local longname=filename_avg_len_is_thirty_two_
15265         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15266                 error "failed to hardlink many files"
15267         links=$($LFS fid2path $DIR $FID | wc -l)
15268         echo -n "${links}/1000 links in link EA"
15269         [[ ${links} -gt 60 ]] ||
15270                 error "expected at least 60 links in link EA"
15271         unlinkmany $remote_dir/foo2/$longname 1000 ||
15272         error "failed to unlink many hardlinks"
15273 }
15274 run_test 161b "link ea sanity under remote directory"
15275
15276 test_161c() {
15277         remote_mds_nodsh && skip "remote MDS with nodsh"
15278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15279         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15280                 skip "Need MDS version at least 2.1.5"
15281
15282         # define CLF_RENAME_LAST 0x0001
15283         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15284         changelog_register || error "changelog_register failed"
15285
15286         rm -rf $DIR/$tdir
15287         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15288         touch $DIR/$tdir/foo_161c
15289         touch $DIR/$tdir/bar_161c
15290         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15291         changelog_dump | grep RENME | tail -n 5
15292         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15293         changelog_clear 0 || error "changelog_clear failed"
15294         if [ x$flags != "x0x1" ]; then
15295                 error "flag $flags is not 0x1"
15296         fi
15297
15298         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15299         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15300         touch $DIR/$tdir/foo_161c
15301         touch $DIR/$tdir/bar_161c
15302         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15303         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15304         changelog_dump | grep RENME | tail -n 5
15305         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15306         changelog_clear 0 || error "changelog_clear failed"
15307         if [ x$flags != "x0x0" ]; then
15308                 error "flag $flags is not 0x0"
15309         fi
15310         echo "rename overwrite a target having nlink > 1," \
15311                 "changelog record has flags of $flags"
15312
15313         # rename doesn't overwrite a target (changelog flag 0x0)
15314         touch $DIR/$tdir/foo_161c
15315         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15316         changelog_dump | grep RENME | tail -n 5
15317         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15318         changelog_clear 0 || error "changelog_clear failed"
15319         if [ x$flags != "x0x0" ]; then
15320                 error "flag $flags is not 0x0"
15321         fi
15322         echo "rename doesn't overwrite a target," \
15323                 "changelog record has flags of $flags"
15324
15325         # define CLF_UNLINK_LAST 0x0001
15326         # unlink a file having nlink = 1 (changelog flag 0x1)
15327         rm -f $DIR/$tdir/foo2_161c
15328         changelog_dump | grep UNLNK | tail -n 5
15329         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15330         changelog_clear 0 || error "changelog_clear failed"
15331         if [ x$flags != "x0x1" ]; then
15332                 error "flag $flags is not 0x1"
15333         fi
15334         echo "unlink a file having nlink = 1," \
15335                 "changelog record has flags of $flags"
15336
15337         # unlink a file having nlink > 1 (changelog flag 0x0)
15338         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15339         rm -f $DIR/$tdir/foobar_161c
15340         changelog_dump | grep UNLNK | tail -n 5
15341         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15342         changelog_clear 0 || error "changelog_clear failed"
15343         if [ x$flags != "x0x0" ]; then
15344                 error "flag $flags is not 0x0"
15345         fi
15346         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15347 }
15348 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15349
15350 test_161d() {
15351         remote_mds_nodsh && skip "remote MDS with nodsh"
15352         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15353
15354         local pid
15355         local fid
15356
15357         changelog_register || error "changelog_register failed"
15358
15359         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15360         # interfer with $MOUNT/.lustre/fid/ access
15361         mkdir $DIR/$tdir
15362         [[ $? -eq 0 ]] || error "mkdir failed"
15363
15364         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15365         $LCTL set_param fail_loc=0x8000140c
15366         # 5s pause
15367         $LCTL set_param fail_val=5
15368
15369         # create file
15370         echo foofoo > $DIR/$tdir/$tfile &
15371         pid=$!
15372
15373         # wait for create to be delayed
15374         sleep 2
15375
15376         ps -p $pid
15377         [[ $? -eq 0 ]] || error "create should be blocked"
15378
15379         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15380         stack_trap "rm -f $tempfile"
15381         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15382         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15383         # some delay may occur during ChangeLog publishing and file read just
15384         # above, that could allow file write to happen finally
15385         [[ -s $tempfile ]] && echo "file should be empty"
15386
15387         $LCTL set_param fail_loc=0
15388
15389         wait $pid
15390         [[ $? -eq 0 ]] || error "create failed"
15391 }
15392 run_test 161d "create with concurrent .lustre/fid access"
15393
15394 check_path() {
15395         local expected="$1"
15396         shift
15397         local fid="$2"
15398
15399         local path
15400         path=$($LFS fid2path "$@")
15401         local rc=$?
15402
15403         if [ $rc -ne 0 ]; then
15404                 error "path looked up of '$expected' failed: rc=$rc"
15405         elif [ "$path" != "$expected" ]; then
15406                 error "path looked up '$path' instead of '$expected'"
15407         else
15408                 echo "FID '$fid' resolves to path '$path' as expected"
15409         fi
15410 }
15411
15412 test_162a() { # was test_162
15413         test_mkdir -p -c1 $DIR/$tdir/d2
15414         touch $DIR/$tdir/d2/$tfile
15415         touch $DIR/$tdir/d2/x1
15416         touch $DIR/$tdir/d2/x2
15417         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15418         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15419         # regular file
15420         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15421         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15422
15423         # softlink
15424         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15425         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15426         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15427
15428         # softlink to wrong file
15429         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15430         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15431         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15432
15433         # hardlink
15434         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15435         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15436         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15437         # fid2path dir/fsname should both work
15438         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15439         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15440
15441         # hardlink count: check that there are 2 links
15442         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15443         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15444
15445         # hardlink indexing: remove the first link
15446         rm $DIR/$tdir/d2/p/q/r/hlink
15447         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15448 }
15449 run_test 162a "path lookup sanity"
15450
15451 test_162b() {
15452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15454
15455         mkdir $DIR/$tdir
15456         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15457                                 error "create striped dir failed"
15458
15459         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15460                                         tail -n 1 | awk '{print $2}')
15461         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15462
15463         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15464         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15465
15466         # regular file
15467         for ((i=0;i<5;i++)); do
15468                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15469                         error "get fid for f$i failed"
15470                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15471
15472                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15473                         error "get fid for d$i failed"
15474                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15475         done
15476
15477         return 0
15478 }
15479 run_test 162b "striped directory path lookup sanity"
15480
15481 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15482 test_162c() {
15483         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15484                 skip "Need MDS version at least 2.7.51"
15485
15486         local lpath=$tdir.local
15487         local rpath=$tdir.remote
15488
15489         test_mkdir $DIR/$lpath
15490         test_mkdir $DIR/$rpath
15491
15492         for ((i = 0; i <= 101; i++)); do
15493                 lpath="$lpath/$i"
15494                 mkdir $DIR/$lpath
15495                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15496                         error "get fid for local directory $DIR/$lpath failed"
15497                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15498
15499                 rpath="$rpath/$i"
15500                 test_mkdir $DIR/$rpath
15501                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15502                         error "get fid for remote directory $DIR/$rpath failed"
15503                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15504         done
15505
15506         return 0
15507 }
15508 run_test 162c "fid2path works with paths 100 or more directories deep"
15509
15510 oalr_event_count() {
15511         local event="${1}"
15512         local trace="${2}"
15513
15514         awk -v name="${FSNAME}-OST0000" \
15515             -v event="${event}" \
15516             '$1 == "TRACE" && $2 == event && $3 == name' \
15517             "${trace}" |
15518         wc -l
15519 }
15520
15521 oalr_expect_event_count() {
15522         local event="${1}"
15523         local trace="${2}"
15524         local expect="${3}"
15525         local count
15526
15527         count=$(oalr_event_count "${event}" "${trace}")
15528         if ((count == expect)); then
15529                 return 0
15530         fi
15531
15532         error_noexit "${event} event count was '${count}', expected ${expect}"
15533         cat "${trace}" >&2
15534         exit 1
15535 }
15536
15537 cleanup_165() {
15538         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15539         stop ost1
15540         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15541 }
15542
15543 setup_165() {
15544         sync # Flush previous IOs so we can count log entries.
15545         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15546         stack_trap cleanup_165 EXIT
15547 }
15548
15549 test_165a() {
15550         local trace="/tmp/${tfile}.trace"
15551         local rc
15552         local count
15553
15554         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15555                 skip "OFD access log unsupported"
15556
15557         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15558         setup_165
15559         sleep 5
15560
15561         do_facet ost1 ofd_access_log_reader --list
15562         stop ost1
15563
15564         do_facet ost1 killall -TERM ofd_access_log_reader
15565         wait
15566         rc=$?
15567
15568         if ((rc != 0)); then
15569                 error "ofd_access_log_reader exited with rc = '${rc}'"
15570         fi
15571
15572         # Parse trace file for discovery events:
15573         oalr_expect_event_count alr_log_add "${trace}" 1
15574         oalr_expect_event_count alr_log_eof "${trace}" 1
15575         oalr_expect_event_count alr_log_free "${trace}" 1
15576 }
15577 run_test 165a "ofd access log discovery"
15578
15579 test_165b() {
15580         local trace="/tmp/${tfile}.trace"
15581         local file="${DIR}/${tfile}"
15582         local pfid1
15583         local pfid2
15584         local -a entry
15585         local rc
15586         local count
15587         local size
15588         local flags
15589
15590         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15591                 skip "OFD access log unsupported"
15592
15593         setup_165
15594
15595         lfs setstripe -c 1 -i 0 "${file}"
15596         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15597                 error "cannot create '${file}'"
15598         do_facet ost1 ofd_access_log_reader --list
15599
15600         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15601         sleep 5
15602         do_facet ost1 killall -TERM ofd_access_log_reader
15603         wait
15604         rc=$?
15605
15606         if ((rc != 0)); then
15607                 error "ofd_access_log_reader exited with rc = '${rc}'"
15608         fi
15609
15610         oalr_expect_event_count alr_log_entry "${trace}" 1
15611
15612         pfid1=$($LFS path2fid "${file}")
15613
15614         # 1     2             3   4    5     6   7    8    9     10
15615         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15616         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15617
15618         echo "entry = '${entry[*]}'" >&2
15619
15620         pfid2=${entry[4]}
15621         if [[ "${pfid1}" != "${pfid2}" ]]; then
15622                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15623         fi
15624
15625         size=${entry[8]}
15626         if ((size != 1048576)); then
15627                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15628         fi
15629
15630         flags=${entry[10]}
15631         if [[ "${flags}" != "w" ]]; then
15632                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15633         fi
15634
15635         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15636         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15637                 error "cannot read '${file}'"
15638         sleep 5
15639         do_facet ost1 killall -TERM ofd_access_log_reader
15640         wait
15641         rc=$?
15642
15643         if ((rc != 0)); then
15644                 error "ofd_access_log_reader exited with rc = '${rc}'"
15645         fi
15646
15647         oalr_expect_event_count alr_log_entry "${trace}" 1
15648
15649         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
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 != 524288)); then
15659                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15660         fi
15661
15662         flags=${entry[10]}
15663         if [[ "${flags}" != "r" ]]; then
15664                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15665         fi
15666 }
15667 run_test 165b "ofd access log entries are produced and consumed"
15668
15669 test_165c() {
15670         local file="${DIR}/${tdir}/${tfile}"
15671
15672         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15673                 skip "OFD access log unsupported"
15674
15675         test_mkdir "${DIR}/${tdir}"
15676
15677         setup_165
15678
15679         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15680
15681         # 4096 / 64 = 64. Create twice as many entries.
15682         for ((i = 0; i < 128; i++)); do
15683                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15684                         error "cannot create file"
15685         done
15686
15687         sync
15688         do_facet ost1 ofd_access_log_reader --list
15689         unlinkmany  "${file}-%d" 128
15690 }
15691 run_test 165c "full ofd access logs do not block IOs"
15692
15693 oal_peek_entry_count() {
15694         do_facet ost1 ofd_access_log_reader --list |
15695                 awk '$1 == "_entry_count:" { print $2; }'
15696 }
15697
15698 oal_expect_entry_count() {
15699         local entry_count=$(oal_peek_entry_count)
15700         local expect="$1"
15701
15702         if ((entry_count == expect)); then
15703                 return 0
15704         fi
15705
15706         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15707         do_facet ost1 ofd_access_log_reader --list >&2
15708         exit 1
15709 }
15710
15711 test_165d() {
15712         local trace="/tmp/${tfile}.trace"
15713         local file="${DIR}/${tdir}/${tfile}"
15714         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15715         local entry_count
15716
15717         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15718                 skip "OFD access log unsupported"
15719
15720         test_mkdir "${DIR}/${tdir}"
15721
15722         setup_165
15723         lfs setstripe -c 1 -i 0 "${file}"
15724
15725         do_facet ost1 lctl set_param "${param}=rw"
15726         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15727                 error "cannot create '${file}'"
15728         oal_expect_entry_count 1
15729
15730         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15731                 error "cannot read '${file}'"
15732         oal_expect_entry_count 2
15733
15734         do_facet ost1 lctl set_param "${param}=r"
15735         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15736                 error "cannot create '${file}'"
15737         oal_expect_entry_count 2
15738
15739         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15740                 error "cannot read '${file}'"
15741         oal_expect_entry_count 3
15742
15743         do_facet ost1 lctl set_param "${param}=w"
15744         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15745                 error "cannot create '${file}'"
15746         oal_expect_entry_count 4
15747
15748         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15749                 error "cannot read '${file}'"
15750         oal_expect_entry_count 4
15751
15752         do_facet ost1 lctl set_param "${param}=0"
15753         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15754                 error "cannot create '${file}'"
15755         oal_expect_entry_count 4
15756
15757         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15758                 error "cannot read '${file}'"
15759         oal_expect_entry_count 4
15760 }
15761 run_test 165d "ofd_access_log mask works"
15762
15763 test_169() {
15764         # do directio so as not to populate the page cache
15765         log "creating a 10 Mb file"
15766         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15767                 error "multiop failed while creating a file"
15768         log "starting reads"
15769         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15770         log "truncating the file"
15771         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15772                 error "multiop failed while truncating the file"
15773         log "killing dd"
15774         kill %+ || true # reads might have finished
15775         echo "wait until dd is finished"
15776         wait
15777         log "removing the temporary file"
15778         rm -rf $DIR/$tfile || error "tmp file removal failed"
15779 }
15780 run_test 169 "parallel read and truncate should not deadlock"
15781
15782 test_170() {
15783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15784
15785         $LCTL clear     # bug 18514
15786         $LCTL debug_daemon start $TMP/${tfile}_log_good
15787         touch $DIR/$tfile
15788         $LCTL debug_daemon stop
15789         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15790                 error "sed failed to read log_good"
15791
15792         $LCTL debug_daemon start $TMP/${tfile}_log_good
15793         rm -rf $DIR/$tfile
15794         $LCTL debug_daemon stop
15795
15796         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15797                error "lctl df log_bad failed"
15798
15799         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15800         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15801
15802         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15803         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15804
15805         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15806                 error "bad_line good_line1 good_line2 are empty"
15807
15808         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15809         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15810         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15811
15812         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15813         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15814         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15815
15816         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15817                 error "bad_line_new good_line_new are empty"
15818
15819         local expected_good=$((good_line1 + good_line2*2))
15820
15821         rm -f $TMP/${tfile}*
15822         # LU-231, short malformed line may not be counted into bad lines
15823         if [ $bad_line -ne $bad_line_new ] &&
15824                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15825                 error "expected $bad_line bad lines, but got $bad_line_new"
15826                 return 1
15827         fi
15828
15829         if [ $expected_good -ne $good_line_new ]; then
15830                 error "expected $expected_good good lines, but got $good_line_new"
15831                 return 2
15832         fi
15833         true
15834 }
15835 run_test 170 "test lctl df to handle corrupted log ====================="
15836
15837 test_171() { # bug20592
15838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15839
15840         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15841         $LCTL set_param fail_loc=0x50e
15842         $LCTL set_param fail_val=3000
15843         multiop_bg_pause $DIR/$tfile O_s || true
15844         local MULTIPID=$!
15845         kill -USR1 $MULTIPID
15846         # cause log dump
15847         sleep 3
15848         wait $MULTIPID
15849         if dmesg | grep "recursive fault"; then
15850                 error "caught a recursive fault"
15851         fi
15852         $LCTL set_param fail_loc=0
15853         true
15854 }
15855 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15856
15857 # it would be good to share it with obdfilter-survey/iokit-libecho code
15858 setup_obdecho_osc () {
15859         local rc=0
15860         local ost_nid=$1
15861         local obdfilter_name=$2
15862         echo "Creating new osc for $obdfilter_name on $ost_nid"
15863         # make sure we can find loopback nid
15864         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15865
15866         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15867                            ${obdfilter_name}_osc_UUID || rc=2; }
15868         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15869                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15870         return $rc
15871 }
15872
15873 cleanup_obdecho_osc () {
15874         local obdfilter_name=$1
15875         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15876         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15877         return 0
15878 }
15879
15880 obdecho_test() {
15881         local OBD=$1
15882         local node=$2
15883         local pages=${3:-64}
15884         local rc=0
15885         local id
15886
15887         local count=10
15888         local obd_size=$(get_obd_size $node $OBD)
15889         local page_size=$(get_page_size $node)
15890         if [[ -n "$obd_size" ]]; then
15891                 local new_count=$((obd_size / (pages * page_size / 1024)))
15892                 [[ $new_count -ge $count ]] || count=$new_count
15893         fi
15894
15895         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15896         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15897                            rc=2; }
15898         if [ $rc -eq 0 ]; then
15899             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15900             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15901         fi
15902         echo "New object id is $id"
15903         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15904                            rc=4; }
15905         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15906                            "test_brw $count w v $pages $id" || rc=4; }
15907         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15908                            rc=4; }
15909         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15910                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15911         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15912                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15913         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15914         return $rc
15915 }
15916
15917 test_180a() {
15918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15919
15920         if ! [ -d /sys/fs/lustre/echo_client ] &&
15921            ! module_loaded obdecho; then
15922                 load_module obdecho/obdecho &&
15923                         stack_trap "rmmod obdecho" EXIT ||
15924                         error "unable to load obdecho on client"
15925         fi
15926
15927         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15928         local host=$($LCTL get_param -n osc.$osc.import |
15929                      awk '/current_connection:/ { print $2 }' )
15930         local target=$($LCTL get_param -n osc.$osc.import |
15931                        awk '/target:/ { print $2 }' )
15932         target=${target%_UUID}
15933
15934         if [ -n "$target" ]; then
15935                 setup_obdecho_osc $host $target &&
15936                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15937                         { error "obdecho setup failed with $?"; return; }
15938
15939                 obdecho_test ${target}_osc client ||
15940                         error "obdecho_test failed on ${target}_osc"
15941         else
15942                 $LCTL get_param osc.$osc.import
15943                 error "there is no osc.$osc.import target"
15944         fi
15945 }
15946 run_test 180a "test obdecho on osc"
15947
15948 test_180b() {
15949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15950         remote_ost_nodsh && skip "remote OST with nodsh"
15951
15952         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15953                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15954                 error "failed to load module obdecho"
15955
15956         local target=$(do_facet ost1 $LCTL dl |
15957                        awk '/obdfilter/ { print $4; exit; }')
15958
15959         if [ -n "$target" ]; then
15960                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15961         else
15962                 do_facet ost1 $LCTL dl
15963                 error "there is no obdfilter target on ost1"
15964         fi
15965 }
15966 run_test 180b "test obdecho directly on obdfilter"
15967
15968 test_180c() { # LU-2598
15969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15970         remote_ost_nodsh && skip "remote OST with nodsh"
15971         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15972                 skip "Need MDS version at least 2.4.0"
15973
15974         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15975                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15976                 error "failed to load module obdecho"
15977
15978         local target=$(do_facet ost1 $LCTL dl |
15979                        awk '/obdfilter/ { print $4; exit; }')
15980
15981         if [ -n "$target" ]; then
15982                 local pages=16384 # 64MB bulk I/O RPC size
15983
15984                 obdecho_test "$target" ost1 "$pages" ||
15985                         error "obdecho_test with pages=$pages failed with $?"
15986         else
15987                 do_facet ost1 $LCTL dl
15988                 error "there is no obdfilter target on ost1"
15989         fi
15990 }
15991 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15992
15993 test_181() { # bug 22177
15994         test_mkdir $DIR/$tdir
15995         # create enough files to index the directory
15996         createmany -o $DIR/$tdir/foobar 4000
15997         # print attributes for debug purpose
15998         lsattr -d .
15999         # open dir
16000         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16001         MULTIPID=$!
16002         # remove the files & current working dir
16003         unlinkmany $DIR/$tdir/foobar 4000
16004         rmdir $DIR/$tdir
16005         kill -USR1 $MULTIPID
16006         wait $MULTIPID
16007         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16008         return 0
16009 }
16010 run_test 181 "Test open-unlinked dir ========================"
16011
16012 test_182() {
16013         local fcount=1000
16014         local tcount=10
16015
16016         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16017
16018         $LCTL set_param mdc.*.rpc_stats=clear
16019
16020         for (( i = 0; i < $tcount; i++ )) ; do
16021                 mkdir $DIR/$tdir/$i
16022         done
16023
16024         for (( i = 0; i < $tcount; i++ )) ; do
16025                 createmany -o $DIR/$tdir/$i/f- $fcount &
16026         done
16027         wait
16028
16029         for (( i = 0; i < $tcount; i++ )) ; do
16030                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16031         done
16032         wait
16033
16034         $LCTL get_param mdc.*.rpc_stats
16035
16036         rm -rf $DIR/$tdir
16037 }
16038 run_test 182 "Test parallel modify metadata operations ================"
16039
16040 test_183() { # LU-2275
16041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16042         remote_mds_nodsh && skip "remote MDS with nodsh"
16043         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16044                 skip "Need MDS version at least 2.3.56"
16045
16046         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16047         echo aaa > $DIR/$tdir/$tfile
16048
16049 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16050         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16051
16052         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16053         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16054
16055         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16056
16057         # Flush negative dentry cache
16058         touch $DIR/$tdir/$tfile
16059
16060         # We are not checking for any leaked references here, they'll
16061         # become evident next time we do cleanup with module unload.
16062         rm -rf $DIR/$tdir
16063 }
16064 run_test 183 "No crash or request leak in case of strange dispositions ========"
16065
16066 # test suite 184 is for LU-2016, LU-2017
16067 test_184a() {
16068         check_swap_layouts_support
16069
16070         dir0=$DIR/$tdir/$testnum
16071         test_mkdir -p -c1 $dir0
16072         ref1=/etc/passwd
16073         ref2=/etc/group
16074         file1=$dir0/f1
16075         file2=$dir0/f2
16076         $LFS setstripe -c1 $file1
16077         cp $ref1 $file1
16078         $LFS setstripe -c2 $file2
16079         cp $ref2 $file2
16080         gen1=$($LFS getstripe -g $file1)
16081         gen2=$($LFS getstripe -g $file2)
16082
16083         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16084         gen=$($LFS getstripe -g $file1)
16085         [[ $gen1 != $gen ]] ||
16086                 "Layout generation on $file1 does not change"
16087         gen=$($LFS getstripe -g $file2)
16088         [[ $gen2 != $gen ]] ||
16089                 "Layout generation on $file2 does not change"
16090
16091         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16092         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16093
16094         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16095 }
16096 run_test 184a "Basic layout swap"
16097
16098 test_184b() {
16099         check_swap_layouts_support
16100
16101         dir0=$DIR/$tdir/$testnum
16102         mkdir -p $dir0 || error "creating dir $dir0"
16103         file1=$dir0/f1
16104         file2=$dir0/f2
16105         file3=$dir0/f3
16106         dir1=$dir0/d1
16107         dir2=$dir0/d2
16108         mkdir $dir1 $dir2
16109         $LFS setstripe -c1 $file1
16110         $LFS setstripe -c2 $file2
16111         $LFS setstripe -c1 $file3
16112         chown $RUNAS_ID $file3
16113         gen1=$($LFS getstripe -g $file1)
16114         gen2=$($LFS getstripe -g $file2)
16115
16116         $LFS swap_layouts $dir1 $dir2 &&
16117                 error "swap of directories layouts should fail"
16118         $LFS swap_layouts $dir1 $file1 &&
16119                 error "swap of directory and file layouts should fail"
16120         $RUNAS $LFS swap_layouts $file1 $file2 &&
16121                 error "swap of file we cannot write should fail"
16122         $LFS swap_layouts $file1 $file3 &&
16123                 error "swap of file with different owner should fail"
16124         /bin/true # to clear error code
16125 }
16126 run_test 184b "Forbidden layout swap (will generate errors)"
16127
16128 test_184c() {
16129         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16130         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16131         check_swap_layouts_support
16132         check_swap_layout_no_dom $DIR
16133
16134         local dir0=$DIR/$tdir/$testnum
16135         mkdir -p $dir0 || error "creating dir $dir0"
16136
16137         local ref1=$dir0/ref1
16138         local ref2=$dir0/ref2
16139         local file1=$dir0/file1
16140         local file2=$dir0/file2
16141         # create a file large enough for the concurrent test
16142         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16143         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16144         echo "ref file size: ref1($(stat -c %s $ref1))," \
16145              "ref2($(stat -c %s $ref2))"
16146
16147         cp $ref2 $file2
16148         dd if=$ref1 of=$file1 bs=16k &
16149         local DD_PID=$!
16150
16151         # Make sure dd starts to copy file, but wait at most 5 seconds
16152         local loops=0
16153         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16154
16155         $LFS swap_layouts $file1 $file2
16156         local rc=$?
16157         wait $DD_PID
16158         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16159         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16160
16161         # how many bytes copied before swapping layout
16162         local copied=$(stat -c %s $file2)
16163         local remaining=$(stat -c %s $ref1)
16164         remaining=$((remaining - copied))
16165         echo "Copied $copied bytes before swapping layout..."
16166
16167         cmp -n $copied $file1 $ref2 | grep differ &&
16168                 error "Content mismatch [0, $copied) of ref2 and file1"
16169         cmp -n $copied $file2 $ref1 ||
16170                 error "Content mismatch [0, $copied) of ref1 and file2"
16171         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16172                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16173
16174         # clean up
16175         rm -f $ref1 $ref2 $file1 $file2
16176 }
16177 run_test 184c "Concurrent write and layout swap"
16178
16179 test_184d() {
16180         check_swap_layouts_support
16181         check_swap_layout_no_dom $DIR
16182         [ -z "$(which getfattr 2>/dev/null)" ] &&
16183                 skip_env "no getfattr command"
16184
16185         local file1=$DIR/$tdir/$tfile-1
16186         local file2=$DIR/$tdir/$tfile-2
16187         local file3=$DIR/$tdir/$tfile-3
16188         local lovea1
16189         local lovea2
16190
16191         mkdir -p $DIR/$tdir
16192         touch $file1 || error "create $file1 failed"
16193         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16194                 error "create $file2 failed"
16195         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16196                 error "create $file3 failed"
16197         lovea1=$(get_layout_param $file1)
16198
16199         $LFS swap_layouts $file2 $file3 ||
16200                 error "swap $file2 $file3 layouts failed"
16201         $LFS swap_layouts $file1 $file2 ||
16202                 error "swap $file1 $file2 layouts failed"
16203
16204         lovea2=$(get_layout_param $file2)
16205         echo "$lovea1"
16206         echo "$lovea2"
16207         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16208
16209         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16210         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16211 }
16212 run_test 184d "allow stripeless layouts swap"
16213
16214 test_184e() {
16215         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16216                 skip "Need MDS version at least 2.6.94"
16217         check_swap_layouts_support
16218         check_swap_layout_no_dom $DIR
16219         [ -z "$(which getfattr 2>/dev/null)" ] &&
16220                 skip_env "no getfattr command"
16221
16222         local file1=$DIR/$tdir/$tfile-1
16223         local file2=$DIR/$tdir/$tfile-2
16224         local file3=$DIR/$tdir/$tfile-3
16225         local lovea
16226
16227         mkdir -p $DIR/$tdir
16228         touch $file1 || error "create $file1 failed"
16229         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16230                 error "create $file2 failed"
16231         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16232                 error "create $file3 failed"
16233
16234         $LFS swap_layouts $file1 $file2 ||
16235                 error "swap $file1 $file2 layouts failed"
16236
16237         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16238         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16239
16240         echo 123 > $file1 || error "Should be able to write into $file1"
16241
16242         $LFS swap_layouts $file1 $file3 ||
16243                 error "swap $file1 $file3 layouts failed"
16244
16245         echo 123 > $file1 || error "Should be able to write into $file1"
16246
16247         rm -rf $file1 $file2 $file3
16248 }
16249 run_test 184e "Recreate layout after stripeless layout swaps"
16250
16251 test_184f() {
16252         # Create a file with name longer than sizeof(struct stat) ==
16253         # 144 to see if we can get chars from the file name to appear
16254         # in the returned striping. Note that 'f' == 0x66.
16255         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16256
16257         mkdir -p $DIR/$tdir
16258         mcreate $DIR/$tdir/$file
16259         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16260                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16261         fi
16262 }
16263 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16264
16265 test_185() { # LU-2441
16266         # LU-3553 - no volatile file support in old servers
16267         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16268                 skip "Need MDS version at least 2.3.60"
16269
16270         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16271         touch $DIR/$tdir/spoo
16272         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16273         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16274                 error "cannot create/write a volatile file"
16275         [ "$FILESET" == "" ] &&
16276         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16277                 error "FID is still valid after close"
16278
16279         multiop_bg_pause $DIR/$tdir vVw4096_c
16280         local multi_pid=$!
16281
16282         local OLD_IFS=$IFS
16283         IFS=":"
16284         local fidv=($fid)
16285         IFS=$OLD_IFS
16286         # assume that the next FID for this client is sequential, since stdout
16287         # is unfortunately eaten by multiop_bg_pause
16288         local n=$((${fidv[1]} + 1))
16289         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16290         if [ "$FILESET" == "" ]; then
16291                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16292                         error "FID is missing before close"
16293         fi
16294         kill -USR1 $multi_pid
16295         # 1 second delay, so if mtime change we will see it
16296         sleep 1
16297         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16298         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16299 }
16300 run_test 185 "Volatile file support"
16301
16302 function create_check_volatile() {
16303         local idx=$1
16304         local tgt
16305
16306         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16307         local PID=$!
16308         sleep 1
16309         local FID=$(cat /tmp/${tfile}.fid)
16310         [ "$FID" == "" ] && error "can't get FID for volatile"
16311         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16312         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16313         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16314         kill -USR1 $PID
16315         wait
16316         sleep 1
16317         cancel_lru_locks mdc # flush opencache
16318         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16319         return 0
16320 }
16321
16322 test_185a(){
16323         # LU-12516 - volatile creation via .lustre
16324         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16325                 skip "Need MDS version at least 2.3.55"
16326
16327         create_check_volatile 0
16328         [ $MDSCOUNT -lt 2 ] && return 0
16329
16330         # DNE case
16331         create_check_volatile 1
16332
16333         return 0
16334 }
16335 run_test 185a "Volatile file creation in .lustre/fid/"
16336
16337 test_187a() {
16338         remote_mds_nodsh && skip "remote MDS with nodsh"
16339         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16340                 skip "Need MDS version at least 2.3.0"
16341
16342         local dir0=$DIR/$tdir/$testnum
16343         mkdir -p $dir0 || error "creating dir $dir0"
16344
16345         local file=$dir0/file1
16346         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16347         local dv1=$($LFS data_version $file)
16348         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16349         local dv2=$($LFS data_version $file)
16350         [[ $dv1 != $dv2 ]] ||
16351                 error "data version did not change on write $dv1 == $dv2"
16352
16353         # clean up
16354         rm -f $file1
16355 }
16356 run_test 187a "Test data version change"
16357
16358 test_187b() {
16359         remote_mds_nodsh && skip "remote MDS with nodsh"
16360         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16361                 skip "Need MDS version at least 2.3.0"
16362
16363         local dir0=$DIR/$tdir/$testnum
16364         mkdir -p $dir0 || error "creating dir $dir0"
16365
16366         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16367         [[ ${DV[0]} != ${DV[1]} ]] ||
16368                 error "data version did not change on write"\
16369                       " ${DV[0]} == ${DV[1]}"
16370
16371         # clean up
16372         rm -f $file1
16373 }
16374 run_test 187b "Test data version change on volatile file"
16375
16376 test_200() {
16377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16378         remote_mgs_nodsh && skip "remote MGS with nodsh"
16379         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16380
16381         local POOL=${POOL:-cea1}
16382         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16383         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16384         # Pool OST targets
16385         local first_ost=0
16386         local last_ost=$(($OSTCOUNT - 1))
16387         local ost_step=2
16388         local ost_list=$(seq $first_ost $ost_step $last_ost)
16389         local ost_range="$first_ost $last_ost $ost_step"
16390         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16391         local file_dir=$POOL_ROOT/file_tst
16392         local subdir=$test_path/subdir
16393         local rc=0
16394
16395         while : ; do
16396                 # former test_200a test_200b
16397                 pool_add $POOL                          || { rc=$? ; break; }
16398                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16399                 # former test_200c test_200d
16400                 mkdir -p $test_path
16401                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16402                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16403                 mkdir -p $subdir
16404                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16405                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16406                                                         || { rc=$? ; break; }
16407                 # former test_200e test_200f
16408                 local files=$((OSTCOUNT*3))
16409                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16410                                                         || { rc=$? ; break; }
16411                 pool_create_files $POOL $file_dir $files "$ost_list" \
16412                                                         || { rc=$? ; break; }
16413                 # former test_200g test_200h
16414                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16415                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16416
16417                 # former test_201a test_201b test_201c
16418                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16419
16420                 local f=$test_path/$tfile
16421                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16422                 pool_remove $POOL $f                    || { rc=$? ; break; }
16423                 break
16424         done
16425
16426         destroy_test_pools
16427
16428         return $rc
16429 }
16430 run_test 200 "OST pools"
16431
16432 # usage: default_attr <count | size | offset>
16433 default_attr() {
16434         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16435 }
16436
16437 # usage: check_default_stripe_attr
16438 check_default_stripe_attr() {
16439         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16440         case $1 in
16441         --stripe-count|-c)
16442                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16443         --stripe-size|-S)
16444                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16445         --stripe-index|-i)
16446                 EXPECTED=-1;;
16447         *)
16448                 error "unknown getstripe attr '$1'"
16449         esac
16450
16451         [ $ACTUAL == $EXPECTED ] ||
16452                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16453 }
16454
16455 test_204a() {
16456         test_mkdir $DIR/$tdir
16457         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16458
16459         check_default_stripe_attr --stripe-count
16460         check_default_stripe_attr --stripe-size
16461         check_default_stripe_attr --stripe-index
16462 }
16463 run_test 204a "Print default stripe attributes"
16464
16465 test_204b() {
16466         test_mkdir $DIR/$tdir
16467         $LFS setstripe --stripe-count 1 $DIR/$tdir
16468
16469         check_default_stripe_attr --stripe-size
16470         check_default_stripe_attr --stripe-index
16471 }
16472 run_test 204b "Print default stripe size and offset"
16473
16474 test_204c() {
16475         test_mkdir $DIR/$tdir
16476         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16477
16478         check_default_stripe_attr --stripe-count
16479         check_default_stripe_attr --stripe-index
16480 }
16481 run_test 204c "Print default stripe count and offset"
16482
16483 test_204d() {
16484         test_mkdir $DIR/$tdir
16485         $LFS setstripe --stripe-index 0 $DIR/$tdir
16486
16487         check_default_stripe_attr --stripe-count
16488         check_default_stripe_attr --stripe-size
16489 }
16490 run_test 204d "Print default stripe count and size"
16491
16492 test_204e() {
16493         test_mkdir $DIR/$tdir
16494         $LFS setstripe -d $DIR/$tdir
16495
16496         check_default_stripe_attr --stripe-count --raw
16497         check_default_stripe_attr --stripe-size --raw
16498         check_default_stripe_attr --stripe-index --raw
16499 }
16500 run_test 204e "Print raw stripe attributes"
16501
16502 test_204f() {
16503         test_mkdir $DIR/$tdir
16504         $LFS setstripe --stripe-count 1 $DIR/$tdir
16505
16506         check_default_stripe_attr --stripe-size --raw
16507         check_default_stripe_attr --stripe-index --raw
16508 }
16509 run_test 204f "Print raw stripe size and offset"
16510
16511 test_204g() {
16512         test_mkdir $DIR/$tdir
16513         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16514
16515         check_default_stripe_attr --stripe-count --raw
16516         check_default_stripe_attr --stripe-index --raw
16517 }
16518 run_test 204g "Print raw stripe count and offset"
16519
16520 test_204h() {
16521         test_mkdir $DIR/$tdir
16522         $LFS setstripe --stripe-index 0 $DIR/$tdir
16523
16524         check_default_stripe_attr --stripe-count --raw
16525         check_default_stripe_attr --stripe-size --raw
16526 }
16527 run_test 204h "Print raw stripe count and size"
16528
16529 # Figure out which job scheduler is being used, if any,
16530 # or use a fake one
16531 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16532         JOBENV=SLURM_JOB_ID
16533 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16534         JOBENV=LSB_JOBID
16535 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16536         JOBENV=PBS_JOBID
16537 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16538         JOBENV=LOADL_STEP_ID
16539 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16540         JOBENV=JOB_ID
16541 else
16542         $LCTL list_param jobid_name > /dev/null 2>&1
16543         if [ $? -eq 0 ]; then
16544                 JOBENV=nodelocal
16545         else
16546                 JOBENV=FAKE_JOBID
16547         fi
16548 fi
16549 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16550
16551 verify_jobstats() {
16552         local cmd=($1)
16553         shift
16554         local facets="$@"
16555
16556 # we don't really need to clear the stats for this test to work, since each
16557 # command has a unique jobid, but it makes debugging easier if needed.
16558 #       for facet in $facets; do
16559 #               local dev=$(convert_facet2label $facet)
16560 #               # clear old jobstats
16561 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16562 #       done
16563
16564         # use a new JobID for each test, or we might see an old one
16565         [ "$JOBENV" = "FAKE_JOBID" ] &&
16566                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16567
16568         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16569
16570         [ "$JOBENV" = "nodelocal" ] && {
16571                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16572                 $LCTL set_param jobid_name=$FAKE_JOBID
16573                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16574         }
16575
16576         log "Test: ${cmd[*]}"
16577         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16578
16579         if [ $JOBENV = "FAKE_JOBID" ]; then
16580                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16581         else
16582                 ${cmd[*]}
16583         fi
16584
16585         # all files are created on OST0000
16586         for facet in $facets; do
16587                 local stats="*.$(convert_facet2label $facet).job_stats"
16588
16589                 # strip out libtool wrappers for in-tree executables
16590                 if [ $(do_facet $facet lctl get_param $stats |
16591                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16592                         do_facet $facet lctl get_param $stats
16593                         error "No jobstats for $JOBVAL found on $facet::$stats"
16594                 fi
16595         done
16596 }
16597
16598 jobstats_set() {
16599         local new_jobenv=$1
16600
16601         set_persistent_param_and_check client "jobid_var" \
16602                 "$FSNAME.sys.jobid_var" $new_jobenv
16603 }
16604
16605 test_205a() { # Job stats
16606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16607         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16608                 skip "Need MDS version with at least 2.7.1"
16609         remote_mgs_nodsh && skip "remote MGS with nodsh"
16610         remote_mds_nodsh && skip "remote MDS with nodsh"
16611         remote_ost_nodsh && skip "remote OST with nodsh"
16612         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16613                 skip "Server doesn't support jobstats"
16614         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16615
16616         local old_jobenv=$($LCTL get_param -n jobid_var)
16617         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16618
16619         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16620                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16621         else
16622                 stack_trap "do_facet mgs $PERM_CMD \
16623                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16624         fi
16625         changelog_register
16626
16627         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16628                                 mdt.*.job_cleanup_interval | head -n 1)
16629         local new_interval=5
16630         do_facet $SINGLEMDS \
16631                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16632         stack_trap "do_facet $SINGLEMDS \
16633                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16634         local start=$SECONDS
16635
16636         local cmd
16637         # mkdir
16638         cmd="mkdir $DIR/$tdir"
16639         verify_jobstats "$cmd" "$SINGLEMDS"
16640         # rmdir
16641         cmd="rmdir $DIR/$tdir"
16642         verify_jobstats "$cmd" "$SINGLEMDS"
16643         # mkdir on secondary MDT
16644         if [ $MDSCOUNT -gt 1 ]; then
16645                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16646                 verify_jobstats "$cmd" "mds2"
16647         fi
16648         # mknod
16649         cmd="mknod $DIR/$tfile c 1 3"
16650         verify_jobstats "$cmd" "$SINGLEMDS"
16651         # unlink
16652         cmd="rm -f $DIR/$tfile"
16653         verify_jobstats "$cmd" "$SINGLEMDS"
16654         # create all files on OST0000 so verify_jobstats can find OST stats
16655         # open & close
16656         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16657         verify_jobstats "$cmd" "$SINGLEMDS"
16658         # setattr
16659         cmd="touch $DIR/$tfile"
16660         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16661         # write
16662         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16663         verify_jobstats "$cmd" "ost1"
16664         # read
16665         cancel_lru_locks osc
16666         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16667         verify_jobstats "$cmd" "ost1"
16668         # truncate
16669         cmd="$TRUNCATE $DIR/$tfile 0"
16670         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16671         # rename
16672         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16673         verify_jobstats "$cmd" "$SINGLEMDS"
16674         # jobstats expiry - sleep until old stats should be expired
16675         local left=$((new_interval + 5 - (SECONDS - start)))
16676         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16677                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16678                         "0" $left
16679         cmd="mkdir $DIR/$tdir.expire"
16680         verify_jobstats "$cmd" "$SINGLEMDS"
16681         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16682             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16683
16684         # Ensure that jobid are present in changelog (if supported by MDS)
16685         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16686                 changelog_dump | tail -10
16687                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16688                 [ $jobids -eq 9 ] ||
16689                         error "Wrong changelog jobid count $jobids != 9"
16690
16691                 # LU-5862
16692                 JOBENV="disable"
16693                 jobstats_set $JOBENV
16694                 touch $DIR/$tfile
16695                 changelog_dump | grep $tfile
16696                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16697                 [ $jobids -eq 0 ] ||
16698                         error "Unexpected jobids when jobid_var=$JOBENV"
16699         fi
16700
16701         # test '%j' access to environment variable - if supported
16702         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16703                 JOBENV="JOBCOMPLEX"
16704                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16705
16706                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16707         fi
16708
16709         # test '%j' access to per-session jobid - if supported
16710         if lctl list_param jobid_this_session > /dev/null 2>&1
16711         then
16712                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16713                 lctl set_param jobid_this_session=$USER
16714
16715                 JOBENV="JOBCOMPLEX"
16716                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16717
16718                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16719         fi
16720 }
16721 run_test 205a "Verify job stats"
16722
16723 # LU-13117, LU-13597
16724 test_205b() {
16725         job_stats="mdt.*.job_stats"
16726         $LCTL set_param $job_stats=clear
16727         # Setting jobid_var to USER might not be supported
16728         $LCTL set_param jobid_var=USER || true
16729         $LCTL set_param jobid_name="%e.%u"
16730         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16731         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16732                 grep "job_id:.*foolish" &&
16733                         error "Unexpected jobid found"
16734         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16735                 grep "open:.*min.*max.*sum" ||
16736                         error "wrong job_stats format found"
16737 }
16738 run_test 205b "Verify job stats jobid and output format"
16739
16740 # LU-13733
16741 test_205c() {
16742         $LCTL set_param llite.*.stats=0
16743         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16744         $LCTL get_param llite.*.stats
16745         $LCTL get_param llite.*.stats | grep \
16746                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16747                         error "wrong client stats format found"
16748 }
16749 run_test 205c "Verify client stats format"
16750
16751 # LU-1480, LU-1773 and LU-1657
16752 test_206() {
16753         mkdir -p $DIR/$tdir
16754         $LFS setstripe -c -1 $DIR/$tdir
16755 #define OBD_FAIL_LOV_INIT 0x1403
16756         $LCTL set_param fail_loc=0xa0001403
16757         $LCTL set_param fail_val=1
16758         touch $DIR/$tdir/$tfile || true
16759 }
16760 run_test 206 "fail lov_init_raid0() doesn't lbug"
16761
16762 test_207a() {
16763         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16764         local fsz=`stat -c %s $DIR/$tfile`
16765         cancel_lru_locks mdc
16766
16767         # do not return layout in getattr intent
16768 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16769         $LCTL set_param fail_loc=0x170
16770         local sz=`stat -c %s $DIR/$tfile`
16771
16772         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16773
16774         rm -rf $DIR/$tfile
16775 }
16776 run_test 207a "can refresh layout at glimpse"
16777
16778 test_207b() {
16779         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16780         local cksum=`md5sum $DIR/$tfile`
16781         local fsz=`stat -c %s $DIR/$tfile`
16782         cancel_lru_locks mdc
16783         cancel_lru_locks osc
16784
16785         # do not return layout in getattr intent
16786 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16787         $LCTL set_param fail_loc=0x171
16788
16789         # it will refresh layout after the file is opened but before read issues
16790         echo checksum is "$cksum"
16791         echo "$cksum" |md5sum -c --quiet || error "file differs"
16792
16793         rm -rf $DIR/$tfile
16794 }
16795 run_test 207b "can refresh layout at open"
16796
16797 test_208() {
16798         # FIXME: in this test suite, only RD lease is used. This is okay
16799         # for now as only exclusive open is supported. After generic lease
16800         # is done, this test suite should be revised. - Jinshan
16801
16802         remote_mds_nodsh && skip "remote MDS with nodsh"
16803         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16804                 skip "Need MDS version at least 2.4.52"
16805
16806         echo "==== test 1: verify get lease work"
16807         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16808
16809         echo "==== test 2: verify lease can be broken by upcoming open"
16810         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16811         local PID=$!
16812         sleep 1
16813
16814         $MULTIOP $DIR/$tfile oO_RDONLY:c
16815         kill -USR1 $PID && wait $PID || error "break lease error"
16816
16817         echo "==== test 3: verify lease can't be granted if an open already exists"
16818         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16819         local PID=$!
16820         sleep 1
16821
16822         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16823         kill -USR1 $PID && wait $PID || error "open file error"
16824
16825         echo "==== test 4: lease can sustain over recovery"
16826         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16827         PID=$!
16828         sleep 1
16829
16830         fail mds1
16831
16832         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16833
16834         echo "==== test 5: lease broken can't be regained by replay"
16835         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16836         PID=$!
16837         sleep 1
16838
16839         # open file to break lease and then recovery
16840         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16841         fail mds1
16842
16843         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16844
16845         rm -f $DIR/$tfile
16846 }
16847 run_test 208 "Exclusive open"
16848
16849 test_209() {
16850         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16851                 skip_env "must have disp_stripe"
16852
16853         touch $DIR/$tfile
16854         sync; sleep 5; sync;
16855
16856         echo 3 > /proc/sys/vm/drop_caches
16857         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16858                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16859         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16860
16861         # open/close 500 times
16862         for i in $(seq 500); do
16863                 cat $DIR/$tfile
16864         done
16865
16866         echo 3 > /proc/sys/vm/drop_caches
16867         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16868                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16869         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16870
16871         echo "before: $req_before, after: $req_after"
16872         [ $((req_after - req_before)) -ge 300 ] &&
16873                 error "open/close requests are not freed"
16874         return 0
16875 }
16876 run_test 209 "read-only open/close requests should be freed promptly"
16877
16878 test_210() {
16879         local pid
16880
16881         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16882         pid=$!
16883         sleep 1
16884
16885         $LFS getstripe $DIR/$tfile
16886         kill -USR1 $pid
16887         wait $pid || error "multiop failed"
16888
16889         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16890         pid=$!
16891         sleep 1
16892
16893         $LFS getstripe $DIR/$tfile
16894         kill -USR1 $pid
16895         wait $pid || error "multiop failed"
16896 }
16897 run_test 210 "lfs getstripe does not break leases"
16898
16899 test_212() {
16900         size=`date +%s`
16901         size=$((size % 8192 + 1))
16902         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16903         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16904         rm -f $DIR/f212 $DIR/f212.xyz
16905 }
16906 run_test 212 "Sendfile test ============================================"
16907
16908 test_213() {
16909         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16910         cancel_lru_locks osc
16911         lctl set_param fail_loc=0x8000040f
16912         # generate a read lock
16913         cat $DIR/$tfile > /dev/null
16914         # write to the file, it will try to cancel the above read lock.
16915         cat /etc/hosts >> $DIR/$tfile
16916 }
16917 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16918
16919 test_214() { # for bug 20133
16920         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16921         for (( i=0; i < 340; i++ )) ; do
16922                 touch $DIR/$tdir/d214c/a$i
16923         done
16924
16925         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16926         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16927         ls $DIR/d214c || error "ls $DIR/d214c failed"
16928         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16929         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16930 }
16931 run_test 214 "hash-indexed directory test - bug 20133"
16932
16933 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16934 create_lnet_proc_files() {
16935         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16936 }
16937
16938 # counterpart of create_lnet_proc_files
16939 remove_lnet_proc_files() {
16940         rm -f $TMP/lnet_$1.sys
16941 }
16942
16943 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16944 # 3rd arg as regexp for body
16945 check_lnet_proc_stats() {
16946         local l=$(cat "$TMP/lnet_$1" |wc -l)
16947         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16948
16949         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16950 }
16951
16952 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16953 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16954 # optional and can be regexp for 2nd line (lnet.routes case)
16955 check_lnet_proc_entry() {
16956         local blp=2          # blp stands for 'position of 1st line of body'
16957         [ -z "$5" ] || blp=3 # lnet.routes case
16958
16959         local l=$(cat "$TMP/lnet_$1" |wc -l)
16960         # subtracting one from $blp because the body can be empty
16961         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16962
16963         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16964                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16965
16966         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16967                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16968
16969         # bail out if any unexpected line happened
16970         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16971         [ "$?" != 0 ] || error "$2 misformatted"
16972 }
16973
16974 test_215() { # for bugs 18102, 21079, 21517
16975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16976
16977         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16978         local P='[1-9][0-9]*'           # positive numeric
16979         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16980         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16981         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16982         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16983
16984         local L1 # regexp for 1st line
16985         local L2 # regexp for 2nd line (optional)
16986         local BR # regexp for the rest (body)
16987
16988         # lnet.stats should look as 11 space-separated non-negative numerics
16989         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16990         create_lnet_proc_files "stats"
16991         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16992         remove_lnet_proc_files "stats"
16993
16994         # lnet.routes should look like this:
16995         # Routing disabled/enabled
16996         # net hops priority state router
16997         # where net is a string like tcp0, hops > 0, priority >= 0,
16998         # state is up/down,
16999         # router is a string like 192.168.1.1@tcp2
17000         L1="^Routing (disabled|enabled)$"
17001         L2="^net +hops +priority +state +router$"
17002         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17003         create_lnet_proc_files "routes"
17004         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17005         remove_lnet_proc_files "routes"
17006
17007         # lnet.routers should look like this:
17008         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17009         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17010         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17011         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17012         L1="^ref +rtr_ref +alive +router$"
17013         BR="^$P +$P +(up|down) +$NID$"
17014         create_lnet_proc_files "routers"
17015         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17016         remove_lnet_proc_files "routers"
17017
17018         # lnet.peers should look like this:
17019         # nid refs state last max rtr min tx min queue
17020         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17021         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17022         # numeric (0 or >0 or <0), queue >= 0.
17023         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17024         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17025         create_lnet_proc_files "peers"
17026         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17027         remove_lnet_proc_files "peers"
17028
17029         # lnet.buffers  should look like this:
17030         # pages count credits min
17031         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17032         L1="^pages +count +credits +min$"
17033         BR="^ +$N +$N +$I +$I$"
17034         create_lnet_proc_files "buffers"
17035         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17036         remove_lnet_proc_files "buffers"
17037
17038         # lnet.nis should look like this:
17039         # nid status alive refs peer rtr max tx min
17040         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17041         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17042         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17043         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17044         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17045         create_lnet_proc_files "nis"
17046         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17047         remove_lnet_proc_files "nis"
17048
17049         # can we successfully write to lnet.stats?
17050         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17051 }
17052 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17053
17054 test_216() { # bug 20317
17055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17056         remote_ost_nodsh && skip "remote OST with nodsh"
17057
17058         local node
17059         local facets=$(get_facets OST)
17060         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17061
17062         save_lustre_params client "osc.*.contention_seconds" > $p
17063         save_lustre_params $facets \
17064                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17065         save_lustre_params $facets \
17066                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17067         save_lustre_params $facets \
17068                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17069         clear_stats osc.*.osc_stats
17070
17071         # agressive lockless i/o settings
17072         do_nodes $(comma_list $(osts_nodes)) \
17073                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17074                         ldlm.namespaces.filter-*.contended_locks=0 \
17075                         ldlm.namespaces.filter-*.contention_seconds=60"
17076         lctl set_param -n osc.*.contention_seconds=60
17077
17078         $DIRECTIO write $DIR/$tfile 0 10 4096
17079         $CHECKSTAT -s 40960 $DIR/$tfile
17080
17081         # disable lockless i/o
17082         do_nodes $(comma_list $(osts_nodes)) \
17083                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17084                         ldlm.namespaces.filter-*.contended_locks=32 \
17085                         ldlm.namespaces.filter-*.contention_seconds=0"
17086         lctl set_param -n osc.*.contention_seconds=0
17087         clear_stats osc.*.osc_stats
17088
17089         dd if=/dev/zero of=$DIR/$tfile count=0
17090         $CHECKSTAT -s 0 $DIR/$tfile
17091
17092         restore_lustre_params <$p
17093         rm -f $p
17094         rm $DIR/$tfile
17095 }
17096 run_test 216 "check lockless direct write updates file size and kms correctly"
17097
17098 test_217() { # bug 22430
17099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17100
17101         local node
17102         local nid
17103
17104         for node in $(nodes_list); do
17105                 nid=$(host_nids_address $node $NETTYPE)
17106                 if [[ $nid = *-* ]] ; then
17107                         echo "lctl ping $(h2nettype $nid)"
17108                         lctl ping $(h2nettype $nid)
17109                 else
17110                         echo "skipping $node (no hyphen detected)"
17111                 fi
17112         done
17113 }
17114 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17115
17116 test_218() {
17117        # do directio so as not to populate the page cache
17118        log "creating a 10 Mb file"
17119        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17120        log "starting reads"
17121        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17122        log "truncating the file"
17123        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17124        log "killing dd"
17125        kill %+ || true # reads might have finished
17126        echo "wait until dd is finished"
17127        wait
17128        log "removing the temporary file"
17129        rm -rf $DIR/$tfile || error "tmp file removal failed"
17130 }
17131 run_test 218 "parallel read and truncate should not deadlock"
17132
17133 test_219() {
17134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17135
17136         # write one partial page
17137         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17138         # set no grant so vvp_io_commit_write will do sync write
17139         $LCTL set_param fail_loc=0x411
17140         # write a full page at the end of file
17141         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17142
17143         $LCTL set_param fail_loc=0
17144         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17145         $LCTL set_param fail_loc=0x411
17146         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17147
17148         # LU-4201
17149         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17150         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17151 }
17152 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17153
17154 test_220() { #LU-325
17155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17156         remote_ost_nodsh && skip "remote OST with nodsh"
17157         remote_mds_nodsh && skip "remote MDS with nodsh"
17158         remote_mgs_nodsh && skip "remote MGS with nodsh"
17159
17160         local OSTIDX=0
17161
17162         # create on MDT0000 so the last_id and next_id are correct
17163         mkdir $DIR/$tdir
17164         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17165         OST=${OST%_UUID}
17166
17167         # on the mdt's osc
17168         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17169         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17170                         osp.$mdtosc_proc1.prealloc_last_id)
17171         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17172                         osp.$mdtosc_proc1.prealloc_next_id)
17173
17174         $LFS df -i
17175
17176         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17177         #define OBD_FAIL_OST_ENOINO              0x229
17178         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17179         create_pool $FSNAME.$TESTNAME || return 1
17180         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17181
17182         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17183
17184         MDSOBJS=$((last_id - next_id))
17185         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17186
17187         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17188         echo "OST still has $count kbytes free"
17189
17190         echo "create $MDSOBJS files @next_id..."
17191         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17192
17193         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17194                         osp.$mdtosc_proc1.prealloc_last_id)
17195         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17196                         osp.$mdtosc_proc1.prealloc_next_id)
17197
17198         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17199         $LFS df -i
17200
17201         echo "cleanup..."
17202
17203         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17204         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17205
17206         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17207                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17208         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17209                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17210         echo "unlink $MDSOBJS files @$next_id..."
17211         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17212 }
17213 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17214
17215 test_221() {
17216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17217
17218         dd if=`which date` of=$MOUNT/date oflag=sync
17219         chmod +x $MOUNT/date
17220
17221         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17222         $LCTL set_param fail_loc=0x80001401
17223
17224         $MOUNT/date > /dev/null
17225         rm -f $MOUNT/date
17226 }
17227 run_test 221 "make sure fault and truncate race to not cause OOM"
17228
17229 test_222a () {
17230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17231
17232         rm -rf $DIR/$tdir
17233         test_mkdir $DIR/$tdir
17234         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17235         createmany -o $DIR/$tdir/$tfile 10
17236         cancel_lru_locks mdc
17237         cancel_lru_locks osc
17238         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17239         $LCTL set_param fail_loc=0x31a
17240         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17241         $LCTL set_param fail_loc=0
17242         rm -r $DIR/$tdir
17243 }
17244 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17245
17246 test_222b () {
17247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17248
17249         rm -rf $DIR/$tdir
17250         test_mkdir $DIR/$tdir
17251         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17252         createmany -o $DIR/$tdir/$tfile 10
17253         cancel_lru_locks mdc
17254         cancel_lru_locks osc
17255         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17256         $LCTL set_param fail_loc=0x31a
17257         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17258         $LCTL set_param fail_loc=0
17259 }
17260 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17261
17262 test_223 () {
17263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17264
17265         rm -rf $DIR/$tdir
17266         test_mkdir $DIR/$tdir
17267         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17268         createmany -o $DIR/$tdir/$tfile 10
17269         cancel_lru_locks mdc
17270         cancel_lru_locks osc
17271         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17272         $LCTL set_param fail_loc=0x31b
17273         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17274         $LCTL set_param fail_loc=0
17275         rm -r $DIR/$tdir
17276 }
17277 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17278
17279 test_224a() { # LU-1039, MRP-303
17280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17281
17282         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17283         $LCTL set_param fail_loc=0x508
17284         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17285         $LCTL set_param fail_loc=0
17286         df $DIR
17287 }
17288 run_test 224a "Don't panic on bulk IO failure"
17289
17290 test_224b() { # LU-1039, MRP-303
17291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17292
17293         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17294         cancel_lru_locks osc
17295         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17296         $LCTL set_param fail_loc=0x515
17297         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17298         $LCTL set_param fail_loc=0
17299         df $DIR
17300 }
17301 run_test 224b "Don't panic on bulk IO failure"
17302
17303 test_224c() { # LU-6441
17304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17305         remote_mds_nodsh && skip "remote MDS with nodsh"
17306
17307         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17308         save_writethrough $p
17309         set_cache writethrough on
17310
17311         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17312         local at_max=$($LCTL get_param -n at_max)
17313         local timeout=$($LCTL get_param -n timeout)
17314         local test_at="at_max"
17315         local param_at="$FSNAME.sys.at_max"
17316         local test_timeout="timeout"
17317         local param_timeout="$FSNAME.sys.timeout"
17318
17319         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17320
17321         set_persistent_param_and_check client "$test_at" "$param_at" 0
17322         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17323
17324         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17325         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17326         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17327         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17328         sync
17329         do_facet ost1 "$LCTL set_param fail_loc=0"
17330
17331         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17332         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17333                 $timeout
17334
17335         $LCTL set_param -n $pages_per_rpc
17336         restore_lustre_params < $p
17337         rm -f $p
17338 }
17339 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17340
17341 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17342 test_225a () {
17343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17344         if [ -z ${MDSSURVEY} ]; then
17345                 skip_env "mds-survey not found"
17346         fi
17347         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17348                 skip "Need MDS version at least 2.2.51"
17349
17350         local mds=$(facet_host $SINGLEMDS)
17351         local target=$(do_nodes $mds 'lctl dl' |
17352                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17353
17354         local cmd1="file_count=1000 thrhi=4"
17355         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17356         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17357         local cmd="$cmd1 $cmd2 $cmd3"
17358
17359         rm -f ${TMP}/mds_survey*
17360         echo + $cmd
17361         eval $cmd || error "mds-survey with zero-stripe failed"
17362         cat ${TMP}/mds_survey*
17363         rm -f ${TMP}/mds_survey*
17364 }
17365 run_test 225a "Metadata survey sanity with zero-stripe"
17366
17367 test_225b () {
17368         if [ -z ${MDSSURVEY} ]; then
17369                 skip_env "mds-survey not found"
17370         fi
17371         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17372                 skip "Need MDS version at least 2.2.51"
17373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17374         remote_mds_nodsh && skip "remote MDS with nodsh"
17375         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17376                 skip_env "Need to mount OST to test"
17377         fi
17378
17379         local mds=$(facet_host $SINGLEMDS)
17380         local target=$(do_nodes $mds 'lctl dl' |
17381                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17382
17383         local cmd1="file_count=1000 thrhi=4"
17384         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17385         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17386         local cmd="$cmd1 $cmd2 $cmd3"
17387
17388         rm -f ${TMP}/mds_survey*
17389         echo + $cmd
17390         eval $cmd || error "mds-survey with stripe_count failed"
17391         cat ${TMP}/mds_survey*
17392         rm -f ${TMP}/mds_survey*
17393 }
17394 run_test 225b "Metadata survey sanity with stripe_count = 1"
17395
17396 mcreate_path2fid () {
17397         local mode=$1
17398         local major=$2
17399         local minor=$3
17400         local name=$4
17401         local desc=$5
17402         local path=$DIR/$tdir/$name
17403         local fid
17404         local rc
17405         local fid_path
17406
17407         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17408                 error "cannot create $desc"
17409
17410         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17411         rc=$?
17412         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17413
17414         fid_path=$($LFS fid2path $MOUNT $fid)
17415         rc=$?
17416         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17417
17418         [ "$path" == "$fid_path" ] ||
17419                 error "fid2path returned $fid_path, expected $path"
17420
17421         echo "pass with $path and $fid"
17422 }
17423
17424 test_226a () {
17425         rm -rf $DIR/$tdir
17426         mkdir -p $DIR/$tdir
17427
17428         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17429         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17430         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17431         mcreate_path2fid 0040666 0 0 dir "directory"
17432         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17433         mcreate_path2fid 0100666 0 0 file "regular file"
17434         mcreate_path2fid 0120666 0 0 link "symbolic link"
17435         mcreate_path2fid 0140666 0 0 sock "socket"
17436 }
17437 run_test 226a "call path2fid and fid2path on files of all type"
17438
17439 test_226b () {
17440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17441
17442         local MDTIDX=1
17443
17444         rm -rf $DIR/$tdir
17445         mkdir -p $DIR/$tdir
17446         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17447                 error "create remote directory failed"
17448         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17449         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17450                                 "character special file (null)"
17451         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17452                                 "character special file (no device)"
17453         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17454         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17455                                 "block special file (loop)"
17456         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17457         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17458         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17459 }
17460 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17461
17462 test_226c () {
17463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17464         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17465                 skip "Need MDS version at least 2.13.55"
17466
17467         local submnt=/mnt/submnt
17468         local srcfile=/etc/passwd
17469         local dstfile=$submnt/passwd
17470         local path
17471         local fid
17472
17473         rm -rf $DIR/$tdir
17474         rm -rf $submnt
17475         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17476                 error "create remote directory failed"
17477         mkdir -p $submnt || error "create $submnt failed"
17478         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17479                 error "mount $submnt failed"
17480         stack_trap "umount $submnt" EXIT
17481
17482         cp $srcfile $dstfile
17483         fid=$($LFS path2fid $dstfile)
17484         path=$($LFS fid2path $submnt "$fid")
17485         [ "$path" = "$dstfile" ] ||
17486                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17487 }
17488 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17489
17490 # LU-1299 Executing or running ldd on a truncated executable does not
17491 # cause an out-of-memory condition.
17492 test_227() {
17493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17494         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17495
17496         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17497         chmod +x $MOUNT/date
17498
17499         $MOUNT/date > /dev/null
17500         ldd $MOUNT/date > /dev/null
17501         rm -f $MOUNT/date
17502 }
17503 run_test 227 "running truncated executable does not cause OOM"
17504
17505 # LU-1512 try to reuse idle OI blocks
17506 test_228a() {
17507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17508         remote_mds_nodsh && skip "remote MDS with nodsh"
17509         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17510
17511         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17512         local myDIR=$DIR/$tdir
17513
17514         mkdir -p $myDIR
17515         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17516         $LCTL set_param fail_loc=0x80001002
17517         createmany -o $myDIR/t- 10000
17518         $LCTL set_param fail_loc=0
17519         # The guard is current the largest FID holder
17520         touch $myDIR/guard
17521         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17522                     tr -d '[')
17523         local IDX=$(($SEQ % 64))
17524
17525         do_facet $SINGLEMDS sync
17526         # Make sure journal flushed.
17527         sleep 6
17528         local blk1=$(do_facet $SINGLEMDS \
17529                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17530                      grep Blockcount | awk '{print $4}')
17531
17532         # Remove old files, some OI blocks will become idle.
17533         unlinkmany $myDIR/t- 10000
17534         # Create new files, idle OI blocks should be reused.
17535         createmany -o $myDIR/t- 2000
17536         do_facet $SINGLEMDS sync
17537         # Make sure journal flushed.
17538         sleep 6
17539         local blk2=$(do_facet $SINGLEMDS \
17540                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17541                      grep Blockcount | awk '{print $4}')
17542
17543         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17544 }
17545 run_test 228a "try to reuse idle OI blocks"
17546
17547 test_228b() {
17548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17549         remote_mds_nodsh && skip "remote MDS with nodsh"
17550         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17551
17552         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17553         local myDIR=$DIR/$tdir
17554
17555         mkdir -p $myDIR
17556         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17557         $LCTL set_param fail_loc=0x80001002
17558         createmany -o $myDIR/t- 10000
17559         $LCTL set_param fail_loc=0
17560         # The guard is current the largest FID holder
17561         touch $myDIR/guard
17562         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17563                     tr -d '[')
17564         local IDX=$(($SEQ % 64))
17565
17566         do_facet $SINGLEMDS sync
17567         # Make sure journal flushed.
17568         sleep 6
17569         local blk1=$(do_facet $SINGLEMDS \
17570                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17571                      grep Blockcount | awk '{print $4}')
17572
17573         # Remove old files, some OI blocks will become idle.
17574         unlinkmany $myDIR/t- 10000
17575
17576         # stop the MDT
17577         stop $SINGLEMDS || error "Fail to stop MDT."
17578         # remount the MDT
17579         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17580
17581         df $MOUNT || error "Fail to df."
17582         # Create new files, idle OI blocks should be reused.
17583         createmany -o $myDIR/t- 2000
17584         do_facet $SINGLEMDS sync
17585         # Make sure journal flushed.
17586         sleep 6
17587         local blk2=$(do_facet $SINGLEMDS \
17588                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17589                      grep Blockcount | awk '{print $4}')
17590
17591         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17592 }
17593 run_test 228b "idle OI blocks can be reused after MDT restart"
17594
17595 #LU-1881
17596 test_228c() {
17597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17598         remote_mds_nodsh && skip "remote MDS with nodsh"
17599         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17600
17601         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17602         local myDIR=$DIR/$tdir
17603
17604         mkdir -p $myDIR
17605         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17606         $LCTL set_param fail_loc=0x80001002
17607         # 20000 files can guarantee there are index nodes in the OI file
17608         createmany -o $myDIR/t- 20000
17609         $LCTL set_param fail_loc=0
17610         # The guard is current the largest FID holder
17611         touch $myDIR/guard
17612         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17613                     tr -d '[')
17614         local IDX=$(($SEQ % 64))
17615
17616         do_facet $SINGLEMDS sync
17617         # Make sure journal flushed.
17618         sleep 6
17619         local blk1=$(do_facet $SINGLEMDS \
17620                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17621                      grep Blockcount | awk '{print $4}')
17622
17623         # Remove old files, some OI blocks will become idle.
17624         unlinkmany $myDIR/t- 20000
17625         rm -f $myDIR/guard
17626         # The OI file should become empty now
17627
17628         # Create new files, idle OI blocks should be reused.
17629         createmany -o $myDIR/t- 2000
17630         do_facet $SINGLEMDS sync
17631         # Make sure journal flushed.
17632         sleep 6
17633         local blk2=$(do_facet $SINGLEMDS \
17634                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17635                      grep Blockcount | awk '{print $4}')
17636
17637         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17638 }
17639 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17640
17641 test_229() { # LU-2482, LU-3448
17642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17643         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17644         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17645                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17646
17647         rm -f $DIR/$tfile
17648
17649         # Create a file with a released layout and stripe count 2.
17650         $MULTIOP $DIR/$tfile H2c ||
17651                 error "failed to create file with released layout"
17652
17653         $LFS getstripe -v $DIR/$tfile
17654
17655         local pattern=$($LFS getstripe -L $DIR/$tfile)
17656         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17657
17658         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17659                 error "getstripe"
17660         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17661         stat $DIR/$tfile || error "failed to stat released file"
17662
17663         chown $RUNAS_ID $DIR/$tfile ||
17664                 error "chown $RUNAS_ID $DIR/$tfile failed"
17665
17666         chgrp $RUNAS_ID $DIR/$tfile ||
17667                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17668
17669         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17670         rm $DIR/$tfile || error "failed to remove released file"
17671 }
17672 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17673
17674 test_230a() {
17675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17677         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17678                 skip "Need MDS version at least 2.11.52"
17679
17680         local MDTIDX=1
17681
17682         test_mkdir $DIR/$tdir
17683         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17684         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17685         [ $mdt_idx -ne 0 ] &&
17686                 error "create local directory on wrong MDT $mdt_idx"
17687
17688         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17689                         error "create remote directory failed"
17690         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17691         [ $mdt_idx -ne $MDTIDX ] &&
17692                 error "create remote directory on wrong MDT $mdt_idx"
17693
17694         createmany -o $DIR/$tdir/test_230/t- 10 ||
17695                 error "create files on remote directory failed"
17696         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17697         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17698         rm -r $DIR/$tdir || error "unlink remote directory failed"
17699 }
17700 run_test 230a "Create remote directory and files under the remote directory"
17701
17702 test_230b() {
17703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17705         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17706                 skip "Need MDS version at least 2.11.52"
17707
17708         local MDTIDX=1
17709         local mdt_index
17710         local i
17711         local file
17712         local pid
17713         local stripe_count
17714         local migrate_dir=$DIR/$tdir/migrate_dir
17715         local other_dir=$DIR/$tdir/other_dir
17716
17717         test_mkdir $DIR/$tdir
17718         test_mkdir -i0 -c1 $migrate_dir
17719         test_mkdir -i0 -c1 $other_dir
17720         for ((i=0; i<10; i++)); do
17721                 mkdir -p $migrate_dir/dir_${i}
17722                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17723                         error "create files under remote dir failed $i"
17724         done
17725
17726         cp /etc/passwd $migrate_dir/$tfile
17727         cp /etc/passwd $other_dir/$tfile
17728         chattr +SAD $migrate_dir
17729         chattr +SAD $migrate_dir/$tfile
17730
17731         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17732         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17733         local old_dir_mode=$(stat -c%f $migrate_dir)
17734         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17735
17736         mkdir -p $migrate_dir/dir_default_stripe2
17737         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17738         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17739
17740         mkdir -p $other_dir
17741         ln $migrate_dir/$tfile $other_dir/luna
17742         ln $migrate_dir/$tfile $migrate_dir/sofia
17743         ln $other_dir/$tfile $migrate_dir/david
17744         ln -s $migrate_dir/$tfile $other_dir/zachary
17745         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17746         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17747
17748         local len
17749         local lnktgt
17750
17751         # inline symlink
17752         for len in 58 59 60; do
17753                 lnktgt=$(str_repeat 'l' $len)
17754                 touch $migrate_dir/$lnktgt
17755                 ln -s $lnktgt $migrate_dir/${len}char_ln
17756         done
17757
17758         # PATH_MAX
17759         for len in 4094 4095; do
17760                 lnktgt=$(str_repeat 'l' $len)
17761                 ln -s $lnktgt $migrate_dir/${len}char_ln
17762         done
17763
17764         # NAME_MAX
17765         for len in 254 255; do
17766                 touch $migrate_dir/$(str_repeat 'l' $len)
17767         done
17768
17769         $LFS migrate -m $MDTIDX $migrate_dir ||
17770                 error "fails on migrating remote dir to MDT1"
17771
17772         echo "migratate to MDT1, then checking.."
17773         for ((i = 0; i < 10; i++)); do
17774                 for file in $(find $migrate_dir/dir_${i}); do
17775                         mdt_index=$($LFS getstripe -m $file)
17776                         # broken symlink getstripe will fail
17777                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17778                                 error "$file is not on MDT${MDTIDX}"
17779                 done
17780         done
17781
17782         # the multiple link file should still in MDT0
17783         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17784         [ $mdt_index == 0 ] ||
17785                 error "$file is not on MDT${MDTIDX}"
17786
17787         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17788         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17789                 error " expect $old_dir_flag get $new_dir_flag"
17790
17791         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17792         [ "$old_file_flag" = "$new_file_flag" ] ||
17793                 error " expect $old_file_flag get $new_file_flag"
17794
17795         local new_dir_mode=$(stat -c%f $migrate_dir)
17796         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17797                 error "expect mode $old_dir_mode get $new_dir_mode"
17798
17799         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17800         [ "$old_file_mode" = "$new_file_mode" ] ||
17801                 error "expect mode $old_file_mode get $new_file_mode"
17802
17803         diff /etc/passwd $migrate_dir/$tfile ||
17804                 error "$tfile different after migration"
17805
17806         diff /etc/passwd $other_dir/luna ||
17807                 error "luna different after migration"
17808
17809         diff /etc/passwd $migrate_dir/sofia ||
17810                 error "sofia different after migration"
17811
17812         diff /etc/passwd $migrate_dir/david ||
17813                 error "david different after migration"
17814
17815         diff /etc/passwd $other_dir/zachary ||
17816                 error "zachary different after migration"
17817
17818         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17819                 error "${tfile}_ln different after migration"
17820
17821         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17822                 error "${tfile}_ln_other different after migration"
17823
17824         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17825         [ $stripe_count = 2 ] ||
17826                 error "dir strpe_count $d != 2 after migration."
17827
17828         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17829         [ $stripe_count = 2 ] ||
17830                 error "file strpe_count $d != 2 after migration."
17831
17832         #migrate back to MDT0
17833         MDTIDX=0
17834
17835         $LFS migrate -m $MDTIDX $migrate_dir ||
17836                 error "fails on migrating remote dir to MDT0"
17837
17838         echo "migrate back to MDT0, checking.."
17839         for file in $(find $migrate_dir); do
17840                 mdt_index=$($LFS getstripe -m $file)
17841                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17842                         error "$file is not on MDT${MDTIDX}"
17843         done
17844
17845         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17846         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17847                 error " expect $old_dir_flag get $new_dir_flag"
17848
17849         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17850         [ "$old_file_flag" = "$new_file_flag" ] ||
17851                 error " expect $old_file_flag get $new_file_flag"
17852
17853         local new_dir_mode=$(stat -c%f $migrate_dir)
17854         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17855                 error "expect mode $old_dir_mode get $new_dir_mode"
17856
17857         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17858         [ "$old_file_mode" = "$new_file_mode" ] ||
17859                 error "expect mode $old_file_mode get $new_file_mode"
17860
17861         diff /etc/passwd ${migrate_dir}/$tfile ||
17862                 error "$tfile different after migration"
17863
17864         diff /etc/passwd ${other_dir}/luna ||
17865                 error "luna different after migration"
17866
17867         diff /etc/passwd ${migrate_dir}/sofia ||
17868                 error "sofia different after migration"
17869
17870         diff /etc/passwd ${other_dir}/zachary ||
17871                 error "zachary different after migration"
17872
17873         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17874                 error "${tfile}_ln different after migration"
17875
17876         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17877                 error "${tfile}_ln_other different after migration"
17878
17879         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17880         [ $stripe_count = 2 ] ||
17881                 error "dir strpe_count $d != 2 after migration."
17882
17883         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17884         [ $stripe_count = 2 ] ||
17885                 error "file strpe_count $d != 2 after migration."
17886
17887         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17888 }
17889 run_test 230b "migrate directory"
17890
17891 test_230c() {
17892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17894         remote_mds_nodsh && skip "remote MDS with nodsh"
17895         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17896                 skip "Need MDS version at least 2.11.52"
17897
17898         local MDTIDX=1
17899         local total=3
17900         local mdt_index
17901         local file
17902         local migrate_dir=$DIR/$tdir/migrate_dir
17903
17904         #If migrating directory fails in the middle, all entries of
17905         #the directory is still accessiable.
17906         test_mkdir $DIR/$tdir
17907         test_mkdir -i0 -c1 $migrate_dir
17908         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17909         stat $migrate_dir
17910         createmany -o $migrate_dir/f $total ||
17911                 error "create files under ${migrate_dir} failed"
17912
17913         # fail after migrating top dir, and this will fail only once, so the
17914         # first sub file migration will fail (currently f3), others succeed.
17915         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17916         do_facet mds1 lctl set_param fail_loc=0x1801
17917         local t=$(ls $migrate_dir | wc -l)
17918         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17919                 error "migrate should fail"
17920         local u=$(ls $migrate_dir | wc -l)
17921         [ "$u" == "$t" ] || error "$u != $t during migration"
17922
17923         # add new dir/file should succeed
17924         mkdir $migrate_dir/dir ||
17925                 error "mkdir failed under migrating directory"
17926         touch $migrate_dir/file ||
17927                 error "create file failed under migrating directory"
17928
17929         # add file with existing name should fail
17930         for file in $migrate_dir/f*; do
17931                 stat $file > /dev/null || error "stat $file failed"
17932                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17933                         error "open(O_CREAT|O_EXCL) $file should fail"
17934                 $MULTIOP $file m && error "create $file should fail"
17935                 touch $DIR/$tdir/remote_dir/$tfile ||
17936                         error "touch $tfile failed"
17937                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17938                         error "link $file should fail"
17939                 mdt_index=$($LFS getstripe -m $file)
17940                 if [ $mdt_index == 0 ]; then
17941                         # file failed to migrate is not allowed to rename to
17942                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17943                                 error "rename to $file should fail"
17944                 else
17945                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17946                                 error "rename to $file failed"
17947                 fi
17948                 echo hello >> $file || error "write $file failed"
17949         done
17950
17951         # resume migration with different options should fail
17952         $LFS migrate -m 0 $migrate_dir &&
17953                 error "migrate -m 0 $migrate_dir should fail"
17954
17955         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17956                 error "migrate -c 2 $migrate_dir should fail"
17957
17958         # resume migration should succeed
17959         $LFS migrate -m $MDTIDX $migrate_dir ||
17960                 error "migrate $migrate_dir failed"
17961
17962         echo "Finish migration, then checking.."
17963         for file in $(find $migrate_dir); do
17964                 mdt_index=$($LFS getstripe -m $file)
17965                 [ $mdt_index == $MDTIDX ] ||
17966                         error "$file is not on MDT${MDTIDX}"
17967         done
17968
17969         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17970 }
17971 run_test 230c "check directory accessiblity if migration failed"
17972
17973 test_230d() {
17974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17976         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17977                 skip "Need MDS version at least 2.11.52"
17978         # LU-11235
17979         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17980
17981         local migrate_dir=$DIR/$tdir/migrate_dir
17982         local old_index
17983         local new_index
17984         local old_count
17985         local new_count
17986         local new_hash
17987         local mdt_index
17988         local i
17989         local j
17990
17991         old_index=$((RANDOM % MDSCOUNT))
17992         old_count=$((MDSCOUNT - old_index))
17993         new_index=$((RANDOM % MDSCOUNT))
17994         new_count=$((MDSCOUNT - new_index))
17995         new_hash=1 # for all_char
17996
17997         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17998         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17999
18000         test_mkdir $DIR/$tdir
18001         test_mkdir -i $old_index -c $old_count $migrate_dir
18002
18003         for ((i=0; i<100; i++)); do
18004                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18005                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18006                         error "create files under remote dir failed $i"
18007         done
18008
18009         echo -n "Migrate from MDT$old_index "
18010         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18011         echo -n "to MDT$new_index"
18012         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18013         echo
18014
18015         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18016         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18017                 error "migrate remote dir error"
18018
18019         echo "Finish migration, then checking.."
18020         for file in $(find $migrate_dir); do
18021                 mdt_index=$($LFS getstripe -m $file)
18022                 if [ $mdt_index -lt $new_index ] ||
18023                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18024                         error "$file is on MDT$mdt_index"
18025                 fi
18026         done
18027
18028         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18029 }
18030 run_test 230d "check migrate big directory"
18031
18032 test_230e() {
18033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18034         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18035         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18036                 skip "Need MDS version at least 2.11.52"
18037
18038         local i
18039         local j
18040         local a_fid
18041         local b_fid
18042
18043         mkdir -p $DIR/$tdir
18044         mkdir $DIR/$tdir/migrate_dir
18045         mkdir $DIR/$tdir/other_dir
18046         touch $DIR/$tdir/migrate_dir/a
18047         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18048         ls $DIR/$tdir/other_dir
18049
18050         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18051                 error "migrate dir fails"
18052
18053         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18054         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18055
18056         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18057         [ $mdt_index == 0 ] || error "a is not on MDT0"
18058
18059         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18060                 error "migrate dir fails"
18061
18062         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18063         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18064
18065         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18066         [ $mdt_index == 1 ] || error "a is not on MDT1"
18067
18068         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18069         [ $mdt_index == 1 ] || error "b is not on MDT1"
18070
18071         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18072         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18073
18074         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18075
18076         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18077 }
18078 run_test 230e "migrate mulitple local link files"
18079
18080 test_230f() {
18081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18082         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18083         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18084                 skip "Need MDS version at least 2.11.52"
18085
18086         local a_fid
18087         local ln_fid
18088
18089         mkdir -p $DIR/$tdir
18090         mkdir $DIR/$tdir/migrate_dir
18091         $LFS mkdir -i1 $DIR/$tdir/other_dir
18092         touch $DIR/$tdir/migrate_dir/a
18093         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18094         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18095         ls $DIR/$tdir/other_dir
18096
18097         # a should be migrated to MDT1, since no other links on MDT0
18098         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18099                 error "#1 migrate dir fails"
18100         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18101         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18102         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18103         [ $mdt_index == 1 ] || error "a is not on MDT1"
18104
18105         # a should stay on MDT1, because it is a mulitple link file
18106         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18107                 error "#2 migrate dir fails"
18108         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18109         [ $mdt_index == 1 ] || error "a is not on MDT1"
18110
18111         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18112                 error "#3 migrate dir fails"
18113
18114         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18115         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18116         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18117
18118         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18119         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18120
18121         # a should be migrated to MDT0, since no other links on MDT1
18122         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18123                 error "#4 migrate dir fails"
18124         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18125         [ $mdt_index == 0 ] || error "a is not on MDT0"
18126
18127         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18128 }
18129 run_test 230f "migrate mulitple remote link files"
18130
18131 test_230g() {
18132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18134         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18135                 skip "Need MDS version at least 2.11.52"
18136
18137         mkdir -p $DIR/$tdir/migrate_dir
18138
18139         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18140                 error "migrating dir to non-exist MDT succeeds"
18141         true
18142 }
18143 run_test 230g "migrate dir to non-exist MDT"
18144
18145 test_230h() {
18146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18148         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18149                 skip "Need MDS version at least 2.11.52"
18150
18151         local mdt_index
18152
18153         mkdir -p $DIR/$tdir/migrate_dir
18154
18155         $LFS migrate -m1 $DIR &&
18156                 error "migrating mountpoint1 should fail"
18157
18158         $LFS migrate -m1 $DIR/$tdir/.. &&
18159                 error "migrating mountpoint2 should fail"
18160
18161         # same as mv
18162         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18163                 error "migrating $tdir/migrate_dir/.. should fail"
18164
18165         true
18166 }
18167 run_test 230h "migrate .. and root"
18168
18169 test_230i() {
18170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18172         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18173                 skip "Need MDS version at least 2.11.52"
18174
18175         mkdir -p $DIR/$tdir/migrate_dir
18176
18177         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18178                 error "migration fails with a tailing slash"
18179
18180         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18181                 error "migration fails with two tailing slashes"
18182 }
18183 run_test 230i "lfs migrate -m tolerates trailing slashes"
18184
18185 test_230j() {
18186         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18187         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18188                 skip "Need MDS version at least 2.11.52"
18189
18190         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18191         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18192                 error "create $tfile failed"
18193         cat /etc/passwd > $DIR/$tdir/$tfile
18194
18195         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18196
18197         cmp /etc/passwd $DIR/$tdir/$tfile ||
18198                 error "DoM file mismatch after migration"
18199 }
18200 run_test 230j "DoM file data not changed after dir migration"
18201
18202 test_230k() {
18203         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18204         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18205                 skip "Need MDS version at least 2.11.56"
18206
18207         local total=20
18208         local files_on_starting_mdt=0
18209
18210         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18211         $LFS getdirstripe $DIR/$tdir
18212         for i in $(seq $total); do
18213                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18214                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18215                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18216         done
18217
18218         echo "$files_on_starting_mdt files on MDT0"
18219
18220         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18221         $LFS getdirstripe $DIR/$tdir
18222
18223         files_on_starting_mdt=0
18224         for i in $(seq $total); do
18225                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18226                         error "file $tfile.$i mismatch after migration"
18227                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18228                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18229         done
18230
18231         echo "$files_on_starting_mdt files on MDT1 after migration"
18232         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18233
18234         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18235         $LFS getdirstripe $DIR/$tdir
18236
18237         files_on_starting_mdt=0
18238         for i in $(seq $total); do
18239                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18240                         error "file $tfile.$i mismatch after 2nd migration"
18241                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18242                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18243         done
18244
18245         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18246         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18247
18248         true
18249 }
18250 run_test 230k "file data not changed after dir migration"
18251
18252 test_230l() {
18253         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18254         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18255                 skip "Need MDS version at least 2.11.56"
18256
18257         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18258         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18259                 error "create files under remote dir failed $i"
18260         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18261 }
18262 run_test 230l "readdir between MDTs won't crash"
18263
18264 test_230m() {
18265         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18266         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18267                 skip "Need MDS version at least 2.11.56"
18268
18269         local MDTIDX=1
18270         local mig_dir=$DIR/$tdir/migrate_dir
18271         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18272         local shortstr="b"
18273         local val
18274
18275         echo "Creating files and dirs with xattrs"
18276         test_mkdir $DIR/$tdir
18277         test_mkdir -i0 -c1 $mig_dir
18278         mkdir $mig_dir/dir
18279         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18280                 error "cannot set xattr attr1 on dir"
18281         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18282                 error "cannot set xattr attr2 on dir"
18283         touch $mig_dir/dir/f0
18284         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18285                 error "cannot set xattr attr1 on file"
18286         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18287                 error "cannot set xattr attr2 on file"
18288         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18289         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18290         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18291         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18292         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18293         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18294         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18295         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18296         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18297
18298         echo "Migrating to MDT1"
18299         $LFS migrate -m $MDTIDX $mig_dir ||
18300                 error "fails on migrating dir to MDT1"
18301
18302         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18303         echo "Checking xattrs"
18304         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18305         [ "$val" = $longstr ] ||
18306                 error "expecting xattr1 $longstr on dir, found $val"
18307         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18308         [ "$val" = $shortstr ] ||
18309                 error "expecting xattr2 $shortstr on dir, found $val"
18310         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18311         [ "$val" = $longstr ] ||
18312                 error "expecting xattr1 $longstr on file, found $val"
18313         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18314         [ "$val" = $shortstr ] ||
18315                 error "expecting xattr2 $shortstr on file, found $val"
18316 }
18317 run_test 230m "xattrs not changed after dir migration"
18318
18319 test_230n() {
18320         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18321         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18322                 skip "Need MDS version at least 2.13.53"
18323
18324         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18325         cat /etc/hosts > $DIR/$tdir/$tfile
18326         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18327         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18328
18329         cmp /etc/hosts $DIR/$tdir/$tfile ||
18330                 error "File data mismatch after migration"
18331 }
18332 run_test 230n "Dir migration with mirrored file"
18333
18334 test_230o() {
18335         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18336         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18337                 skip "Need MDS version at least 2.13.52"
18338
18339         local mdts=$(comma_list $(mdts_nodes))
18340         local timeout=100
18341
18342         local restripe_status
18343         local delta
18344         local i
18345         local j
18346
18347         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18348
18349         # in case "crush" hash type is not set
18350         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18351
18352         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18353                            mdt.*MDT0000.enable_dir_restripe)
18354         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18355         stack_trap "do_nodes $mdts $LCTL set_param \
18356                     mdt.*.enable_dir_restripe=$restripe_status"
18357
18358         mkdir $DIR/$tdir
18359         createmany -m $DIR/$tdir/f 100 ||
18360                 error "create files under remote dir failed $i"
18361         createmany -d $DIR/$tdir/d 100 ||
18362                 error "create dirs under remote dir failed $i"
18363
18364         for i in $(seq 2 $MDSCOUNT); do
18365                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18366                 $LFS setdirstripe -c $i $DIR/$tdir ||
18367                         error "split -c $i $tdir failed"
18368                 wait_update $HOSTNAME \
18369                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18370                         error "dir split not finished"
18371                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18372                         awk '/migrate/ {sum += $2} END { print sum }')
18373                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18374                 # delta is around total_files/stripe_count
18375                 [ $delta -lt $((200 /(i - 1))) ] ||
18376                         error "$delta files migrated"
18377         done
18378 }
18379 run_test 230o "dir split"
18380
18381 test_230p() {
18382         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18383         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18384                 skip "Need MDS version at least 2.13.52"
18385
18386         local mdts=$(comma_list $(mdts_nodes))
18387         local timeout=100
18388
18389         local restripe_status
18390         local delta
18391         local i
18392         local j
18393
18394         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18395
18396         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18397
18398         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18399                            mdt.*MDT0000.enable_dir_restripe)
18400         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18401         stack_trap "do_nodes $mdts $LCTL set_param \
18402                     mdt.*.enable_dir_restripe=$restripe_status"
18403
18404         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18405         createmany -m $DIR/$tdir/f 100 ||
18406                 error "create files under remote dir failed $i"
18407         createmany -d $DIR/$tdir/d 100 ||
18408                 error "create dirs under remote dir failed $i"
18409
18410         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18411                 local mdt_hash="crush"
18412
18413                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18414                 $LFS setdirstripe -c $i $DIR/$tdir ||
18415                         error "split -c $i $tdir failed"
18416                 [ $i -eq 1 ] && mdt_hash="none"
18417                 wait_update $HOSTNAME \
18418                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18419                         error "dir merge not finished"
18420                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18421                         awk '/migrate/ {sum += $2} END { print sum }')
18422                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18423                 # delta is around total_files/stripe_count
18424                 [ $delta -lt $((200 / i)) ] ||
18425                         error "$delta files migrated"
18426         done
18427 }
18428 run_test 230p "dir merge"
18429
18430 test_230q() {
18431         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18432         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18433                 skip "Need MDS version at least 2.13.52"
18434
18435         local mdts=$(comma_list $(mdts_nodes))
18436         local saved_threshold=$(do_facet mds1 \
18437                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18438         local saved_delta=$(do_facet mds1 \
18439                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18440         local threshold=100
18441         local delta=2
18442         local total=0
18443         local stripe_count=0
18444         local stripe_index
18445         local nr_files
18446
18447         # test with fewer files on ZFS
18448         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18449
18450         stack_trap "do_nodes $mdts $LCTL set_param \
18451                     mdt.*.dir_split_count=$saved_threshold"
18452         stack_trap "do_nodes $mdts $LCTL set_param \
18453                     mdt.*.dir_split_delta=$saved_delta"
18454         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18455         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18456         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18457         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18458         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18459         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18460
18461         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18462         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18463
18464         while [ $stripe_count -lt $MDSCOUNT ]; do
18465                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18466                         error "create sub files failed"
18467                 stat $DIR/$tdir > /dev/null
18468                 total=$((total + threshold * 3 / 2))
18469                 stripe_count=$((stripe_count + delta))
18470                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18471
18472                 wait_update $HOSTNAME \
18473                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18474                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18475
18476                 wait_update $HOSTNAME \
18477                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18478                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18479
18480                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18481                            grep -w $stripe_index | wc -l)
18482                 echo "$nr_files files on MDT$stripe_index after split"
18483                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18484                         error "$nr_files files on MDT$stripe_index after split"
18485
18486                 nr_files=$(ls $DIR/$tdir | wc -w)
18487                 [ $nr_files -eq $total ] ||
18488                         error "total sub files $nr_files != $total"
18489         done
18490 }
18491 run_test 230q "dir auto split"
18492
18493 test_230r() {
18494         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18495         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18496         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18497                 skip "Need MDS version at least 2.13.54"
18498
18499         # maximum amount of local locks:
18500         # parent striped dir - 2 locks
18501         # new stripe in parent to migrate to - 1 lock
18502         # source and target - 2 locks
18503         # Total 5 locks for regular file
18504         mkdir -p $DIR/$tdir
18505         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18506         touch $DIR/$tdir/dir1/eee
18507
18508         # create 4 hardlink for 4 more locks
18509         # Total: 9 locks > RS_MAX_LOCKS (8)
18510         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18511         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18512         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18513         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18514         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18515         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18516         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18517         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18518
18519         cancel_lru_locks mdc
18520
18521         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18522                 error "migrate dir fails"
18523
18524         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18525 }
18526 run_test 230r "migrate with too many local locks"
18527
18528 test_231a()
18529 {
18530         # For simplicity this test assumes that max_pages_per_rpc
18531         # is the same across all OSCs
18532         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18533         local bulk_size=$((max_pages * PAGE_SIZE))
18534         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18535                                        head -n 1)
18536
18537         mkdir -p $DIR/$tdir
18538         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18539                 error "failed to set stripe with -S ${brw_size}M option"
18540
18541         # clear the OSC stats
18542         $LCTL set_param osc.*.stats=0 &>/dev/null
18543         stop_writeback
18544
18545         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18547                 oflag=direct &>/dev/null || error "dd failed"
18548
18549         sync; sleep 1; sync # just to be safe
18550         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18551         if [ x$nrpcs != "x1" ]; then
18552                 $LCTL get_param osc.*.stats
18553                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18554         fi
18555
18556         start_writeback
18557         # Drop the OSC cache, otherwise we will read from it
18558         cancel_lru_locks osc
18559
18560         # clear the OSC stats
18561         $LCTL set_param osc.*.stats=0 &>/dev/null
18562
18563         # Client reads $bulk_size.
18564         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18565                 iflag=direct &>/dev/null || error "dd failed"
18566
18567         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18568         if [ x$nrpcs != "x1" ]; then
18569                 $LCTL get_param osc.*.stats
18570                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18571         fi
18572 }
18573 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18574
18575 test_231b() {
18576         mkdir -p $DIR/$tdir
18577         local i
18578         for i in {0..1023}; do
18579                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18580                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18581                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18582         done
18583         sync
18584 }
18585 run_test 231b "must not assert on fully utilized OST request buffer"
18586
18587 test_232a() {
18588         mkdir -p $DIR/$tdir
18589         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18590
18591         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18592         do_facet ost1 $LCTL set_param fail_loc=0x31c
18593
18594         # ignore dd failure
18595         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18596
18597         do_facet ost1 $LCTL set_param fail_loc=0
18598         umount_client $MOUNT || error "umount failed"
18599         mount_client $MOUNT || error "mount failed"
18600         stop ost1 || error "cannot stop ost1"
18601         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18602 }
18603 run_test 232a "failed lock should not block umount"
18604
18605 test_232b() {
18606         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18607                 skip "Need MDS version at least 2.10.58"
18608
18609         mkdir -p $DIR/$tdir
18610         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18611         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18612         sync
18613         cancel_lru_locks osc
18614
18615         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18616         do_facet ost1 $LCTL set_param fail_loc=0x31c
18617
18618         # ignore failure
18619         $LFS data_version $DIR/$tdir/$tfile || true
18620
18621         do_facet ost1 $LCTL set_param fail_loc=0
18622         umount_client $MOUNT || error "umount failed"
18623         mount_client $MOUNT || error "mount failed"
18624         stop ost1 || error "cannot stop ost1"
18625         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18626 }
18627 run_test 232b "failed data version lock should not block umount"
18628
18629 test_233a() {
18630         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18631                 skip "Need MDS version at least 2.3.64"
18632         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18633
18634         local fid=$($LFS path2fid $MOUNT)
18635
18636         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18637                 error "cannot access $MOUNT using its FID '$fid'"
18638 }
18639 run_test 233a "checking that OBF of the FS root succeeds"
18640
18641 test_233b() {
18642         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18643                 skip "Need MDS version at least 2.5.90"
18644         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18645
18646         local fid=$($LFS path2fid $MOUNT/.lustre)
18647
18648         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18649                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18650
18651         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18652         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18653                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18654 }
18655 run_test 233b "checking that OBF of the FS .lustre succeeds"
18656
18657 test_234() {
18658         local p="$TMP/sanityN-$TESTNAME.parameters"
18659         save_lustre_params client "llite.*.xattr_cache" > $p
18660         lctl set_param llite.*.xattr_cache 1 ||
18661                 skip_env "xattr cache is not supported"
18662
18663         mkdir -p $DIR/$tdir || error "mkdir failed"
18664         touch $DIR/$tdir/$tfile || error "touch failed"
18665         # OBD_FAIL_LLITE_XATTR_ENOMEM
18666         $LCTL set_param fail_loc=0x1405
18667         getfattr -n user.attr $DIR/$tdir/$tfile &&
18668                 error "getfattr should have failed with ENOMEM"
18669         $LCTL set_param fail_loc=0x0
18670         rm -rf $DIR/$tdir
18671
18672         restore_lustre_params < $p
18673         rm -f $p
18674 }
18675 run_test 234 "xattr cache should not crash on ENOMEM"
18676
18677 test_235() {
18678         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18679                 skip "Need MDS version at least 2.4.52"
18680
18681         flock_deadlock $DIR/$tfile
18682         local RC=$?
18683         case $RC in
18684                 0)
18685                 ;;
18686                 124) error "process hangs on a deadlock"
18687                 ;;
18688                 *) error "error executing flock_deadlock $DIR/$tfile"
18689                 ;;
18690         esac
18691 }
18692 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18693
18694 #LU-2935
18695 test_236() {
18696         check_swap_layouts_support
18697
18698         local ref1=/etc/passwd
18699         local ref2=/etc/group
18700         local file1=$DIR/$tdir/f1
18701         local file2=$DIR/$tdir/f2
18702
18703         test_mkdir -c1 $DIR/$tdir
18704         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18705         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18706         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18707         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18708         local fd=$(free_fd)
18709         local cmd="exec $fd<>$file2"
18710         eval $cmd
18711         rm $file2
18712         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18713                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18714         cmd="exec $fd>&-"
18715         eval $cmd
18716         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18717
18718         #cleanup
18719         rm -rf $DIR/$tdir
18720 }
18721 run_test 236 "Layout swap on open unlinked file"
18722
18723 # LU-4659 linkea consistency
18724 test_238() {
18725         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18726                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18727                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18728                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18729
18730         touch $DIR/$tfile
18731         ln $DIR/$tfile $DIR/$tfile.lnk
18732         touch $DIR/$tfile.new
18733         mv $DIR/$tfile.new $DIR/$tfile
18734         local fid1=$($LFS path2fid $DIR/$tfile)
18735         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18736         local path1=$($LFS fid2path $FSNAME "$fid1")
18737         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18738         local path2=$($LFS fid2path $FSNAME "$fid2")
18739         [ $tfile.lnk == $path2 ] ||
18740                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18741         rm -f $DIR/$tfile*
18742 }
18743 run_test 238 "Verify linkea consistency"
18744
18745 test_239A() { # was test_239
18746         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18747                 skip "Need MDS version at least 2.5.60"
18748
18749         local list=$(comma_list $(mdts_nodes))
18750
18751         mkdir -p $DIR/$tdir
18752         createmany -o $DIR/$tdir/f- 5000
18753         unlinkmany $DIR/$tdir/f- 5000
18754         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18755                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18756         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18757                         osp.*MDT*.sync_in_flight" | calc_sum)
18758         [ "$changes" -eq 0 ] || error "$changes not synced"
18759 }
18760 run_test 239A "osp_sync test"
18761
18762 test_239a() { #LU-5297
18763         remote_mds_nodsh && skip "remote MDS with nodsh"
18764
18765         touch $DIR/$tfile
18766         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18767         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18768         chgrp $RUNAS_GID $DIR/$tfile
18769         wait_delete_completed
18770 }
18771 run_test 239a "process invalid osp sync record correctly"
18772
18773 test_239b() { #LU-5297
18774         remote_mds_nodsh && skip "remote MDS with nodsh"
18775
18776         touch $DIR/$tfile1
18777         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18778         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18779         chgrp $RUNAS_GID $DIR/$tfile1
18780         wait_delete_completed
18781         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18782         touch $DIR/$tfile2
18783         chgrp $RUNAS_GID $DIR/$tfile2
18784         wait_delete_completed
18785 }
18786 run_test 239b "process osp sync record with ENOMEM error correctly"
18787
18788 test_240() {
18789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18790         remote_mds_nodsh && skip "remote MDS with nodsh"
18791
18792         mkdir -p $DIR/$tdir
18793
18794         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18795                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18796         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18797                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18798
18799         umount_client $MOUNT || error "umount failed"
18800         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18801         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18802         mount_client $MOUNT || error "failed to mount client"
18803
18804         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18805         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18806 }
18807 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18808
18809 test_241_bio() {
18810         local count=$1
18811         local bsize=$2
18812
18813         for LOOP in $(seq $count); do
18814                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18815                 cancel_lru_locks $OSC || true
18816         done
18817 }
18818
18819 test_241_dio() {
18820         local count=$1
18821         local bsize=$2
18822
18823         for LOOP in $(seq $1); do
18824                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18825                         2>/dev/null
18826         done
18827 }
18828
18829 test_241a() { # was test_241
18830         local bsize=$PAGE_SIZE
18831
18832         (( bsize < 40960 )) && bsize=40960
18833         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18834         ls -la $DIR/$tfile
18835         cancel_lru_locks $OSC
18836         test_241_bio 1000 $bsize &
18837         PID=$!
18838         test_241_dio 1000 $bsize
18839         wait $PID
18840 }
18841 run_test 241a "bio vs dio"
18842
18843 test_241b() {
18844         local bsize=$PAGE_SIZE
18845
18846         (( bsize < 40960 )) && bsize=40960
18847         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18848         ls -la $DIR/$tfile
18849         test_241_dio 1000 $bsize &
18850         PID=$!
18851         test_241_dio 1000 $bsize
18852         wait $PID
18853 }
18854 run_test 241b "dio vs dio"
18855
18856 test_242() {
18857         remote_mds_nodsh && skip "remote MDS with nodsh"
18858
18859         mkdir -p $DIR/$tdir
18860         touch $DIR/$tdir/$tfile
18861
18862         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18863         do_facet mds1 lctl set_param fail_loc=0x105
18864         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18865
18866         do_facet mds1 lctl set_param fail_loc=0
18867         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18868 }
18869 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18870
18871 test_243()
18872 {
18873         test_mkdir $DIR/$tdir
18874         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18875 }
18876 run_test 243 "various group lock tests"
18877
18878 test_244a()
18879 {
18880         test_mkdir $DIR/$tdir
18881         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18882         sendfile_grouplock $DIR/$tdir/$tfile || \
18883                 error "sendfile+grouplock failed"
18884         rm -rf $DIR/$tdir
18885 }
18886 run_test 244a "sendfile with group lock tests"
18887
18888 test_244b()
18889 {
18890         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18891
18892         local threads=50
18893         local size=$((1024*1024))
18894
18895         test_mkdir $DIR/$tdir
18896         for i in $(seq 1 $threads); do
18897                 local file=$DIR/$tdir/file_$((i / 10))
18898                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18899                 local pids[$i]=$!
18900         done
18901         for i in $(seq 1 $threads); do
18902                 wait ${pids[$i]}
18903         done
18904 }
18905 run_test 244b "multi-threaded write with group lock"
18906
18907 test_245() {
18908         local flagname="multi_mod_rpcs"
18909         local connect_data_name="max_mod_rpcs"
18910         local out
18911
18912         # check if multiple modify RPCs flag is set
18913         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18914                 grep "connect_flags:")
18915         echo "$out"
18916
18917         echo "$out" | grep -qw $flagname
18918         if [ $? -ne 0 ]; then
18919                 echo "connect flag $flagname is not set"
18920                 return
18921         fi
18922
18923         # check if multiple modify RPCs data is set
18924         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18925         echo "$out"
18926
18927         echo "$out" | grep -qw $connect_data_name ||
18928                 error "import should have connect data $connect_data_name"
18929 }
18930 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18931
18932 cleanup_247() {
18933         local submount=$1
18934
18935         trap 0
18936         umount_client $submount
18937         rmdir $submount
18938 }
18939
18940 test_247a() {
18941         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18942                 grep -q subtree ||
18943                 skip_env "Fileset feature is not supported"
18944
18945         local submount=${MOUNT}_$tdir
18946
18947         mkdir $MOUNT/$tdir
18948         mkdir -p $submount || error "mkdir $submount failed"
18949         FILESET="$FILESET/$tdir" mount_client $submount ||
18950                 error "mount $submount failed"
18951         trap "cleanup_247 $submount" EXIT
18952         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18953         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18954                 error "read $MOUNT/$tdir/$tfile failed"
18955         cleanup_247 $submount
18956 }
18957 run_test 247a "mount subdir as fileset"
18958
18959 test_247b() {
18960         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18961                 skip_env "Fileset feature is not supported"
18962
18963         local submount=${MOUNT}_$tdir
18964
18965         rm -rf $MOUNT/$tdir
18966         mkdir -p $submount || error "mkdir $submount failed"
18967         SKIP_FILESET=1
18968         FILESET="$FILESET/$tdir" mount_client $submount &&
18969                 error "mount $submount should fail"
18970         rmdir $submount
18971 }
18972 run_test 247b "mount subdir that dose not exist"
18973
18974 test_247c() {
18975         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18976                 skip_env "Fileset feature is not supported"
18977
18978         local submount=${MOUNT}_$tdir
18979
18980         mkdir -p $MOUNT/$tdir/dir1
18981         mkdir -p $submount || error "mkdir $submount failed"
18982         trap "cleanup_247 $submount" EXIT
18983         FILESET="$FILESET/$tdir" mount_client $submount ||
18984                 error "mount $submount failed"
18985         local fid=$($LFS path2fid $MOUNT/)
18986         $LFS fid2path $submount $fid && error "fid2path should fail"
18987         cleanup_247 $submount
18988 }
18989 run_test 247c "running fid2path outside subdirectory root"
18990
18991 test_247d() {
18992         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18993                 skip "Fileset feature is not supported"
18994
18995         local submount=${MOUNT}_$tdir
18996
18997         mkdir -p $MOUNT/$tdir/dir1
18998         mkdir -p $submount || error "mkdir $submount failed"
18999         FILESET="$FILESET/$tdir" mount_client $submount ||
19000                 error "mount $submount failed"
19001         trap "cleanup_247 $submount" EXIT
19002
19003         local td=$submount/dir1
19004         local fid=$($LFS path2fid $td)
19005         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19006
19007         # check that we get the same pathname back
19008         local rootpath
19009         local found
19010         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19011                 echo "$rootpath $fid"
19012                 found=$($LFS fid2path $rootpath "$fid")
19013                 [ -n "found" ] || error "fid2path should succeed"
19014                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19015         done
19016         # check wrong root path format
19017         rootpath=$submount"_wrong"
19018         found=$($LFS fid2path $rootpath "$fid")
19019         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19020
19021         cleanup_247 $submount
19022 }
19023 run_test 247d "running fid2path inside subdirectory root"
19024
19025 # LU-8037
19026 test_247e() {
19027         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19028                 grep -q subtree ||
19029                 skip "Fileset feature is not supported"
19030
19031         local submount=${MOUNT}_$tdir
19032
19033         mkdir $MOUNT/$tdir
19034         mkdir -p $submount || error "mkdir $submount failed"
19035         FILESET="$FILESET/.." mount_client $submount &&
19036                 error "mount $submount should fail"
19037         rmdir $submount
19038 }
19039 run_test 247e "mount .. as fileset"
19040
19041 test_247f() {
19042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19043         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19044                 skip "Need at least version 2.13.52"
19045         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19046                 grep -q subtree ||
19047                 skip "Fileset feature is not supported"
19048
19049         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19050         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19051                 error "mkdir remote failed"
19052         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19053         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19054                 error "mkdir striped failed"
19055         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19056
19057         local submount=${MOUNT}_$tdir
19058
19059         mkdir -p $submount || error "mkdir $submount failed"
19060
19061         local dir
19062         local fileset=$FILESET
19063
19064         for dir in $tdir/remote $tdir/remote/subdir \
19065                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19066                 FILESET="$fileset/$dir" mount_client $submount ||
19067                         error "mount $dir failed"
19068                 umount_client $submount
19069         done
19070 }
19071 run_test 247f "mount striped or remote directory as fileset"
19072
19073 test_248a() {
19074         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19075         [ -z "$fast_read_sav" ] && skip "no fast read support"
19076
19077         # create a large file for fast read verification
19078         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19079
19080         # make sure the file is created correctly
19081         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19082                 { rm -f $DIR/$tfile; skip "file creation error"; }
19083
19084         echo "Test 1: verify that fast read is 4 times faster on cache read"
19085
19086         # small read with fast read enabled
19087         $LCTL set_param -n llite.*.fast_read=1
19088         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19089                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19090                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19091         # small read with fast read disabled
19092         $LCTL set_param -n llite.*.fast_read=0
19093         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19094                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19095                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19096
19097         # verify that fast read is 4 times faster for cache read
19098         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19099                 error_not_in_vm "fast read was not 4 times faster: " \
19100                            "$t_fast vs $t_slow"
19101
19102         echo "Test 2: verify the performance between big and small read"
19103         $LCTL set_param -n llite.*.fast_read=1
19104
19105         # 1k non-cache read
19106         cancel_lru_locks osc
19107         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19108                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19109                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19110
19111         # 1M non-cache read
19112         cancel_lru_locks osc
19113         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19114                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19115                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19116
19117         # verify that big IO is not 4 times faster than small IO
19118         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19119                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19120
19121         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19122         rm -f $DIR/$tfile
19123 }
19124 run_test 248a "fast read verification"
19125
19126 test_248b() {
19127         # Default short_io_bytes=16384, try both smaller and larger sizes.
19128         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19129         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19130         echo "bs=53248 count=113 normal buffered write"
19131         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19132                 error "dd of initial data file failed"
19133         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19134
19135         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19136         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19137                 error "dd with sync normal writes failed"
19138         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19139
19140         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19141         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19142                 error "dd with sync small writes failed"
19143         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19144
19145         cancel_lru_locks osc
19146
19147         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19148         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19149         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19150         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19151                 iflag=direct || error "dd with O_DIRECT small read failed"
19152         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19153         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19154                 error "compare $TMP/$tfile.1 failed"
19155
19156         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19157         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19158
19159         # just to see what the maximum tunable value is, and test parsing
19160         echo "test invalid parameter 2MB"
19161         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19162                 error "too-large short_io_bytes allowed"
19163         echo "test maximum parameter 512KB"
19164         # if we can set a larger short_io_bytes, run test regardless of version
19165         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19166                 # older clients may not allow setting it this large, that's OK
19167                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19168                         skip "Need at least client version 2.13.50"
19169                 error "medium short_io_bytes failed"
19170         fi
19171         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19172         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19173
19174         echo "test large parameter 64KB"
19175         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19176         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19177
19178         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19179         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19180                 error "dd with sync large writes failed"
19181         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19182
19183         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19184         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19185         num=$((113 * 4096 / PAGE_SIZE))
19186         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19187         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19188                 error "dd with O_DIRECT large writes failed"
19189         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19190                 error "compare $DIR/$tfile.3 failed"
19191
19192         cancel_lru_locks osc
19193
19194         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19195         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19196                 error "dd with O_DIRECT large read failed"
19197         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19198                 error "compare $TMP/$tfile.2 failed"
19199
19200         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19201         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19202                 error "dd with O_DIRECT large read failed"
19203         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19204                 error "compare $TMP/$tfile.3 failed"
19205 }
19206 run_test 248b "test short_io read and write for both small and large sizes"
19207
19208 test_249() { # LU-7890
19209         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19210                 skip "Need at least version 2.8.54"
19211
19212         rm -f $DIR/$tfile
19213         $LFS setstripe -c 1 $DIR/$tfile
19214         # Offset 2T == 4k * 512M
19215         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19216                 error "dd to 2T offset failed"
19217 }
19218 run_test 249 "Write above 2T file size"
19219
19220 test_250() {
19221         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19222          && skip "no 16TB file size limit on ZFS"
19223
19224         $LFS setstripe -c 1 $DIR/$tfile
19225         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19226         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19227         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19228         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19229                 conv=notrunc,fsync && error "append succeeded"
19230         return 0
19231 }
19232 run_test 250 "Write above 16T limit"
19233
19234 test_251() {
19235         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19236
19237         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19238         #Skip once - writing the first stripe will succeed
19239         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19240         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19241                 error "short write happened"
19242
19243         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19244         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19245                 error "short read happened"
19246
19247         rm -f $DIR/$tfile
19248 }
19249 run_test 251 "Handling short read and write correctly"
19250
19251 test_252() {
19252         remote_mds_nodsh && skip "remote MDS with nodsh"
19253         remote_ost_nodsh && skip "remote OST with nodsh"
19254         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19255                 skip_env "ldiskfs only test"
19256         fi
19257
19258         local tgt
19259         local dev
19260         local out
19261         local uuid
19262         local num
19263         local gen
19264
19265         # check lr_reader on OST0000
19266         tgt=ost1
19267         dev=$(facet_device $tgt)
19268         out=$(do_facet $tgt $LR_READER $dev)
19269         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19270         echo "$out"
19271         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19272         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19273                 error "Invalid uuid returned by $LR_READER on target $tgt"
19274         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19275
19276         # check lr_reader -c on MDT0000
19277         tgt=mds1
19278         dev=$(facet_device $tgt)
19279         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19280                 skip "$LR_READER does not support additional options"
19281         fi
19282         out=$(do_facet $tgt $LR_READER -c $dev)
19283         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19284         echo "$out"
19285         num=$(echo "$out" | grep -c "mdtlov")
19286         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19287                 error "Invalid number of mdtlov clients returned by $LR_READER"
19288         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19289
19290         # check lr_reader -cr on MDT0000
19291         out=$(do_facet $tgt $LR_READER -cr $dev)
19292         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19293         echo "$out"
19294         echo "$out" | grep -q "^reply_data:$" ||
19295                 error "$LR_READER should have returned 'reply_data' section"
19296         num=$(echo "$out" | grep -c "client_generation")
19297         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19298 }
19299 run_test 252 "check lr_reader tool"
19300
19301 test_253() {
19302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19303         remote_mds_nodsh && skip "remote MDS with nodsh"
19304         remote_mgs_nodsh && skip "remote MGS with nodsh"
19305
19306         local ostidx=0
19307         local rc=0
19308         local ost_name=$(ostname_from_index $ostidx)
19309
19310         # on the mdt's osc
19311         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19312         do_facet $SINGLEMDS $LCTL get_param -n \
19313                 osp.$mdtosc_proc1.reserved_mb_high ||
19314                 skip  "remote MDS does not support reserved_mb_high"
19315
19316         rm -rf $DIR/$tdir
19317         wait_mds_ost_sync
19318         wait_delete_completed
19319         mkdir $DIR/$tdir
19320
19321         pool_add $TESTNAME || error "Pool creation failed"
19322         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19323
19324         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19325                 error "Setstripe failed"
19326
19327         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19328
19329         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19330                     grep "watermarks")
19331         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19332
19333         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19334                         osp.$mdtosc_proc1.prealloc_status)
19335         echo "prealloc_status $oa_status"
19336
19337         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19338                 error "File creation should fail"
19339
19340         #object allocation was stopped, but we still able to append files
19341         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19342                 oflag=append || error "Append failed"
19343
19344         rm -f $DIR/$tdir/$tfile.0
19345
19346         # For this test, we want to delete the files we created to go out of
19347         # space but leave the watermark, so we remain nearly out of space
19348         ost_watermarks_enospc_delete_files $tfile $ostidx
19349
19350         wait_delete_completed
19351
19352         sleep_maxage
19353
19354         for i in $(seq 10 12); do
19355                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19356                         2>/dev/null || error "File creation failed after rm"
19357         done
19358
19359         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19360                         osp.$mdtosc_proc1.prealloc_status)
19361         echo "prealloc_status $oa_status"
19362
19363         if (( oa_status != 0 )); then
19364                 error "Object allocation still disable after rm"
19365         fi
19366 }
19367 run_test 253 "Check object allocation limit"
19368
19369 test_254() {
19370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19371         remote_mds_nodsh && skip "remote MDS with nodsh"
19372         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19373                 skip "MDS does not support changelog_size"
19374
19375         local cl_user
19376         local MDT0=$(facet_svc $SINGLEMDS)
19377
19378         changelog_register || error "changelog_register failed"
19379
19380         changelog_clear 0 || error "changelog_clear failed"
19381
19382         local size1=$(do_facet $SINGLEMDS \
19383                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19384         echo "Changelog size $size1"
19385
19386         rm -rf $DIR/$tdir
19387         $LFS mkdir -i 0 $DIR/$tdir
19388         # change something
19389         mkdir -p $DIR/$tdir/pics/2008/zachy
19390         touch $DIR/$tdir/pics/2008/zachy/timestamp
19391         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19392         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19393         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19394         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19395         rm $DIR/$tdir/pics/desktop.jpg
19396
19397         local size2=$(do_facet $SINGLEMDS \
19398                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19399         echo "Changelog size after work $size2"
19400
19401         (( $size2 > $size1 )) ||
19402                 error "new Changelog size=$size2 less than old size=$size1"
19403 }
19404 run_test 254 "Check changelog size"
19405
19406 ladvise_no_type()
19407 {
19408         local type=$1
19409         local file=$2
19410
19411         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19412                 awk -F: '{print $2}' | grep $type > /dev/null
19413         if [ $? -ne 0 ]; then
19414                 return 0
19415         fi
19416         return 1
19417 }
19418
19419 ladvise_no_ioctl()
19420 {
19421         local file=$1
19422
19423         lfs ladvise -a willread $file > /dev/null 2>&1
19424         if [ $? -eq 0 ]; then
19425                 return 1
19426         fi
19427
19428         lfs ladvise -a willread $file 2>&1 |
19429                 grep "Inappropriate ioctl for device" > /dev/null
19430         if [ $? -eq 0 ]; then
19431                 return 0
19432         fi
19433         return 1
19434 }
19435
19436 percent() {
19437         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19438 }
19439
19440 # run a random read IO workload
19441 # usage: random_read_iops <filename> <filesize> <iosize>
19442 random_read_iops() {
19443         local file=$1
19444         local fsize=$2
19445         local iosize=${3:-4096}
19446
19447         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19448                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19449 }
19450
19451 drop_file_oss_cache() {
19452         local file="$1"
19453         local nodes="$2"
19454
19455         $LFS ladvise -a dontneed $file 2>/dev/null ||
19456                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19457 }
19458
19459 ladvise_willread_performance()
19460 {
19461         local repeat=10
19462         local average_origin=0
19463         local average_cache=0
19464         local average_ladvise=0
19465
19466         for ((i = 1; i <= $repeat; i++)); do
19467                 echo "Iter $i/$repeat: reading without willread hint"
19468                 cancel_lru_locks osc
19469                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19470                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19471                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19472                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19473
19474                 cancel_lru_locks osc
19475                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19476                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19477                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19478
19479                 cancel_lru_locks osc
19480                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19481                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19482                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19483                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19484                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19485         done
19486         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19487         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19488         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19489
19490         speedup_cache=$(percent $average_cache $average_origin)
19491         speedup_ladvise=$(percent $average_ladvise $average_origin)
19492
19493         echo "Average uncached read: $average_origin"
19494         echo "Average speedup with OSS cached read: " \
19495                 "$average_cache = +$speedup_cache%"
19496         echo "Average speedup with ladvise willread: " \
19497                 "$average_ladvise = +$speedup_ladvise%"
19498
19499         local lowest_speedup=20
19500         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19501                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19502                         "got $average_cache%. Skipping ladvise willread check."
19503                 return 0
19504         fi
19505
19506         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19507         # it is still good to run until then to exercise 'ladvise willread'
19508         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19509                 [ "$ost1_FSTYPE" = "zfs" ] &&
19510                 echo "osd-zfs does not support dontneed or drop_caches" &&
19511                 return 0
19512
19513         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19514         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19515                 error_not_in_vm "Speedup with willread is less than " \
19516                         "$lowest_speedup%, got $average_ladvise%"
19517 }
19518
19519 test_255a() {
19520         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19521                 skip "lustre < 2.8.54 does not support ladvise "
19522         remote_ost_nodsh && skip "remote OST with nodsh"
19523
19524         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19525
19526         ladvise_no_type willread $DIR/$tfile &&
19527                 skip "willread ladvise is not supported"
19528
19529         ladvise_no_ioctl $DIR/$tfile &&
19530                 skip "ladvise ioctl is not supported"
19531
19532         local size_mb=100
19533         local size=$((size_mb * 1048576))
19534         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19535                 error "dd to $DIR/$tfile failed"
19536
19537         lfs ladvise -a willread $DIR/$tfile ||
19538                 error "Ladvise failed with no range argument"
19539
19540         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19541                 error "Ladvise failed with no -l or -e argument"
19542
19543         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19544                 error "Ladvise failed with only -e argument"
19545
19546         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19547                 error "Ladvise failed with only -l argument"
19548
19549         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19550                 error "End offset should not be smaller than start offset"
19551
19552         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19553                 error "End offset should not be equal to start offset"
19554
19555         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19556                 error "Ladvise failed with overflowing -s argument"
19557
19558         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19559                 error "Ladvise failed with overflowing -e argument"
19560
19561         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19562                 error "Ladvise failed with overflowing -l argument"
19563
19564         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19565                 error "Ladvise succeeded with conflicting -l and -e arguments"
19566
19567         echo "Synchronous ladvise should wait"
19568         local delay=4
19569 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19570         do_nodes $(comma_list $(osts_nodes)) \
19571                 $LCTL set_param fail_val=$delay fail_loc=0x237
19572
19573         local start_ts=$SECONDS
19574         lfs ladvise -a willread $DIR/$tfile ||
19575                 error "Ladvise failed with no range argument"
19576         local end_ts=$SECONDS
19577         local inteval_ts=$((end_ts - start_ts))
19578
19579         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19580                 error "Synchronous advice didn't wait reply"
19581         fi
19582
19583         echo "Asynchronous ladvise shouldn't wait"
19584         local start_ts=$SECONDS
19585         lfs ladvise -a willread -b $DIR/$tfile ||
19586                 error "Ladvise failed with no range argument"
19587         local end_ts=$SECONDS
19588         local inteval_ts=$((end_ts - start_ts))
19589
19590         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19591                 error "Asynchronous advice blocked"
19592         fi
19593
19594         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19595         ladvise_willread_performance
19596 }
19597 run_test 255a "check 'lfs ladvise -a willread'"
19598
19599 facet_meminfo() {
19600         local facet=$1
19601         local info=$2
19602
19603         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19604 }
19605
19606 test_255b() {
19607         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19608                 skip "lustre < 2.8.54 does not support ladvise "
19609         remote_ost_nodsh && skip "remote OST with nodsh"
19610
19611         lfs setstripe -c 1 -i 0 $DIR/$tfile
19612
19613         ladvise_no_type dontneed $DIR/$tfile &&
19614                 skip "dontneed ladvise is not supported"
19615
19616         ladvise_no_ioctl $DIR/$tfile &&
19617                 skip "ladvise ioctl is not supported"
19618
19619         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19620                 [ "$ost1_FSTYPE" = "zfs" ] &&
19621                 skip "zfs-osd does not support 'ladvise dontneed'"
19622
19623         local size_mb=100
19624         local size=$((size_mb * 1048576))
19625         # In order to prevent disturbance of other processes, only check 3/4
19626         # of the memory usage
19627         local kibibytes=$((size_mb * 1024 * 3 / 4))
19628
19629         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19630                 error "dd to $DIR/$tfile failed"
19631
19632         #force write to complete before dropping OST cache & checking memory
19633         sync
19634
19635         local total=$(facet_meminfo ost1 MemTotal)
19636         echo "Total memory: $total KiB"
19637
19638         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19639         local before_read=$(facet_meminfo ost1 Cached)
19640         echo "Cache used before read: $before_read KiB"
19641
19642         lfs ladvise -a willread $DIR/$tfile ||
19643                 error "Ladvise willread failed"
19644         local after_read=$(facet_meminfo ost1 Cached)
19645         echo "Cache used after read: $after_read KiB"
19646
19647         lfs ladvise -a dontneed $DIR/$tfile ||
19648                 error "Ladvise dontneed again failed"
19649         local no_read=$(facet_meminfo ost1 Cached)
19650         echo "Cache used after dontneed ladvise: $no_read KiB"
19651
19652         if [ $total -lt $((before_read + kibibytes)) ]; then
19653                 echo "Memory is too small, abort checking"
19654                 return 0
19655         fi
19656
19657         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19658                 error "Ladvise willread should use more memory" \
19659                         "than $kibibytes KiB"
19660         fi
19661
19662         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19663                 error "Ladvise dontneed should release more memory" \
19664                         "than $kibibytes KiB"
19665         fi
19666 }
19667 run_test 255b "check 'lfs ladvise -a dontneed'"
19668
19669 test_255c() {
19670         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19671                 skip "lustre < 2.10.50 does not support lockahead"
19672
19673         local count
19674         local new_count
19675         local difference
19676         local i
19677         local rc
19678
19679         test_mkdir -p $DIR/$tdir
19680         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19681
19682         #test 10 returns only success/failure
19683         i=10
19684         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19685         rc=$?
19686         if [ $rc -eq 255 ]; then
19687                 error "Ladvise test${i} failed, ${rc}"
19688         fi
19689
19690         #test 11 counts lock enqueue requests, all others count new locks
19691         i=11
19692         count=$(do_facet ost1 \
19693                 $LCTL get_param -n ost.OSS.ost.stats)
19694         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19695
19696         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19697         rc=$?
19698         if [ $rc -eq 255 ]; then
19699                 error "Ladvise test${i} failed, ${rc}"
19700         fi
19701
19702         new_count=$(do_facet ost1 \
19703                 $LCTL get_param -n ost.OSS.ost.stats)
19704         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19705                    awk '{ print $2 }')
19706
19707         difference="$((new_count - count))"
19708         if [ $difference -ne $rc ]; then
19709                 error "Ladvise test${i}, bad enqueue count, returned " \
19710                       "${rc}, actual ${difference}"
19711         fi
19712
19713         for i in $(seq 12 21); do
19714                 # If we do not do this, we run the risk of having too many
19715                 # locks and starting lock cancellation while we are checking
19716                 # lock counts.
19717                 cancel_lru_locks osc
19718
19719                 count=$($LCTL get_param -n \
19720                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19721
19722                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19723                 rc=$?
19724                 if [ $rc -eq 255 ]; then
19725                         error "Ladvise test ${i} failed, ${rc}"
19726                 fi
19727
19728                 new_count=$($LCTL get_param -n \
19729                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19730                 difference="$((new_count - count))"
19731
19732                 # Test 15 output is divided by 100 to map down to valid return
19733                 if [ $i -eq 15 ]; then
19734                         rc="$((rc * 100))"
19735                 fi
19736
19737                 if [ $difference -ne $rc ]; then
19738                         error "Ladvise test ${i}, bad lock count, returned " \
19739                               "${rc}, actual ${difference}"
19740                 fi
19741         done
19742
19743         #test 22 returns only success/failure
19744         i=22
19745         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19746         rc=$?
19747         if [ $rc -eq 255 ]; then
19748                 error "Ladvise test${i} failed, ${rc}"
19749         fi
19750 }
19751 run_test 255c "suite of ladvise lockahead tests"
19752
19753 test_256() {
19754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19755         remote_mds_nodsh && skip "remote MDS with nodsh"
19756         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19757         changelog_users $SINGLEMDS | grep "^cl" &&
19758                 skip "active changelog user"
19759
19760         local cl_user
19761         local cat_sl
19762         local mdt_dev
19763
19764         mdt_dev=$(mdsdevname 1)
19765         echo $mdt_dev
19766
19767         changelog_register || error "changelog_register failed"
19768
19769         rm -rf $DIR/$tdir
19770         mkdir -p $DIR/$tdir
19771
19772         changelog_clear 0 || error "changelog_clear failed"
19773
19774         # change something
19775         touch $DIR/$tdir/{1..10}
19776
19777         # stop the MDT
19778         stop $SINGLEMDS || error "Fail to stop MDT"
19779
19780         # remount the MDT
19781
19782         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19783
19784         #after mount new plainllog is used
19785         touch $DIR/$tdir/{11..19}
19786         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19787         stack_trap "rm -f $tmpfile"
19788         cat_sl=$(do_facet $SINGLEMDS "sync; \
19789                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19790                  llog_reader $tmpfile | grep -c type=1064553b")
19791         do_facet $SINGLEMDS llog_reader $tmpfile
19792
19793         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19794
19795         changelog_clear 0 || error "changelog_clear failed"
19796
19797         cat_sl=$(do_facet $SINGLEMDS "sync; \
19798                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19799                  llog_reader $tmpfile | grep -c type=1064553b")
19800
19801         if (( cat_sl == 2 )); then
19802                 error "Empty plain llog was not deleted from changelog catalog"
19803         elif (( cat_sl != 1 )); then
19804                 error "Active plain llog shouldn't be deleted from catalog"
19805         fi
19806 }
19807 run_test 256 "Check llog delete for empty and not full state"
19808
19809 test_257() {
19810         remote_mds_nodsh && skip "remote MDS with nodsh"
19811         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19812                 skip "Need MDS version at least 2.8.55"
19813
19814         test_mkdir $DIR/$tdir
19815
19816         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19817                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19818         stat $DIR/$tdir
19819
19820 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19821         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19822         local facet=mds$((mdtidx + 1))
19823         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19824         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19825
19826         stop $facet || error "stop MDS failed"
19827         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19828                 error "start MDS fail"
19829         wait_recovery_complete $facet
19830 }
19831 run_test 257 "xattr locks are not lost"
19832
19833 # Verify we take the i_mutex when security requires it
19834 test_258a() {
19835 #define OBD_FAIL_IMUTEX_SEC 0x141c
19836         $LCTL set_param fail_loc=0x141c
19837         touch $DIR/$tfile
19838         chmod u+s $DIR/$tfile
19839         chmod a+rwx $DIR/$tfile
19840         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19841         RC=$?
19842         if [ $RC -ne 0 ]; then
19843                 error "error, failed to take i_mutex, rc=$?"
19844         fi
19845         rm -f $DIR/$tfile
19846 }
19847 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19848
19849 # Verify we do NOT take the i_mutex in the normal case
19850 test_258b() {
19851 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19852         $LCTL set_param fail_loc=0x141d
19853         touch $DIR/$tfile
19854         chmod a+rwx $DIR
19855         chmod a+rw $DIR/$tfile
19856         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19857         RC=$?
19858         if [ $RC -ne 0 ]; then
19859                 error "error, took i_mutex unnecessarily, rc=$?"
19860         fi
19861         rm -f $DIR/$tfile
19862
19863 }
19864 run_test 258b "verify i_mutex security behavior"
19865
19866 test_259() {
19867         local file=$DIR/$tfile
19868         local before
19869         local after
19870
19871         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19872
19873         stack_trap "rm -f $file" EXIT
19874
19875         wait_delete_completed
19876         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19877         echo "before: $before"
19878
19879         $LFS setstripe -i 0 -c 1 $file
19880         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19881         sync_all_data
19882         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19883         echo "after write: $after"
19884
19885 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19886         do_facet ost1 $LCTL set_param fail_loc=0x2301
19887         $TRUNCATE $file 0
19888         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19889         echo "after truncate: $after"
19890
19891         stop ost1
19892         do_facet ost1 $LCTL set_param fail_loc=0
19893         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19894         sleep 2
19895         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19896         echo "after restart: $after"
19897         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19898                 error "missing truncate?"
19899
19900         return 0
19901 }
19902 run_test 259 "crash at delayed truncate"
19903
19904 test_260() {
19905 #define OBD_FAIL_MDC_CLOSE               0x806
19906         $LCTL set_param fail_loc=0x80000806
19907         touch $DIR/$tfile
19908
19909 }
19910 run_test 260 "Check mdc_close fail"
19911
19912 ### Data-on-MDT sanity tests ###
19913 test_270a() {
19914         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19915                 skip "Need MDS version at least 2.10.55 for DoM"
19916
19917         # create DoM file
19918         local dom=$DIR/$tdir/dom_file
19919         local tmp=$DIR/$tdir/tmp_file
19920
19921         mkdir -p $DIR/$tdir
19922
19923         # basic checks for DoM component creation
19924         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19925                 error "Can set MDT layout to non-first entry"
19926
19927         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19928                 error "Can define multiple entries as MDT layout"
19929
19930         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19931
19932         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19933         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19934         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19935
19936         local mdtidx=$($LFS getstripe -m $dom)
19937         local mdtname=MDT$(printf %04x $mdtidx)
19938         local facet=mds$((mdtidx + 1))
19939         local space_check=1
19940
19941         # Skip free space checks with ZFS
19942         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19943
19944         # write
19945         sync
19946         local size_tmp=$((65536 * 3))
19947         local mdtfree1=$(do_facet $facet \
19948                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19949
19950         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19951         # check also direct IO along write
19952         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19953         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19954         sync
19955         cmp $tmp $dom || error "file data is different"
19956         [ $(stat -c%s $dom) == $size_tmp ] ||
19957                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19958         if [ $space_check == 1 ]; then
19959                 local mdtfree2=$(do_facet $facet \
19960                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19961
19962                 # increase in usage from by $size_tmp
19963                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19964                         error "MDT free space wrong after write: " \
19965                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19966         fi
19967
19968         # truncate
19969         local size_dom=10000
19970
19971         $TRUNCATE $dom $size_dom
19972         [ $(stat -c%s $dom) == $size_dom ] ||
19973                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19974         if [ $space_check == 1 ]; then
19975                 mdtfree1=$(do_facet $facet \
19976                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19977                 # decrease in usage from $size_tmp to new $size_dom
19978                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19979                   $(((size_tmp - size_dom) / 1024)) ] ||
19980                         error "MDT free space is wrong after truncate: " \
19981                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19982         fi
19983
19984         # append
19985         cat $tmp >> $dom
19986         sync
19987         size_dom=$((size_dom + size_tmp))
19988         [ $(stat -c%s $dom) == $size_dom ] ||
19989                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19990         if [ $space_check == 1 ]; then
19991                 mdtfree2=$(do_facet $facet \
19992                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19993                 # increase in usage by $size_tmp from previous
19994                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19995                         error "MDT free space is wrong after append: " \
19996                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19997         fi
19998
19999         # delete
20000         rm $dom
20001         if [ $space_check == 1 ]; then
20002                 mdtfree1=$(do_facet $facet \
20003                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20004                 # decrease in usage by $size_dom from previous
20005                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20006                         error "MDT free space is wrong after removal: " \
20007                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20008         fi
20009
20010         # combined striping
20011         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20012                 error "Can't create DoM + OST striping"
20013
20014         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20015         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20016         # check also direct IO along write
20017         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20018         sync
20019         cmp $tmp $dom || error "file data is different"
20020         [ $(stat -c%s $dom) == $size_tmp ] ||
20021                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20022         rm $dom $tmp
20023
20024         return 0
20025 }
20026 run_test 270a "DoM: basic functionality tests"
20027
20028 test_270b() {
20029         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20030                 skip "Need MDS version at least 2.10.55"
20031
20032         local dom=$DIR/$tdir/dom_file
20033         local max_size=1048576
20034
20035         mkdir -p $DIR/$tdir
20036         $LFS setstripe -E $max_size -L mdt $dom
20037
20038         # truncate over the limit
20039         $TRUNCATE $dom $(($max_size + 1)) &&
20040                 error "successful truncate over the maximum size"
20041         # write over the limit
20042         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20043                 error "successful write over the maximum size"
20044         # append over the limit
20045         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20046         echo "12345" >> $dom && error "successful append over the maximum size"
20047         rm $dom
20048
20049         return 0
20050 }
20051 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20052
20053 test_270c() {
20054         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20055                 skip "Need MDS version at least 2.10.55"
20056
20057         mkdir -p $DIR/$tdir
20058         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20059
20060         # check files inherit DoM EA
20061         touch $DIR/$tdir/first
20062         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20063                 error "bad pattern"
20064         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20065                 error "bad stripe count"
20066         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20067                 error "bad stripe size"
20068
20069         # check directory inherits DoM EA and uses it as default
20070         mkdir $DIR/$tdir/subdir
20071         touch $DIR/$tdir/subdir/second
20072         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20073                 error "bad pattern in sub-directory"
20074         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20075                 error "bad stripe count in sub-directory"
20076         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20077                 error "bad stripe size in sub-directory"
20078         return 0
20079 }
20080 run_test 270c "DoM: DoM EA inheritance tests"
20081
20082 test_270d() {
20083         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20084                 skip "Need MDS version at least 2.10.55"
20085
20086         mkdir -p $DIR/$tdir
20087         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20088
20089         # inherit default DoM striping
20090         mkdir $DIR/$tdir/subdir
20091         touch $DIR/$tdir/subdir/f1
20092
20093         # change default directory striping
20094         $LFS setstripe -c 1 $DIR/$tdir/subdir
20095         touch $DIR/$tdir/subdir/f2
20096         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20097                 error "wrong default striping in file 2"
20098         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20099                 error "bad pattern in file 2"
20100         return 0
20101 }
20102 run_test 270d "DoM: change striping from DoM to RAID0"
20103
20104 test_270e() {
20105         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20106                 skip "Need MDS version at least 2.10.55"
20107
20108         mkdir -p $DIR/$tdir/dom
20109         mkdir -p $DIR/$tdir/norm
20110         DOMFILES=20
20111         NORMFILES=10
20112         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20113         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20114
20115         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20116         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20117
20118         # find DoM files by layout
20119         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20120         [ $NUM -eq  $DOMFILES ] ||
20121                 error "lfs find -L: found $NUM, expected $DOMFILES"
20122         echo "Test 1: lfs find 20 DOM files by layout: OK"
20123
20124         # there should be 1 dir with default DOM striping
20125         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20126         [ $NUM -eq  1 ] ||
20127                 error "lfs find -L: found $NUM, expected 1 dir"
20128         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20129
20130         # find DoM files by stripe size
20131         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20132         [ $NUM -eq  $DOMFILES ] ||
20133                 error "lfs find -S: found $NUM, expected $DOMFILES"
20134         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20135
20136         # find files by stripe offset except DoM files
20137         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20138         [ $NUM -eq  $NORMFILES ] ||
20139                 error "lfs find -i: found $NUM, expected $NORMFILES"
20140         echo "Test 5: lfs find no DOM files by stripe index: OK"
20141         return 0
20142 }
20143 run_test 270e "DoM: lfs find with DoM files test"
20144
20145 test_270f() {
20146         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20147                 skip "Need MDS version at least 2.10.55"
20148
20149         local mdtname=${FSNAME}-MDT0000-mdtlov
20150         local dom=$DIR/$tdir/dom_file
20151         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20152                                                 lod.$mdtname.dom_stripesize)
20153         local dom_limit=131072
20154
20155         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20156         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20157                                                 lod.$mdtname.dom_stripesize)
20158         [ ${dom_limit} -eq ${dom_current} ] ||
20159                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20160
20161         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20162         $LFS setstripe -d $DIR/$tdir
20163         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20164                 error "Can't set directory default striping"
20165
20166         # exceed maximum stripe size
20167         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20168                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20169         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20170                 error "Able to create DoM component size more than LOD limit"
20171
20172         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20173         dom_current=$(do_facet mds1 $LCTL get_param -n \
20174                                                 lod.$mdtname.dom_stripesize)
20175         [ 0 -eq ${dom_current} ] ||
20176                 error "Can't set zero DoM stripe limit"
20177         rm $dom
20178
20179         # attempt to create DoM file on server with disabled DoM should
20180         # remove DoM entry from layout and be succeed
20181         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20182                 error "Can't create DoM file (DoM is disabled)"
20183         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20184                 error "File has DoM component while DoM is disabled"
20185         rm $dom
20186
20187         # attempt to create DoM file with only DoM stripe should return error
20188         $LFS setstripe -E $dom_limit -L mdt $dom &&
20189                 error "Able to create DoM-only file while DoM is disabled"
20190
20191         # too low values to be aligned with smallest stripe size 64K
20192         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20193         dom_current=$(do_facet mds1 $LCTL get_param -n \
20194                                                 lod.$mdtname.dom_stripesize)
20195         [ 30000 -eq ${dom_current} ] &&
20196                 error "Can set too small DoM stripe limit"
20197
20198         # 64K is a minimal stripe size in Lustre, expect limit of that size
20199         [ 65536 -eq ${dom_current} ] ||
20200                 error "Limit is not set to 64K but ${dom_current}"
20201
20202         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20203         dom_current=$(do_facet mds1 $LCTL get_param -n \
20204                                                 lod.$mdtname.dom_stripesize)
20205         echo $dom_current
20206         [ 2147483648 -eq ${dom_current} ] &&
20207                 error "Can set too large DoM stripe limit"
20208
20209         do_facet mds1 $LCTL set_param -n \
20210                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20211         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20212                 error "Can't create DoM component size after limit change"
20213         do_facet mds1 $LCTL set_param -n \
20214                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20215         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20216                 error "Can't create DoM file after limit decrease"
20217         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20218                 error "Can create big DoM component after limit decrease"
20219         touch ${dom}_def ||
20220                 error "Can't create file with old default layout"
20221
20222         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20223         return 0
20224 }
20225 run_test 270f "DoM: maximum DoM stripe size checks"
20226
20227 test_270g() {
20228         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20229                 skip "Need MDS version at least 2.13.52"
20230         local dom=$DIR/$tdir/$tfile
20231
20232         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20233         local lodname=${FSNAME}-MDT0000-mdtlov
20234
20235         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20236         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20237         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20238         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20239
20240         local dom_limit=1024
20241         local dom_threshold="50%"
20242
20243         $LFS setstripe -d $DIR/$tdir
20244         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20245                 error "Can't set directory default striping"
20246
20247         do_facet mds1 $LCTL set_param -n \
20248                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20249         # set 0 threshold and create DOM file to change tunable stripesize
20250         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20251         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20252                 error "Failed to create $dom file"
20253         # now tunable dom_cur_stripesize should reach maximum
20254         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20255                                         lod.${lodname}.dom_stripesize_cur_kb)
20256         [[ $dom_current == $dom_limit ]] ||
20257                 error "Current DOM stripesize is not maximum"
20258         rm $dom
20259
20260         # set threshold for further tests
20261         do_facet mds1 $LCTL set_param -n \
20262                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20263         echo "DOM threshold is $dom_threshold free space"
20264         local dom_def
20265         local dom_set
20266         # Spoof bfree to exceed threshold
20267         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20268         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20269         for spfree in 40 20 0 15 30 55; do
20270                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20271                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20272                         error "Failed to create $dom file"
20273                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20274                                         lod.${lodname}.dom_stripesize_cur_kb)
20275                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20276                 [[ $dom_def != $dom_current ]] ||
20277                         error "Default stripe size was not changed"
20278                 if [[ $spfree > 0 ]] ; then
20279                         dom_set=$($LFS getstripe -S $dom)
20280                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20281                                 error "DOM component size is still old"
20282                 else
20283                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20284                                 error "DoM component is set with no free space"
20285                 fi
20286                 rm $dom
20287                 dom_current=$dom_def
20288         done
20289 }
20290 run_test 270g "DoM: default DoM stripe size depends on free space"
20291
20292 test_270h() {
20293         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20294                 skip "Need MDS version at least 2.13.53"
20295
20296         local mdtname=${FSNAME}-MDT0000-mdtlov
20297         local dom=$DIR/$tdir/$tfile
20298         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20299
20300         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20301         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20302
20303         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20304         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20305                 error "can't create OST file"
20306         # mirrored file with DOM entry in the second mirror
20307         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20308                 error "can't create mirror with DoM component"
20309
20310         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20311
20312         # DOM component in the middle and has other enries in the same mirror,
20313         # should succeed but lost DoM component
20314         $LFS setstripe --copy=${dom}_1 $dom ||
20315                 error "Can't create file from OST|DOM mirror layout"
20316         # check new file has no DoM layout after all
20317         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20318                 error "File has DoM component while DoM is disabled"
20319 }
20320 run_test 270h "DoM: DoM stripe removal when disabled on server"
20321
20322 test_271a() {
20323         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20324                 skip "Need MDS version at least 2.10.55"
20325
20326         local dom=$DIR/$tdir/dom
20327
20328         mkdir -p $DIR/$tdir
20329
20330         $LFS setstripe -E 1024K -L mdt $dom
20331
20332         lctl set_param -n mdc.*.stats=clear
20333         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20334         cat $dom > /dev/null
20335         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20336         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20337         ls $dom
20338         rm -f $dom
20339 }
20340 run_test 271a "DoM: data is cached for read after write"
20341
20342 test_271b() {
20343         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20344                 skip "Need MDS version at least 2.10.55"
20345
20346         local dom=$DIR/$tdir/dom
20347
20348         mkdir -p $DIR/$tdir
20349
20350         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20351
20352         lctl set_param -n mdc.*.stats=clear
20353         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20354         cancel_lru_locks mdc
20355         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20356         # second stat to check size is cached on client
20357         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20358         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20359         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20360         rm -f $dom
20361 }
20362 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20363
20364 test_271ba() {
20365         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20366                 skip "Need MDS version at least 2.10.55"
20367
20368         local dom=$DIR/$tdir/dom
20369
20370         mkdir -p $DIR/$tdir
20371
20372         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20373
20374         lctl set_param -n mdc.*.stats=clear
20375         lctl set_param -n osc.*.stats=clear
20376         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20377         cancel_lru_locks mdc
20378         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20379         # second stat to check size is cached on client
20380         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20381         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20382         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20383         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20384         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20385         rm -f $dom
20386 }
20387 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20388
20389
20390 get_mdc_stats() {
20391         local mdtidx=$1
20392         local param=$2
20393         local mdt=MDT$(printf %04x $mdtidx)
20394
20395         if [ -z $param ]; then
20396                 lctl get_param -n mdc.*$mdt*.stats
20397         else
20398                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20399         fi
20400 }
20401
20402 test_271c() {
20403         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20404                 skip "Need MDS version at least 2.10.55"
20405
20406         local dom=$DIR/$tdir/dom
20407
20408         mkdir -p $DIR/$tdir
20409
20410         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20411
20412         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20413         local facet=mds$((mdtidx + 1))
20414
20415         cancel_lru_locks mdc
20416         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20417         createmany -o $dom 1000
20418         lctl set_param -n mdc.*.stats=clear
20419         smalliomany -w $dom 1000 200
20420         get_mdc_stats $mdtidx
20421         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20422         # Each file has 1 open, 1 IO enqueues, total 2000
20423         # but now we have also +1 getxattr for security.capability, total 3000
20424         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20425         unlinkmany $dom 1000
20426
20427         cancel_lru_locks mdc
20428         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20429         createmany -o $dom 1000
20430         lctl set_param -n mdc.*.stats=clear
20431         smalliomany -w $dom 1000 200
20432         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20433         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20434         # for OPEN and IO lock.
20435         [ $((enq - enq_2)) -ge 1000 ] ||
20436                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20437         unlinkmany $dom 1000
20438         return 0
20439 }
20440 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20441
20442 cleanup_271def_tests() {
20443         trap 0
20444         rm -f $1
20445 }
20446
20447 test_271d() {
20448         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20449                 skip "Need MDS version at least 2.10.57"
20450
20451         local dom=$DIR/$tdir/dom
20452         local tmp=$TMP/$tfile
20453         trap "cleanup_271def_tests $tmp" EXIT
20454
20455         mkdir -p $DIR/$tdir
20456
20457         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20458
20459         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20460
20461         cancel_lru_locks mdc
20462         dd if=/dev/urandom of=$tmp bs=1000 count=1
20463         dd if=$tmp of=$dom bs=1000 count=1
20464         cancel_lru_locks mdc
20465
20466         cat /etc/hosts >> $tmp
20467         lctl set_param -n mdc.*.stats=clear
20468
20469         # append data to the same file it should update local page
20470         echo "Append to the same page"
20471         cat /etc/hosts >> $dom
20472         local num=$(get_mdc_stats $mdtidx ost_read)
20473         local ra=$(get_mdc_stats $mdtidx req_active)
20474         local rw=$(get_mdc_stats $mdtidx req_waittime)
20475
20476         [ -z $num ] || error "$num READ RPC occured"
20477         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20478         echo "... DONE"
20479
20480         # compare content
20481         cmp $tmp $dom || error "file miscompare"
20482
20483         cancel_lru_locks mdc
20484         lctl set_param -n mdc.*.stats=clear
20485
20486         echo "Open and read file"
20487         cat $dom > /dev/null
20488         local num=$(get_mdc_stats $mdtidx ost_read)
20489         local ra=$(get_mdc_stats $mdtidx req_active)
20490         local rw=$(get_mdc_stats $mdtidx req_waittime)
20491
20492         [ -z $num ] || error "$num READ RPC occured"
20493         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20494         echo "... DONE"
20495
20496         # compare content
20497         cmp $tmp $dom || error "file miscompare"
20498
20499         return 0
20500 }
20501 run_test 271d "DoM: read on open (1K file in reply buffer)"
20502
20503 test_271f() {
20504         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20505                 skip "Need MDS version at least 2.10.57"
20506
20507         local dom=$DIR/$tdir/dom
20508         local tmp=$TMP/$tfile
20509         trap "cleanup_271def_tests $tmp" EXIT
20510
20511         mkdir -p $DIR/$tdir
20512
20513         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20514
20515         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20516
20517         cancel_lru_locks mdc
20518         dd if=/dev/urandom of=$tmp bs=265000 count=1
20519         dd if=$tmp of=$dom bs=265000 count=1
20520         cancel_lru_locks mdc
20521         cat /etc/hosts >> $tmp
20522         lctl set_param -n mdc.*.stats=clear
20523
20524         echo "Append to the same page"
20525         cat /etc/hosts >> $dom
20526         local num=$(get_mdc_stats $mdtidx ost_read)
20527         local ra=$(get_mdc_stats $mdtidx req_active)
20528         local rw=$(get_mdc_stats $mdtidx req_waittime)
20529
20530         [ -z $num ] || error "$num READ RPC occured"
20531         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20532         echo "... DONE"
20533
20534         # compare content
20535         cmp $tmp $dom || error "file miscompare"
20536
20537         cancel_lru_locks mdc
20538         lctl set_param -n mdc.*.stats=clear
20539
20540         echo "Open and read file"
20541         cat $dom > /dev/null
20542         local num=$(get_mdc_stats $mdtidx ost_read)
20543         local ra=$(get_mdc_stats $mdtidx req_active)
20544         local rw=$(get_mdc_stats $mdtidx req_waittime)
20545
20546         [ -z $num ] && num=0
20547         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20548         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20549         echo "... DONE"
20550
20551         # compare content
20552         cmp $tmp $dom || error "file miscompare"
20553
20554         return 0
20555 }
20556 run_test 271f "DoM: read on open (200K file and read tail)"
20557
20558 test_271g() {
20559         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20560                 skip "Skipping due to old client or server version"
20561
20562         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20563         # to get layout
20564         $CHECKSTAT -t file $DIR1/$tfile
20565
20566         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20567         MULTIOP_PID=$!
20568         sleep 1
20569         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20570         $LCTL set_param fail_loc=0x80000314
20571         rm $DIR1/$tfile || error "Unlink fails"
20572         RC=$?
20573         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20574         [ $RC -eq 0 ] || error "Failed write to stale object"
20575 }
20576 run_test 271g "Discard DoM data vs client flush race"
20577
20578 test_272a() {
20579         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20580                 skip "Need MDS version at least 2.11.50"
20581
20582         local dom=$DIR/$tdir/dom
20583         mkdir -p $DIR/$tdir
20584
20585         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20586         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20587                 error "failed to write data into $dom"
20588         local old_md5=$(md5sum $dom)
20589
20590         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20591                 error "failed to migrate to the same DoM component"
20592
20593         local new_md5=$(md5sum $dom)
20594
20595         [ "$old_md5" == "$new_md5" ] ||
20596                 error "md5sum differ: $old_md5, $new_md5"
20597
20598         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20599                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20600 }
20601 run_test 272a "DoM migration: new layout with the same DOM component"
20602
20603 test_272b() {
20604         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20605                 skip "Need MDS version at least 2.11.50"
20606
20607         local dom=$DIR/$tdir/dom
20608         mkdir -p $DIR/$tdir
20609         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20610
20611         local mdtidx=$($LFS getstripe -m $dom)
20612         local mdtname=MDT$(printf %04x $mdtidx)
20613         local facet=mds$((mdtidx + 1))
20614
20615         local mdtfree1=$(do_facet $facet \
20616                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20617         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20618                 error "failed to write data into $dom"
20619         local old_md5=$(md5sum $dom)
20620         cancel_lru_locks mdc
20621         local mdtfree1=$(do_facet $facet \
20622                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20623
20624         $LFS migrate -c2 $dom ||
20625                 error "failed to migrate to the new composite layout"
20626         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20627                 error "MDT stripe was not removed"
20628
20629         cancel_lru_locks mdc
20630         local new_md5=$(md5sum $dom)
20631         [ "$old_md5" == "$new_md5" ] ||
20632                 error "$old_md5 != $new_md5"
20633
20634         # Skip free space checks with ZFS
20635         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20636                 local mdtfree2=$(do_facet $facet \
20637                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20638                 [ $mdtfree2 -gt $mdtfree1 ] ||
20639                         error "MDT space is not freed after migration"
20640         fi
20641         return 0
20642 }
20643 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20644
20645 test_272c() {
20646         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20647                 skip "Need MDS version at least 2.11.50"
20648
20649         local dom=$DIR/$tdir/$tfile
20650         mkdir -p $DIR/$tdir
20651         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20652
20653         local mdtidx=$($LFS getstripe -m $dom)
20654         local mdtname=MDT$(printf %04x $mdtidx)
20655         local facet=mds$((mdtidx + 1))
20656
20657         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20658                 error "failed to write data into $dom"
20659         local old_md5=$(md5sum $dom)
20660         cancel_lru_locks mdc
20661         local mdtfree1=$(do_facet $facet \
20662                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20663
20664         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20665                 error "failed to migrate to the new composite layout"
20666         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20667                 error "MDT stripe was not removed"
20668
20669         cancel_lru_locks mdc
20670         local new_md5=$(md5sum $dom)
20671         [ "$old_md5" == "$new_md5" ] ||
20672                 error "$old_md5 != $new_md5"
20673
20674         # Skip free space checks with ZFS
20675         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20676                 local mdtfree2=$(do_facet $facet \
20677                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20678                 [ $mdtfree2 -gt $mdtfree1 ] ||
20679                         error "MDS space is not freed after migration"
20680         fi
20681         return 0
20682 }
20683 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20684
20685 test_272d() {
20686         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20687                 skip "Need MDS version at least 2.12.55"
20688
20689         local dom=$DIR/$tdir/$tfile
20690         mkdir -p $DIR/$tdir
20691         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20692
20693         local mdtidx=$($LFS getstripe -m $dom)
20694         local mdtname=MDT$(printf %04x $mdtidx)
20695         local facet=mds$((mdtidx + 1))
20696
20697         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20698                 error "failed to write data into $dom"
20699         local old_md5=$(md5sum $dom)
20700         cancel_lru_locks mdc
20701         local mdtfree1=$(do_facet $facet \
20702                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20703
20704         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20705                 error "failed mirroring to the new composite layout"
20706         $LFS mirror resync $dom ||
20707                 error "failed mirror resync"
20708         $LFS mirror split --mirror-id 1 -d $dom ||
20709                 error "failed mirror split"
20710
20711         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20712                 error "MDT stripe was not removed"
20713
20714         cancel_lru_locks mdc
20715         local new_md5=$(md5sum $dom)
20716         [ "$old_md5" == "$new_md5" ] ||
20717                 error "$old_md5 != $new_md5"
20718
20719         # Skip free space checks with ZFS
20720         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20721                 local mdtfree2=$(do_facet $facet \
20722                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20723                 [ $mdtfree2 -gt $mdtfree1 ] ||
20724                         error "MDS space is not freed after DOM mirror deletion"
20725         fi
20726         return 0
20727 }
20728 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20729
20730 test_272e() {
20731         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20732                 skip "Need MDS version at least 2.12.55"
20733
20734         local dom=$DIR/$tdir/$tfile
20735         mkdir -p $DIR/$tdir
20736         $LFS setstripe -c 2 $dom
20737
20738         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20739                 error "failed to write data into $dom"
20740         local old_md5=$(md5sum $dom)
20741         cancel_lru_locks mdc
20742
20743         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20744                 error "failed mirroring to the DOM layout"
20745         $LFS mirror resync $dom ||
20746                 error "failed mirror resync"
20747         $LFS mirror split --mirror-id 1 -d $dom ||
20748                 error "failed mirror split"
20749
20750         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20751                 error "MDT stripe was not removed"
20752
20753         cancel_lru_locks mdc
20754         local new_md5=$(md5sum $dom)
20755         [ "$old_md5" == "$new_md5" ] ||
20756                 error "$old_md5 != $new_md5"
20757
20758         return 0
20759 }
20760 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20761
20762 test_272f() {
20763         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20764                 skip "Need MDS version at least 2.12.55"
20765
20766         local dom=$DIR/$tdir/$tfile
20767         mkdir -p $DIR/$tdir
20768         $LFS setstripe -c 2 $dom
20769
20770         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20771                 error "failed to write data into $dom"
20772         local old_md5=$(md5sum $dom)
20773         cancel_lru_locks mdc
20774
20775         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20776                 error "failed migrating to the DOM file"
20777
20778         cancel_lru_locks mdc
20779         local new_md5=$(md5sum $dom)
20780         [ "$old_md5" != "$new_md5" ] &&
20781                 error "$old_md5 != $new_md5"
20782
20783         return 0
20784 }
20785 run_test 272f "DoM migration: OST-striped file to DOM file"
20786
20787 test_273a() {
20788         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20789                 skip "Need MDS version at least 2.11.50"
20790
20791         # Layout swap cannot be done if either file has DOM component,
20792         # this will never be supported, migration should be used instead
20793
20794         local dom=$DIR/$tdir/$tfile
20795         mkdir -p $DIR/$tdir
20796
20797         $LFS setstripe -c2 ${dom}_plain
20798         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20799         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20800                 error "can swap layout with DoM component"
20801         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20802                 error "can swap layout with DoM component"
20803
20804         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20805         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20806                 error "can swap layout with DoM component"
20807         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20808                 error "can swap layout with DoM component"
20809         return 0
20810 }
20811 run_test 273a "DoM: layout swapping should fail with DOM"
20812
20813 test_275() {
20814         remote_ost_nodsh && skip "remote OST with nodsh"
20815         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20816                 skip "Need OST version >= 2.10.57"
20817
20818         local file=$DIR/$tfile
20819         local oss
20820
20821         oss=$(comma_list $(osts_nodes))
20822
20823         dd if=/dev/urandom of=$file bs=1M count=2 ||
20824                 error "failed to create a file"
20825         cancel_lru_locks osc
20826
20827         #lock 1
20828         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20829                 error "failed to read a file"
20830
20831 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20832         $LCTL set_param fail_loc=0x8000031f
20833
20834         cancel_lru_locks osc &
20835         sleep 1
20836
20837 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20838         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20839         #IO takes another lock, but matches the PENDING one
20840         #and places it to the IO RPC
20841         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20842                 error "failed to read a file with PENDING lock"
20843 }
20844 run_test 275 "Read on a canceled duplicate lock"
20845
20846 test_276() {
20847         remote_ost_nodsh && skip "remote OST with nodsh"
20848         local pid
20849
20850         do_facet ost1 "(while true; do \
20851                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20852                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20853         pid=$!
20854
20855         for LOOP in $(seq 20); do
20856                 stop ost1
20857                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20858         done
20859         kill -9 $pid
20860         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20861                 rm $TMP/sanity_276_pid"
20862 }
20863 run_test 276 "Race between mount and obd_statfs"
20864
20865 test_277() {
20866         $LCTL set_param ldlm.namespaces.*.lru_size=0
20867         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20868         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20869                         grep ^used_mb | awk '{print $2}')
20870         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20871         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20872                 oflag=direct conv=notrunc
20873         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20874                         grep ^used_mb | awk '{print $2}')
20875         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20876 }
20877 run_test 277 "Direct IO shall drop page cache"
20878
20879 test_278() {
20880         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20881         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20882         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20883                 skip "needs the same host for mdt1 mdt2" && return
20884
20885         local pid1
20886         local pid2
20887
20888 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20889         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20890         stop mds2 &
20891         pid2=$!
20892
20893         stop mds1
20894
20895         echo "Starting MDTs"
20896         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20897         wait $pid2
20898 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20899 #will return NULL
20900         do_facet mds2 $LCTL set_param fail_loc=0
20901
20902         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20903         wait_recovery_complete mds2
20904 }
20905 run_test 278 "Race starting MDS between MDTs stop/start"
20906
20907 test_280() {
20908         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20909                 skip "Need MGS version at least 2.13.52"
20910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20911         combined_mgs_mds || skip "needs combined MGS/MDT"
20912
20913         umount_client $MOUNT
20914 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20915         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20916
20917         mount_client $MOUNT &
20918         sleep 1
20919         stop mgs || error "stop mgs failed"
20920         #for a race mgs would crash
20921         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20922         mount_client $MOUNT || error "mount client failed"
20923 }
20924 run_test 280 "Race between MGS umount and client llog processing"
20925
20926 cleanup_test_300() {
20927         trap 0
20928         umask $SAVE_UMASK
20929 }
20930 test_striped_dir() {
20931         local mdt_index=$1
20932         local stripe_count
20933         local stripe_index
20934
20935         mkdir -p $DIR/$tdir
20936
20937         SAVE_UMASK=$(umask)
20938         trap cleanup_test_300 RETURN EXIT
20939
20940         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20941                                                 $DIR/$tdir/striped_dir ||
20942                 error "set striped dir error"
20943
20944         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20945         [ "$mode" = "755" ] || error "expect 755 got $mode"
20946
20947         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20948                 error "getdirstripe failed"
20949         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20950         if [ "$stripe_count" != "2" ]; then
20951                 error "1:stripe_count is $stripe_count, expect 2"
20952         fi
20953         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20954         if [ "$stripe_count" != "2" ]; then
20955                 error "2:stripe_count is $stripe_count, expect 2"
20956         fi
20957
20958         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20959         if [ "$stripe_index" != "$mdt_index" ]; then
20960                 error "stripe_index is $stripe_index, expect $mdt_index"
20961         fi
20962
20963         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20964                 error "nlink error after create striped dir"
20965
20966         mkdir $DIR/$tdir/striped_dir/a
20967         mkdir $DIR/$tdir/striped_dir/b
20968
20969         stat $DIR/$tdir/striped_dir/a ||
20970                 error "create dir under striped dir failed"
20971         stat $DIR/$tdir/striped_dir/b ||
20972                 error "create dir under striped dir failed"
20973
20974         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20975                 error "nlink error after mkdir"
20976
20977         rmdir $DIR/$tdir/striped_dir/a
20978         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20979                 error "nlink error after rmdir"
20980
20981         rmdir $DIR/$tdir/striped_dir/b
20982         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20983                 error "nlink error after rmdir"
20984
20985         chattr +i $DIR/$tdir/striped_dir
20986         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20987                 error "immutable flags not working under striped dir!"
20988         chattr -i $DIR/$tdir/striped_dir
20989
20990         rmdir $DIR/$tdir/striped_dir ||
20991                 error "rmdir striped dir error"
20992
20993         cleanup_test_300
20994
20995         true
20996 }
20997
20998 test_300a() {
20999         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21000                 skip "skipped for lustre < 2.7.0"
21001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21003
21004         test_striped_dir 0 || error "failed on striped dir on MDT0"
21005         test_striped_dir 1 || error "failed on striped dir on MDT0"
21006 }
21007 run_test 300a "basic striped dir sanity test"
21008
21009 test_300b() {
21010         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21011                 skip "skipped for lustre < 2.7.0"
21012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21014
21015         local i
21016         local mtime1
21017         local mtime2
21018         local mtime3
21019
21020         test_mkdir $DIR/$tdir || error "mkdir fail"
21021         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21022                 error "set striped dir error"
21023         for i in {0..9}; do
21024                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21025                 sleep 1
21026                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21027                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21028                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21029                 sleep 1
21030                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21031                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21032                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21033         done
21034         true
21035 }
21036 run_test 300b "check ctime/mtime for striped dir"
21037
21038 test_300c() {
21039         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21040                 skip "skipped for lustre < 2.7.0"
21041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21043
21044         local file_count
21045
21046         mkdir -p $DIR/$tdir
21047         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21048                 error "set striped dir error"
21049
21050         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21051                 error "chown striped dir failed"
21052
21053         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21054                 error "create 5k files failed"
21055
21056         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21057
21058         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21059
21060         rm -rf $DIR/$tdir
21061 }
21062 run_test 300c "chown && check ls under striped directory"
21063
21064 test_300d() {
21065         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21066                 skip "skipped for lustre < 2.7.0"
21067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21069
21070         local stripe_count
21071         local file
21072
21073         mkdir -p $DIR/$tdir
21074         $LFS setstripe -c 2 $DIR/$tdir
21075
21076         #local striped directory
21077         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21078                 error "set striped dir error"
21079         #look at the directories for debug purposes
21080         ls -l $DIR/$tdir
21081         $LFS getdirstripe $DIR/$tdir
21082         ls -l $DIR/$tdir/striped_dir
21083         $LFS getdirstripe $DIR/$tdir/striped_dir
21084         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21085                 error "create 10 files failed"
21086
21087         #remote striped directory
21088         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21089                 error "set striped dir error"
21090         #look at the directories for debug purposes
21091         ls -l $DIR/$tdir
21092         $LFS getdirstripe $DIR/$tdir
21093         ls -l $DIR/$tdir/remote_striped_dir
21094         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21095         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21096                 error "create 10 files failed"
21097
21098         for file in $(find $DIR/$tdir); do
21099                 stripe_count=$($LFS getstripe -c $file)
21100                 [ $stripe_count -eq 2 ] ||
21101                         error "wrong stripe $stripe_count for $file"
21102         done
21103
21104         rm -rf $DIR/$tdir
21105 }
21106 run_test 300d "check default stripe under striped directory"
21107
21108 test_300e() {
21109         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21110                 skip "Need MDS version at least 2.7.55"
21111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21113
21114         local stripe_count
21115         local file
21116
21117         mkdir -p $DIR/$tdir
21118
21119         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21120                 error "set striped dir error"
21121
21122         touch $DIR/$tdir/striped_dir/a
21123         touch $DIR/$tdir/striped_dir/b
21124         touch $DIR/$tdir/striped_dir/c
21125
21126         mkdir $DIR/$tdir/striped_dir/dir_a
21127         mkdir $DIR/$tdir/striped_dir/dir_b
21128         mkdir $DIR/$tdir/striped_dir/dir_c
21129
21130         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21131                 error "set striped adir under striped dir error"
21132
21133         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21134                 error "set striped bdir under striped dir error"
21135
21136         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21137                 error "set striped cdir under striped dir error"
21138
21139         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21140                 error "rename dir under striped dir fails"
21141
21142         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21143                 error "rename dir under different stripes fails"
21144
21145         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21146                 error "rename file under striped dir should succeed"
21147
21148         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21149                 error "rename dir under striped dir should succeed"
21150
21151         rm -rf $DIR/$tdir
21152 }
21153 run_test 300e "check rename under striped directory"
21154
21155 test_300f() {
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21158         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21159                 skip "Need MDS version at least 2.7.55"
21160
21161         local stripe_count
21162         local file
21163
21164         rm -rf $DIR/$tdir
21165         mkdir -p $DIR/$tdir
21166
21167         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21168                 error "set striped dir error"
21169
21170         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21171                 error "set striped dir error"
21172
21173         touch $DIR/$tdir/striped_dir/a
21174         mkdir $DIR/$tdir/striped_dir/dir_a
21175         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21176                 error "create striped dir under striped dir fails"
21177
21178         touch $DIR/$tdir/striped_dir1/b
21179         mkdir $DIR/$tdir/striped_dir1/dir_b
21180         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21181                 error "create striped dir under striped dir fails"
21182
21183         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21184                 error "rename dir under different striped dir should fail"
21185
21186         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21187                 error "rename striped dir under diff striped dir should fail"
21188
21189         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21190                 error "rename file under diff striped dirs fails"
21191
21192         rm -rf $DIR/$tdir
21193 }
21194 run_test 300f "check rename cross striped directory"
21195
21196 test_300_check_default_striped_dir()
21197 {
21198         local dirname=$1
21199         local default_count=$2
21200         local default_index=$3
21201         local stripe_count
21202         local stripe_index
21203         local dir_stripe_index
21204         local dir
21205
21206         echo "checking $dirname $default_count $default_index"
21207         $LFS setdirstripe -D -c $default_count -i $default_index \
21208                                 -t all_char $DIR/$tdir/$dirname ||
21209                 error "set default stripe on striped dir error"
21210         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21211         [ $stripe_count -eq $default_count ] ||
21212                 error "expect $default_count get $stripe_count for $dirname"
21213
21214         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21215         [ $stripe_index -eq $default_index ] ||
21216                 error "expect $default_index get $stripe_index for $dirname"
21217
21218         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21219                                                 error "create dirs failed"
21220
21221         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21222         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21223         for dir in $(find $DIR/$tdir/$dirname/*); do
21224                 stripe_count=$($LFS getdirstripe -c $dir)
21225                 [ $stripe_count -eq $default_count ] ||
21226                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21227                 error "stripe count $default_count != $stripe_count for $dir"
21228
21229                 stripe_index=$($LFS getdirstripe -i $dir)
21230                 [ $default_index -eq -1 ] ||
21231                         [ $stripe_index -eq $default_index ] ||
21232                         error "$stripe_index != $default_index for $dir"
21233
21234                 #check default stripe
21235                 stripe_count=$($LFS getdirstripe -D -c $dir)
21236                 [ $stripe_count -eq $default_count ] ||
21237                 error "default count $default_count != $stripe_count for $dir"
21238
21239                 stripe_index=$($LFS getdirstripe -D -i $dir)
21240                 [ $stripe_index -eq $default_index ] ||
21241                 error "default index $default_index != $stripe_index for $dir"
21242         done
21243         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21244 }
21245
21246 test_300g() {
21247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21248         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21249                 skip "Need MDS version at least 2.7.55"
21250
21251         local dir
21252         local stripe_count
21253         local stripe_index
21254
21255         mkdir $DIR/$tdir
21256         mkdir $DIR/$tdir/normal_dir
21257
21258         #Checking when client cache stripe index
21259         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21260         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21261                 error "create striped_dir failed"
21262
21263         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21264                 error "create dir0 fails"
21265         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21266         [ $stripe_index -eq 0 ] ||
21267                 error "dir0 expect index 0 got $stripe_index"
21268
21269         mkdir $DIR/$tdir/striped_dir/dir1 ||
21270                 error "create dir1 fails"
21271         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21272         [ $stripe_index -eq 1 ] ||
21273                 error "dir1 expect index 1 got $stripe_index"
21274
21275         #check default stripe count/stripe index
21276         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21277         test_300_check_default_striped_dir normal_dir 1 0
21278         test_300_check_default_striped_dir normal_dir 2 1
21279         test_300_check_default_striped_dir normal_dir 2 -1
21280
21281         #delete default stripe information
21282         echo "delete default stripeEA"
21283         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21284                 error "set default stripe on striped dir error"
21285
21286         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21287         for dir in $(find $DIR/$tdir/normal_dir/*); do
21288                 stripe_count=$($LFS getdirstripe -c $dir)
21289                 [ $stripe_count -eq 0 ] ||
21290                         error "expect 1 get $stripe_count for $dir"
21291                 stripe_index=$($LFS getdirstripe -i $dir)
21292                 [ $stripe_index -eq 0 ] ||
21293                         error "expect 0 get $stripe_index for $dir"
21294         done
21295 }
21296 run_test 300g "check default striped directory for normal directory"
21297
21298 test_300h() {
21299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21300         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21301                 skip "Need MDS version at least 2.7.55"
21302
21303         local dir
21304         local stripe_count
21305
21306         mkdir $DIR/$tdir
21307         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21308                 error "set striped dir error"
21309
21310         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21311         test_300_check_default_striped_dir striped_dir 1 0
21312         test_300_check_default_striped_dir striped_dir 2 1
21313         test_300_check_default_striped_dir striped_dir 2 -1
21314
21315         #delete default stripe information
21316         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21317                 error "set default stripe on striped dir error"
21318
21319         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21320         for dir in $(find $DIR/$tdir/striped_dir/*); do
21321                 stripe_count=$($LFS getdirstripe -c $dir)
21322                 [ $stripe_count -eq 0 ] ||
21323                         error "expect 1 get $stripe_count for $dir"
21324         done
21325 }
21326 run_test 300h "check default striped directory for striped directory"
21327
21328 test_300i() {
21329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21331         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21332                 skip "Need MDS version at least 2.7.55"
21333
21334         local stripe_count
21335         local file
21336
21337         mkdir $DIR/$tdir
21338
21339         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21340                 error "set striped dir error"
21341
21342         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21343                 error "create files under striped dir failed"
21344
21345         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21346                 error "set striped hashdir error"
21347
21348         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21349                 error "create dir0 under hash dir failed"
21350         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21351                 error "create dir1 under hash dir failed"
21352
21353         # unfortunately, we need to umount to clear dir layout cache for now
21354         # once we fully implement dir layout, we can drop this
21355         umount_client $MOUNT || error "umount failed"
21356         mount_client $MOUNT || error "mount failed"
21357
21358         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21359         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21360         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21361
21362         #set the stripe to be unknown hash type
21363         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21364         $LCTL set_param fail_loc=0x1901
21365         for ((i = 0; i < 10; i++)); do
21366                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21367                         error "stat f-$i failed"
21368                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21369         done
21370
21371         touch $DIR/$tdir/striped_dir/f0 &&
21372                 error "create under striped dir with unknown hash should fail"
21373
21374         $LCTL set_param fail_loc=0
21375
21376         umount_client $MOUNT || error "umount failed"
21377         mount_client $MOUNT || error "mount failed"
21378
21379         return 0
21380 }
21381 run_test 300i "client handle unknown hash type striped directory"
21382
21383 test_300j() {
21384         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21386         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21387                 skip "Need MDS version at least 2.7.55"
21388
21389         local stripe_count
21390         local file
21391
21392         mkdir $DIR/$tdir
21393
21394         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21395         $LCTL set_param fail_loc=0x1702
21396         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21397                 error "set striped dir error"
21398
21399         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21400                 error "create files under striped dir failed"
21401
21402         $LCTL set_param fail_loc=0
21403
21404         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21405
21406         return 0
21407 }
21408 run_test 300j "test large update record"
21409
21410 test_300k() {
21411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21413         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21414                 skip "Need MDS version at least 2.7.55"
21415
21416         # this test needs a huge transaction
21417         local kb
21418         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21419              osd*.$FSNAME-MDT0000.kbytestotal")
21420         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21421
21422         local stripe_count
21423         local file
21424
21425         mkdir $DIR/$tdir
21426
21427         #define OBD_FAIL_LARGE_STRIPE   0x1703
21428         $LCTL set_param fail_loc=0x1703
21429         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21430                 error "set striped dir error"
21431         $LCTL set_param fail_loc=0
21432
21433         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21434                 error "getstripeddir fails"
21435         rm -rf $DIR/$tdir/striped_dir ||
21436                 error "unlink striped dir fails"
21437
21438         return 0
21439 }
21440 run_test 300k "test large striped directory"
21441
21442 test_300l() {
21443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21445         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21446                 skip "Need MDS version at least 2.7.55"
21447
21448         local stripe_index
21449
21450         test_mkdir -p $DIR/$tdir/striped_dir
21451         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21452                         error "chown $RUNAS_ID failed"
21453         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21454                 error "set default striped dir failed"
21455
21456         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21457         $LCTL set_param fail_loc=0x80000158
21458         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21459
21460         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21461         [ $stripe_index -eq 1 ] ||
21462                 error "expect 1 get $stripe_index for $dir"
21463 }
21464 run_test 300l "non-root user to create dir under striped dir with stale layout"
21465
21466 test_300m() {
21467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21468         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21469         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21470                 skip "Need MDS version at least 2.7.55"
21471
21472         mkdir -p $DIR/$tdir/striped_dir
21473         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21474                 error "set default stripes dir error"
21475
21476         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21477
21478         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21479         [ $stripe_count -eq 0 ] ||
21480                         error "expect 0 get $stripe_count for a"
21481
21482         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21483                 error "set default stripes dir error"
21484
21485         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21486
21487         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21488         [ $stripe_count -eq 0 ] ||
21489                         error "expect 0 get $stripe_count for b"
21490
21491         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21492                 error "set default stripes dir error"
21493
21494         mkdir $DIR/$tdir/striped_dir/c &&
21495                 error "default stripe_index is invalid, mkdir c should fails"
21496
21497         rm -rf $DIR/$tdir || error "rmdir fails"
21498 }
21499 run_test 300m "setstriped directory on single MDT FS"
21500
21501 cleanup_300n() {
21502         local list=$(comma_list $(mdts_nodes))
21503
21504         trap 0
21505         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21506 }
21507
21508 test_300n() {
21509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21511         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21512                 skip "Need MDS version at least 2.7.55"
21513         remote_mds_nodsh && skip "remote MDS with nodsh"
21514
21515         local stripe_index
21516         local list=$(comma_list $(mdts_nodes))
21517
21518         trap cleanup_300n RETURN EXIT
21519         mkdir -p $DIR/$tdir
21520         chmod 777 $DIR/$tdir
21521         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21522                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21523                 error "create striped dir succeeds with gid=0"
21524
21525         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21526         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21527                 error "create striped dir fails with gid=-1"
21528
21529         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21530         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21531                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21532                 error "set default striped dir succeeds with gid=0"
21533
21534
21535         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21536         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21537                 error "set default striped dir fails with gid=-1"
21538
21539
21540         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21541         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21542                                         error "create test_dir fails"
21543         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21544                                         error "create test_dir1 fails"
21545         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21546                                         error "create test_dir2 fails"
21547         cleanup_300n
21548 }
21549 run_test 300n "non-root user to create dir under striped dir with default EA"
21550
21551 test_300o() {
21552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21554         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21555                 skip "Need MDS version at least 2.7.55"
21556
21557         local numfree1
21558         local numfree2
21559
21560         mkdir -p $DIR/$tdir
21561
21562         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21563         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21564         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21565                 skip "not enough free inodes $numfree1 $numfree2"
21566         fi
21567
21568         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21569         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21570         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21571                 skip "not enough free space $numfree1 $numfree2"
21572         fi
21573
21574         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21575                 error "setdirstripe fails"
21576
21577         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21578                 error "create dirs fails"
21579
21580         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21581         ls $DIR/$tdir/striped_dir > /dev/null ||
21582                 error "ls striped dir fails"
21583         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21584                 error "unlink big striped dir fails"
21585 }
21586 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21587
21588 test_300p() {
21589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21590         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21591         remote_mds_nodsh && skip "remote MDS with nodsh"
21592
21593         mkdir -p $DIR/$tdir
21594
21595         #define OBD_FAIL_OUT_ENOSPC     0x1704
21596         do_facet mds2 lctl set_param fail_loc=0x80001704
21597         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21598                  && error "create striped directory should fail"
21599
21600         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21601
21602         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21603         true
21604 }
21605 run_test 300p "create striped directory without space"
21606
21607 test_300q() {
21608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21610
21611         local fd=$(free_fd)
21612         local cmd="exec $fd<$tdir"
21613         cd $DIR
21614         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21615         eval $cmd
21616         cmd="exec $fd<&-"
21617         trap "eval $cmd" EXIT
21618         cd $tdir || error "cd $tdir fails"
21619         rmdir  ../$tdir || error "rmdir $tdir fails"
21620         mkdir local_dir && error "create dir succeeds"
21621         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21622         eval $cmd
21623         return 0
21624 }
21625 run_test 300q "create remote directory under orphan directory"
21626
21627 test_300r() {
21628         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21629                 skip "Need MDS version at least 2.7.55" && return
21630         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21631
21632         mkdir $DIR/$tdir
21633
21634         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21635                 error "set striped dir error"
21636
21637         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21638                 error "getstripeddir fails"
21639
21640         local stripe_count
21641         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21642                       awk '/lmv_stripe_count:/ { print $2 }')
21643
21644         [ $MDSCOUNT -ne $stripe_count ] &&
21645                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21646
21647         rm -rf $DIR/$tdir/striped_dir ||
21648                 error "unlink striped dir fails"
21649 }
21650 run_test 300r "test -1 striped directory"
21651
21652 test_300s_helper() {
21653         local count=$1
21654
21655         local stripe_dir=$DIR/$tdir/striped_dir.$count
21656
21657         $LFS mkdir -c $count $stripe_dir ||
21658                 error "lfs mkdir -c error"
21659
21660         $LFS getdirstripe $stripe_dir ||
21661                 error "lfs getdirstripe fails"
21662
21663         local stripe_count
21664         stripe_count=$($LFS getdirstripe $stripe_dir |
21665                       awk '/lmv_stripe_count:/ { print $2 }')
21666
21667         [ $count -ne $stripe_count ] &&
21668                 error_noexit "bad stripe count $stripe_count expected $count"
21669
21670         local dupe_stripes
21671         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21672                 awk '/0x/ {count[$1] += 1}; END {
21673                         for (idx in count) {
21674                                 if (count[idx]>1) {
21675                                         print "index " idx " count " count[idx]
21676                                 }
21677                         }
21678                 }')
21679
21680         if [[ -n "$dupe_stripes" ]] ; then
21681                 lfs getdirstripe $stripe_dir
21682                 error_noexit "Dupe MDT above: $dupe_stripes "
21683         fi
21684
21685         rm -rf $stripe_dir ||
21686                 error_noexit "unlink $stripe_dir fails"
21687 }
21688
21689 test_300s() {
21690         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21691                 skip "Need MDS version at least 2.7.55" && return
21692         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21693
21694         mkdir $DIR/$tdir
21695         for count in $(seq 2 $MDSCOUNT); do
21696                 test_300s_helper $count
21697         done
21698 }
21699 run_test 300s "test lfs mkdir -c without -i"
21700
21701
21702 prepare_remote_file() {
21703         mkdir $DIR/$tdir/src_dir ||
21704                 error "create remote source failed"
21705
21706         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21707                  error "cp to remote source failed"
21708         touch $DIR/$tdir/src_dir/a
21709
21710         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21711                 error "create remote target dir failed"
21712
21713         touch $DIR/$tdir/tgt_dir/b
21714
21715         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21716                 error "rename dir cross MDT failed!"
21717
21718         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21719                 error "src_child still exists after rename"
21720
21721         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21722                 error "missing file(a) after rename"
21723
21724         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21725                 error "diff after rename"
21726 }
21727
21728 test_310a() {
21729         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21731
21732         local remote_file=$DIR/$tdir/tgt_dir/b
21733
21734         mkdir -p $DIR/$tdir
21735
21736         prepare_remote_file || error "prepare remote file failed"
21737
21738         #open-unlink file
21739         $OPENUNLINK $remote_file $remote_file ||
21740                 error "openunlink $remote_file failed"
21741         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21742 }
21743 run_test 310a "open unlink remote file"
21744
21745 test_310b() {
21746         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21748
21749         local remote_file=$DIR/$tdir/tgt_dir/b
21750
21751         mkdir -p $DIR/$tdir
21752
21753         prepare_remote_file || error "prepare remote file failed"
21754
21755         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21756         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21757         $CHECKSTAT -t file $remote_file || error "check file failed"
21758 }
21759 run_test 310b "unlink remote file with multiple links while open"
21760
21761 test_310c() {
21762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21763         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21764
21765         local remote_file=$DIR/$tdir/tgt_dir/b
21766
21767         mkdir -p $DIR/$tdir
21768
21769         prepare_remote_file || error "prepare remote file failed"
21770
21771         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21772         multiop_bg_pause $remote_file O_uc ||
21773                         error "mulitop failed for remote file"
21774         MULTIPID=$!
21775         $MULTIOP $DIR/$tfile Ouc
21776         kill -USR1 $MULTIPID
21777         wait $MULTIPID
21778 }
21779 run_test 310c "open-unlink remote file with multiple links"
21780
21781 #LU-4825
21782 test_311() {
21783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21784         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21785         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21786                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21787         remote_mds_nodsh && skip "remote MDS with nodsh"
21788
21789         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21790         local mdts=$(comma_list $(mdts_nodes))
21791
21792         mkdir -p $DIR/$tdir
21793         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21794         createmany -o $DIR/$tdir/$tfile. 1000
21795
21796         # statfs data is not real time, let's just calculate it
21797         old_iused=$((old_iused + 1000))
21798
21799         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21800                         osp.*OST0000*MDT0000.create_count")
21801         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21802                                 osp.*OST0000*MDT0000.max_create_count")
21803         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21804
21805         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21806         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21807         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21808
21809         unlinkmany $DIR/$tdir/$tfile. 1000
21810
21811         do_nodes $mdts "$LCTL set_param -n \
21812                         osp.*OST0000*.max_create_count=$max_count"
21813         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21814                 do_nodes $mdts "$LCTL set_param -n \
21815                                 osp.*OST0000*.create_count=$count"
21816         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21817                         grep "=0" && error "create_count is zero"
21818
21819         local new_iused
21820         for i in $(seq 120); do
21821                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21822                 # system may be too busy to destroy all objs in time, use
21823                 # a somewhat small value to not fail autotest
21824                 [ $((old_iused - new_iused)) -gt 400 ] && break
21825                 sleep 1
21826         done
21827
21828         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21829         [ $((old_iused - new_iused)) -gt 400 ] ||
21830                 error "objs not destroyed after unlink"
21831 }
21832 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21833
21834 zfs_oid_to_objid()
21835 {
21836         local ost=$1
21837         local objid=$2
21838
21839         local vdevdir=$(dirname $(facet_vdevice $ost))
21840         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21841         local zfs_zapid=$(do_facet $ost $cmd |
21842                           grep -w "/O/0/d$((objid%32))" -C 5 |
21843                           awk '/Object/{getline; print $1}')
21844         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21845                           awk "/$objid = /"'{printf $3}')
21846
21847         echo $zfs_objid
21848 }
21849
21850 zfs_object_blksz() {
21851         local ost=$1
21852         local objid=$2
21853
21854         local vdevdir=$(dirname $(facet_vdevice $ost))
21855         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21856         local blksz=$(do_facet $ost $cmd $objid |
21857                       awk '/dblk/{getline; printf $4}')
21858
21859         case "${blksz: -1}" in
21860                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21861                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21862                 *) ;;
21863         esac
21864
21865         echo $blksz
21866 }
21867
21868 test_312() { # LU-4856
21869         remote_ost_nodsh && skip "remote OST with nodsh"
21870         [ "$ost1_FSTYPE" = "zfs" ] ||
21871                 skip_env "the test only applies to zfs"
21872
21873         local max_blksz=$(do_facet ost1 \
21874                           $ZFS get -p recordsize $(facet_device ost1) |
21875                           awk '!/VALUE/{print $3}')
21876
21877         # to make life a little bit easier
21878         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21879         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21880
21881         local tf=$DIR/$tdir/$tfile
21882         touch $tf
21883         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21884
21885         # Get ZFS object id
21886         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21887         # block size change by sequential overwrite
21888         local bs
21889
21890         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21891                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21892
21893                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21894                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21895         done
21896         rm -f $tf
21897
21898         # block size change by sequential append write
21899         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21900         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21901         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21902         local count
21903
21904         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21905                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21906                         oflag=sync conv=notrunc
21907
21908                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21909                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21910                         error "blksz error, actual $blksz, " \
21911                                 "expected: 2 * $count * $PAGE_SIZE"
21912         done
21913         rm -f $tf
21914
21915         # random write
21916         touch $tf
21917         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21918         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21919
21920         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21921         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21922         [ $blksz -eq $PAGE_SIZE ] ||
21923                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21924
21925         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21926         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21927         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21928
21929         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21930         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21931         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21932 }
21933 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21934
21935 test_313() {
21936         remote_ost_nodsh && skip "remote OST with nodsh"
21937
21938         local file=$DIR/$tfile
21939
21940         rm -f $file
21941         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21942
21943         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21944         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21945         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21946                 error "write should failed"
21947         do_facet ost1 "$LCTL set_param fail_loc=0"
21948         rm -f $file
21949 }
21950 run_test 313 "io should fail after last_rcvd update fail"
21951
21952 test_314() {
21953         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21954
21955         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21956         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21957         rm -f $DIR/$tfile
21958         wait_delete_completed
21959         do_facet ost1 "$LCTL set_param fail_loc=0"
21960 }
21961 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21962
21963 test_315() { # LU-618
21964         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21965
21966         local file=$DIR/$tfile
21967         rm -f $file
21968
21969         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21970                 error "multiop file write failed"
21971         $MULTIOP $file oO_RDONLY:r4063232_c &
21972         PID=$!
21973
21974         sleep 2
21975
21976         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21977         kill -USR1 $PID
21978
21979         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21980         rm -f $file
21981 }
21982 run_test 315 "read should be accounted"
21983
21984 test_316() {
21985         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21986         large_xattr_enabled || skip_env "ea_inode feature disabled"
21987
21988         rm -rf $DIR/$tdir/d
21989         mkdir -p $DIR/$tdir/d
21990         chown nobody $DIR/$tdir/d
21991         touch $DIR/$tdir/d/file
21992
21993         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21994 }
21995 run_test 316 "lfs mv"
21996
21997 test_317() {
21998         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21999                 skip "Need MDS version at least 2.11.53"
22000         if [ "$ost1_FSTYPE" == "zfs" ]; then
22001                 skip "LU-10370: no implementation for ZFS"
22002         fi
22003
22004         local trunc_sz
22005         local grant_blk_size
22006
22007         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22008                         awk '/grant_block_size:/ { print $2; exit; }')
22009         #
22010         # Create File of size 5M. Truncate it to below size's and verify
22011         # blocks count.
22012         #
22013         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22014                 error "Create file $DIR/$tfile failed"
22015         stack_trap "rm -f $DIR/$tfile" EXIT
22016
22017         for trunc_sz in 2097152 4097 4000 509 0; do
22018                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22019                         error "truncate $tfile to $trunc_sz failed"
22020                 local sz=$(stat --format=%s $DIR/$tfile)
22021                 local blk=$(stat --format=%b $DIR/$tfile)
22022                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22023                                      grant_blk_size) * 8))
22024
22025                 if [[ $blk -ne $trunc_blk ]]; then
22026                         $(which stat) $DIR/$tfile
22027                         error "Expected Block $trunc_blk got $blk for $tfile"
22028                 fi
22029
22030                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22031                         error "Expected Size $trunc_sz got $sz for $tfile"
22032         done
22033
22034         #
22035         # sparse file test
22036         # Create file with a hole and write actual two blocks. Block count
22037         # must be 16.
22038         #
22039         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22040                 conv=fsync || error "Create file : $DIR/$tfile"
22041
22042         # Calculate the final truncate size.
22043         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22044
22045         #
22046         # truncate to size $trunc_sz bytes. Strip the last block
22047         # The block count must drop to 8
22048         #
22049         $TRUNCATE $DIR/$tfile $trunc_sz ||
22050                 error "truncate $tfile to $trunc_sz failed"
22051
22052         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22053         sz=$(stat --format=%s $DIR/$tfile)
22054         blk=$(stat --format=%b $DIR/$tfile)
22055
22056         if [[ $blk -ne $trunc_bsz ]]; then
22057                 $(which stat) $DIR/$tfile
22058                 error "Expected Block $trunc_bsz got $blk for $tfile"
22059         fi
22060
22061         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22062                 error "Expected Size $trunc_sz got $sz for $tfile"
22063 }
22064 run_test 317 "Verify blocks get correctly update after truncate"
22065
22066 test_318() {
22067         local old_max_active=$($LCTL get_param -n \
22068                             llite.*.max_read_ahead_async_active 2>/dev/null)
22069
22070         $LCTL set_param llite.*.max_read_ahead_async_active=256
22071         local max_active=$($LCTL get_param -n \
22072                            llite.*.max_read_ahead_async_active 2>/dev/null)
22073         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22074
22075         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22076                 error "set max_read_ahead_async_active should succeed"
22077
22078         $LCTL set_param llite.*.max_read_ahead_async_active=512
22079         max_active=$($LCTL get_param -n \
22080                      llite.*.max_read_ahead_async_active 2>/dev/null)
22081         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22082
22083         # restore @max_active
22084         [ $old_max_active -ne 0 ] && $LCTL set_param \
22085                 llite.*.max_read_ahead_async_active=$old_max_active
22086
22087         local old_threshold=$($LCTL get_param -n \
22088                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22089         local max_per_file_mb=$($LCTL get_param -n \
22090                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22091
22092         local invalid=$(($max_per_file_mb + 1))
22093         $LCTL set_param \
22094                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22095                         && error "set $invalid should fail"
22096
22097         local valid=$(($invalid - 1))
22098         $LCTL set_param \
22099                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22100                         error "set $valid should succeed"
22101         local threshold=$($LCTL get_param -n \
22102                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22103         [ $threshold -eq $valid ] || error \
22104                 "expect threshold $valid got $threshold"
22105         $LCTL set_param \
22106                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22107 }
22108 run_test 318 "Verify async readahead tunables"
22109
22110 test_319() {
22111         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22112
22113         local before=$(date +%s)
22114         local evict
22115         local mdir=$DIR/$tdir
22116         local file=$mdir/xxx
22117
22118         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22119         touch $file
22120
22121 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22122         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22123         $LFS mv -m1 $file &
22124
22125         sleep 1
22126         dd if=$file of=/dev/null
22127         wait
22128         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22129           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22130
22131         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22132 }
22133 run_test 319 "lost lease lock on migrate error"
22134
22135 test_398a() { # LU-4198
22136         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22137         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22138
22139         # request a new lock on client
22140         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22141
22142         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22143         local lock_count=$($LCTL get_param -n \
22144                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22145         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22146
22147         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22148
22149         # no lock cached, should use lockless IO and not enqueue new lock
22150         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22151         lock_count=$($LCTL get_param -n \
22152                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22153         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22154 }
22155 run_test 398a "direct IO should cancel lock otherwise lockless"
22156
22157 test_398b() { # LU-4198
22158         which fio || skip_env "no fio installed"
22159         $LFS setstripe -c -1 $DIR/$tfile
22160
22161         local size=12
22162         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22163
22164         local njobs=4
22165         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22166         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22167                 --numjobs=$njobs --fallocate=none \
22168                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22169                 --filename=$DIR/$tfile &
22170         bg_pid=$!
22171
22172         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22173         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22174                 --numjobs=$njobs --fallocate=none \
22175                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22176                 --filename=$DIR/$tfile || true
22177         wait $bg_pid
22178
22179         rm -rf $DIR/$tfile
22180 }
22181 run_test 398b "DIO and buffer IO race"
22182
22183 test_398c() { # LU-4198
22184         which fio || skip_env "no fio installed"
22185
22186         saved_debug=$($LCTL get_param -n debug)
22187         $LCTL set_param debug=0
22188
22189         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22190         ((size /= 1024)) # by megabytes
22191         ((size /= 2)) # write half of the OST at most
22192         [ $size -gt 40 ] && size=40 #reduce test time anyway
22193
22194         $LFS setstripe -c 1 $DIR/$tfile
22195
22196         # it seems like ldiskfs reserves more space than necessary if the
22197         # writing blocks are not mapped, so it extends the file firstly
22198         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22199         cancel_lru_locks osc
22200
22201         # clear and verify rpc_stats later
22202         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22203
22204         local njobs=4
22205         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22206         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22207                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22208                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22209                 --filename=$DIR/$tfile
22210         [ $? -eq 0 ] || error "fio write error"
22211
22212         [ $($LCTL get_param -n \
22213          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22214                 error "Locks were requested while doing AIO"
22215
22216         # get the percentage of 1-page I/O
22217         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22218                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22219                 awk '{print $7}')
22220         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22221
22222         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22223         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22224                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22225                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22226                 --filename=$DIR/$tfile
22227         [ $? -eq 0 ] || error "fio mixed read write error"
22228
22229         echo "AIO with large block size ${size}M"
22230         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22231                 --numjobs=1 --fallocate=none --ioengine=libaio \
22232                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22233                 --filename=$DIR/$tfile
22234         [ $? -eq 0 ] || error "fio large block size failed"
22235
22236         rm -rf $DIR/$tfile
22237         $LCTL set_param debug="$saved_debug"
22238 }
22239 run_test 398c "run fio to test AIO"
22240
22241 test_398d() { #  LU-13846
22242         test -f aiocp || skip_env "no aiocp installed"
22243         local aio_file=$DIR/aio_file
22244
22245         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22246
22247         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22248         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22249
22250         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22251
22252         # make sure we don't crash and fail properly
22253         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22254                 error "aio not aligned with PAGE SIZE should fail"
22255
22256         rm -rf $DIR/$tfile $aio_file
22257 }
22258 run_test 398d "run aiocp to verify block size > stripe size"
22259
22260 test_fake_rw() {
22261         local read_write=$1
22262         if [ "$read_write" = "write" ]; then
22263                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22264         elif [ "$read_write" = "read" ]; then
22265                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22266         else
22267                 error "argument error"
22268         fi
22269
22270         # turn off debug for performance testing
22271         local saved_debug=$($LCTL get_param -n debug)
22272         $LCTL set_param debug=0
22273
22274         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22275
22276         # get ost1 size - $FSNAME-OST0000
22277         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22278         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22279         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22280
22281         if [ "$read_write" = "read" ]; then
22282                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22283         fi
22284
22285         local start_time=$(date +%s.%N)
22286         $dd_cmd bs=1M count=$blocks oflag=sync ||
22287                 error "real dd $read_write error"
22288         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22289
22290         if [ "$read_write" = "write" ]; then
22291                 rm -f $DIR/$tfile
22292         fi
22293
22294         # define OBD_FAIL_OST_FAKE_RW           0x238
22295         do_facet ost1 $LCTL set_param fail_loc=0x238
22296
22297         local start_time=$(date +%s.%N)
22298         $dd_cmd bs=1M count=$blocks oflag=sync ||
22299                 error "fake dd $read_write error"
22300         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22301
22302         if [ "$read_write" = "write" ]; then
22303                 # verify file size
22304                 cancel_lru_locks osc
22305                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22306                         error "$tfile size not $blocks MB"
22307         fi
22308         do_facet ost1 $LCTL set_param fail_loc=0
22309
22310         echo "fake $read_write $duration_fake vs. normal $read_write" \
22311                 "$duration in seconds"
22312         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22313                 error_not_in_vm "fake write is slower"
22314
22315         $LCTL set_param -n debug="$saved_debug"
22316         rm -f $DIR/$tfile
22317 }
22318 test_399a() { # LU-7655 for OST fake write
22319         remote_ost_nodsh && skip "remote OST with nodsh"
22320
22321         test_fake_rw write
22322 }
22323 run_test 399a "fake write should not be slower than normal write"
22324
22325 test_399b() { # LU-8726 for OST fake read
22326         remote_ost_nodsh && skip "remote OST with nodsh"
22327         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22328                 skip_env "ldiskfs only test"
22329         fi
22330
22331         test_fake_rw read
22332 }
22333 run_test 399b "fake read should not be slower than normal read"
22334
22335 test_400a() { # LU-1606, was conf-sanity test_74
22336         if ! which $CC > /dev/null 2>&1; then
22337                 skip_env "$CC is not installed"
22338         fi
22339
22340         local extra_flags=''
22341         local out=$TMP/$tfile
22342         local prefix=/usr/include/lustre
22343         local prog
22344
22345         # Oleg removes c files in his test rig so test if any c files exist
22346         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22347                 skip_env "Needed c test files are missing"
22348
22349         if ! [[ -d $prefix ]]; then
22350                 # Assume we're running in tree and fixup the include path.
22351                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22352                 extra_flags+=" -L$LUSTRE/utils/.lib"
22353         fi
22354
22355         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22356                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22357                         error "client api broken"
22358         done
22359         rm -f $out
22360 }
22361 run_test 400a "Lustre client api program can compile and link"
22362
22363 test_400b() { # LU-1606, LU-5011
22364         local header
22365         local out=$TMP/$tfile
22366         local prefix=/usr/include/linux/lustre
22367
22368         # We use a hard coded prefix so that this test will not fail
22369         # when run in tree. There are headers in lustre/include/lustre/
22370         # that are not packaged (like lustre_idl.h) and have more
22371         # complicated include dependencies (like config.h and lnet/types.h).
22372         # Since this test about correct packaging we just skip them when
22373         # they don't exist (see below) rather than try to fixup cppflags.
22374
22375         if ! which $CC > /dev/null 2>&1; then
22376                 skip_env "$CC is not installed"
22377         fi
22378
22379         for header in $prefix/*.h; do
22380                 if ! [[ -f "$header" ]]; then
22381                         continue
22382                 fi
22383
22384                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22385                         continue # lustre_ioctl.h is internal header
22386                 fi
22387
22388                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22389                         error "cannot compile '$header'"
22390         done
22391         rm -f $out
22392 }
22393 run_test 400b "packaged headers can be compiled"
22394
22395 test_401a() { #LU-7437
22396         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22397         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22398
22399         #count the number of parameters by "list_param -R"
22400         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22401         #count the number of parameters by listing proc files
22402         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22403         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22404         echo "proc_dirs='$proc_dirs'"
22405         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22406         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22407                       sort -u | wc -l)
22408
22409         [ $params -eq $procs ] ||
22410                 error "found $params parameters vs. $procs proc files"
22411
22412         # test the list_param -D option only returns directories
22413         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22414         #count the number of parameters by listing proc directories
22415         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22416                 sort -u | wc -l)
22417
22418         [ $params -eq $procs ] ||
22419                 error "found $params parameters vs. $procs proc files"
22420 }
22421 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22422
22423 test_401b() {
22424         # jobid_var may not allow arbitrary values, so use jobid_name
22425         # if available
22426         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22427                 local testname=jobid_name tmp='testing%p'
22428         else
22429                 local testname=jobid_var tmp=testing
22430         fi
22431
22432         local save=$($LCTL get_param -n $testname)
22433
22434         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22435                 error "no error returned when setting bad parameters"
22436
22437         local jobid_new=$($LCTL get_param -n foe $testname baz)
22438         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22439
22440         $LCTL set_param -n fog=bam $testname=$save bat=fog
22441         local jobid_old=$($LCTL get_param -n foe $testname bag)
22442         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22443 }
22444 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22445
22446 test_401c() {
22447         # jobid_var may not allow arbitrary values, so use jobid_name
22448         # if available
22449         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22450                 local testname=jobid_name
22451         else
22452                 local testname=jobid_var
22453         fi
22454
22455         local jobid_var_old=$($LCTL get_param -n $testname)
22456         local jobid_var_new
22457
22458         $LCTL set_param $testname= &&
22459                 error "no error returned for 'set_param a='"
22460
22461         jobid_var_new=$($LCTL get_param -n $testname)
22462         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22463                 error "$testname was changed by setting without value"
22464
22465         $LCTL set_param $testname &&
22466                 error "no error returned for 'set_param a'"
22467
22468         jobid_var_new=$($LCTL get_param -n $testname)
22469         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22470                 error "$testname was changed by setting without value"
22471 }
22472 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22473
22474 test_401d() {
22475         # jobid_var may not allow arbitrary values, so use jobid_name
22476         # if available
22477         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22478                 local testname=jobid_name new_value='foo=bar%p'
22479         else
22480                 local testname=jobid_var new_valuie=foo=bar
22481         fi
22482
22483         local jobid_var_old=$($LCTL get_param -n $testname)
22484         local jobid_var_new
22485
22486         $LCTL set_param $testname=$new_value ||
22487                 error "'set_param a=b' did not accept a value containing '='"
22488
22489         jobid_var_new=$($LCTL get_param -n $testname)
22490         [[ "$jobid_var_new" == "$new_value" ]] ||
22491                 error "'set_param a=b' failed on a value containing '='"
22492
22493         # Reset the $testname to test the other format
22494         $LCTL set_param $testname=$jobid_var_old
22495         jobid_var_new=$($LCTL get_param -n $testname)
22496         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22497                 error "failed to reset $testname"
22498
22499         $LCTL set_param $testname $new_value ||
22500                 error "'set_param a b' did not accept a value containing '='"
22501
22502         jobid_var_new=$($LCTL get_param -n $testname)
22503         [[ "$jobid_var_new" == "$new_value" ]] ||
22504                 error "'set_param a b' failed on a value containing '='"
22505
22506         $LCTL set_param $testname $jobid_var_old
22507         jobid_var_new=$($LCTL get_param -n $testname)
22508         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22509                 error "failed to reset $testname"
22510 }
22511 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22512
22513 test_402() {
22514         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22515         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22516                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22517         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22518                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22519                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22520         remote_mds_nodsh && skip "remote MDS with nodsh"
22521
22522         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22523 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22524         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22525         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22526                 echo "Touch failed - OK"
22527 }
22528 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22529
22530 test_403() {
22531         local file1=$DIR/$tfile.1
22532         local file2=$DIR/$tfile.2
22533         local tfile=$TMP/$tfile
22534
22535         rm -f $file1 $file2 $tfile
22536
22537         touch $file1
22538         ln $file1 $file2
22539
22540         # 30 sec OBD_TIMEOUT in ll_getattr()
22541         # right before populating st_nlink
22542         $LCTL set_param fail_loc=0x80001409
22543         stat -c %h $file1 > $tfile &
22544
22545         # create an alias, drop all locks and reclaim the dentry
22546         < $file2
22547         cancel_lru_locks mdc
22548         cancel_lru_locks osc
22549         sysctl -w vm.drop_caches=2
22550
22551         wait
22552
22553         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22554
22555         rm -f $tfile $file1 $file2
22556 }
22557 run_test 403 "i_nlink should not drop to zero due to aliasing"
22558
22559 test_404() { # LU-6601
22560         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22561                 skip "Need server version newer than 2.8.52"
22562         remote_mds_nodsh && skip "remote MDS with nodsh"
22563
22564         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22565                 awk '/osp .*-osc-MDT/ { print $4}')
22566
22567         local osp
22568         for osp in $mosps; do
22569                 echo "Deactivate: " $osp
22570                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22571                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22572                         awk -vp=$osp '$4 == p { print $2 }')
22573                 [ $stat = IN ] || {
22574                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22575                         error "deactivate error"
22576                 }
22577                 echo "Activate: " $osp
22578                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22579                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22580                         awk -vp=$osp '$4 == p { print $2 }')
22581                 [ $stat = UP ] || {
22582                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22583                         error "activate error"
22584                 }
22585         done
22586 }
22587 run_test 404 "validate manual {de}activated works properly for OSPs"
22588
22589 test_405() {
22590         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22591         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22592                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22593                         skip "Layout swap lock is not supported"
22594
22595         check_swap_layouts_support
22596         check_swap_layout_no_dom $DIR
22597
22598         test_mkdir $DIR/$tdir
22599         swap_lock_test -d $DIR/$tdir ||
22600                 error "One layout swap locked test failed"
22601 }
22602 run_test 405 "Various layout swap lock tests"
22603
22604 test_406() {
22605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22606         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22607         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22609         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22610                 skip "Need MDS version at least 2.8.50"
22611
22612         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22613         local test_pool=$TESTNAME
22614
22615         pool_add $test_pool || error "pool_add failed"
22616         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22617                 error "pool_add_targets failed"
22618
22619         save_layout_restore_at_exit $MOUNT
22620
22621         # parent set default stripe count only, child will stripe from both
22622         # parent and fs default
22623         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22624                 error "setstripe $MOUNT failed"
22625         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22626         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22627         for i in $(seq 10); do
22628                 local f=$DIR/$tdir/$tfile.$i
22629                 touch $f || error "touch failed"
22630                 local count=$($LFS getstripe -c $f)
22631                 [ $count -eq $OSTCOUNT ] ||
22632                         error "$f stripe count $count != $OSTCOUNT"
22633                 local offset=$($LFS getstripe -i $f)
22634                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22635                 local size=$($LFS getstripe -S $f)
22636                 [ $size -eq $((def_stripe_size * 2)) ] ||
22637                         error "$f stripe size $size != $((def_stripe_size * 2))"
22638                 local pool=$($LFS getstripe -p $f)
22639                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22640         done
22641
22642         # change fs default striping, delete parent default striping, now child
22643         # will stripe from new fs default striping only
22644         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22645                 error "change $MOUNT default stripe failed"
22646         $LFS setstripe -c 0 $DIR/$tdir ||
22647                 error "delete $tdir default stripe failed"
22648         for i in $(seq 11 20); do
22649                 local f=$DIR/$tdir/$tfile.$i
22650                 touch $f || error "touch $f failed"
22651                 local count=$($LFS getstripe -c $f)
22652                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22653                 local offset=$($LFS getstripe -i $f)
22654                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22655                 local size=$($LFS getstripe -S $f)
22656                 [ $size -eq $def_stripe_size ] ||
22657                         error "$f stripe size $size != $def_stripe_size"
22658                 local pool=$($LFS getstripe -p $f)
22659                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22660         done
22661
22662         unlinkmany $DIR/$tdir/$tfile. 1 20
22663
22664         local f=$DIR/$tdir/$tfile
22665         pool_remove_all_targets $test_pool $f
22666         pool_remove $test_pool $f
22667 }
22668 run_test 406 "DNE support fs default striping"
22669
22670 test_407() {
22671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22672         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22673                 skip "Need MDS version at least 2.8.55"
22674         remote_mds_nodsh && skip "remote MDS with nodsh"
22675
22676         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22677                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22678         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22679                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22680         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22681
22682         #define OBD_FAIL_DT_TXN_STOP    0x2019
22683         for idx in $(seq $MDSCOUNT); do
22684                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22685         done
22686         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22687         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22688                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22689         true
22690 }
22691 run_test 407 "transaction fail should cause operation fail"
22692
22693 test_408() {
22694         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22695
22696         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22697         lctl set_param fail_loc=0x8000040a
22698         # let ll_prepare_partial_page() fail
22699         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22700
22701         rm -f $DIR/$tfile
22702
22703         # create at least 100 unused inodes so that
22704         # shrink_icache_memory(0) should not return 0
22705         touch $DIR/$tfile-{0..100}
22706         rm -f $DIR/$tfile-{0..100}
22707         sync
22708
22709         echo 2 > /proc/sys/vm/drop_caches
22710 }
22711 run_test 408 "drop_caches should not hang due to page leaks"
22712
22713 test_409()
22714 {
22715         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22716
22717         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22718         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22719         touch $DIR/$tdir/guard || error "(2) Fail to create"
22720
22721         local PREFIX=$(str_repeat 'A' 128)
22722         echo "Create 1K hard links start at $(date)"
22723         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22724                 error "(3) Fail to hard link"
22725
22726         echo "Links count should be right although linkEA overflow"
22727         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22728         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22729         [ $linkcount -eq 1001 ] ||
22730                 error "(5) Unexpected hard links count: $linkcount"
22731
22732         echo "List all links start at $(date)"
22733         ls -l $DIR/$tdir/foo > /dev/null ||
22734                 error "(6) Fail to list $DIR/$tdir/foo"
22735
22736         echo "Unlink hard links start at $(date)"
22737         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22738                 error "(7) Fail to unlink"
22739         echo "Unlink hard links finished at $(date)"
22740 }
22741 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22742
22743 test_410()
22744 {
22745         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22746                 skip "Need client version at least 2.9.59"
22747         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22748                 skip "Need MODULES build"
22749
22750         # Create a file, and stat it from the kernel
22751         local testfile=$DIR/$tfile
22752         touch $testfile
22753
22754         local run_id=$RANDOM
22755         local my_ino=$(stat --format "%i" $testfile)
22756
22757         # Try to insert the module. This will always fail as the
22758         # module is designed to not be inserted.
22759         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22760             &> /dev/null
22761
22762         # Anything but success is a test failure
22763         dmesg | grep -q \
22764             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22765             error "no inode match"
22766 }
22767 run_test 410 "Test inode number returned from kernel thread"
22768
22769 cleanup_test411_cgroup() {
22770         trap 0
22771         rmdir "$1"
22772 }
22773
22774 test_411() {
22775         local cg_basedir=/sys/fs/cgroup/memory
22776         # LU-9966
22777         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22778                 skip "no setup for cgroup"
22779
22780         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22781                 error "test file creation failed"
22782         cancel_lru_locks osc
22783
22784         # Create a very small memory cgroup to force a slab allocation error
22785         local cgdir=$cg_basedir/osc_slab_alloc
22786         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22787         trap "cleanup_test411_cgroup $cgdir" EXIT
22788         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22789         echo 1M > $cgdir/memory.limit_in_bytes
22790
22791         # Should not LBUG, just be killed by oom-killer
22792         # dd will return 0 even allocation failure in some environment.
22793         # So don't check return value
22794         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22795         cleanup_test411_cgroup $cgdir
22796
22797         return 0
22798 }
22799 run_test 411 "Slab allocation error with cgroup does not LBUG"
22800
22801 test_412() {
22802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22803         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22804                 skip "Need server version at least 2.10.55"
22805         fi
22806
22807         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22808                 error "mkdir failed"
22809         $LFS getdirstripe $DIR/$tdir
22810         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22811         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22812                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22813         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22814         [ $stripe_count -eq 2 ] ||
22815                 error "expect 2 get $stripe_count"
22816 }
22817 run_test 412 "mkdir on specific MDTs"
22818
22819 test_qos_mkdir() {
22820         local mkdir_cmd=$1
22821         local stripe_count=$2
22822         local mdts=$(comma_list $(mdts_nodes))
22823
22824         local testdir
22825         local lmv_qos_prio_free
22826         local lmv_qos_threshold_rr
22827         local lmv_qos_maxage
22828         local lod_qos_prio_free
22829         local lod_qos_threshold_rr
22830         local lod_qos_maxage
22831         local count
22832         local i
22833
22834         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22835         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22836         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22837                 head -n1)
22838         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22839         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22840         stack_trap "$LCTL set_param \
22841                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22842         stack_trap "$LCTL set_param \
22843                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22844         stack_trap "$LCTL set_param \
22845                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22846
22847         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22848                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22849         lod_qos_prio_free=${lod_qos_prio_free%%%}
22850         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22851                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22852         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22853         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22854                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22855         stack_trap "do_nodes $mdts $LCTL set_param \
22856                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22857         stack_trap "do_nodes $mdts $LCTL set_param \
22858                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22859                 EXIT
22860         stack_trap "do_nodes $mdts $LCTL set_param \
22861                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22862
22863         echo
22864         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22865
22866         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22867         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22868
22869         testdir=$DIR/$tdir-s$stripe_count/rr
22870
22871         for i in $(seq $((100 * MDSCOUNT))); do
22872                 eval $mkdir_cmd $testdir/subdir$i ||
22873                         error "$mkdir_cmd subdir$i failed"
22874         done
22875
22876         for i in $(seq $MDSCOUNT); do
22877                 count=$($LFS getdirstripe -i $testdir/* |
22878                                 grep ^$((i - 1))$ | wc -l)
22879                 echo "$count directories created on MDT$((i - 1))"
22880                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22881
22882                 if [ $stripe_count -gt 1 ]; then
22883                         count=$($LFS getdirstripe $testdir/* |
22884                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22885                         echo "$count stripes created on MDT$((i - 1))"
22886                         # deviation should < 5% of average
22887                         [ $count -lt $((95 * stripe_count)) ] ||
22888                         [ $count -gt $((105 * stripe_count)) ] &&
22889                                 error "stripes are not evenly distributed"
22890                 fi
22891         done
22892
22893         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22894         do_nodes $mdts $LCTL set_param \
22895                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22896
22897         echo
22898         echo "Check for uneven MDTs: "
22899
22900         local ffree
22901         local bavail
22902         local max
22903         local min
22904         local max_index
22905         local min_index
22906         local tmp
22907
22908         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22909         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22910         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22911
22912         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22913         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22914         max_index=0
22915         min_index=0
22916         for ((i = 1; i < ${#ffree[@]}; i++)); do
22917                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22918                 if [ $tmp -gt $max ]; then
22919                         max=$tmp
22920                         max_index=$i
22921                 fi
22922                 if [ $tmp -lt $min ]; then
22923                         min=$tmp
22924                         min_index=$i
22925                 fi
22926         done
22927
22928         [ ${ffree[min_index]} -eq 0 ] &&
22929                 skip "no free files in MDT$min_index"
22930         [ ${ffree[min_index]} -gt 100000000 ] &&
22931                 skip "too much free files in MDT$min_index"
22932
22933         # Check if we need to generate uneven MDTs
22934         local threshold=50
22935         local diff=$(((max - min) * 100 / min))
22936         local value="$(generate_string 1024)"
22937
22938         while [ $diff -lt $threshold ]; do
22939                 # generate uneven MDTs, create till $threshold% diff
22940                 echo -n "weight diff=$diff% must be > $threshold% ..."
22941                 count=$((${ffree[min_index]} / 10))
22942                 # 50 sec per 10000 files in vm
22943                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22944                         skip "$count files to create"
22945                 echo "Fill MDT$min_index with $count files"
22946                 [ -d $DIR/$tdir-MDT$min_index ] ||
22947                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22948                         error "mkdir $tdir-MDT$min_index failed"
22949                 for i in $(seq $count); do
22950                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22951                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22952                                 error "create f$j_$i failed"
22953                         setfattr -n user.413b -v $value \
22954                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22955                                 error "setfattr f$j_$i failed"
22956                 done
22957
22958                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22959                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22960                 max=$(((${ffree[max_index]} >> 8) * \
22961                         (${bavail[max_index]} * bsize >> 16)))
22962                 min=$(((${ffree[min_index]} >> 8) * \
22963                         (${bavail[min_index]} * bsize >> 16)))
22964                 diff=$(((max - min) * 100 / min))
22965         done
22966
22967         echo "MDT filesfree available: ${ffree[@]}"
22968         echo "MDT blocks available: ${bavail[@]}"
22969         echo "weight diff=$diff%"
22970
22971         echo
22972         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22973
22974         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22975         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22976         # decrease statfs age, so that it can be updated in time
22977         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22978         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22979
22980         sleep 1
22981
22982         testdir=$DIR/$tdir-s$stripe_count/qos
22983
22984         for i in $(seq $((100 * MDSCOUNT))); do
22985                 eval $mkdir_cmd $testdir/subdir$i ||
22986                         error "$mkdir_cmd subdir$i failed"
22987         done
22988
22989         for i in $(seq $MDSCOUNT); do
22990                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22991                         wc -l)
22992                 echo "$count directories created on MDT$((i - 1))"
22993
22994                 if [ $stripe_count -gt 1 ]; then
22995                         count=$($LFS getdirstripe $testdir/* |
22996                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22997                         echo "$count stripes created on MDT$((i - 1))"
22998                 fi
22999         done
23000
23001         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23002         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23003
23004         # D-value should > 10% of averge
23005         [ $((max - min)) -lt 10 ] &&
23006                 error "subdirs shouldn't be evenly distributed"
23007
23008         # ditto
23009         if [ $stripe_count -gt 1 ]; then
23010                 max=$($LFS getdirstripe $testdir/* |
23011                         grep -P "^\s+$max_index\t" | wc -l)
23012                 min=$($LFS getdirstripe $testdir/* |
23013                         grep -P "^\s+$min_index\t" | wc -l)
23014                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23015                         error "stripes shouldn't be evenly distributed"|| true
23016         fi
23017 }
23018
23019 test_413a() {
23020         [ $MDSCOUNT -lt 2 ] &&
23021                 skip "We need at least 2 MDTs for this test"
23022
23023         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23024                 skip "Need server version at least 2.12.52"
23025
23026         local stripe_count
23027
23028         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23029                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23030                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23031                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23032                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23033         done
23034 }
23035 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23036
23037 test_413b() {
23038         [ $MDSCOUNT -lt 2 ] &&
23039                 skip "We need at least 2 MDTs for this test"
23040
23041         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23042                 skip "Need server version at least 2.12.52"
23043
23044         local stripe_count
23045
23046         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23047                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23048                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23049                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23050                 $LFS setdirstripe -D -c $stripe_count \
23051                         $DIR/$tdir-s$stripe_count/rr ||
23052                         error "setdirstripe failed"
23053                 $LFS setdirstripe -D -c $stripe_count \
23054                         $DIR/$tdir-s$stripe_count/qos ||
23055                         error "setdirstripe failed"
23056                 test_qos_mkdir "mkdir" $stripe_count
23057         done
23058 }
23059 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23060
23061 test_414() {
23062 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23063         $LCTL set_param fail_loc=0x80000521
23064         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23065         rm -f $DIR/$tfile
23066 }
23067 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23068
23069 test_415() {
23070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23071         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23072                 skip "Need server version at least 2.11.52"
23073
23074         # LU-11102
23075         local total
23076         local setattr_pid
23077         local start_time
23078         local end_time
23079         local duration
23080
23081         total=500
23082         # this test may be slow on ZFS
23083         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23084
23085         # though this test is designed for striped directory, let's test normal
23086         # directory too since lock is always saved as CoS lock.
23087         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23088         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23089
23090         (
23091                 while true; do
23092                         touch $DIR/$tdir
23093                 done
23094         ) &
23095         setattr_pid=$!
23096
23097         start_time=$(date +%s)
23098         for i in $(seq $total); do
23099                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23100                         > /dev/null
23101         done
23102         end_time=$(date +%s)
23103         duration=$((end_time - start_time))
23104
23105         kill -9 $setattr_pid
23106
23107         echo "rename $total files took $duration sec"
23108         [ $duration -lt 100 ] || error "rename took $duration sec"
23109 }
23110 run_test 415 "lock revoke is not missing"
23111
23112 test_416() {
23113         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23114                 skip "Need server version at least 2.11.55"
23115
23116         # define OBD_FAIL_OSD_TXN_START    0x19a
23117         do_facet mds1 lctl set_param fail_loc=0x19a
23118
23119         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23120
23121         true
23122 }
23123 run_test 416 "transaction start failure won't cause system hung"
23124
23125 cleanup_417() {
23126         trap 0
23127         do_nodes $(comma_list $(mdts_nodes)) \
23128                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23129         do_nodes $(comma_list $(mdts_nodes)) \
23130                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23131         do_nodes $(comma_list $(mdts_nodes)) \
23132                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23133 }
23134
23135 test_417() {
23136         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23137         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23138                 skip "Need MDS version at least 2.11.56"
23139
23140         trap cleanup_417 RETURN EXIT
23141
23142         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23143         do_nodes $(comma_list $(mdts_nodes)) \
23144                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23145         $LFS migrate -m 0 $DIR/$tdir.1 &&
23146                 error "migrate dir $tdir.1 should fail"
23147
23148         do_nodes $(comma_list $(mdts_nodes)) \
23149                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23150         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23151                 error "create remote dir $tdir.2 should fail"
23152
23153         do_nodes $(comma_list $(mdts_nodes)) \
23154                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23155         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23156                 error "create striped dir $tdir.3 should fail"
23157         true
23158 }
23159 run_test 417 "disable remote dir, striped dir and dir migration"
23160
23161 # Checks that the outputs of df [-i] and lfs df [-i] match
23162 #
23163 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23164 check_lfs_df() {
23165         local dir=$2
23166         local inodes
23167         local df_out
23168         local lfs_df_out
23169         local count
23170         local passed=false
23171
23172         # blocks or inodes
23173         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23174
23175         for count in {1..100}; do
23176                 cancel_lru_locks
23177                 sync; sleep 0.2
23178
23179                 # read the lines of interest
23180                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23181                         error "df $inodes $dir | tail -n +2 failed"
23182                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23183                         error "lfs df $inodes $dir | grep summary: failed"
23184
23185                 # skip first substrings of each output as they are different
23186                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23187                 # compare the two outputs
23188                 passed=true
23189                 for i in {1..5}; do
23190                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23191                 done
23192                 $passed && break
23193         done
23194
23195         if ! $passed; then
23196                 df -P $inodes $dir
23197                 echo
23198                 lfs df $inodes $dir
23199                 error "df and lfs df $1 output mismatch: "      \
23200                       "df ${inodes}: ${df_out[*]}, "            \
23201                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23202         fi
23203 }
23204
23205 test_418() {
23206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23207
23208         local dir=$DIR/$tdir
23209         local numfiles=$((RANDOM % 4096 + 2))
23210         local numblocks=$((RANDOM % 256 + 1))
23211
23212         wait_delete_completed
23213         test_mkdir $dir
23214
23215         # check block output
23216         check_lfs_df blocks $dir
23217         # check inode output
23218         check_lfs_df inodes $dir
23219
23220         # create a single file and retest
23221         echo "Creating a single file and testing"
23222         createmany -o $dir/$tfile- 1 &>/dev/null ||
23223                 error "creating 1 file in $dir failed"
23224         check_lfs_df blocks $dir
23225         check_lfs_df inodes $dir
23226
23227         # create a random number of files
23228         echo "Creating $((numfiles - 1)) files and testing"
23229         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23230                 error "creating $((numfiles - 1)) files in $dir failed"
23231
23232         # write a random number of blocks to the first test file
23233         echo "Writing $numblocks 4K blocks and testing"
23234         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23235                 count=$numblocks &>/dev/null ||
23236                 error "dd to $dir/${tfile}-0 failed"
23237
23238         # retest
23239         check_lfs_df blocks $dir
23240         check_lfs_df inodes $dir
23241
23242         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23243                 error "unlinking $numfiles files in $dir failed"
23244 }
23245 run_test 418 "df and lfs df outputs match"
23246
23247 test_419()
23248 {
23249         local dir=$DIR/$tdir
23250
23251         mkdir -p $dir
23252         touch $dir/file
23253
23254         cancel_lru_locks mdc
23255
23256         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23257         $LCTL set_param fail_loc=0x1410
23258         cat $dir/file
23259         $LCTL set_param fail_loc=0
23260         rm -rf $dir
23261 }
23262 run_test 419 "Verify open file by name doesn't crash kernel"
23263
23264 test_420()
23265 {
23266         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23267                 skip "Need MDS version at least 2.12.53"
23268
23269         local SAVE_UMASK=$(umask)
23270         local dir=$DIR/$tdir
23271         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23272
23273         mkdir -p $dir
23274         umask 0000
23275         mkdir -m03777 $dir/testdir
23276         ls -dn $dir/testdir
23277         # Need to remove trailing '.' when SELinux is enabled
23278         local dirperms=$(ls -dn $dir/testdir |
23279                          awk '{ sub(/\.$/, "", $1); print $1}')
23280         [ $dirperms == "drwxrwsrwt" ] ||
23281                 error "incorrect perms on $dir/testdir"
23282
23283         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23284                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23285         ls -n $dir/testdir/testfile
23286         local fileperms=$(ls -n $dir/testdir/testfile |
23287                           awk '{ sub(/\.$/, "", $1); print $1}')
23288         [ $fileperms == "-rwxr-xr-x" ] ||
23289                 error "incorrect perms on $dir/testdir/testfile"
23290
23291         umask $SAVE_UMASK
23292 }
23293 run_test 420 "clear SGID bit on non-directories for non-members"
23294
23295 test_421a() {
23296         local cnt
23297         local fid1
23298         local fid2
23299
23300         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23301                 skip "Need MDS version at least 2.12.54"
23302
23303         test_mkdir $DIR/$tdir
23304         createmany -o $DIR/$tdir/f 3
23305         cnt=$(ls -1 $DIR/$tdir | wc -l)
23306         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23307
23308         fid1=$(lfs path2fid $DIR/$tdir/f1)
23309         fid2=$(lfs path2fid $DIR/$tdir/f2)
23310         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23311
23312         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23313         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23314
23315         cnt=$(ls -1 $DIR/$tdir | wc -l)
23316         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23317
23318         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23319         createmany -o $DIR/$tdir/f 3
23320         cnt=$(ls -1 $DIR/$tdir | wc -l)
23321         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23322
23323         fid1=$(lfs path2fid $DIR/$tdir/f1)
23324         fid2=$(lfs path2fid $DIR/$tdir/f2)
23325         echo "remove using fsname $FSNAME"
23326         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23327
23328         cnt=$(ls -1 $DIR/$tdir | wc -l)
23329         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23330 }
23331 run_test 421a "simple rm by fid"
23332
23333 test_421b() {
23334         local cnt
23335         local FID1
23336         local FID2
23337
23338         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23339                 skip "Need MDS version at least 2.12.54"
23340
23341         test_mkdir $DIR/$tdir
23342         createmany -o $DIR/$tdir/f 3
23343         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23344         MULTIPID=$!
23345
23346         FID1=$(lfs path2fid $DIR/$tdir/f1)
23347         FID2=$(lfs path2fid $DIR/$tdir/f2)
23348         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23349
23350         kill -USR1 $MULTIPID
23351         wait
23352
23353         cnt=$(ls $DIR/$tdir | wc -l)
23354         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23355 }
23356 run_test 421b "rm by fid on open file"
23357
23358 test_421c() {
23359         local cnt
23360         local FIDS
23361
23362         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23363                 skip "Need MDS version at least 2.12.54"
23364
23365         test_mkdir $DIR/$tdir
23366         createmany -o $DIR/$tdir/f 3
23367         touch $DIR/$tdir/$tfile
23368         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23369         cnt=$(ls -1 $DIR/$tdir | wc -l)
23370         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23371
23372         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23373         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23374
23375         cnt=$(ls $DIR/$tdir | wc -l)
23376         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23377 }
23378 run_test 421c "rm by fid against hardlinked files"
23379
23380 test_421d() {
23381         local cnt
23382         local FIDS
23383
23384         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23385                 skip "Need MDS version at least 2.12.54"
23386
23387         test_mkdir $DIR/$tdir
23388         createmany -o $DIR/$tdir/f 4097
23389         cnt=$(ls -1 $DIR/$tdir | wc -l)
23390         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23391
23392         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23393         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23394
23395         cnt=$(ls $DIR/$tdir | wc -l)
23396         rm -rf $DIR/$tdir
23397         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23398 }
23399 run_test 421d "rmfid en masse"
23400
23401 test_421e() {
23402         local cnt
23403         local FID
23404
23405         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23406         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23407                 skip "Need MDS version at least 2.12.54"
23408
23409         mkdir -p $DIR/$tdir
23410         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23411         createmany -o $DIR/$tdir/striped_dir/f 512
23412         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23413         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23414
23415         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23416                 sed "s/[/][^:]*://g")
23417         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23418
23419         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23420         rm -rf $DIR/$tdir
23421         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23422 }
23423 run_test 421e "rmfid in DNE"
23424
23425 test_421f() {
23426         local cnt
23427         local FID
23428
23429         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23430                 skip "Need MDS version at least 2.12.54"
23431
23432         test_mkdir $DIR/$tdir
23433         touch $DIR/$tdir/f
23434         cnt=$(ls -1 $DIR/$tdir | wc -l)
23435         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23436
23437         FID=$(lfs path2fid $DIR/$tdir/f)
23438         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23439         # rmfid should fail
23440         cnt=$(ls -1 $DIR/$tdir | wc -l)
23441         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23442
23443         chmod a+rw $DIR/$tdir
23444         ls -la $DIR/$tdir
23445         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23446         # rmfid should fail
23447         cnt=$(ls -1 $DIR/$tdir | wc -l)
23448         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23449
23450         rm -f $DIR/$tdir/f
23451         $RUNAS touch $DIR/$tdir/f
23452         FID=$(lfs path2fid $DIR/$tdir/f)
23453         echo "rmfid as root"
23454         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23455         cnt=$(ls -1 $DIR/$tdir | wc -l)
23456         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23457
23458         rm -f $DIR/$tdir/f
23459         $RUNAS touch $DIR/$tdir/f
23460         cnt=$(ls -1 $DIR/$tdir | wc -l)
23461         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23462         FID=$(lfs path2fid $DIR/$tdir/f)
23463         # rmfid w/o user_fid2path mount option should fail
23464         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23465         cnt=$(ls -1 $DIR/$tdir | wc -l)
23466         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23467
23468         umount_client $MOUNT || error "failed to umount client"
23469         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23470                 error "failed to mount client'"
23471
23472         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23473         # rmfid should succeed
23474         cnt=$(ls -1 $DIR/$tdir | wc -l)
23475         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23476
23477         # rmfid shouldn't allow to remove files due to dir's permission
23478         chmod a+rwx $DIR/$tdir
23479         touch $DIR/$tdir/f
23480         ls -la $DIR/$tdir
23481         FID=$(lfs path2fid $DIR/$tdir/f)
23482         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23483
23484         umount_client $MOUNT || error "failed to umount client"
23485         mount_client $MOUNT "$MOUNT_OPTS" ||
23486                 error "failed to mount client'"
23487
23488 }
23489 run_test 421f "rmfid checks permissions"
23490
23491 test_421g() {
23492         local cnt
23493         local FIDS
23494
23495         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23496         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23497                 skip "Need MDS version at least 2.12.54"
23498
23499         mkdir -p $DIR/$tdir
23500         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23501         createmany -o $DIR/$tdir/striped_dir/f 512
23502         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23503         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23504
23505         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23506                 sed "s/[/][^:]*://g")
23507
23508         rm -f $DIR/$tdir/striped_dir/f1*
23509         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23510         removed=$((512 - cnt))
23511
23512         # few files have been just removed, so we expect
23513         # rmfid to fail on their fids
23514         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23515         [ $removed != $errors ] && error "$errors != $removed"
23516
23517         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23518         rm -rf $DIR/$tdir
23519         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23520 }
23521 run_test 421g "rmfid to return errors properly"
23522
23523 test_422() {
23524         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23525         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23526         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23527         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23528         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23529
23530         local amc=$(at_max_get client)
23531         local amo=$(at_max_get mds1)
23532         local timeout=`lctl get_param -n timeout`
23533
23534         at_max_set 0 client
23535         at_max_set 0 mds1
23536
23537 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23538         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23539                         fail_val=$(((2*timeout + 10)*1000))
23540         touch $DIR/$tdir/d3/file &
23541         sleep 2
23542 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23543         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23544                         fail_val=$((2*timeout + 5))
23545         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23546         local pid=$!
23547         sleep 1
23548         kill -9 $pid
23549         sleep $((2 * timeout))
23550         echo kill $pid
23551         kill -9 $pid
23552         lctl mark touch
23553         touch $DIR/$tdir/d2/file3
23554         touch $DIR/$tdir/d2/file4
23555         touch $DIR/$tdir/d2/file5
23556
23557         wait
23558         at_max_set $amc client
23559         at_max_set $amo mds1
23560
23561         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23562         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23563                 error "Watchdog is always throttled"
23564 }
23565 run_test 422 "kill a process with RPC in progress"
23566
23567 stat_test() {
23568     df -h $MOUNT &
23569     df -h $MOUNT &
23570     df -h $MOUNT &
23571     df -h $MOUNT &
23572     df -h $MOUNT &
23573     df -h $MOUNT &
23574 }
23575
23576 test_423() {
23577     local _stats
23578     # ensure statfs cache is expired
23579     sleep 2;
23580
23581     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23582     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23583
23584     return 0
23585 }
23586 run_test 423 "statfs should return a right data"
23587
23588 test_424() {
23589 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23590         $LCTL set_param fail_loc=0x80000522
23591         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23592         rm -f $DIR/$tfile
23593 }
23594 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23595
23596 test_425() {
23597         test_mkdir -c -1 $DIR/$tdir
23598         $LFS setstripe -c -1 $DIR/$tdir
23599
23600         lru_resize_disable "" 100
23601         stack_trap "lru_resize_enable" EXIT
23602
23603         sleep 5
23604
23605         for i in $(seq $((MDSCOUNT * 125))); do
23606                 local t=$DIR/$tdir/$tfile_$i
23607
23608                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23609                         error_noexit "Create file $t"
23610         done
23611         stack_trap "rm -rf $DIR/$tdir" EXIT
23612
23613         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23614                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23615                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23616
23617                 [ $lock_count -le $lru_size ] ||
23618                         error "osc lock count $lock_count > lru size $lru_size"
23619         done
23620
23621         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23622                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23623                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23624
23625                 [ $lock_count -le $lru_size ] ||
23626                         error "mdc lock count $lock_count > lru size $lru_size"
23627         done
23628 }
23629 run_test 425 "lock count should not exceed lru size"
23630
23631 test_426() {
23632         splice-test -r $DIR/$tfile
23633         splice-test -rd $DIR/$tfile
23634         splice-test $DIR/$tfile
23635         splice-test -d $DIR/$tfile
23636 }
23637 run_test 426 "splice test on Lustre"
23638
23639 lseek_test_430() {
23640         local offset
23641         local file=$1
23642
23643         # data at [200K, 400K)
23644         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23645                 error "256K->512K dd fails"
23646         # data at [2M, 3M)
23647         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23648                 error "2M->3M dd fails"
23649         # data at [4M, 5M)
23650         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23651                 error "4M->5M dd fails"
23652         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23653         # start at first component hole #1
23654         printf "Seeking hole from 1000 ... "
23655         offset=$(lseek_test -l 1000 $file)
23656         echo $offset
23657         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23658         printf "Seeking data from 1000 ... "
23659         offset=$(lseek_test -d 1000 $file)
23660         echo $offset
23661         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23662
23663         # start at first component data block
23664         printf "Seeking hole from 300000 ... "
23665         offset=$(lseek_test -l 300000 $file)
23666         echo $offset
23667         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23668         printf "Seeking data from 300000 ... "
23669         offset=$(lseek_test -d 300000 $file)
23670         echo $offset
23671         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23672
23673         # start at the first component but beyond end of object size
23674         printf "Seeking hole from 1000000 ... "
23675         offset=$(lseek_test -l 1000000 $file)
23676         echo $offset
23677         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23678         printf "Seeking data from 1000000 ... "
23679         offset=$(lseek_test -d 1000000 $file)
23680         echo $offset
23681         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23682
23683         # start at second component stripe 2 (empty file)
23684         printf "Seeking hole from 1500000 ... "
23685         offset=$(lseek_test -l 1500000 $file)
23686         echo $offset
23687         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23688         printf "Seeking data from 1500000 ... "
23689         offset=$(lseek_test -d 1500000 $file)
23690         echo $offset
23691         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23692
23693         # start at second component stripe 1 (all data)
23694         printf "Seeking hole from 3000000 ... "
23695         offset=$(lseek_test -l 3000000 $file)
23696         echo $offset
23697         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23698         printf "Seeking data from 3000000 ... "
23699         offset=$(lseek_test -d 3000000 $file)
23700         echo $offset
23701         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23702
23703         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23704                 error "2nd dd fails"
23705         echo "Add data block at 640K...1280K"
23706
23707         # start at before new data block, in hole
23708         printf "Seeking hole from 600000 ... "
23709         offset=$(lseek_test -l 600000 $file)
23710         echo $offset
23711         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23712         printf "Seeking data from 600000 ... "
23713         offset=$(lseek_test -d 600000 $file)
23714         echo $offset
23715         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23716
23717         # start at the first component new data block
23718         printf "Seeking hole from 1000000 ... "
23719         offset=$(lseek_test -l 1000000 $file)
23720         echo $offset
23721         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23722         printf "Seeking data from 1000000 ... "
23723         offset=$(lseek_test -d 1000000 $file)
23724         echo $offset
23725         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23726
23727         # start at second component stripe 2, new data
23728         printf "Seeking hole from 1200000 ... "
23729         offset=$(lseek_test -l 1200000 $file)
23730         echo $offset
23731         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23732         printf "Seeking data from 1200000 ... "
23733         offset=$(lseek_test -d 1200000 $file)
23734         echo $offset
23735         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23736
23737         # start beyond file end
23738         printf "Using offset > filesize ... "
23739         lseek_test -l 4000000 $file && error "lseek should fail"
23740         printf "Using offset > filesize ... "
23741         lseek_test -d 4000000 $file && error "lseek should fail"
23742
23743         printf "Done\n\n"
23744 }
23745
23746 test_430a() {
23747         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23748                 skip "MDT does not support SEEK_HOLE"
23749
23750         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23751                 skip "OST does not support SEEK_HOLE"
23752
23753         local file=$DIR/$tdir/$tfile
23754
23755         mkdir -p $DIR/$tdir
23756
23757         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23758         # OST stripe #1 will have continuous data at [1M, 3M)
23759         # OST stripe #2 is empty
23760         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23761         lseek_test_430 $file
23762         rm $file
23763         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23764         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23765         lseek_test_430 $file
23766         rm $file
23767         $LFS setstripe -c2 -S 512K $file
23768         echo "Two stripes, stripe size 512K"
23769         lseek_test_430 $file
23770         rm $file
23771         # FLR with stale mirror
23772         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23773                        -N -c2 -S 1M $file
23774         echo "Mirrored file:"
23775         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23776         echo "Plain 2 stripes 1M"
23777         lseek_test_430 $file
23778         rm $file
23779 }
23780 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23781
23782 test_430b() {
23783         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23784                 skip "OST does not support SEEK_HOLE"
23785
23786         local offset
23787         local file=$DIR/$tdir/$tfile
23788
23789         mkdir -p $DIR/$tdir
23790         # Empty layout lseek should fail
23791         $MCREATE $file
23792         # seek from 0
23793         printf "Seeking hole from 0 ... "
23794         lseek_test -l 0 $file && error "lseek should fail"
23795         printf "Seeking data from 0 ... "
23796         lseek_test -d 0 $file && error "lseek should fail"
23797         rm $file
23798
23799         # 1M-hole file
23800         $LFS setstripe -E 1M -c2 -E eof $file
23801         $TRUNCATE $file 1048576
23802         printf "Seeking hole from 1000000 ... "
23803         offset=$(lseek_test -l 1000000 $file)
23804         echo $offset
23805         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23806         printf "Seeking data from 1000000 ... "
23807         lseek_test -d 1000000 $file && error "lseek should fail"
23808         # full first component, non-inited second one
23809         dd if=/dev/urandom of=$file bs=1M count=1
23810         printf "Seeking hole from 1000000 ... "
23811         offset=$(lseek_test -l 1000000 $file)
23812         echo $offset
23813         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23814         printf "Seeking hole from 1048576 ... "
23815         lseek_test -l 1048576 $file && error "lseek should fail"
23816         # init second component and truncate back
23817         echo "123" >> $file
23818         $TRUNCATE $file 1048576
23819         ls -lia $file
23820         printf "Seeking hole from 1000000 ... "
23821         offset=$(lseek_test -l 1000000 $file)
23822         echo $offset
23823         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23824         printf "Seeking hole from 1048576 ... "
23825         lseek_test -l 1048576 $file && error "lseek should fail"
23826         # boundary checks for big values
23827         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
23828         offset=$(lseek_test -d 0 $file.10g)
23829         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
23830         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
23831         offset=$(lseek_test -d 0 $file.100g)
23832         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
23833         return 0
23834 }
23835 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
23836
23837 test_430c() {
23838         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23839                 skip "OST does not support SEEK_HOLE"
23840
23841         local file=$DIR/$tdir/$tfile
23842         local start
23843
23844         mkdir -p $DIR/$tdir
23845         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
23846
23847         # cp version 8.33+ prefers lseek over fiemap
23848         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
23849                 start=$SECONDS
23850                 time cp $file /dev/null
23851                 (( SECONDS - start < 5 )) ||
23852                         error "cp: too long runtime $((SECONDS - start))"
23853
23854         fi
23855         # tar version 1.29+ supports SEEK_HOLE/DATA
23856         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
23857                 start=$SECONDS
23858                 time tar cS $file - | cat > /dev/null
23859                 (( SECONDS - start < 5 )) ||
23860                         error "tar: too long runtime $((SECONDS - start))"
23861         fi
23862 }
23863 run_test 430c "lseek: external tools check"
23864
23865 prep_801() {
23866         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23867         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23868                 skip "Need server version at least 2.9.55"
23869
23870         start_full_debug_logging
23871 }
23872
23873 post_801() {
23874         stop_full_debug_logging
23875 }
23876
23877 barrier_stat() {
23878         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23879                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23880                            awk '/The barrier for/ { print $7 }')
23881                 echo $st
23882         else
23883                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23884                 echo \'$st\'
23885         fi
23886 }
23887
23888 barrier_expired() {
23889         local expired
23890
23891         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23892                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23893                           awk '/will be expired/ { print $7 }')
23894         else
23895                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23896         fi
23897
23898         echo $expired
23899 }
23900
23901 test_801a() {
23902         prep_801
23903
23904         echo "Start barrier_freeze at: $(date)"
23905         #define OBD_FAIL_BARRIER_DELAY          0x2202
23906         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23907         # Do not reduce barrier time - See LU-11873
23908         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23909
23910         sleep 2
23911         local b_status=$(barrier_stat)
23912         echo "Got barrier status at: $(date)"
23913         [ "$b_status" = "'freezing_p1'" ] ||
23914                 error "(1) unexpected barrier status $b_status"
23915
23916         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23917         wait
23918         b_status=$(barrier_stat)
23919         [ "$b_status" = "'frozen'" ] ||
23920                 error "(2) unexpected barrier status $b_status"
23921
23922         local expired=$(barrier_expired)
23923         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23924         sleep $((expired + 3))
23925
23926         b_status=$(barrier_stat)
23927         [ "$b_status" = "'expired'" ] ||
23928                 error "(3) unexpected barrier status $b_status"
23929
23930         # Do not reduce barrier time - See LU-11873
23931         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23932                 error "(4) fail to freeze barrier"
23933
23934         b_status=$(barrier_stat)
23935         [ "$b_status" = "'frozen'" ] ||
23936                 error "(5) unexpected barrier status $b_status"
23937
23938         echo "Start barrier_thaw at: $(date)"
23939         #define OBD_FAIL_BARRIER_DELAY          0x2202
23940         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23941         do_facet mgs $LCTL barrier_thaw $FSNAME &
23942
23943         sleep 2
23944         b_status=$(barrier_stat)
23945         echo "Got barrier status at: $(date)"
23946         [ "$b_status" = "'thawing'" ] ||
23947                 error "(6) unexpected barrier status $b_status"
23948
23949         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23950         wait
23951         b_status=$(barrier_stat)
23952         [ "$b_status" = "'thawed'" ] ||
23953                 error "(7) unexpected barrier status $b_status"
23954
23955         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23956         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23957         do_facet mgs $LCTL barrier_freeze $FSNAME
23958
23959         b_status=$(barrier_stat)
23960         [ "$b_status" = "'failed'" ] ||
23961                 error "(8) unexpected barrier status $b_status"
23962
23963         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23964         do_facet mgs $LCTL barrier_thaw $FSNAME
23965
23966         post_801
23967 }
23968 run_test 801a "write barrier user interfaces and stat machine"
23969
23970 test_801b() {
23971         prep_801
23972
23973         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23974         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23975         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23976         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23977         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23978
23979         cancel_lru_locks mdc
23980
23981         # 180 seconds should be long enough
23982         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23983
23984         local b_status=$(barrier_stat)
23985         [ "$b_status" = "'frozen'" ] ||
23986                 error "(6) unexpected barrier status $b_status"
23987
23988         mkdir $DIR/$tdir/d0/d10 &
23989         mkdir_pid=$!
23990
23991         touch $DIR/$tdir/d1/f13 &
23992         touch_pid=$!
23993
23994         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23995         ln_pid=$!
23996
23997         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23998         mv_pid=$!
23999
24000         rm -f $DIR/$tdir/d4/f12 &
24001         rm_pid=$!
24002
24003         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24004
24005         # To guarantee taht the 'stat' is not blocked
24006         b_status=$(barrier_stat)
24007         [ "$b_status" = "'frozen'" ] ||
24008                 error "(8) unexpected barrier status $b_status"
24009
24010         # let above commands to run at background
24011         sleep 5
24012
24013         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24014         ps -p $touch_pid || error "(10) touch should be blocked"
24015         ps -p $ln_pid || error "(11) link should be blocked"
24016         ps -p $mv_pid || error "(12) rename should be blocked"
24017         ps -p $rm_pid || error "(13) unlink should be blocked"
24018
24019         b_status=$(barrier_stat)
24020         [ "$b_status" = "'frozen'" ] ||
24021                 error "(14) unexpected barrier status $b_status"
24022
24023         do_facet mgs $LCTL barrier_thaw $FSNAME
24024         b_status=$(barrier_stat)
24025         [ "$b_status" = "'thawed'" ] ||
24026                 error "(15) unexpected barrier status $b_status"
24027
24028         wait $mkdir_pid || error "(16) mkdir should succeed"
24029         wait $touch_pid || error "(17) touch should succeed"
24030         wait $ln_pid || error "(18) link should succeed"
24031         wait $mv_pid || error "(19) rename should succeed"
24032         wait $rm_pid || error "(20) unlink should succeed"
24033
24034         post_801
24035 }
24036 run_test 801b "modification will be blocked by write barrier"
24037
24038 test_801c() {
24039         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24040
24041         prep_801
24042
24043         stop mds2 || error "(1) Fail to stop mds2"
24044
24045         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24046
24047         local b_status=$(barrier_stat)
24048         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24049                 do_facet mgs $LCTL barrier_thaw $FSNAME
24050                 error "(2) unexpected barrier status $b_status"
24051         }
24052
24053         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24054                 error "(3) Fail to rescan barrier bitmap"
24055
24056         # Do not reduce barrier time - See LU-11873
24057         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24058
24059         b_status=$(barrier_stat)
24060         [ "$b_status" = "'frozen'" ] ||
24061                 error "(4) unexpected barrier status $b_status"
24062
24063         do_facet mgs $LCTL barrier_thaw $FSNAME
24064         b_status=$(barrier_stat)
24065         [ "$b_status" = "'thawed'" ] ||
24066                 error "(5) unexpected barrier status $b_status"
24067
24068         local devname=$(mdsdevname 2)
24069
24070         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24071
24072         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24073                 error "(7) Fail to rescan barrier bitmap"
24074
24075         post_801
24076 }
24077 run_test 801c "rescan barrier bitmap"
24078
24079 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24080 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24081 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24082 saved_MOUNT_OPTS=$MOUNT_OPTS
24083
24084 cleanup_802a() {
24085         trap 0
24086
24087         stopall
24088         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24089         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24090         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24091         MOUNT_OPTS=$saved_MOUNT_OPTS
24092         setupall
24093 }
24094
24095 test_802a() {
24096         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24097         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24098         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24099                 skip "Need server version at least 2.9.55"
24100
24101         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24102
24103         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24104
24105         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24106                 error "(2) Fail to copy"
24107
24108         trap cleanup_802a EXIT
24109
24110         # sync by force before remount as readonly
24111         sync; sync_all_data; sleep 3; sync_all_data
24112
24113         stopall
24114
24115         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24116         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24117         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24118
24119         echo "Mount the server as read only"
24120         setupall server_only || error "(3) Fail to start servers"
24121
24122         echo "Mount client without ro should fail"
24123         mount_client $MOUNT &&
24124                 error "(4) Mount client without 'ro' should fail"
24125
24126         echo "Mount client with ro should succeed"
24127         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24128         mount_client $MOUNT ||
24129                 error "(5) Mount client with 'ro' should succeed"
24130
24131         echo "Modify should be refused"
24132         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24133
24134         echo "Read should be allowed"
24135         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24136                 error "(7) Read should succeed under ro mode"
24137
24138         cleanup_802a
24139 }
24140 run_test 802a "simulate readonly device"
24141
24142 test_802b() {
24143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24144         remote_mds_nodsh && skip "remote MDS with nodsh"
24145
24146         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24147                 skip "readonly option not available"
24148
24149         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24150
24151         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24152                 error "(2) Fail to copy"
24153
24154         # write back all cached data before setting MDT to readonly
24155         cancel_lru_locks
24156         sync_all_data
24157
24158         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24159         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24160
24161         echo "Modify should be refused"
24162         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24163
24164         echo "Read should be allowed"
24165         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24166                 error "(7) Read should succeed under ro mode"
24167
24168         # disable readonly
24169         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24170 }
24171 run_test 802b "be able to set MDTs to readonly"
24172
24173 test_803a() {
24174         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24175         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24176                 skip "MDS needs to be newer than 2.10.54"
24177
24178         mkdir -p $DIR/$tdir
24179         # Create some objects on all MDTs to trigger related logs objects
24180         for idx in $(seq $MDSCOUNT); do
24181                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24182                         $DIR/$tdir/dir${idx} ||
24183                         error "Fail to create $DIR/$tdir/dir${idx}"
24184         done
24185
24186         sync; sleep 3
24187         wait_delete_completed # ensure old test cleanups are finished
24188         echo "before create:"
24189         $LFS df -i $MOUNT
24190         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24191
24192         for i in {1..10}; do
24193                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24194                         error "Fail to create $DIR/$tdir/foo$i"
24195         done
24196
24197         sync; sleep 3
24198         echo "after create:"
24199         $LFS df -i $MOUNT
24200         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24201
24202         # allow for an llog to be cleaned up during the test
24203         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24204                 error "before ($before_used) + 10 > after ($after_used)"
24205
24206         for i in {1..10}; do
24207                 rm -rf $DIR/$tdir/foo$i ||
24208                         error "Fail to remove $DIR/$tdir/foo$i"
24209         done
24210
24211         sleep 3 # avoid MDT return cached statfs
24212         wait_delete_completed
24213         echo "after unlink:"
24214         $LFS df -i $MOUNT
24215         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24216
24217         # allow for an llog to be created during the test
24218         [ $after_used -le $((before_used + 1)) ] ||
24219                 error "after ($after_used) > before ($before_used) + 1"
24220 }
24221 run_test 803a "verify agent object for remote object"
24222
24223 test_803b() {
24224         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24225         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24226                 skip "MDS needs to be newer than 2.13.56"
24227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24228
24229         for i in $(seq 0 $((MDSCOUNT - 1))); do
24230                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24231         done
24232
24233         local before=0
24234         local after=0
24235
24236         local tmp
24237
24238         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24239         for i in $(seq 0 $((MDSCOUNT - 1))); do
24240                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24241                         awk '/getattr/ { print $2 }')
24242                 before=$((before + tmp))
24243         done
24244         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24245         for i in $(seq 0 $((MDSCOUNT - 1))); do
24246                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24247                         awk '/getattr/ { print $2 }')
24248                 after=$((after + tmp))
24249         done
24250
24251         [ $before -eq $after ] || error "getattr count $before != $after"
24252 }
24253 run_test 803b "remote object can getattr from cache"
24254
24255 test_804() {
24256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24257         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24258                 skip "MDS needs to be newer than 2.10.54"
24259         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24260
24261         mkdir -p $DIR/$tdir
24262         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24263                 error "Fail to create $DIR/$tdir/dir0"
24264
24265         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24266         local dev=$(mdsdevname 2)
24267
24268         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24269                 grep ${fid} || error "NOT found agent entry for dir0"
24270
24271         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24272                 error "Fail to create $DIR/$tdir/dir1"
24273
24274         touch $DIR/$tdir/dir1/foo0 ||
24275                 error "Fail to create $DIR/$tdir/dir1/foo0"
24276         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24277         local rc=0
24278
24279         for idx in $(seq $MDSCOUNT); do
24280                 dev=$(mdsdevname $idx)
24281                 do_facet mds${idx} \
24282                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24283                         grep ${fid} && rc=$idx
24284         done
24285
24286         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24287                 error "Fail to rename foo0 to foo1"
24288         if [ $rc -eq 0 ]; then
24289                 for idx in $(seq $MDSCOUNT); do
24290                         dev=$(mdsdevname $idx)
24291                         do_facet mds${idx} \
24292                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24293                         grep ${fid} && rc=$idx
24294                 done
24295         fi
24296
24297         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24298                 error "Fail to rename foo1 to foo2"
24299         if [ $rc -eq 0 ]; then
24300                 for idx in $(seq $MDSCOUNT); do
24301                         dev=$(mdsdevname $idx)
24302                         do_facet mds${idx} \
24303                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24304                         grep ${fid} && rc=$idx
24305                 done
24306         fi
24307
24308         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24309
24310         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24311                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24312         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24313                 error "Fail to rename foo2 to foo0"
24314         unlink $DIR/$tdir/dir1/foo0 ||
24315                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24316         rm -rf $DIR/$tdir/dir0 ||
24317                 error "Fail to rm $DIR/$tdir/dir0"
24318
24319         for idx in $(seq $MDSCOUNT); do
24320                 dev=$(mdsdevname $idx)
24321                 rc=0
24322
24323                 stop mds${idx}
24324                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24325                         rc=$?
24326                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24327                         error "mount mds$idx failed"
24328                 df $MOUNT > /dev/null 2>&1
24329
24330                 # e2fsck should not return error
24331                 [ $rc -eq 0 ] ||
24332                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24333         done
24334 }
24335 run_test 804 "verify agent entry for remote entry"
24336
24337 cleanup_805() {
24338         do_facet $SINGLEMDS zfs set quota=$old $fsset
24339         unlinkmany $DIR/$tdir/f- 1000000
24340         trap 0
24341 }
24342
24343 test_805() {
24344         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24345         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24346         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24347                 skip "netfree not implemented before 0.7"
24348         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24349                 skip "Need MDS version at least 2.10.57"
24350
24351         local fsset
24352         local freekb
24353         local usedkb
24354         local old
24355         local quota
24356         local pref="osd-zfs.$FSNAME-MDT0000."
24357
24358         # limit available space on MDS dataset to meet nospace issue
24359         # quickly. then ZFS 0.7.2 can use reserved space if asked
24360         # properly (using netfree flag in osd_declare_destroy()
24361         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24362         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24363                 gawk '{print $3}')
24364         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24365         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24366         let "usedkb=usedkb-freekb"
24367         let "freekb=freekb/2"
24368         if let "freekb > 5000"; then
24369                 let "freekb=5000"
24370         fi
24371         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24372         trap cleanup_805 EXIT
24373         mkdir $DIR/$tdir
24374         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24375                 error "Can't set PFL layout"
24376         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24377         rm -rf $DIR/$tdir || error "not able to remove"
24378         do_facet $SINGLEMDS zfs set quota=$old $fsset
24379         trap 0
24380 }
24381 run_test 805 "ZFS can remove from full fs"
24382
24383 # Size-on-MDS test
24384 check_lsom_data()
24385 {
24386         local file=$1
24387         local size=$($LFS getsom -s $file)
24388         local expect=$(stat -c %s $file)
24389
24390         [[ $size == $expect ]] ||
24391                 error "$file expected size: $expect, got: $size"
24392
24393         local blocks=$($LFS getsom -b $file)
24394         expect=$(stat -c %b $file)
24395         [[ $blocks == $expect ]] ||
24396                 error "$file expected blocks: $expect, got: $blocks"
24397 }
24398
24399 check_lsom_size()
24400 {
24401         local size=$($LFS getsom -s $1)
24402         local expect=$2
24403
24404         [[ $size == $expect ]] ||
24405                 error "$file expected size: $expect, got: $size"
24406 }
24407
24408 test_806() {
24409         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24410                 skip "Need MDS version at least 2.11.52"
24411
24412         local bs=1048576
24413
24414         touch $DIR/$tfile || error "touch $tfile failed"
24415
24416         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24417         save_lustre_params client "llite.*.xattr_cache" > $save
24418         lctl set_param llite.*.xattr_cache=0
24419         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24420
24421         # single-threaded write
24422         echo "Test SOM for single-threaded write"
24423         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24424                 error "write $tfile failed"
24425         check_lsom_size $DIR/$tfile $bs
24426
24427         local num=32
24428         local size=$(($num * $bs))
24429         local offset=0
24430         local i
24431
24432         echo "Test SOM for single client multi-threaded($num) write"
24433         $TRUNCATE $DIR/$tfile 0
24434         for ((i = 0; i < $num; i++)); do
24435                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24436                 local pids[$i]=$!
24437                 offset=$((offset + $bs))
24438         done
24439         for (( i=0; i < $num; i++ )); do
24440                 wait ${pids[$i]}
24441         done
24442         check_lsom_size $DIR/$tfile $size
24443
24444         $TRUNCATE $DIR/$tfile 0
24445         for ((i = 0; i < $num; i++)); do
24446                 offset=$((offset - $bs))
24447                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24448                 local pids[$i]=$!
24449         done
24450         for (( i=0; i < $num; i++ )); do
24451                 wait ${pids[$i]}
24452         done
24453         check_lsom_size $DIR/$tfile $size
24454
24455         # multi-client writes
24456         num=$(get_node_count ${CLIENTS//,/ })
24457         size=$(($num * $bs))
24458         offset=0
24459         i=0
24460
24461         echo "Test SOM for multi-client ($num) writes"
24462         $TRUNCATE $DIR/$tfile 0
24463         for client in ${CLIENTS//,/ }; do
24464                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24465                 local pids[$i]=$!
24466                 i=$((i + 1))
24467                 offset=$((offset + $bs))
24468         done
24469         for (( i=0; i < $num; i++ )); do
24470                 wait ${pids[$i]}
24471         done
24472         check_lsom_size $DIR/$tfile $offset
24473
24474         i=0
24475         $TRUNCATE $DIR/$tfile 0
24476         for client in ${CLIENTS//,/ }; do
24477                 offset=$((offset - $bs))
24478                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24479                 local pids[$i]=$!
24480                 i=$((i + 1))
24481         done
24482         for (( i=0; i < $num; i++ )); do
24483                 wait ${pids[$i]}
24484         done
24485         check_lsom_size $DIR/$tfile $size
24486
24487         # verify truncate
24488         echo "Test SOM for truncate"
24489         $TRUNCATE $DIR/$tfile 1048576
24490         check_lsom_size $DIR/$tfile 1048576
24491         $TRUNCATE $DIR/$tfile 1234
24492         check_lsom_size $DIR/$tfile 1234
24493
24494         # verify SOM blocks count
24495         echo "Verify SOM block count"
24496         $TRUNCATE $DIR/$tfile 0
24497         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24498                 error "failed to write file $tfile"
24499         check_lsom_data $DIR/$tfile
24500 }
24501 run_test 806 "Verify Lazy Size on MDS"
24502
24503 test_807() {
24504         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24505         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24506                 skip "Need MDS version at least 2.11.52"
24507
24508         # Registration step
24509         changelog_register || error "changelog_register failed"
24510         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24511         changelog_users $SINGLEMDS | grep -q $cl_user ||
24512                 error "User $cl_user not found in changelog_users"
24513
24514         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24515         save_lustre_params client "llite.*.xattr_cache" > $save
24516         lctl set_param llite.*.xattr_cache=0
24517         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24518
24519         rm -rf $DIR/$tdir || error "rm $tdir failed"
24520         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24521         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24522         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24523         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24524                 error "truncate $tdir/trunc failed"
24525
24526         local bs=1048576
24527         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24528                 error "write $tfile failed"
24529
24530         # multi-client wirtes
24531         local num=$(get_node_count ${CLIENTS//,/ })
24532         local offset=0
24533         local i=0
24534
24535         echo "Test SOM for multi-client ($num) writes"
24536         touch $DIR/$tfile || error "touch $tfile failed"
24537         $TRUNCATE $DIR/$tfile 0
24538         for client in ${CLIENTS//,/ }; do
24539                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24540                 local pids[$i]=$!
24541                 i=$((i + 1))
24542                 offset=$((offset + $bs))
24543         done
24544         for (( i=0; i < $num; i++ )); do
24545                 wait ${pids[$i]}
24546         done
24547
24548         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24549         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24550         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24551         check_lsom_data $DIR/$tdir/trunc
24552         check_lsom_data $DIR/$tdir/single_dd
24553         check_lsom_data $DIR/$tfile
24554
24555         rm -rf $DIR/$tdir
24556         # Deregistration step
24557         changelog_deregister || error "changelog_deregister failed"
24558 }
24559 run_test 807 "verify LSOM syncing tool"
24560
24561 check_som_nologged()
24562 {
24563         local lines=$($LFS changelog $FSNAME-MDT0000 |
24564                 grep 'x=trusted.som' | wc -l)
24565         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24566 }
24567
24568 test_808() {
24569         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24570                 skip "Need MDS version at least 2.11.55"
24571
24572         # Registration step
24573         changelog_register || error "changelog_register failed"
24574
24575         touch $DIR/$tfile || error "touch $tfile failed"
24576         check_som_nologged
24577
24578         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24579                 error "write $tfile failed"
24580         check_som_nologged
24581
24582         $TRUNCATE $DIR/$tfile 1234
24583         check_som_nologged
24584
24585         $TRUNCATE $DIR/$tfile 1048576
24586         check_som_nologged
24587
24588         # Deregistration step
24589         changelog_deregister || error "changelog_deregister failed"
24590 }
24591 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24592
24593 check_som_nodata()
24594 {
24595         $LFS getsom $1
24596         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24597 }
24598
24599 test_809() {
24600         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24601                 skip "Need MDS version at least 2.11.56"
24602
24603         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24604                 error "failed to create DoM-only file $DIR/$tfile"
24605         touch $DIR/$tfile || error "touch $tfile failed"
24606         check_som_nodata $DIR/$tfile
24607
24608         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24609                 error "write $tfile failed"
24610         check_som_nodata $DIR/$tfile
24611
24612         $TRUNCATE $DIR/$tfile 1234
24613         check_som_nodata $DIR/$tfile
24614
24615         $TRUNCATE $DIR/$tfile 4097
24616         check_som_nodata $DIR/$file
24617 }
24618 run_test 809 "Verify no SOM xattr store for DoM-only files"
24619
24620 test_810() {
24621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24622         $GSS && skip_env "could not run with gss"
24623         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24624                 skip "OST < 2.12.58 doesn't align checksum"
24625
24626         set_checksums 1
24627         stack_trap "set_checksums $ORIG_CSUM" EXIT
24628         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24629
24630         local csum
24631         local before
24632         local after
24633         for csum in $CKSUM_TYPES; do
24634                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24635                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24636                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24637                         eval set -- $i
24638                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24639                         before=$(md5sum $DIR/$tfile)
24640                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24641                         after=$(md5sum $DIR/$tfile)
24642                         [ "$before" == "$after" ] ||
24643                                 error "$csum: $before != $after bs=$1 seek=$2"
24644                 done
24645         done
24646 }
24647 run_test 810 "partial page writes on ZFS (LU-11663)"
24648
24649 test_812a() {
24650         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24651                 skip "OST < 2.12.51 doesn't support this fail_loc"
24652
24653         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24654         # ensure ost1 is connected
24655         stat $DIR/$tfile >/dev/null || error "can't stat"
24656         wait_osc_import_state client ost1 FULL
24657         # no locks, no reqs to let the connection idle
24658         cancel_lru_locks osc
24659
24660         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24661 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24662         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24663         wait_osc_import_state client ost1 CONNECTING
24664         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24665
24666         stat $DIR/$tfile >/dev/null || error "can't stat file"
24667 }
24668 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24669
24670 test_812b() { # LU-12378
24671         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24672                 skip "OST < 2.12.51 doesn't support this fail_loc"
24673
24674         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24675         # ensure ost1 is connected
24676         stat $DIR/$tfile >/dev/null || error "can't stat"
24677         wait_osc_import_state client ost1 FULL
24678         # no locks, no reqs to let the connection idle
24679         cancel_lru_locks osc
24680
24681         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24682 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24683         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24684         wait_osc_import_state client ost1 CONNECTING
24685         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24686
24687         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24688         wait_osc_import_state client ost1 IDLE
24689 }
24690 run_test 812b "do not drop no resend request for idle connect"
24691
24692 test_813() {
24693         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24694         [ -z "$file_heat_sav" ] && skip "no file heat support"
24695
24696         local readsample
24697         local writesample
24698         local readbyte
24699         local writebyte
24700         local readsample1
24701         local writesample1
24702         local readbyte1
24703         local writebyte1
24704
24705         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24706         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24707
24708         $LCTL set_param -n llite.*.file_heat=1
24709         echo "Turn on file heat"
24710         echo "Period second: $period_second, Decay percentage: $decay_pct"
24711
24712         echo "QQQQ" > $DIR/$tfile
24713         echo "QQQQ" > $DIR/$tfile
24714         echo "QQQQ" > $DIR/$tfile
24715         cat $DIR/$tfile > /dev/null
24716         cat $DIR/$tfile > /dev/null
24717         cat $DIR/$tfile > /dev/null
24718         cat $DIR/$tfile > /dev/null
24719
24720         local out=$($LFS heat_get $DIR/$tfile)
24721
24722         $LFS heat_get $DIR/$tfile
24723         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24724         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24725         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24726         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24727
24728         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24729         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24730         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24731         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24732
24733         sleep $((period_second + 3))
24734         echo "Sleep $((period_second + 3)) seconds..."
24735         # The recursion formula to calculate the heat of the file f is as
24736         # follow:
24737         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24738         # Where Hi is the heat value in the period between time points i*I and
24739         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24740         # to the weight of Ci.
24741         out=$($LFS heat_get $DIR/$tfile)
24742         $LFS heat_get $DIR/$tfile
24743         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24744         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24745         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24746         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24747
24748         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24749                 error "read sample ($readsample) is wrong"
24750         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24751                 error "write sample ($writesample) is wrong"
24752         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24753                 error "read bytes ($readbyte) is wrong"
24754         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24755                 error "write bytes ($writebyte) is wrong"
24756
24757         echo "QQQQ" > $DIR/$tfile
24758         echo "QQQQ" > $DIR/$tfile
24759         echo "QQQQ" > $DIR/$tfile
24760         cat $DIR/$tfile > /dev/null
24761         cat $DIR/$tfile > /dev/null
24762         cat $DIR/$tfile > /dev/null
24763         cat $DIR/$tfile > /dev/null
24764
24765         sleep $((period_second + 3))
24766         echo "Sleep $((period_second + 3)) seconds..."
24767
24768         out=$($LFS heat_get $DIR/$tfile)
24769         $LFS heat_get $DIR/$tfile
24770         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24771         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24772         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24773         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24774
24775         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24776                 4 * $decay_pct) / 100") -eq 1 ] ||
24777                 error "read sample ($readsample1) is wrong"
24778         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24779                 3 * $decay_pct) / 100") -eq 1 ] ||
24780                 error "write sample ($writesample1) is wrong"
24781         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24782                 20 * $decay_pct) / 100") -eq 1 ] ||
24783                 error "read bytes ($readbyte1) is wrong"
24784         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24785                 15 * $decay_pct) / 100") -eq 1 ] ||
24786                 error "write bytes ($writebyte1) is wrong"
24787
24788         echo "Turn off file heat for the file $DIR/$tfile"
24789         $LFS heat_set -o $DIR/$tfile
24790
24791         echo "QQQQ" > $DIR/$tfile
24792         echo "QQQQ" > $DIR/$tfile
24793         echo "QQQQ" > $DIR/$tfile
24794         cat $DIR/$tfile > /dev/null
24795         cat $DIR/$tfile > /dev/null
24796         cat $DIR/$tfile > /dev/null
24797         cat $DIR/$tfile > /dev/null
24798
24799         out=$($LFS heat_get $DIR/$tfile)
24800         $LFS heat_get $DIR/$tfile
24801         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24802         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24803         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24804         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24805
24806         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24807         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24808         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24809         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24810
24811         echo "Trun on file heat for the file $DIR/$tfile"
24812         $LFS heat_set -O $DIR/$tfile
24813
24814         echo "QQQQ" > $DIR/$tfile
24815         echo "QQQQ" > $DIR/$tfile
24816         echo "QQQQ" > $DIR/$tfile
24817         cat $DIR/$tfile > /dev/null
24818         cat $DIR/$tfile > /dev/null
24819         cat $DIR/$tfile > /dev/null
24820         cat $DIR/$tfile > /dev/null
24821
24822         out=$($LFS heat_get $DIR/$tfile)
24823         $LFS heat_get $DIR/$tfile
24824         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24825         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24826         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24827         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24828
24829         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24830         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24831         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24832         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24833
24834         $LFS heat_set -c $DIR/$tfile
24835         $LCTL set_param -n llite.*.file_heat=0
24836         echo "Turn off file heat support for the Lustre filesystem"
24837
24838         echo "QQQQ" > $DIR/$tfile
24839         echo "QQQQ" > $DIR/$tfile
24840         echo "QQQQ" > $DIR/$tfile
24841         cat $DIR/$tfile > /dev/null
24842         cat $DIR/$tfile > /dev/null
24843         cat $DIR/$tfile > /dev/null
24844         cat $DIR/$tfile > /dev/null
24845
24846         out=$($LFS heat_get $DIR/$tfile)
24847         $LFS heat_get $DIR/$tfile
24848         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24849         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24850         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24851         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24852
24853         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24854         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24855         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24856         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24857
24858         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24859         rm -f $DIR/$tfile
24860 }
24861 run_test 813 "File heat verfication"
24862
24863 test_814()
24864 {
24865         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24866         echo -n y >> $DIR/$tfile
24867         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24868         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24869 }
24870 run_test 814 "sparse cp works as expected (LU-12361)"
24871
24872 test_815()
24873 {
24874         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24875         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24876 }
24877 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24878
24879 test_816() {
24880         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24881         # ensure ost1 is connected
24882         stat $DIR/$tfile >/dev/null || error "can't stat"
24883         wait_osc_import_state client ost1 FULL
24884         # no locks, no reqs to let the connection idle
24885         cancel_lru_locks osc
24886         lru_resize_disable osc
24887         local before
24888         local now
24889         before=$($LCTL get_param -n \
24890                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24891
24892         wait_osc_import_state client ost1 IDLE
24893         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24894         now=$($LCTL get_param -n \
24895               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24896         [ $before == $now ] || error "lru_size changed $before != $now"
24897 }
24898 run_test 816 "do not reset lru_resize on idle reconnect"
24899
24900 cleanup_817() {
24901         umount $tmpdir
24902         exportfs -u localhost:$DIR/nfsexp
24903         rm -rf $DIR/nfsexp
24904 }
24905
24906 test_817() {
24907         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24908
24909         mkdir -p $DIR/nfsexp
24910         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24911                 error "failed to export nfs"
24912
24913         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24914         stack_trap cleanup_817 EXIT
24915
24916         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24917                 error "failed to mount nfs to $tmpdir"
24918
24919         cp /bin/true $tmpdir
24920         $DIR/nfsexp/true || error "failed to execute 'true' command"
24921 }
24922 run_test 817 "nfsd won't cache write lock for exec file"
24923
24924 test_818() {
24925         mkdir $DIR/$tdir
24926         $LFS setstripe -c1 -i0 $DIR/$tfile
24927         $LFS setstripe -c1 -i1 $DIR/$tfile
24928         stop $SINGLEMDS
24929         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24930         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24931         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24932                 error "start $SINGLEMDS failed"
24933         rm -rf $DIR/$tdir
24934 }
24935 run_test 818 "unlink with failed llog"
24936
24937 test_819a() {
24938         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24939         cancel_lru_locks osc
24940         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24941         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24942         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24943         rm -f $TDIR/$tfile
24944 }
24945 run_test 819a "too big niobuf in read"
24946
24947 test_819b() {
24948         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24949         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24951         cancel_lru_locks osc
24952         sleep 1
24953         rm -f $TDIR/$tfile
24954 }
24955 run_test 819b "too big niobuf in write"
24956
24957
24958 function test_820_start_ost() {
24959         sleep 5
24960
24961         for num in $(seq $OSTCOUNT); do
24962                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24963         done
24964 }
24965
24966 test_820() {
24967         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24968
24969         mkdir $DIR/$tdir
24970         umount_client $MOUNT || error "umount failed"
24971         for num in $(seq $OSTCOUNT); do
24972                 stop ost$num
24973         done
24974
24975         # mount client with no active OSTs
24976         # so that the client can't initialize max LOV EA size
24977         # from OSC notifications
24978         mount_client $MOUNT || error "mount failed"
24979         # delay OST starting to keep this 0 max EA size for a while
24980         test_820_start_ost &
24981
24982         # create a directory on MDS2
24983         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24984                 error "Failed to create directory"
24985         # open intent should update default EA size
24986         # see mdc_update_max_ea_from_body()
24987         # notice this is the very first RPC to MDS2
24988         cp /etc/services $DIR/$tdir/mds2 ||
24989                 error "Failed to copy files to mds$n"
24990 }
24991 run_test 820 "update max EA from open intent"
24992
24993 #
24994 # tests that do cleanup/setup should be run at the end
24995 #
24996
24997 test_900() {
24998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24999         local ls
25000
25001         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25002         $LCTL set_param fail_loc=0x903
25003
25004         cancel_lru_locks MGC
25005
25006         FAIL_ON_ERROR=true cleanup
25007         FAIL_ON_ERROR=true setup
25008 }
25009 run_test 900 "umount should not race with any mgc requeue thread"
25010
25011 # LUS-6253/LU-11185
25012 test_901() {
25013         local oldc
25014         local newc
25015         local olds
25016         local news
25017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25018
25019         # some get_param have a bug to handle dot in param name
25020         cancel_lru_locks MGC
25021         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25022         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25023         umount_client $MOUNT || error "umount failed"
25024         mount_client $MOUNT || error "mount failed"
25025         cancel_lru_locks MGC
25026         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25027         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25028
25029         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25030         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25031
25032         return 0
25033 }
25034 run_test 901 "don't leak a mgc lock on client umount"
25035
25036 # LU-13377
25037 test_902() {
25038         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25039                 skip "client does not have LU-13377 fix"
25040         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25041         $LCTL set_param fail_loc=0x1415
25042         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25043         cancel_lru_locks osc
25044         rm -f $DIR/$tfile
25045 }
25046 run_test 902 "test short write doesn't hang lustre"
25047
25048 complete $SECONDS
25049 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25050 check_and_cleanup_lustre
25051 if [ "$I_MOUNTED" != "yes" ]; then
25052         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25053 fi
25054 exit_status