Whamcloud - gitweb
LU-14054 utils: add --exit-on-close to ofd_access_log_reader
[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         {
8393                 echo "file2_stripe_size: '$file2_stripe_size'"
8394                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8395                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8396         }
8397
8398         local dir3=$MOUNT/$tdir-3
8399         mkdir $dir3 || error "mkdir $dir3 failed"
8400         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8401         # the root layout, which is the actual default layout that will be used
8402         # when new files are created in $dir3.
8403         local dir3_layout=$(get_layout_param $dir3)
8404         local root_dir_layout=$(get_layout_param $MOUNT)
8405         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8406         {
8407                 echo "dir3_layout: '$dir3_layout'"
8408                 echo "root_dir_layout: '$root_dir_layout'"
8409                 error "$dir3 should show the default layout from $MOUNT"
8410         }
8411
8412         # set OST pool on root directory
8413         local pool=$TESTNAME
8414         pool_add $pool || error "add $pool failed"
8415         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8416                 error "add targets to $pool failed"
8417
8418         $LFS setstripe -p $pool $MOUNT ||
8419                 error "set OST pool on $MOUNT failed"
8420
8421         # new file created in $dir3 should inherit the pool from
8422         # the filesystem default
8423         local file3=$dir3/$tfile-3
8424         touch $file3 || error "touch $file3 failed"
8425
8426         local file3_pool=$($LFS getstripe -p $file3)
8427         [[ "$file3_pool" = "$pool" ]] ||
8428                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8429
8430         local dir4=$MOUNT/$tdir-4
8431         mkdir $dir4 || error "mkdir $dir4 failed"
8432         local dir4_layout=$(get_layout_param $dir4)
8433         root_dir_layout=$(get_layout_param $MOUNT)
8434         echo "$LFS getstripe -d $dir4"
8435         $LFS getstripe -d $dir4
8436         echo "$LFS getstripe -d $MOUNT"
8437         $LFS getstripe -d $MOUNT
8438         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8439         {
8440                 echo "dir4_layout: '$dir4_layout'"
8441                 echo "root_dir_layout: '$root_dir_layout'"
8442                 error "$dir4 should show the default layout from $MOUNT"
8443         }
8444
8445         # new file created in $dir4 should inherit the pool from
8446         # the filesystem default
8447         local file4=$dir4/$tfile-4
8448         touch $file4 || error "touch $file4 failed"
8449
8450         local file4_pool=$($LFS getstripe -p $file4)
8451         [[ "$file4_pool" = "$pool" ]] ||
8452                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8453
8454         # new subdirectory under non-root directory should inherit
8455         # the default layout from its parent directory
8456         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8457                 error "set directory layout on $dir4 failed"
8458
8459         local dir5=$dir4/$tdir-5
8460         mkdir $dir5 || error "mkdir $dir5 failed"
8461
8462         dir4_layout=$(get_layout_param $dir4)
8463         local dir5_layout=$(get_layout_param $dir5)
8464         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8465         {
8466                 echo "dir4_layout: '$dir4_layout'"
8467                 echo "dir5_layout: '$dir5_layout'"
8468                 error "$dir5 should inherit the default layout from $dir4"
8469         }
8470
8471         # though subdir under ROOT doesn't inherit default layout, but
8472         # its sub dir/file should be created with default layout.
8473         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8474         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8475                 skip "Need MDS version at least 2.12.59"
8476
8477         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8478         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8479         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8480
8481         if [ $default_lmv_hash == "none" ]; then
8482                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8483         else
8484                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8485                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8486         fi
8487
8488         $LFS setdirstripe -D -c 2 $MOUNT ||
8489                 error "setdirstripe -D -c 2 failed"
8490         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8491         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8492         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8493 }
8494 run_test 65n "don't inherit default layout from root for new subdirectories"
8495
8496 # bug 2543 - update blocks count on client
8497 test_66() {
8498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8499
8500         COUNT=${COUNT:-8}
8501         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8502         sync; sync_all_data; sync; sync_all_data
8503         cancel_lru_locks osc
8504         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8505         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8506 }
8507 run_test 66 "update inode blocks count on client ==============="
8508
8509 meminfo() {
8510         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8511 }
8512
8513 swap_used() {
8514         swapon -s | awk '($1 == "'$1'") { print $4 }'
8515 }
8516
8517 # bug5265, obdfilter oa2dentry return -ENOENT
8518 # #define OBD_FAIL_SRV_ENOENT 0x217
8519 test_69() {
8520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8521         remote_ost_nodsh && skip "remote OST with nodsh"
8522
8523         f="$DIR/$tfile"
8524         $LFS setstripe -c 1 -i 0 $f
8525
8526         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8527
8528         do_facet ost1 lctl set_param fail_loc=0x217
8529         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8530         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8531
8532         do_facet ost1 lctl set_param fail_loc=0
8533         $DIRECTIO write $f 0 2 || error "write error"
8534
8535         cancel_lru_locks osc
8536         $DIRECTIO read $f 0 1 || error "read error"
8537
8538         do_facet ost1 lctl set_param fail_loc=0x217
8539         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8540
8541         do_facet ost1 lctl set_param fail_loc=0
8542         rm -f $f
8543 }
8544 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8545
8546 test_71() {
8547         test_mkdir $DIR/$tdir
8548         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8549         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8550 }
8551 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8552
8553 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8555         [ "$RUNAS_ID" = "$UID" ] &&
8556                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8557         # Check that testing environment is properly set up. Skip if not
8558         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8559                 skip_env "User $RUNAS_ID does not exist - skipping"
8560
8561         touch $DIR/$tfile
8562         chmod 777 $DIR/$tfile
8563         chmod ug+s $DIR/$tfile
8564         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8565                 error "$RUNAS dd $DIR/$tfile failed"
8566         # See if we are still setuid/sgid
8567         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8568                 error "S/gid is not dropped on write"
8569         # Now test that MDS is updated too
8570         cancel_lru_locks mdc
8571         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8572                 error "S/gid is not dropped on MDS"
8573         rm -f $DIR/$tfile
8574 }
8575 run_test 72a "Test that remove suid works properly (bug5695) ===="
8576
8577 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8578         local perm
8579
8580         [ "$RUNAS_ID" = "$UID" ] &&
8581                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8582         [ "$RUNAS_ID" -eq 0 ] &&
8583                 skip_env "RUNAS_ID = 0 -- skipping"
8584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8585         # Check that testing environment is properly set up. Skip if not
8586         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8587                 skip_env "User $RUNAS_ID does not exist - skipping"
8588
8589         touch $DIR/${tfile}-f{g,u}
8590         test_mkdir $DIR/${tfile}-dg
8591         test_mkdir $DIR/${tfile}-du
8592         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8593         chmod g+s $DIR/${tfile}-{f,d}g
8594         chmod u+s $DIR/${tfile}-{f,d}u
8595         for perm in 777 2777 4777; do
8596                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8597                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8598                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8599                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8600         done
8601         true
8602 }
8603 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8604
8605 # bug 3462 - multiple simultaneous MDC requests
8606 test_73() {
8607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8608
8609         test_mkdir $DIR/d73-1
8610         test_mkdir $DIR/d73-2
8611         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8612         pid1=$!
8613
8614         lctl set_param fail_loc=0x80000129
8615         $MULTIOP $DIR/d73-1/f73-2 Oc &
8616         sleep 1
8617         lctl set_param fail_loc=0
8618
8619         $MULTIOP $DIR/d73-2/f73-3 Oc &
8620         pid3=$!
8621
8622         kill -USR1 $pid1
8623         wait $pid1 || return 1
8624
8625         sleep 25
8626
8627         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8628         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8629         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8630
8631         rm -rf $DIR/d73-*
8632 }
8633 run_test 73 "multiple MDC requests (should not deadlock)"
8634
8635 test_74a() { # bug 6149, 6184
8636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8637
8638         touch $DIR/f74a
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 any lock that won't be difficult - lookup works.
8645         ls $DIR/f74a
8646         $LCTL set_param fail_loc=0
8647         rm -f $DIR/f74a
8648         true
8649 }
8650 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8651
8652 test_74b() { # bug 13310
8653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8654
8655         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8656         #
8657         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8658         # will spin in a tight reconnection loop
8659         $LCTL set_param fail_loc=0x8000030e
8660         # get a "difficult" lock
8661         touch $DIR/f74b
8662         $LCTL set_param fail_loc=0
8663         rm -f $DIR/f74b
8664         true
8665 }
8666 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8667
8668 test_74c() {
8669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8670
8671         #define OBD_FAIL_LDLM_NEW_LOCK
8672         $LCTL set_param fail_loc=0x319
8673         touch $DIR/$tfile && error "touch successful"
8674         $LCTL set_param fail_loc=0
8675         true
8676 }
8677 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8678
8679 slab_lic=/sys/kernel/slab/lustre_inode_cache
8680 num_objects() {
8681         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8682         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8683                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8684 }
8685
8686 test_76a() { # Now for b=20433, added originally in b=1443
8687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8688
8689         cancel_lru_locks osc
8690         # there may be some slab objects cached per core
8691         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8692         local before=$(num_objects)
8693         local count=$((512 * cpus))
8694         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8695         local margin=$((count / 10))
8696         if [[ -f $slab_lic/aliases ]]; then
8697                 local aliases=$(cat $slab_lic/aliases)
8698                 (( aliases > 0 )) && margin=$((margin * aliases))
8699         fi
8700
8701         echo "before slab objects: $before"
8702         for i in $(seq $count); do
8703                 touch $DIR/$tfile
8704                 rm -f $DIR/$tfile
8705         done
8706         cancel_lru_locks osc
8707         local after=$(num_objects)
8708         echo "created: $count, after slab objects: $after"
8709         # shared slab counts are not very accurate, allow significant margin
8710         # the main goal is that the cache growth is not permanently > $count
8711         while (( after > before + margin )); do
8712                 sleep 1
8713                 after=$(num_objects)
8714                 wait=$((wait + 1))
8715                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8716                 if (( wait > 60 )); then
8717                         error "inode slab grew from $before+$margin to $after"
8718                 fi
8719         done
8720 }
8721 run_test 76a "confirm clients recycle inodes properly ===="
8722
8723 test_76b() {
8724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8725         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8726
8727         local count=512
8728         local before=$(num_objects)
8729
8730         for i in $(seq $count); do
8731                 mkdir $DIR/$tdir
8732                 rmdir $DIR/$tdir
8733         done
8734
8735         local after=$(num_objects)
8736         local wait=0
8737
8738         while (( after > before )); do
8739                 sleep 1
8740                 after=$(num_objects)
8741                 wait=$((wait + 1))
8742                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8743                 if (( wait > 60 )); then
8744                         error "inode slab grew from $before to $after"
8745                 fi
8746         done
8747
8748         echo "slab objects before: $before, after: $after"
8749 }
8750 run_test 76b "confirm clients recycle directory inodes properly ===="
8751
8752 export ORIG_CSUM=""
8753 set_checksums()
8754 {
8755         # Note: in sptlrpc modes which enable its own bulk checksum, the
8756         # original crc32_le bulk checksum will be automatically disabled,
8757         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8758         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8759         # In this case set_checksums() will not be no-op, because sptlrpc
8760         # bulk checksum will be enabled all through the test.
8761
8762         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8763         lctl set_param -n osc.*.checksums $1
8764         return 0
8765 }
8766
8767 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8768                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8769 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8770                              tr -d [] | head -n1)}
8771 set_checksum_type()
8772 {
8773         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8774         rc=$?
8775         log "set checksum type to $1, rc = $rc"
8776         return $rc
8777 }
8778
8779 get_osc_checksum_type()
8780 {
8781         # arugment 1: OST name, like OST0000
8782         ost=$1
8783         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8784                         sed 's/.*\[\(.*\)\].*/\1/g')
8785         rc=$?
8786         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8787         echo $checksum_type
8788 }
8789
8790 F77_TMP=$TMP/f77-temp
8791 F77SZ=8
8792 setup_f77() {
8793         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8794                 error "error writing to $F77_TMP"
8795 }
8796
8797 test_77a() { # bug 10889
8798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8799         $GSS && skip_env "could not run with gss"
8800
8801         [ ! -f $F77_TMP ] && setup_f77
8802         set_checksums 1
8803         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8804         set_checksums 0
8805         rm -f $DIR/$tfile
8806 }
8807 run_test 77a "normal checksum read/write operation"
8808
8809 test_77b() { # bug 10889
8810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8811         $GSS && skip_env "could not run with gss"
8812
8813         [ ! -f $F77_TMP ] && setup_f77
8814         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8815         $LCTL set_param fail_loc=0x80000409
8816         set_checksums 1
8817
8818         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8819                 error "dd error: $?"
8820         $LCTL set_param fail_loc=0
8821
8822         for algo in $CKSUM_TYPES; do
8823                 cancel_lru_locks osc
8824                 set_checksum_type $algo
8825                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8826                 $LCTL set_param fail_loc=0x80000408
8827                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8828                 $LCTL set_param fail_loc=0
8829         done
8830         set_checksums 0
8831         set_checksum_type $ORIG_CSUM_TYPE
8832         rm -f $DIR/$tfile
8833 }
8834 run_test 77b "checksum error on client write, read"
8835
8836 cleanup_77c() {
8837         trap 0
8838         set_checksums 0
8839         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8840         $check_ost &&
8841                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8842         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8843         $check_ost && [ -n "$ost_file_prefix" ] &&
8844                 do_facet ost1 rm -f ${ost_file_prefix}\*
8845 }
8846
8847 test_77c() {
8848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8849         $GSS && skip_env "could not run with gss"
8850         remote_ost_nodsh && skip "remote OST with nodsh"
8851
8852         local bad1
8853         local osc_file_prefix
8854         local osc_file
8855         local check_ost=false
8856         local ost_file_prefix
8857         local ost_file
8858         local orig_cksum
8859         local dump_cksum
8860         local fid
8861
8862         # ensure corruption will occur on first OSS/OST
8863         $LFS setstripe -i 0 $DIR/$tfile
8864
8865         [ ! -f $F77_TMP ] && setup_f77
8866         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8867                 error "dd write error: $?"
8868         fid=$($LFS path2fid $DIR/$tfile)
8869
8870         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8871         then
8872                 check_ost=true
8873                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8874                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8875         else
8876                 echo "OSS do not support bulk pages dump upon error"
8877         fi
8878
8879         osc_file_prefix=$($LCTL get_param -n debug_path)
8880         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8881
8882         trap cleanup_77c EXIT
8883
8884         set_checksums 1
8885         # enable bulk pages dump upon error on Client
8886         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8887         # enable bulk pages dump upon error on OSS
8888         $check_ost &&
8889                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8890
8891         # flush Client cache to allow next read to reach OSS
8892         cancel_lru_locks osc
8893
8894         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8895         $LCTL set_param fail_loc=0x80000408
8896         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8897         $LCTL set_param fail_loc=0
8898
8899         rm -f $DIR/$tfile
8900
8901         # check cksum dump on Client
8902         osc_file=$(ls ${osc_file_prefix}*)
8903         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8904         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8905         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8906         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8907         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8908                      cksum)
8909         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8910         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8911                 error "dump content does not match on Client"
8912
8913         $check_ost || skip "No need to check cksum dump on OSS"
8914
8915         # check cksum dump on OSS
8916         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8917         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8918         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8919         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8920         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8921                 error "dump content does not match on OSS"
8922
8923         cleanup_77c
8924 }
8925 run_test 77c "checksum error on client read with debug"
8926
8927 test_77d() { # bug 10889
8928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8929         $GSS && skip_env "could not run with gss"
8930
8931         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8932         $LCTL set_param fail_loc=0x80000409
8933         set_checksums 1
8934         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8935                 error "direct write: rc=$?"
8936         $LCTL set_param fail_loc=0
8937         set_checksums 0
8938
8939         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8940         $LCTL set_param fail_loc=0x80000408
8941         set_checksums 1
8942         cancel_lru_locks osc
8943         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8944                 error "direct read: rc=$?"
8945         $LCTL set_param fail_loc=0
8946         set_checksums 0
8947 }
8948 run_test 77d "checksum error on OST direct write, read"
8949
8950 test_77f() { # bug 10889
8951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8952         $GSS && skip_env "could not run with gss"
8953
8954         set_checksums 1
8955         for algo in $CKSUM_TYPES; do
8956                 cancel_lru_locks osc
8957                 set_checksum_type $algo
8958                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8959                 $LCTL set_param fail_loc=0x409
8960                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8961                         error "direct write succeeded"
8962                 $LCTL set_param fail_loc=0
8963         done
8964         set_checksum_type $ORIG_CSUM_TYPE
8965         set_checksums 0
8966 }
8967 run_test 77f "repeat checksum error on write (expect error)"
8968
8969 test_77g() { # bug 10889
8970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8971         $GSS && skip_env "could not run with gss"
8972         remote_ost_nodsh && skip "remote OST with nodsh"
8973
8974         [ ! -f $F77_TMP ] && setup_f77
8975
8976         local file=$DIR/$tfile
8977         stack_trap "rm -f $file" EXIT
8978
8979         $LFS setstripe -c 1 -i 0 $file
8980         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8981         do_facet ost1 lctl set_param fail_loc=0x8000021a
8982         set_checksums 1
8983         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8984                 error "write error: rc=$?"
8985         do_facet ost1 lctl set_param fail_loc=0
8986         set_checksums 0
8987
8988         cancel_lru_locks osc
8989         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8990         do_facet ost1 lctl set_param fail_loc=0x8000021b
8991         set_checksums 1
8992         cmp $F77_TMP $file || error "file compare failed"
8993         do_facet ost1 lctl set_param fail_loc=0
8994         set_checksums 0
8995 }
8996 run_test 77g "checksum error on OST write, read"
8997
8998 test_77k() { # LU-10906
8999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9000         $GSS && skip_env "could not run with gss"
9001
9002         local cksum_param="osc.$FSNAME*.checksums"
9003         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9004         local checksum
9005         local i
9006
9007         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9008         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9009         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9010
9011         for i in 0 1; do
9012                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9013                         error "failed to set checksum=$i on MGS"
9014                 wait_update $HOSTNAME "$get_checksum" $i
9015                 #remount
9016                 echo "remount client, checksum should be $i"
9017                 remount_client $MOUNT || error "failed to remount client"
9018                 checksum=$(eval $get_checksum)
9019                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9020         done
9021         # remove persistent param to avoid races with checksum mountopt below
9022         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9023                 error "failed to delete checksum on MGS"
9024
9025         for opt in "checksum" "nochecksum"; do
9026                 #remount with mount option
9027                 echo "remount client with option $opt, checksum should be $i"
9028                 umount_client $MOUNT || error "failed to umount client"
9029                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9030                         error "failed to mount client with option '$opt'"
9031                 checksum=$(eval $get_checksum)
9032                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9033                 i=$((i - 1))
9034         done
9035
9036         remount_client $MOUNT || error "failed to remount client"
9037 }
9038 run_test 77k "enable/disable checksum correctly"
9039
9040 test_77l() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         $GSS && skip_env "could not run with gss"
9043
9044         set_checksums 1
9045         stack_trap "set_checksums $ORIG_CSUM" EXIT
9046         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9047
9048         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9049
9050         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9051         for algo in $CKSUM_TYPES; do
9052                 set_checksum_type $algo || error "fail to set checksum type $algo"
9053                 osc_algo=$(get_osc_checksum_type OST0000)
9054                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9055
9056                 # no locks, no reqs to let the connection idle
9057                 cancel_lru_locks osc
9058                 lru_resize_disable osc
9059                 wait_osc_import_state client ost1 IDLE
9060
9061                 # ensure ost1 is connected
9062                 stat $DIR/$tfile >/dev/null || error "can't stat"
9063                 wait_osc_import_state client ost1 FULL
9064
9065                 osc_algo=$(get_osc_checksum_type OST0000)
9066                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9067         done
9068         return 0
9069 }
9070 run_test 77l "preferred checksum type is remembered after reconnected"
9071
9072 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9073 rm -f $F77_TMP
9074 unset F77_TMP
9075
9076 cleanup_test_78() {
9077         trap 0
9078         rm -f $DIR/$tfile
9079 }
9080
9081 test_78() { # bug 10901
9082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9083         remote_ost || skip_env "local OST"
9084
9085         NSEQ=5
9086         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9087         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9088         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9089         echo "MemTotal: $MEMTOTAL"
9090
9091         # reserve 256MB of memory for the kernel and other running processes,
9092         # and then take 1/2 of the remaining memory for the read/write buffers.
9093         if [ $MEMTOTAL -gt 512 ] ;then
9094                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9095         else
9096                 # for those poor memory-starved high-end clusters...
9097                 MEMTOTAL=$((MEMTOTAL / 2))
9098         fi
9099         echo "Mem to use for directio: $MEMTOTAL"
9100
9101         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9102         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9103         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9104         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9105                 head -n1)
9106         echo "Smallest OST: $SMALLESTOST"
9107         [[ $SMALLESTOST -lt 10240 ]] &&
9108                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9109
9110         trap cleanup_test_78 EXIT
9111
9112         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9113                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9114
9115         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9116         echo "File size: $F78SIZE"
9117         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9118         for i in $(seq 1 $NSEQ); do
9119                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9120                 echo directIO rdwr round $i of $NSEQ
9121                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9122         done
9123
9124         cleanup_test_78
9125 }
9126 run_test 78 "handle large O_DIRECT writes correctly ============"
9127
9128 test_79() { # bug 12743
9129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9130
9131         wait_delete_completed
9132
9133         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9134         BKFREE=$(calc_osc_kbytes kbytesfree)
9135         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9136
9137         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9138         DFTOTAL=`echo $STRING | cut -d, -f1`
9139         DFUSED=`echo $STRING  | cut -d, -f2`
9140         DFAVAIL=`echo $STRING | cut -d, -f3`
9141         DFFREE=$(($DFTOTAL - $DFUSED))
9142
9143         ALLOWANCE=$((64 * $OSTCOUNT))
9144
9145         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9146            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9147                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9148         fi
9149         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9150            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9151                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9152         fi
9153         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9154            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9155                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9156         fi
9157 }
9158 run_test 79 "df report consistency check ======================="
9159
9160 test_80() { # bug 10718
9161         remote_ost_nodsh && skip "remote OST with nodsh"
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163
9164         # relax strong synchronous semantics for slow backends like ZFS
9165         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9166                 local soc="obdfilter.*.sync_lock_cancel"
9167                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9168
9169                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9170                 if [ -z "$save" ]; then
9171                         soc="obdfilter.*.sync_on_lock_cancel"
9172                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9173                 fi
9174
9175                 if [ "$save" != "never" ]; then
9176                         local hosts=$(comma_list $(osts_nodes))
9177
9178                         do_nodes $hosts $LCTL set_param $soc=never
9179                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9180                 fi
9181         fi
9182
9183         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9184         sync; sleep 1; sync
9185         local before=$(date +%s)
9186         cancel_lru_locks osc
9187         local after=$(date +%s)
9188         local diff=$((after - before))
9189         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9190
9191         rm -f $DIR/$tfile
9192 }
9193 run_test 80 "Page eviction is equally fast at high offsets too"
9194
9195 test_81a() { # LU-456
9196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9197         remote_ost_nodsh && skip "remote OST with nodsh"
9198
9199         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9200         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9201         do_facet ost1 lctl set_param fail_loc=0x80000228
9202
9203         # write should trigger a retry and success
9204         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9205         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9206         RC=$?
9207         if [ $RC -ne 0 ] ; then
9208                 error "write should success, but failed for $RC"
9209         fi
9210 }
9211 run_test 81a "OST should retry write when get -ENOSPC ==============="
9212
9213 test_81b() { # LU-456
9214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9215         remote_ost_nodsh && skip "remote OST with nodsh"
9216
9217         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9218         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9219         do_facet ost1 lctl set_param fail_loc=0x228
9220
9221         # write should retry several times and return -ENOSPC finally
9222         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9223         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9224         RC=$?
9225         ENOSPC=28
9226         if [ $RC -ne $ENOSPC ] ; then
9227                 error "dd should fail for -ENOSPC, but succeed."
9228         fi
9229 }
9230 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9231
9232 test_99() {
9233         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9234
9235         test_mkdir $DIR/$tdir.cvsroot
9236         chown $RUNAS_ID $DIR/$tdir.cvsroot
9237
9238         cd $TMP
9239         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9240
9241         cd /etc/init.d
9242         # some versions of cvs import exit(1) when asked to import links or
9243         # files they can't read.  ignore those files.
9244         local toignore=$(find . -type l -printf '-I %f\n' -o \
9245                          ! -perm /4 -printf '-I %f\n')
9246         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9247                 $tdir.reposname vtag rtag
9248
9249         cd $DIR
9250         test_mkdir $DIR/$tdir.reposname
9251         chown $RUNAS_ID $DIR/$tdir.reposname
9252         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9253
9254         cd $DIR/$tdir.reposname
9255         $RUNAS touch foo99
9256         $RUNAS cvs add -m 'addmsg' foo99
9257         $RUNAS cvs update
9258         $RUNAS cvs commit -m 'nomsg' foo99
9259         rm -fr $DIR/$tdir.cvsroot
9260 }
9261 run_test 99 "cvs strange file/directory operations"
9262
9263 test_100() {
9264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9265         [[ "$NETTYPE" =~ tcp ]] ||
9266                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9267         remote_ost_nodsh && skip "remote OST with nodsh"
9268         remote_mds_nodsh && skip "remote MDS with nodsh"
9269         remote_servers ||
9270                 skip "useless for local single node setup"
9271
9272         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9273                 [ "$PROT" != "tcp" ] && continue
9274                 RPORT=$(echo $REMOTE | cut -d: -f2)
9275                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9276
9277                 rc=0
9278                 LPORT=`echo $LOCAL | cut -d: -f2`
9279                 if [ $LPORT -ge 1024 ]; then
9280                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9281                         netstat -tna
9282                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9283                 fi
9284         done
9285         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9286 }
9287 run_test 100 "check local port using privileged port ==========="
9288
9289 function get_named_value()
9290 {
9291     local tag
9292
9293     tag=$1
9294     while read ;do
9295         line=$REPLY
9296         case $line in
9297         $tag*)
9298             echo $line | sed "s/^$tag[ ]*//"
9299             break
9300             ;;
9301         esac
9302     done
9303 }
9304
9305 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9306                    awk '/^max_cached_mb/ { print $2 }')
9307
9308 cleanup_101a() {
9309         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9310         trap 0
9311 }
9312
9313 test_101a() {
9314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9315
9316         local s
9317         local discard
9318         local nreads=10000
9319         local cache_limit=32
9320
9321         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9322         trap cleanup_101a EXIT
9323         $LCTL set_param -n llite.*.read_ahead_stats 0
9324         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9325
9326         #
9327         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9328         #
9329         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9330         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9331
9332         discard=0
9333         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9334                 get_named_value 'read but discarded' | cut -d" " -f1); do
9335                         discard=$(($discard + $s))
9336         done
9337         cleanup_101a
9338
9339         $LCTL get_param osc.*-osc*.rpc_stats
9340         $LCTL get_param llite.*.read_ahead_stats
9341
9342         # Discard is generally zero, but sometimes a few random reads line up
9343         # and trigger larger readahead, which is wasted & leads to discards.
9344         if [[ $(($discard)) -gt $nreads ]]; then
9345                 error "too many ($discard) discarded pages"
9346         fi
9347         rm -f $DIR/$tfile || true
9348 }
9349 run_test 101a "check read-ahead for random reads"
9350
9351 setup_test101bc() {
9352         test_mkdir $DIR/$tdir
9353         local ssize=$1
9354         local FILE_LENGTH=$2
9355         STRIPE_OFFSET=0
9356
9357         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9358
9359         local list=$(comma_list $(osts_nodes))
9360         set_osd_param $list '' read_cache_enable 0
9361         set_osd_param $list '' writethrough_cache_enable 0
9362
9363         trap cleanup_test101bc EXIT
9364         # prepare the read-ahead file
9365         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9366
9367         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9368                                 count=$FILE_SIZE_MB 2> /dev/null
9369
9370 }
9371
9372 cleanup_test101bc() {
9373         trap 0
9374         rm -rf $DIR/$tdir
9375         rm -f $DIR/$tfile
9376
9377         local list=$(comma_list $(osts_nodes))
9378         set_osd_param $list '' read_cache_enable 1
9379         set_osd_param $list '' writethrough_cache_enable 1
9380 }
9381
9382 calc_total() {
9383         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9384 }
9385
9386 ra_check_101() {
9387         local READ_SIZE=$1
9388         local STRIPE_SIZE=$2
9389         local FILE_LENGTH=$3
9390         local RA_INC=1048576
9391         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9392         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9393                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9394         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9395                         get_named_value 'read but discarded' |
9396                         cut -d" " -f1 | calc_total)
9397         if [[ $DISCARD -gt $discard_limit ]]; then
9398                 $LCTL get_param llite.*.read_ahead_stats
9399                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9400         else
9401                 echo "Read-ahead success for size ${READ_SIZE}"
9402         fi
9403 }
9404
9405 test_101b() {
9406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9407         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9408
9409         local STRIPE_SIZE=1048576
9410         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9411
9412         if [ $SLOW == "yes" ]; then
9413                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9414         else
9415                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9416         fi
9417
9418         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9419
9420         # prepare the read-ahead file
9421         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9422         cancel_lru_locks osc
9423         for BIDX in 2 4 8 16 32 64 128 256
9424         do
9425                 local BSIZE=$((BIDX*4096))
9426                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9427                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9428                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9429                 $LCTL set_param -n llite.*.read_ahead_stats 0
9430                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9431                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9432                 cancel_lru_locks osc
9433                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9434         done
9435         cleanup_test101bc
9436         true
9437 }
9438 run_test 101b "check stride-io mode read-ahead ================="
9439
9440 test_101c() {
9441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9442
9443         local STRIPE_SIZE=1048576
9444         local FILE_LENGTH=$((STRIPE_SIZE*100))
9445         local nreads=10000
9446         local rsize=65536
9447         local osc_rpc_stats
9448
9449         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9450
9451         cancel_lru_locks osc
9452         $LCTL set_param osc.*.rpc_stats 0
9453         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9454         $LCTL get_param osc.*.rpc_stats
9455         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9456                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9457                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9458                 local size
9459
9460                 if [ $lines -le 20 ]; then
9461                         echo "continue debug"
9462                         continue
9463                 fi
9464                 for size in 1 2 4 8; do
9465                         local rpc=$(echo "$stats" |
9466                                     awk '($1 == "'$size':") {print $2; exit; }')
9467                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9468                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9469                 done
9470                 echo "$osc_rpc_stats check passed!"
9471         done
9472         cleanup_test101bc
9473         true
9474 }
9475 run_test 101c "check stripe_size aligned read-ahead ================="
9476
9477 test_101d() {
9478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9479
9480         local file=$DIR/$tfile
9481         local sz_MB=${FILESIZE_101d:-80}
9482         local ra_MB=${READAHEAD_MB:-40}
9483
9484         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9485         [ $free_MB -lt $sz_MB ] &&
9486                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9487
9488         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9489         $LFS setstripe -c -1 $file || error "setstripe failed"
9490
9491         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9492         echo Cancel LRU locks on lustre client to flush the client cache
9493         cancel_lru_locks osc
9494
9495         echo Disable read-ahead
9496         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9497         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9498         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9499         $LCTL get_param -n llite.*.max_read_ahead_mb
9500
9501         echo "Reading the test file $file with read-ahead disabled"
9502         local sz_KB=$((sz_MB * 1024 / 4))
9503         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9504         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9505         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9506                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9507
9508         echo "Cancel LRU locks on lustre client to flush the client cache"
9509         cancel_lru_locks osc
9510         echo Enable read-ahead with ${ra_MB}MB
9511         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9512
9513         echo "Reading the test file $file with read-ahead enabled"
9514         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9515                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9516
9517         echo "read-ahead disabled time read $raOFF"
9518         echo "read-ahead enabled time read $raON"
9519
9520         rm -f $file
9521         wait_delete_completed
9522
9523         # use awk for this check instead of bash because it handles decimals
9524         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9525                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9526 }
9527 run_test 101d "file read with and without read-ahead enabled"
9528
9529 test_101e() {
9530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9531
9532         local file=$DIR/$tfile
9533         local size_KB=500  #KB
9534         local count=100
9535         local bsize=1024
9536
9537         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9538         local need_KB=$((count * size_KB))
9539         [[ $free_KB -le $need_KB ]] &&
9540                 skip_env "Need free space $need_KB, have $free_KB"
9541
9542         echo "Creating $count ${size_KB}K test files"
9543         for ((i = 0; i < $count; i++)); do
9544                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9545         done
9546
9547         echo "Cancel LRU locks on lustre client to flush the client cache"
9548         cancel_lru_locks $OSC
9549
9550         echo "Reset readahead stats"
9551         $LCTL set_param -n llite.*.read_ahead_stats 0
9552
9553         for ((i = 0; i < $count; i++)); do
9554                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9555         done
9556
9557         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9558                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9559
9560         for ((i = 0; i < $count; i++)); do
9561                 rm -rf $file.$i 2>/dev/null
9562         done
9563
9564         #10000 means 20% reads are missing in readahead
9565         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9566 }
9567 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9568
9569 test_101f() {
9570         which iozone || skip_env "no iozone installed"
9571
9572         local old_debug=$($LCTL get_param debug)
9573         old_debug=${old_debug#*=}
9574         $LCTL set_param debug="reada mmap"
9575
9576         # create a test file
9577         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9578
9579         echo Cancel LRU locks on lustre client to flush the client cache
9580         cancel_lru_locks osc
9581
9582         echo Reset readahead stats
9583         $LCTL set_param -n llite.*.read_ahead_stats 0
9584
9585         echo mmap read the file with small block size
9586         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9587                 > /dev/null 2>&1
9588
9589         echo checking missing pages
9590         $LCTL get_param llite.*.read_ahead_stats
9591         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9592                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9593
9594         $LCTL set_param debug="$old_debug"
9595         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9596         rm -f $DIR/$tfile
9597 }
9598 run_test 101f "check mmap read performance"
9599
9600 test_101g_brw_size_test() {
9601         local mb=$1
9602         local pages=$((mb * 1048576 / PAGE_SIZE))
9603         local file=$DIR/$tfile
9604
9605         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9606                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9607         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9608                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9609                         return 2
9610         done
9611
9612         stack_trap "rm -f $file" EXIT
9613         $LCTL set_param -n osc.*.rpc_stats=0
9614
9615         # 10 RPCs should be enough for the test
9616         local count=10
9617         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9618                 { error "dd write ${mb} MB blocks failed"; return 3; }
9619         cancel_lru_locks osc
9620         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9621                 { error "dd write ${mb} MB blocks failed"; return 4; }
9622
9623         # calculate number of full-sized read and write RPCs
9624         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9625                 sed -n '/pages per rpc/,/^$/p' |
9626                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9627                 END { print reads,writes }'))
9628         # allow one extra full-sized read RPC for async readahead
9629         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9630                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9631         [[ ${rpcs[1]} == $count ]] ||
9632                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9633 }
9634
9635 test_101g() {
9636         remote_ost_nodsh && skip "remote OST with nodsh"
9637
9638         local rpcs
9639         local osts=$(get_facets OST)
9640         local list=$(comma_list $(osts_nodes))
9641         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9642         local brw_size="obdfilter.*.brw_size"
9643
9644         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9645
9646         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9647
9648         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9649                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9650                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9651            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9652                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9653                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9654
9655                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9656                         suffix="M"
9657
9658                 if [[ $orig_mb -lt 16 ]]; then
9659                         save_lustre_params $osts "$brw_size" > $p
9660                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9661                                 error "set 16MB RPC size failed"
9662
9663                         echo "remount client to enable new RPC size"
9664                         remount_client $MOUNT || error "remount_client failed"
9665                 fi
9666
9667                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9668                 # should be able to set brw_size=12, but no rpc_stats for that
9669                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9670         fi
9671
9672         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9673
9674         if [[ $orig_mb -lt 16 ]]; then
9675                 restore_lustre_params < $p
9676                 remount_client $MOUNT || error "remount_client restore failed"
9677         fi
9678
9679         rm -f $p $DIR/$tfile
9680 }
9681 run_test 101g "Big bulk(4/16 MiB) readahead"
9682
9683 test_101h() {
9684         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9685
9686         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9687                 error "dd 70M file failed"
9688         echo Cancel LRU locks on lustre client to flush the client cache
9689         cancel_lru_locks osc
9690
9691         echo "Reset readahead stats"
9692         $LCTL set_param -n llite.*.read_ahead_stats 0
9693
9694         echo "Read 10M of data but cross 64M bundary"
9695         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9696         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9697                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9698         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9699         rm -f $p $DIR/$tfile
9700 }
9701 run_test 101h "Readahead should cover current read window"
9702
9703 test_101i() {
9704         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9705                 error "dd 10M file failed"
9706
9707         local max_per_file_mb=$($LCTL get_param -n \
9708                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9709         cancel_lru_locks osc
9710         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9711         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9712                 error "set max_read_ahead_per_file_mb to 1 failed"
9713
9714         echo "Reset readahead stats"
9715         $LCTL set_param llite.*.read_ahead_stats=0
9716
9717         dd if=$DIR/$tfile of=/dev/null bs=2M
9718
9719         $LCTL get_param llite.*.read_ahead_stats
9720         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9721                      awk '/misses/ { print $2 }')
9722         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9723         rm -f $DIR/$tfile
9724 }
9725 run_test 101i "allow current readahead to exceed reservation"
9726
9727 test_101j() {
9728         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9729                 error "setstripe $DIR/$tfile failed"
9730         local file_size=$((1048576 * 16))
9731         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9732         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9733
9734         echo Disable read-ahead
9735         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9736
9737         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9738         for blk in $PAGE_SIZE 1048576 $file_size; do
9739                 cancel_lru_locks osc
9740                 echo "Reset readahead stats"
9741                 $LCTL set_param -n llite.*.read_ahead_stats=0
9742                 local count=$(($file_size / $blk))
9743                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9744                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9745                              get_named_value 'failed to fast read' |
9746                              cut -d" " -f1 | calc_total)
9747                 $LCTL get_param -n llite.*.read_ahead_stats
9748                 [ $miss -eq $count ] || error "expected $count got $miss"
9749         done
9750
9751         rm -f $p $DIR/$tfile
9752 }
9753 run_test 101j "A complete read block should be submitted when no RA"
9754
9755 setup_test102() {
9756         test_mkdir $DIR/$tdir
9757         chown $RUNAS_ID $DIR/$tdir
9758         STRIPE_SIZE=65536
9759         STRIPE_OFFSET=1
9760         STRIPE_COUNT=$OSTCOUNT
9761         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9762
9763         trap cleanup_test102 EXIT
9764         cd $DIR
9765         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9766         cd $DIR/$tdir
9767         for num in 1 2 3 4; do
9768                 for count in $(seq 1 $STRIPE_COUNT); do
9769                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9770                                 local size=`expr $STRIPE_SIZE \* $num`
9771                                 local file=file"$num-$idx-$count"
9772                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9773                         done
9774                 done
9775         done
9776
9777         cd $DIR
9778         $1 tar cf $TMP/f102.tar $tdir --xattrs
9779 }
9780
9781 cleanup_test102() {
9782         trap 0
9783         rm -f $TMP/f102.tar
9784         rm -rf $DIR/d0.sanity/d102
9785 }
9786
9787 test_102a() {
9788         [ "$UID" != 0 ] && skip "must run as root"
9789         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9790                 skip_env "must have user_xattr"
9791
9792         [ -z "$(which setfattr 2>/dev/null)" ] &&
9793                 skip_env "could not find setfattr"
9794
9795         local testfile=$DIR/$tfile
9796
9797         touch $testfile
9798         echo "set/get xattr..."
9799         setfattr -n trusted.name1 -v value1 $testfile ||
9800                 error "setfattr -n trusted.name1=value1 $testfile failed"
9801         getfattr -n trusted.name1 $testfile 2> /dev/null |
9802           grep "trusted.name1=.value1" ||
9803                 error "$testfile missing trusted.name1=value1"
9804
9805         setfattr -n user.author1 -v author1 $testfile ||
9806                 error "setfattr -n user.author1=author1 $testfile failed"
9807         getfattr -n user.author1 $testfile 2> /dev/null |
9808           grep "user.author1=.author1" ||
9809                 error "$testfile missing trusted.author1=author1"
9810
9811         echo "listxattr..."
9812         setfattr -n trusted.name2 -v value2 $testfile ||
9813                 error "$testfile unable to set trusted.name2"
9814         setfattr -n trusted.name3 -v value3 $testfile ||
9815                 error "$testfile unable to set trusted.name3"
9816         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9817             grep "trusted.name" | wc -l) -eq 3 ] ||
9818                 error "$testfile missing 3 trusted.name xattrs"
9819
9820         setfattr -n user.author2 -v author2 $testfile ||
9821                 error "$testfile unable to set user.author2"
9822         setfattr -n user.author3 -v author3 $testfile ||
9823                 error "$testfile unable to set user.author3"
9824         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9825             grep "user.author" | wc -l) -eq 3 ] ||
9826                 error "$testfile missing 3 user.author xattrs"
9827
9828         echo "remove xattr..."
9829         setfattr -x trusted.name1 $testfile ||
9830                 error "$testfile error deleting trusted.name1"
9831         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9832                 error "$testfile did not delete trusted.name1 xattr"
9833
9834         setfattr -x user.author1 $testfile ||
9835                 error "$testfile error deleting user.author1"
9836         echo "set lustre special xattr ..."
9837         $LFS setstripe -c1 $testfile
9838         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9839                 awk -F "=" '/trusted.lov/ { print $2 }' )
9840         setfattr -n "trusted.lov" -v $lovea $testfile ||
9841                 error "$testfile doesn't ignore setting trusted.lov again"
9842         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9843                 error "$testfile allow setting invalid trusted.lov"
9844         rm -f $testfile
9845 }
9846 run_test 102a "user xattr test =================================="
9847
9848 check_102b_layout() {
9849         local layout="$*"
9850         local testfile=$DIR/$tfile
9851
9852         echo "test layout '$layout'"
9853         $LFS setstripe $layout $testfile || error "setstripe failed"
9854         $LFS getstripe -y $testfile
9855
9856         echo "get/set/list trusted.lov xattr ..." # b=10930
9857         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9858         [[ "$value" =~ "trusted.lov" ]] ||
9859                 error "can't get trusted.lov from $testfile"
9860         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9861                 error "getstripe failed"
9862
9863         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9864
9865         value=$(cut -d= -f2 <<<$value)
9866         # LU-13168: truncated xattr should fail if short lov_user_md header
9867         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9868                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9869         for len in $lens; do
9870                 echo "setfattr $len $testfile.2"
9871                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9872                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9873         done
9874         local stripe_size=$($LFS getstripe -S $testfile.2)
9875         local stripe_count=$($LFS getstripe -c $testfile.2)
9876         [[ $stripe_size -eq 65536 ]] ||
9877                 error "stripe size $stripe_size != 65536"
9878         [[ $stripe_count -eq $stripe_count_orig ]] ||
9879                 error "stripe count $stripe_count != $stripe_count_orig"
9880         rm $testfile $testfile.2
9881 }
9882
9883 test_102b() {
9884         [ -z "$(which setfattr 2>/dev/null)" ] &&
9885                 skip_env "could not find setfattr"
9886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9887
9888         # check plain layout
9889         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9890
9891         # and also check composite layout
9892         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9893
9894 }
9895 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9896
9897 test_102c() {
9898         [ -z "$(which setfattr 2>/dev/null)" ] &&
9899                 skip_env "could not find setfattr"
9900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9901
9902         # b10930: get/set/list lustre.lov xattr
9903         echo "get/set/list lustre.lov xattr ..."
9904         test_mkdir $DIR/$tdir
9905         chown $RUNAS_ID $DIR/$tdir
9906         local testfile=$DIR/$tdir/$tfile
9907         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9908                 error "setstripe failed"
9909         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9910                 error "getstripe failed"
9911         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9912         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9913
9914         local testfile2=${testfile}2
9915         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9916                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9917
9918         $RUNAS $MCREATE $testfile2
9919         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9920         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9921         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9922         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9923         [ $stripe_count -eq $STRIPECOUNT ] ||
9924                 error "stripe count $stripe_count != $STRIPECOUNT"
9925 }
9926 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9927
9928 compare_stripe_info1() {
9929         local stripe_index_all_zero=true
9930
9931         for num in 1 2 3 4; do
9932                 for count in $(seq 1 $STRIPE_COUNT); do
9933                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9934                                 local size=$((STRIPE_SIZE * num))
9935                                 local file=file"$num-$offset-$count"
9936                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9937                                 [[ $stripe_size -ne $size ]] &&
9938                                     error "$file: size $stripe_size != $size"
9939                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9940                                 # allow fewer stripes to be created, ORI-601
9941                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9942                                     error "$file: count $stripe_count != $count"
9943                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9944                                 [[ $stripe_index -ne 0 ]] &&
9945                                         stripe_index_all_zero=false
9946                         done
9947                 done
9948         done
9949         $stripe_index_all_zero &&
9950                 error "all files are being extracted starting from OST index 0"
9951         return 0
9952 }
9953
9954 have_xattrs_include() {
9955         tar --help | grep -q xattrs-include &&
9956                 echo --xattrs-include="lustre.*"
9957 }
9958
9959 test_102d() {
9960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9961         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9962
9963         XINC=$(have_xattrs_include)
9964         setup_test102
9965         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9966         cd $DIR/$tdir/$tdir
9967         compare_stripe_info1
9968 }
9969 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9970
9971 test_102f() {
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9974
9975         XINC=$(have_xattrs_include)
9976         setup_test102
9977         test_mkdir $DIR/$tdir.restore
9978         cd $DIR
9979         tar cf - --xattrs $tdir | tar xf - \
9980                 -C $DIR/$tdir.restore --xattrs $XINC
9981         cd $DIR/$tdir.restore/$tdir
9982         compare_stripe_info1
9983 }
9984 run_test 102f "tar copy files, not keep osts"
9985
9986 grow_xattr() {
9987         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9988                 skip "must have user_xattr"
9989         [ -z "$(which setfattr 2>/dev/null)" ] &&
9990                 skip_env "could not find setfattr"
9991         [ -z "$(which getfattr 2>/dev/null)" ] &&
9992                 skip_env "could not find getfattr"
9993
9994         local xsize=${1:-1024}  # in bytes
9995         local file=$DIR/$tfile
9996         local value="$(generate_string $xsize)"
9997         local xbig=trusted.big
9998         local toobig=$2
9999
10000         touch $file
10001         log "save $xbig on $file"
10002         if [ -z "$toobig" ]
10003         then
10004                 setfattr -n $xbig -v $value $file ||
10005                         error "saving $xbig on $file failed"
10006         else
10007                 setfattr -n $xbig -v $value $file &&
10008                         error "saving $xbig on $file succeeded"
10009                 return 0
10010         fi
10011
10012         local orig=$(get_xattr_value $xbig $file)
10013         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10014
10015         local xsml=trusted.sml
10016         log "save $xsml on $file"
10017         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10018
10019         local new=$(get_xattr_value $xbig $file)
10020         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10021
10022         log "grow $xsml on $file"
10023         setfattr -n $xsml -v "$value" $file ||
10024                 error "growing $xsml on $file failed"
10025
10026         new=$(get_xattr_value $xbig $file)
10027         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10028         log "$xbig still valid after growing $xsml"
10029
10030         rm -f $file
10031 }
10032
10033 test_102h() { # bug 15777
10034         grow_xattr 1024
10035 }
10036 run_test 102h "grow xattr from inside inode to external block"
10037
10038 test_102ha() {
10039         large_xattr_enabled || skip_env "ea_inode feature disabled"
10040
10041         echo "setting xattr of max xattr size: $(max_xattr_size)"
10042         grow_xattr $(max_xattr_size)
10043
10044         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10045         echo "This should fail:"
10046         grow_xattr $(($(max_xattr_size) + 10)) 1
10047 }
10048 run_test 102ha "grow xattr from inside inode to external inode"
10049
10050 test_102i() { # bug 17038
10051         [ -z "$(which getfattr 2>/dev/null)" ] &&
10052                 skip "could not find getfattr"
10053
10054         touch $DIR/$tfile
10055         ln -s $DIR/$tfile $DIR/${tfile}link
10056         getfattr -n trusted.lov $DIR/$tfile ||
10057                 error "lgetxattr on $DIR/$tfile failed"
10058         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10059                 grep -i "no such attr" ||
10060                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10061         rm -f $DIR/$tfile $DIR/${tfile}link
10062 }
10063 run_test 102i "lgetxattr test on symbolic link ============"
10064
10065 test_102j() {
10066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10068
10069         XINC=$(have_xattrs_include)
10070         setup_test102 "$RUNAS"
10071         chown $RUNAS_ID $DIR/$tdir
10072         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10073         cd $DIR/$tdir/$tdir
10074         compare_stripe_info1 "$RUNAS"
10075 }
10076 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10077
10078 test_102k() {
10079         [ -z "$(which setfattr 2>/dev/null)" ] &&
10080                 skip "could not find setfattr"
10081
10082         touch $DIR/$tfile
10083         # b22187 just check that does not crash for regular file.
10084         setfattr -n trusted.lov $DIR/$tfile
10085         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10086         local test_kdir=$DIR/$tdir
10087         test_mkdir $test_kdir
10088         local default_size=$($LFS getstripe -S $test_kdir)
10089         local default_count=$($LFS getstripe -c $test_kdir)
10090         local default_offset=$($LFS getstripe -i $test_kdir)
10091         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10092                 error 'dir setstripe failed'
10093         setfattr -n trusted.lov $test_kdir
10094         local stripe_size=$($LFS getstripe -S $test_kdir)
10095         local stripe_count=$($LFS getstripe -c $test_kdir)
10096         local stripe_offset=$($LFS getstripe -i $test_kdir)
10097         [ $stripe_size -eq $default_size ] ||
10098                 error "stripe size $stripe_size != $default_size"
10099         [ $stripe_count -eq $default_count ] ||
10100                 error "stripe count $stripe_count != $default_count"
10101         [ $stripe_offset -eq $default_offset ] ||
10102                 error "stripe offset $stripe_offset != $default_offset"
10103         rm -rf $DIR/$tfile $test_kdir
10104 }
10105 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10106
10107 test_102l() {
10108         [ -z "$(which getfattr 2>/dev/null)" ] &&
10109                 skip "could not find getfattr"
10110
10111         # LU-532 trusted. xattr is invisible to non-root
10112         local testfile=$DIR/$tfile
10113
10114         touch $testfile
10115
10116         echo "listxattr as user..."
10117         chown $RUNAS_ID $testfile
10118         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10119             grep -q "trusted" &&
10120                 error "$testfile trusted xattrs are user visible"
10121
10122         return 0;
10123 }
10124 run_test 102l "listxattr size test =================================="
10125
10126 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10127         local path=$DIR/$tfile
10128         touch $path
10129
10130         listxattr_size_check $path || error "listattr_size_check $path failed"
10131 }
10132 run_test 102m "Ensure listxattr fails on small bufffer ========"
10133
10134 cleanup_test102
10135
10136 getxattr() { # getxattr path name
10137         # Return the base64 encoding of the value of xattr name on path.
10138         local path=$1
10139         local name=$2
10140
10141         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10142         # file: $path
10143         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10144         #
10145         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10146
10147         getfattr --absolute-names --encoding=base64 --name=$name $path |
10148                 awk -F= -v name=$name '$1 == name {
10149                         print substr($0, index($0, "=") + 1);
10150         }'
10151 }
10152
10153 test_102n() { # LU-4101 mdt: protect internal xattrs
10154         [ -z "$(which setfattr 2>/dev/null)" ] &&
10155                 skip "could not find setfattr"
10156         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10157         then
10158                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10159         fi
10160
10161         local file0=$DIR/$tfile.0
10162         local file1=$DIR/$tfile.1
10163         local xattr0=$TMP/$tfile.0
10164         local xattr1=$TMP/$tfile.1
10165         local namelist="lov lma lmv link fid version som hsm"
10166         local name
10167         local value
10168
10169         rm -rf $file0 $file1 $xattr0 $xattr1
10170         touch $file0 $file1
10171
10172         # Get 'before' xattrs of $file1.
10173         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10174
10175         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10176                 namelist+=" lfsck_namespace"
10177         for name in $namelist; do
10178                 # Try to copy xattr from $file0 to $file1.
10179                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10180
10181                 setfattr --name=trusted.$name --value="$value" $file1 ||
10182                         error "setxattr 'trusted.$name' failed"
10183
10184                 # Try to set a garbage xattr.
10185                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10186
10187                 if [[ x$name == "xlov" ]]; then
10188                         setfattr --name=trusted.lov --value="$value" $file1 &&
10189                         error "setxattr invalid 'trusted.lov' success"
10190                 else
10191                         setfattr --name=trusted.$name --value="$value" $file1 ||
10192                                 error "setxattr invalid 'trusted.$name' failed"
10193                 fi
10194
10195                 # Try to remove the xattr from $file1. We don't care if this
10196                 # appears to succeed or fail, we just don't want there to be
10197                 # any changes or crashes.
10198                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10199         done
10200
10201         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10202         then
10203                 name="lfsck_ns"
10204                 # Try to copy xattr from $file0 to $file1.
10205                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10206
10207                 setfattr --name=trusted.$name --value="$value" $file1 ||
10208                         error "setxattr 'trusted.$name' failed"
10209
10210                 # Try to set a garbage xattr.
10211                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10212
10213                 setfattr --name=trusted.$name --value="$value" $file1 ||
10214                         error "setxattr 'trusted.$name' failed"
10215
10216                 # Try to remove the xattr from $file1. We don't care if this
10217                 # appears to succeed or fail, we just don't want there to be
10218                 # any changes or crashes.
10219                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10220         fi
10221
10222         # Get 'after' xattrs of file1.
10223         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10224
10225         if ! diff $xattr0 $xattr1; then
10226                 error "before and after xattrs of '$file1' differ"
10227         fi
10228
10229         rm -rf $file0 $file1 $xattr0 $xattr1
10230
10231         return 0
10232 }
10233 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10234
10235 test_102p() { # LU-4703 setxattr did not check ownership
10236         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10237                 skip "MDS needs to be at least 2.5.56"
10238
10239         local testfile=$DIR/$tfile
10240
10241         touch $testfile
10242
10243         echo "setfacl as user..."
10244         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10245         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10246
10247         echo "setfattr as user..."
10248         setfacl -m "u:$RUNAS_ID:---" $testfile
10249         $RUNAS setfattr -x system.posix_acl_access $testfile
10250         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10251 }
10252 run_test 102p "check setxattr(2) correctly fails without permission"
10253
10254 test_102q() {
10255         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10256                 skip "MDS needs to be at least 2.6.92"
10257
10258         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10259 }
10260 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10261
10262 test_102r() {
10263         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10264                 skip "MDS needs to be at least 2.6.93"
10265
10266         touch $DIR/$tfile || error "touch"
10267         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10268         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10269         rm $DIR/$tfile || error "rm"
10270
10271         #normal directory
10272         mkdir -p $DIR/$tdir || error "mkdir"
10273         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10274         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10275         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10276                 error "$testfile error deleting user.author1"
10277         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10278                 grep "user.$(basename $tdir)" &&
10279                 error "$tdir did not delete user.$(basename $tdir)"
10280         rmdir $DIR/$tdir || error "rmdir"
10281
10282         #striped directory
10283         test_mkdir $DIR/$tdir
10284         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10285         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10286         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10287                 error "$testfile error deleting user.author1"
10288         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10289                 grep "user.$(basename $tdir)" &&
10290                 error "$tdir did not delete user.$(basename $tdir)"
10291         rmdir $DIR/$tdir || error "rm striped dir"
10292 }
10293 run_test 102r "set EAs with empty values"
10294
10295 test_102s() {
10296         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10297                 skip "MDS needs to be at least 2.11.52"
10298
10299         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10300
10301         save_lustre_params client "llite.*.xattr_cache" > $save
10302
10303         for cache in 0 1; do
10304                 lctl set_param llite.*.xattr_cache=$cache
10305
10306                 rm -f $DIR/$tfile
10307                 touch $DIR/$tfile || error "touch"
10308                 for prefix in lustre security system trusted user; do
10309                         # Note getxattr() may fail with 'Operation not
10310                         # supported' or 'No such attribute' depending
10311                         # on prefix and cache.
10312                         getfattr -n $prefix.n102s $DIR/$tfile &&
10313                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10314                 done
10315         done
10316
10317         restore_lustre_params < $save
10318 }
10319 run_test 102s "getting nonexistent xattrs should fail"
10320
10321 test_102t() {
10322         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10323                 skip "MDS needs to be at least 2.11.52"
10324
10325         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10326
10327         save_lustre_params client "llite.*.xattr_cache" > $save
10328
10329         for cache in 0 1; do
10330                 lctl set_param llite.*.xattr_cache=$cache
10331
10332                 for buf_size in 0 256; do
10333                         rm -f $DIR/$tfile
10334                         touch $DIR/$tfile || error "touch"
10335                         setfattr -n user.multiop $DIR/$tfile
10336                         $MULTIOP $DIR/$tfile oa$buf_size ||
10337                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10338                 done
10339         done
10340
10341         restore_lustre_params < $save
10342 }
10343 run_test 102t "zero length xattr values handled correctly"
10344
10345 run_acl_subtest()
10346 {
10347     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10348     return $?
10349 }
10350
10351 test_103a() {
10352         [ "$UID" != 0 ] && skip "must run as root"
10353         $GSS && skip_env "could not run under gss"
10354         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10355                 skip_env "must have acl enabled"
10356         [ -z "$(which setfacl 2>/dev/null)" ] &&
10357                 skip_env "could not find setfacl"
10358         remote_mds_nodsh && skip "remote MDS with nodsh"
10359
10360         gpasswd -a daemon bin                           # LU-5641
10361         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10362
10363         declare -a identity_old
10364
10365         for num in $(seq $MDSCOUNT); do
10366                 switch_identity $num true || identity_old[$num]=$?
10367         done
10368
10369         SAVE_UMASK=$(umask)
10370         umask 0022
10371         mkdir -p $DIR/$tdir
10372         cd $DIR/$tdir
10373
10374         echo "performing cp ..."
10375         run_acl_subtest cp || error "run_acl_subtest cp failed"
10376         echo "performing getfacl-noacl..."
10377         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10378         echo "performing misc..."
10379         run_acl_subtest misc || error  "misc test failed"
10380         echo "performing permissions..."
10381         run_acl_subtest permissions || error "permissions failed"
10382         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10383         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10384                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10385                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10386         then
10387                 echo "performing permissions xattr..."
10388                 run_acl_subtest permissions_xattr ||
10389                         error "permissions_xattr failed"
10390         fi
10391         echo "performing setfacl..."
10392         run_acl_subtest setfacl || error  "setfacl test failed"
10393
10394         # inheritance test got from HP
10395         echo "performing inheritance..."
10396         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10397         chmod +x make-tree || error "chmod +x failed"
10398         run_acl_subtest inheritance || error "inheritance test failed"
10399         rm -f make-tree
10400
10401         echo "LU-974 ignore umask when acl is enabled..."
10402         run_acl_subtest 974 || error "LU-974 umask test failed"
10403         if [ $MDSCOUNT -ge 2 ]; then
10404                 run_acl_subtest 974_remote ||
10405                         error "LU-974 umask test failed under remote dir"
10406         fi
10407
10408         echo "LU-2561 newly created file is same size as directory..."
10409         if [ "$mds1_FSTYPE" != "zfs" ]; then
10410                 run_acl_subtest 2561 || error "LU-2561 test failed"
10411         else
10412                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10413         fi
10414
10415         run_acl_subtest 4924 || error "LU-4924 test failed"
10416
10417         cd $SAVE_PWD
10418         umask $SAVE_UMASK
10419
10420         for num in $(seq $MDSCOUNT); do
10421                 if [ "${identity_old[$num]}" = 1 ]; then
10422                         switch_identity $num false || identity_old[$num]=$?
10423                 fi
10424         done
10425 }
10426 run_test 103a "acl test"
10427
10428 test_103b() {
10429         declare -a pids
10430         local U
10431
10432         for U in {0..511}; do
10433                 {
10434                 local O=$(printf "%04o" $U)
10435
10436                 umask $(printf "%04o" $((511 ^ $O)))
10437                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10438                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10439
10440                 (( $S == ($O & 0666) )) ||
10441                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10442
10443                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10444                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10445                 (( $S == ($O & 0666) )) ||
10446                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10447
10448                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10449                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10450                 (( $S == ($O & 0666) )) ||
10451                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10452                 rm -f $DIR/$tfile.[smp]$0
10453                 } &
10454                 local pid=$!
10455
10456                 # limit the concurrently running threads to 64. LU-11878
10457                 local idx=$((U % 64))
10458                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10459                 pids[idx]=$pid
10460         done
10461         wait
10462 }
10463 run_test 103b "umask lfs setstripe"
10464
10465 test_103c() {
10466         mkdir -p $DIR/$tdir
10467         cp -rp $DIR/$tdir $DIR/$tdir.bak
10468
10469         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10470                 error "$DIR/$tdir shouldn't contain default ACL"
10471         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10472                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10473         true
10474 }
10475 run_test 103c "'cp -rp' won't set empty acl"
10476
10477 test_104a() {
10478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10479
10480         touch $DIR/$tfile
10481         lfs df || error "lfs df failed"
10482         lfs df -ih || error "lfs df -ih failed"
10483         lfs df -h $DIR || error "lfs df -h $DIR failed"
10484         lfs df -i $DIR || error "lfs df -i $DIR failed"
10485         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10486         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10487
10488         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10489         lctl --device %$OSC deactivate
10490         lfs df || error "lfs df with deactivated OSC failed"
10491         lctl --device %$OSC activate
10492         # wait the osc back to normal
10493         wait_osc_import_ready client ost
10494
10495         lfs df || error "lfs df with reactivated OSC failed"
10496         rm -f $DIR/$tfile
10497 }
10498 run_test 104a "lfs df [-ih] [path] test ========================="
10499
10500 test_104b() {
10501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10502         [ $RUNAS_ID -eq $UID ] &&
10503                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10504
10505         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10506                         grep "Permission denied" | wc -l)))
10507         if [ $denied_cnt -ne 0 ]; then
10508                 error "lfs check servers test failed"
10509         fi
10510 }
10511 run_test 104b "$RUNAS lfs check servers test ===================="
10512
10513 test_105a() {
10514         # doesn't work on 2.4 kernels
10515         touch $DIR/$tfile
10516         if $(flock_is_enabled); then
10517                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10518         else
10519                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10520         fi
10521         rm -f $DIR/$tfile
10522 }
10523 run_test 105a "flock when mounted without -o flock test ========"
10524
10525 test_105b() {
10526         touch $DIR/$tfile
10527         if $(flock_is_enabled); then
10528                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10529         else
10530                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10531         fi
10532         rm -f $DIR/$tfile
10533 }
10534 run_test 105b "fcntl when mounted without -o flock test ========"
10535
10536 test_105c() {
10537         touch $DIR/$tfile
10538         if $(flock_is_enabled); then
10539                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10540         else
10541                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10542         fi
10543         rm -f $DIR/$tfile
10544 }
10545 run_test 105c "lockf when mounted without -o flock test"
10546
10547 test_105d() { # bug 15924
10548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10549
10550         test_mkdir $DIR/$tdir
10551         flock_is_enabled || skip_env "mount w/o flock enabled"
10552         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10553         $LCTL set_param fail_loc=0x80000315
10554         flocks_test 2 $DIR/$tdir
10555 }
10556 run_test 105d "flock race (should not freeze) ========"
10557
10558 test_105e() { # bug 22660 && 22040
10559         flock_is_enabled || skip_env "mount w/o flock enabled"
10560
10561         touch $DIR/$tfile
10562         flocks_test 3 $DIR/$tfile
10563 }
10564 run_test 105e "Two conflicting flocks from same process"
10565
10566 test_106() { #bug 10921
10567         test_mkdir $DIR/$tdir
10568         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10569         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10570 }
10571 run_test 106 "attempt exec of dir followed by chown of that dir"
10572
10573 test_107() {
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575
10576         CDIR=`pwd`
10577         local file=core
10578
10579         cd $DIR
10580         rm -f $file
10581
10582         local save_pattern=$(sysctl -n kernel.core_pattern)
10583         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10584         sysctl -w kernel.core_pattern=$file
10585         sysctl -w kernel.core_uses_pid=0
10586
10587         ulimit -c unlimited
10588         sleep 60 &
10589         SLEEPPID=$!
10590
10591         sleep 1
10592
10593         kill -s 11 $SLEEPPID
10594         wait $SLEEPPID
10595         if [ -e $file ]; then
10596                 size=`stat -c%s $file`
10597                 [ $size -eq 0 ] && error "Fail to create core file $file"
10598         else
10599                 error "Fail to create core file $file"
10600         fi
10601         rm -f $file
10602         sysctl -w kernel.core_pattern=$save_pattern
10603         sysctl -w kernel.core_uses_pid=$save_uses_pid
10604         cd $CDIR
10605 }
10606 run_test 107 "Coredump on SIG"
10607
10608 test_110() {
10609         test_mkdir $DIR/$tdir
10610         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10611         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10612                 error "mkdir with 256 char should fail, but did not"
10613         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10614                 error "create with 255 char failed"
10615         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10616                 error "create with 256 char should fail, but did not"
10617
10618         ls -l $DIR/$tdir
10619         rm -rf $DIR/$tdir
10620 }
10621 run_test 110 "filename length checking"
10622
10623 #
10624 # Purpose: To verify dynamic thread (OSS) creation.
10625 #
10626 test_115() {
10627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10628         remote_ost_nodsh && skip "remote OST with nodsh"
10629
10630         # Lustre does not stop service threads once they are started.
10631         # Reset number of running threads to default.
10632         stopall
10633         setupall
10634
10635         local OSTIO_pre
10636         local save_params="$TMP/sanity-$TESTNAME.parameters"
10637
10638         # Get ll_ost_io count before I/O
10639         OSTIO_pre=$(do_facet ost1 \
10640                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10641         # Exit if lustre is not running (ll_ost_io not running).
10642         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10643
10644         echo "Starting with $OSTIO_pre threads"
10645         local thread_max=$((OSTIO_pre * 2))
10646         local rpc_in_flight=$((thread_max * 2))
10647         # Number of I/O Process proposed to be started.
10648         local nfiles
10649         local facets=$(get_facets OST)
10650
10651         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10652         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10653
10654         # Set in_flight to $rpc_in_flight
10655         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10656                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10657         nfiles=${rpc_in_flight}
10658         # Set ost thread_max to $thread_max
10659         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10660
10661         # 5 Minutes should be sufficient for max number of OSS
10662         # threads(thread_max) to be created.
10663         local timeout=300
10664
10665         # Start I/O.
10666         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10667         test_mkdir $DIR/$tdir
10668         for i in $(seq $nfiles); do
10669                 local file=$DIR/$tdir/${tfile}-$i
10670                 $LFS setstripe -c -1 -i 0 $file
10671                 ($WTL $file $timeout)&
10672         done
10673
10674         # I/O Started - Wait for thread_started to reach thread_max or report
10675         # error if thread_started is more than thread_max.
10676         echo "Waiting for thread_started to reach thread_max"
10677         local thread_started=0
10678         local end_time=$((SECONDS + timeout))
10679
10680         while [ $SECONDS -le $end_time ] ; do
10681                 echo -n "."
10682                 # Get ost i/o thread_started count.
10683                 thread_started=$(do_facet ost1 \
10684                         "$LCTL get_param \
10685                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10686                 # Break out if thread_started is equal/greater than thread_max
10687                 if [[ $thread_started -ge $thread_max ]]; then
10688                         echo ll_ost_io thread_started $thread_started, \
10689                                 equal/greater than thread_max $thread_max
10690                         break
10691                 fi
10692                 sleep 1
10693         done
10694
10695         # Cleanup - We have the numbers, Kill i/o jobs if running.
10696         jobcount=($(jobs -p))
10697         for i in $(seq 0 $((${#jobcount[@]}-1)))
10698         do
10699                 kill -9 ${jobcount[$i]}
10700                 if [ $? -ne 0 ] ; then
10701                         echo Warning: \
10702                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10703                 fi
10704         done
10705
10706         # Cleanup files left by WTL binary.
10707         for i in $(seq $nfiles); do
10708                 local file=$DIR/$tdir/${tfile}-$i
10709                 rm -rf $file
10710                 if [ $? -ne 0 ] ; then
10711                         echo "Warning: Failed to delete file $file"
10712                 fi
10713         done
10714
10715         restore_lustre_params <$save_params
10716         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10717
10718         # Error out if no new thread has started or Thread started is greater
10719         # than thread max.
10720         if [[ $thread_started -le $OSTIO_pre ||
10721                         $thread_started -gt $thread_max ]]; then
10722                 error "ll_ost_io: thread_started $thread_started" \
10723                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10724                       "No new thread started or thread started greater " \
10725                       "than thread_max."
10726         fi
10727 }
10728 run_test 115 "verify dynamic thread creation===================="
10729
10730 free_min_max () {
10731         wait_delete_completed
10732         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10733         echo "OST kbytes available: ${AVAIL[@]}"
10734         MAXV=${AVAIL[0]}
10735         MAXI=0
10736         MINV=${AVAIL[0]}
10737         MINI=0
10738         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10739                 #echo OST $i: ${AVAIL[i]}kb
10740                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10741                         MAXV=${AVAIL[i]}
10742                         MAXI=$i
10743                 fi
10744                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10745                         MINV=${AVAIL[i]}
10746                         MINI=$i
10747                 fi
10748         done
10749         echo "Min free space: OST $MINI: $MINV"
10750         echo "Max free space: OST $MAXI: $MAXV"
10751 }
10752
10753 test_116a() { # was previously test_116()
10754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10755         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10756         remote_mds_nodsh && skip "remote MDS with nodsh"
10757
10758         echo -n "Free space priority "
10759         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10760                 head -n1
10761         declare -a AVAIL
10762         free_min_max
10763
10764         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10765         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10766         trap simple_cleanup_common EXIT
10767
10768         # Check if we need to generate uneven OSTs
10769         test_mkdir -p $DIR/$tdir/OST${MINI}
10770         local FILL=$((MINV / 4))
10771         local DIFF=$((MAXV - MINV))
10772         local DIFF2=$((DIFF * 100 / MINV))
10773
10774         local threshold=$(do_facet $SINGLEMDS \
10775                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10776         threshold=${threshold%%%}
10777         echo -n "Check for uneven OSTs: "
10778         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10779
10780         if [[ $DIFF2 -gt $threshold ]]; then
10781                 echo "ok"
10782                 echo "Don't need to fill OST$MINI"
10783         else
10784                 # generate uneven OSTs. Write 2% over the QOS threshold value
10785                 echo "no"
10786                 DIFF=$((threshold - DIFF2 + 2))
10787                 DIFF2=$((MINV * DIFF / 100))
10788                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10789                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10790                         error "setstripe failed"
10791                 DIFF=$((DIFF2 / 2048))
10792                 i=0
10793                 while [ $i -lt $DIFF ]; do
10794                         i=$((i + 1))
10795                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10796                                 bs=2M count=1 2>/dev/null
10797                         echo -n .
10798                 done
10799                 echo .
10800                 sync
10801                 sleep_maxage
10802                 free_min_max
10803         fi
10804
10805         DIFF=$((MAXV - MINV))
10806         DIFF2=$((DIFF * 100 / MINV))
10807         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10808         if [ $DIFF2 -gt $threshold ]; then
10809                 echo "ok"
10810         else
10811                 echo "failed - QOS mode won't be used"
10812                 simple_cleanup_common
10813                 skip "QOS imbalance criteria not met"
10814         fi
10815
10816         MINI1=$MINI
10817         MINV1=$MINV
10818         MAXI1=$MAXI
10819         MAXV1=$MAXV
10820
10821         # now fill using QOS
10822         $LFS setstripe -c 1 $DIR/$tdir
10823         FILL=$((FILL / 200))
10824         if [ $FILL -gt 600 ]; then
10825                 FILL=600
10826         fi
10827         echo "writing $FILL files to QOS-assigned OSTs"
10828         i=0
10829         while [ $i -lt $FILL ]; do
10830                 i=$((i + 1))
10831                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10832                         count=1 2>/dev/null
10833                 echo -n .
10834         done
10835         echo "wrote $i 200k files"
10836         sync
10837         sleep_maxage
10838
10839         echo "Note: free space may not be updated, so measurements might be off"
10840         free_min_max
10841         DIFF2=$((MAXV - MINV))
10842         echo "free space delta: orig $DIFF final $DIFF2"
10843         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10844         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10845         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10846         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10847         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10848         if [[ $DIFF -gt 0 ]]; then
10849                 FILL=$((DIFF2 * 100 / DIFF - 100))
10850                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10851         fi
10852
10853         # Figure out which files were written where
10854         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10855                awk '/'$MINI1': / {print $2; exit}')
10856         echo $UUID
10857         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10858         echo "$MINC files created on smaller OST $MINI1"
10859         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10860                awk '/'$MAXI1': / {print $2; exit}')
10861         echo $UUID
10862         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10863         echo "$MAXC files created on larger OST $MAXI1"
10864         if [[ $MINC -gt 0 ]]; then
10865                 FILL=$((MAXC * 100 / MINC - 100))
10866                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10867         fi
10868         [[ $MAXC -gt $MINC ]] ||
10869                 error_ignore LU-9 "stripe QOS didn't balance free space"
10870         simple_cleanup_common
10871 }
10872 run_test 116a "stripe QOS: free space balance ==================="
10873
10874 test_116b() { # LU-2093
10875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10876         remote_mds_nodsh && skip "remote MDS with nodsh"
10877
10878 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10879         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10880                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10881         [ -z "$old_rr" ] && skip "no QOS"
10882         do_facet $SINGLEMDS lctl set_param \
10883                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10884         mkdir -p $DIR/$tdir
10885         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10886         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10887         do_facet $SINGLEMDS lctl set_param fail_loc=0
10888         rm -rf $DIR/$tdir
10889         do_facet $SINGLEMDS lctl set_param \
10890                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10891 }
10892 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10893
10894 test_117() # bug 10891
10895 {
10896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10897
10898         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10899         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10900         lctl set_param fail_loc=0x21e
10901         > $DIR/$tfile || error "truncate failed"
10902         lctl set_param fail_loc=0
10903         echo "Truncate succeeded."
10904         rm -f $DIR/$tfile
10905 }
10906 run_test 117 "verify osd extend =========="
10907
10908 NO_SLOW_RESENDCOUNT=4
10909 export OLD_RESENDCOUNT=""
10910 set_resend_count () {
10911         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10912         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10913         lctl set_param -n $PROC_RESENDCOUNT $1
10914         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10915 }
10916
10917 # for reduce test_118* time (b=14842)
10918 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10919
10920 # Reset async IO behavior after error case
10921 reset_async() {
10922         FILE=$DIR/reset_async
10923
10924         # Ensure all OSCs are cleared
10925         $LFS setstripe -c -1 $FILE
10926         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10927         sync
10928         rm $FILE
10929 }
10930
10931 test_118a() #bug 11710
10932 {
10933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10934
10935         reset_async
10936
10937         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10938         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10939         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10940
10941         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10942                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10943                 return 1;
10944         fi
10945         rm -f $DIR/$tfile
10946 }
10947 run_test 118a "verify O_SYNC works =========="
10948
10949 test_118b()
10950 {
10951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10952         remote_ost_nodsh && skip "remote OST with nodsh"
10953
10954         reset_async
10955
10956         #define OBD_FAIL_SRV_ENOENT 0x217
10957         set_nodes_failloc "$(osts_nodes)" 0x217
10958         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10959         RC=$?
10960         set_nodes_failloc "$(osts_nodes)" 0
10961         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10962         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10963                     grep -c writeback)
10964
10965         if [[ $RC -eq 0 ]]; then
10966                 error "Must return error due to dropped pages, rc=$RC"
10967                 return 1;
10968         fi
10969
10970         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10971                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10972                 return 1;
10973         fi
10974
10975         echo "Dirty pages not leaked on ENOENT"
10976
10977         # Due to the above error the OSC will issue all RPCs syncronously
10978         # until a subsequent RPC completes successfully without error.
10979         $MULTIOP $DIR/$tfile Ow4096yc
10980         rm -f $DIR/$tfile
10981
10982         return 0
10983 }
10984 run_test 118b "Reclaim dirty pages on fatal error =========="
10985
10986 test_118c()
10987 {
10988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10989
10990         # for 118c, restore the original resend count, LU-1940
10991         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10992                                 set_resend_count $OLD_RESENDCOUNT
10993         remote_ost_nodsh && skip "remote OST with nodsh"
10994
10995         reset_async
10996
10997         #define OBD_FAIL_OST_EROFS               0x216
10998         set_nodes_failloc "$(osts_nodes)" 0x216
10999
11000         # multiop should block due to fsync until pages are written
11001         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11002         MULTIPID=$!
11003         sleep 1
11004
11005         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11006                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11007         fi
11008
11009         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11010                     grep -c writeback)
11011         if [[ $WRITEBACK -eq 0 ]]; then
11012                 error "No page in writeback, writeback=$WRITEBACK"
11013         fi
11014
11015         set_nodes_failloc "$(osts_nodes)" 0
11016         wait $MULTIPID
11017         RC=$?
11018         if [[ $RC -ne 0 ]]; then
11019                 error "Multiop fsync failed, rc=$RC"
11020         fi
11021
11022         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11023         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11024                     grep -c writeback)
11025         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11026                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11027         fi
11028
11029         rm -f $DIR/$tfile
11030         echo "Dirty pages flushed via fsync on EROFS"
11031         return 0
11032 }
11033 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11034
11035 # continue to use small resend count to reduce test_118* time (b=14842)
11036 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11037
11038 test_118d()
11039 {
11040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11041         remote_ost_nodsh && skip "remote OST with nodsh"
11042
11043         reset_async
11044
11045         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11046         set_nodes_failloc "$(osts_nodes)" 0x214
11047         # multiop should block due to fsync until pages are written
11048         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11049         MULTIPID=$!
11050         sleep 1
11051
11052         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11053                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11054         fi
11055
11056         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11057                     grep -c writeback)
11058         if [[ $WRITEBACK -eq 0 ]]; then
11059                 error "No page in writeback, writeback=$WRITEBACK"
11060         fi
11061
11062         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11063         set_nodes_failloc "$(osts_nodes)" 0
11064
11065         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11066         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11067                     grep -c writeback)
11068         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11069                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11070         fi
11071
11072         rm -f $DIR/$tfile
11073         echo "Dirty pages gaurenteed flushed via fsync"
11074         return 0
11075 }
11076 run_test 118d "Fsync validation inject a delay of the bulk =========="
11077
11078 test_118f() {
11079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11080
11081         reset_async
11082
11083         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11084         lctl set_param fail_loc=0x8000040a
11085
11086         # Should simulate EINVAL error which is fatal
11087         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11088         RC=$?
11089         if [[ $RC -eq 0 ]]; then
11090                 error "Must return error due to dropped pages, rc=$RC"
11091         fi
11092
11093         lctl set_param fail_loc=0x0
11094
11095         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11096         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11097         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11098                     grep -c writeback)
11099         if [[ $LOCKED -ne 0 ]]; then
11100                 error "Locked pages remain in cache, locked=$LOCKED"
11101         fi
11102
11103         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11104                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11105         fi
11106
11107         rm -f $DIR/$tfile
11108         echo "No pages locked after fsync"
11109
11110         reset_async
11111         return 0
11112 }
11113 run_test 118f "Simulate unrecoverable OSC side error =========="
11114
11115 test_118g() {
11116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11117
11118         reset_async
11119
11120         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11121         lctl set_param fail_loc=0x406
11122
11123         # simulate local -ENOMEM
11124         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11125         RC=$?
11126
11127         lctl set_param fail_loc=0
11128         if [[ $RC -eq 0 ]]; then
11129                 error "Must return error due to dropped pages, rc=$RC"
11130         fi
11131
11132         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11133         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11134         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11135                         grep -c writeback)
11136         if [[ $LOCKED -ne 0 ]]; then
11137                 error "Locked pages remain in cache, locked=$LOCKED"
11138         fi
11139
11140         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11141                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11142         fi
11143
11144         rm -f $DIR/$tfile
11145         echo "No pages locked after fsync"
11146
11147         reset_async
11148         return 0
11149 }
11150 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11151
11152 test_118h() {
11153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11154         remote_ost_nodsh && skip "remote OST with nodsh"
11155
11156         reset_async
11157
11158         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11159         set_nodes_failloc "$(osts_nodes)" 0x20e
11160         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11161         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11162         RC=$?
11163
11164         set_nodes_failloc "$(osts_nodes)" 0
11165         if [[ $RC -eq 0 ]]; then
11166                 error "Must return error due to dropped pages, rc=$RC"
11167         fi
11168
11169         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11170         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11171         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11172                     grep -c writeback)
11173         if [[ $LOCKED -ne 0 ]]; then
11174                 error "Locked pages remain in cache, locked=$LOCKED"
11175         fi
11176
11177         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11178                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11179         fi
11180
11181         rm -f $DIR/$tfile
11182         echo "No pages locked after fsync"
11183
11184         return 0
11185 }
11186 run_test 118h "Verify timeout in handling recoverables errors  =========="
11187
11188 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11189
11190 test_118i() {
11191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11192         remote_ost_nodsh && skip "remote OST with nodsh"
11193
11194         reset_async
11195
11196         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11197         set_nodes_failloc "$(osts_nodes)" 0x20e
11198
11199         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11201         PID=$!
11202         sleep 5
11203         set_nodes_failloc "$(osts_nodes)" 0
11204
11205         wait $PID
11206         RC=$?
11207         if [[ $RC -ne 0 ]]; then
11208                 error "got error, but should be not, rc=$RC"
11209         fi
11210
11211         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11212         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11213         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11214         if [[ $LOCKED -ne 0 ]]; then
11215                 error "Locked pages remain in cache, locked=$LOCKED"
11216         fi
11217
11218         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11219                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11220         fi
11221
11222         rm -f $DIR/$tfile
11223         echo "No pages locked after fsync"
11224
11225         return 0
11226 }
11227 run_test 118i "Fix error before timeout in recoverable error  =========="
11228
11229 [ "$SLOW" = "no" ] && set_resend_count 4
11230
11231 test_118j() {
11232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11233         remote_ost_nodsh && skip "remote OST with nodsh"
11234
11235         reset_async
11236
11237         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11238         set_nodes_failloc "$(osts_nodes)" 0x220
11239
11240         # return -EIO from OST
11241         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11242         RC=$?
11243         set_nodes_failloc "$(osts_nodes)" 0x0
11244         if [[ $RC -eq 0 ]]; then
11245                 error "Must return error due to dropped pages, rc=$RC"
11246         fi
11247
11248         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11249         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11250         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11251         if [[ $LOCKED -ne 0 ]]; then
11252                 error "Locked pages remain in cache, locked=$LOCKED"
11253         fi
11254
11255         # in recoverable error on OST we want resend and stay until it finished
11256         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11257                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11258         fi
11259
11260         rm -f $DIR/$tfile
11261         echo "No pages locked after fsync"
11262
11263         return 0
11264 }
11265 run_test 118j "Simulate unrecoverable OST side error =========="
11266
11267 test_118k()
11268 {
11269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11270         remote_ost_nodsh && skip "remote OSTs with nodsh"
11271
11272         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11273         set_nodes_failloc "$(osts_nodes)" 0x20e
11274         test_mkdir $DIR/$tdir
11275
11276         for ((i=0;i<10;i++)); do
11277                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11278                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11279                 SLEEPPID=$!
11280                 sleep 0.500s
11281                 kill $SLEEPPID
11282                 wait $SLEEPPID
11283         done
11284
11285         set_nodes_failloc "$(osts_nodes)" 0
11286         rm -rf $DIR/$tdir
11287 }
11288 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11289
11290 test_118l() # LU-646
11291 {
11292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11293
11294         test_mkdir $DIR/$tdir
11295         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11296         rm -rf $DIR/$tdir
11297 }
11298 run_test 118l "fsync dir"
11299
11300 test_118m() # LU-3066
11301 {
11302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11303
11304         test_mkdir $DIR/$tdir
11305         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11306         rm -rf $DIR/$tdir
11307 }
11308 run_test 118m "fdatasync dir ========="
11309
11310 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11311
11312 test_118n()
11313 {
11314         local begin
11315         local end
11316
11317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11318         remote_ost_nodsh && skip "remote OSTs with nodsh"
11319
11320         # Sleep to avoid a cached response.
11321         #define OBD_STATFS_CACHE_SECONDS 1
11322         sleep 2
11323
11324         # Inject a 10 second delay in the OST_STATFS handler.
11325         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11326         set_nodes_failloc "$(osts_nodes)" 0x242
11327
11328         begin=$SECONDS
11329         stat --file-system $MOUNT > /dev/null
11330         end=$SECONDS
11331
11332         set_nodes_failloc "$(osts_nodes)" 0
11333
11334         if ((end - begin > 20)); then
11335             error "statfs took $((end - begin)) seconds, expected 10"
11336         fi
11337 }
11338 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11339
11340 test_119a() # bug 11737
11341 {
11342         BSIZE=$((512 * 1024))
11343         directio write $DIR/$tfile 0 1 $BSIZE
11344         # We ask to read two blocks, which is more than a file size.
11345         # directio will indicate an error when requested and actual
11346         # sizes aren't equeal (a normal situation in this case) and
11347         # print actual read amount.
11348         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11349         if [ "$NOB" != "$BSIZE" ]; then
11350                 error "read $NOB bytes instead of $BSIZE"
11351         fi
11352         rm -f $DIR/$tfile
11353 }
11354 run_test 119a "Short directIO read must return actual read amount"
11355
11356 test_119b() # bug 11737
11357 {
11358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11359
11360         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11361         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11362         sync
11363         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11364                 error "direct read failed"
11365         rm -f $DIR/$tfile
11366 }
11367 run_test 119b "Sparse directIO read must return actual read amount"
11368
11369 test_119c() # bug 13099
11370 {
11371         BSIZE=1048576
11372         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11373         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11374         rm -f $DIR/$tfile
11375 }
11376 run_test 119c "Testing for direct read hitting hole"
11377
11378 test_119d() # bug 15950
11379 {
11380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11381
11382         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11383         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11384         BSIZE=1048576
11385         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11386         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11387         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11388         lctl set_param fail_loc=0x40d
11389         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11390         pid_dio=$!
11391         sleep 1
11392         cat $DIR/$tfile > /dev/null &
11393         lctl set_param fail_loc=0
11394         pid_reads=$!
11395         wait $pid_dio
11396         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11397         sleep 2
11398         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11399         error "the read rpcs have not completed in 2s"
11400         rm -f $DIR/$tfile
11401         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11402 }
11403 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11404
11405 test_120a() {
11406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11407         remote_mds_nodsh && skip "remote MDS with nodsh"
11408         test_mkdir -i0 -c1 $DIR/$tdir
11409         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11410                 skip_env "no early lock cancel on server"
11411
11412         lru_resize_disable mdc
11413         lru_resize_disable osc
11414         cancel_lru_locks mdc
11415         # asynchronous object destroy at MDT could cause bl ast to client
11416         cancel_lru_locks osc
11417
11418         stat $DIR/$tdir > /dev/null
11419         can1=$(do_facet mds1 \
11420                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11421                awk '/ldlm_cancel/ {print $2}')
11422         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11423                awk '/ldlm_bl_callback/ {print $2}')
11424         test_mkdir -i0 -c1 $DIR/$tdir/d1
11425         can2=$(do_facet mds1 \
11426                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11427                awk '/ldlm_cancel/ {print $2}')
11428         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11429                awk '/ldlm_bl_callback/ {print $2}')
11430         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11431         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11432         lru_resize_enable mdc
11433         lru_resize_enable osc
11434 }
11435 run_test 120a "Early Lock Cancel: mkdir test"
11436
11437 test_120b() {
11438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11439         remote_mds_nodsh && skip "remote MDS with nodsh"
11440         test_mkdir $DIR/$tdir
11441         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11442                 skip_env "no early lock cancel on server"
11443
11444         lru_resize_disable mdc
11445         lru_resize_disable osc
11446         cancel_lru_locks mdc
11447         stat $DIR/$tdir > /dev/null
11448         can1=$(do_facet $SINGLEMDS \
11449                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11450                awk '/ldlm_cancel/ {print $2}')
11451         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11452                awk '/ldlm_bl_callback/ {print $2}')
11453         touch $DIR/$tdir/f1
11454         can2=$(do_facet $SINGLEMDS \
11455                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11456                awk '/ldlm_cancel/ {print $2}')
11457         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11458                awk '/ldlm_bl_callback/ {print $2}')
11459         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11460         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11461         lru_resize_enable mdc
11462         lru_resize_enable osc
11463 }
11464 run_test 120b "Early Lock Cancel: create test"
11465
11466 test_120c() {
11467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11468         remote_mds_nodsh && skip "remote MDS with nodsh"
11469         test_mkdir -i0 -c1 $DIR/$tdir
11470         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11471                 skip "no early lock cancel on server"
11472
11473         lru_resize_disable mdc
11474         lru_resize_disable osc
11475         test_mkdir -i0 -c1 $DIR/$tdir/d1
11476         test_mkdir -i0 -c1 $DIR/$tdir/d2
11477         touch $DIR/$tdir/d1/f1
11478         cancel_lru_locks mdc
11479         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11480         can1=$(do_facet mds1 \
11481                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11482                awk '/ldlm_cancel/ {print $2}')
11483         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11484                awk '/ldlm_bl_callback/ {print $2}')
11485         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11486         can2=$(do_facet mds1 \
11487                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11488                awk '/ldlm_cancel/ {print $2}')
11489         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11490                awk '/ldlm_bl_callback/ {print $2}')
11491         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11492         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11493         lru_resize_enable mdc
11494         lru_resize_enable osc
11495 }
11496 run_test 120c "Early Lock Cancel: link test"
11497
11498 test_120d() {
11499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11500         remote_mds_nodsh && skip "remote MDS with nodsh"
11501         test_mkdir -i0 -c1 $DIR/$tdir
11502         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11503                 skip_env "no early lock cancel on server"
11504
11505         lru_resize_disable mdc
11506         lru_resize_disable osc
11507         touch $DIR/$tdir
11508         cancel_lru_locks mdc
11509         stat $DIR/$tdir > /dev/null
11510         can1=$(do_facet mds1 \
11511                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11512                awk '/ldlm_cancel/ {print $2}')
11513         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11514                awk '/ldlm_bl_callback/ {print $2}')
11515         chmod a+x $DIR/$tdir
11516         can2=$(do_facet mds1 \
11517                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11518                awk '/ldlm_cancel/ {print $2}')
11519         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11520                awk '/ldlm_bl_callback/ {print $2}')
11521         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11522         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11523         lru_resize_enable mdc
11524         lru_resize_enable osc
11525 }
11526 run_test 120d "Early Lock Cancel: setattr test"
11527
11528 test_120e() {
11529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11530         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11531                 skip_env "no early lock cancel on server"
11532         remote_mds_nodsh && skip "remote MDS with nodsh"
11533
11534         local dlmtrace_set=false
11535
11536         test_mkdir -i0 -c1 $DIR/$tdir
11537         lru_resize_disable mdc
11538         lru_resize_disable osc
11539         ! $LCTL get_param debug | grep -q dlmtrace &&
11540                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11541         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11542         cancel_lru_locks mdc
11543         cancel_lru_locks osc
11544         dd if=$DIR/$tdir/f1 of=/dev/null
11545         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11546         # XXX client can not do early lock cancel of OST lock
11547         # during unlink (LU-4206), so cancel osc lock now.
11548         sleep 2
11549         cancel_lru_locks osc
11550         can1=$(do_facet mds1 \
11551                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11552                awk '/ldlm_cancel/ {print $2}')
11553         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11554                awk '/ldlm_bl_callback/ {print $2}')
11555         unlink $DIR/$tdir/f1
11556         sleep 5
11557         can2=$(do_facet mds1 \
11558                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11559                awk '/ldlm_cancel/ {print $2}')
11560         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11561                awk '/ldlm_bl_callback/ {print $2}')
11562         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11563                 $LCTL dk $TMP/cancel.debug.txt
11564         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11565                 $LCTL dk $TMP/blocking.debug.txt
11566         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11567         lru_resize_enable mdc
11568         lru_resize_enable osc
11569 }
11570 run_test 120e "Early Lock Cancel: unlink test"
11571
11572 test_120f() {
11573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11574         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11575                 skip_env "no early lock cancel on server"
11576         remote_mds_nodsh && skip "remote MDS with nodsh"
11577
11578         test_mkdir -i0 -c1 $DIR/$tdir
11579         lru_resize_disable mdc
11580         lru_resize_disable osc
11581         test_mkdir -i0 -c1 $DIR/$tdir/d1
11582         test_mkdir -i0 -c1 $DIR/$tdir/d2
11583         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11584         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11585         cancel_lru_locks mdc
11586         cancel_lru_locks osc
11587         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11588         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11589         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11590         # XXX client can not do early lock cancel of OST lock
11591         # during rename (LU-4206), so cancel osc lock now.
11592         sleep 2
11593         cancel_lru_locks osc
11594         can1=$(do_facet mds1 \
11595                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11596                awk '/ldlm_cancel/ {print $2}')
11597         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11598                awk '/ldlm_bl_callback/ {print $2}')
11599         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11600         sleep 5
11601         can2=$(do_facet mds1 \
11602                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11603                awk '/ldlm_cancel/ {print $2}')
11604         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11605                awk '/ldlm_bl_callback/ {print $2}')
11606         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11607         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11608         lru_resize_enable mdc
11609         lru_resize_enable osc
11610 }
11611 run_test 120f "Early Lock Cancel: rename test"
11612
11613 test_120g() {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11616                 skip_env "no early lock cancel on server"
11617         remote_mds_nodsh && skip "remote MDS with nodsh"
11618
11619         lru_resize_disable mdc
11620         lru_resize_disable osc
11621         count=10000
11622         echo create $count files
11623         test_mkdir $DIR/$tdir
11624         cancel_lru_locks mdc
11625         cancel_lru_locks osc
11626         t0=$(date +%s)
11627
11628         can0=$(do_facet $SINGLEMDS \
11629                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11630                awk '/ldlm_cancel/ {print $2}')
11631         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11632                awk '/ldlm_bl_callback/ {print $2}')
11633         createmany -o $DIR/$tdir/f $count
11634         sync
11635         can1=$(do_facet $SINGLEMDS \
11636                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11637                awk '/ldlm_cancel/ {print $2}')
11638         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11639                awk '/ldlm_bl_callback/ {print $2}')
11640         t1=$(date +%s)
11641         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11642         echo rm $count files
11643         rm -r $DIR/$tdir
11644         sync
11645         can2=$(do_facet $SINGLEMDS \
11646                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11647                awk '/ldlm_cancel/ {print $2}')
11648         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11649                awk '/ldlm_bl_callback/ {print $2}')
11650         t2=$(date +%s)
11651         echo total: $count removes in $((t2-t1))
11652         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11653         sleep 2
11654         # wait for commitment of removal
11655         lru_resize_enable mdc
11656         lru_resize_enable osc
11657 }
11658 run_test 120g "Early Lock Cancel: performance test"
11659
11660 test_121() { #bug #10589
11661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11662
11663         rm -rf $DIR/$tfile
11664         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11665 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11666         lctl set_param fail_loc=0x310
11667         cancel_lru_locks osc > /dev/null
11668         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11669         lctl set_param fail_loc=0
11670         [[ $reads -eq $writes ]] ||
11671                 error "read $reads blocks, must be $writes blocks"
11672 }
11673 run_test 121 "read cancel race ========="
11674
11675 test_123a_base() { # was test 123, statahead(bug 11401)
11676         local lsx="$1"
11677
11678         SLOWOK=0
11679         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11680                 log "testing UP system. Performance may be lower than expected."
11681                 SLOWOK=1
11682         fi
11683
11684         rm -rf $DIR/$tdir
11685         test_mkdir $DIR/$tdir
11686         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11687         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11688         MULT=10
11689         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11690                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11691
11692                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11693                 lctl set_param -n llite.*.statahead_max 0
11694                 lctl get_param llite.*.statahead_max
11695                 cancel_lru_locks mdc
11696                 cancel_lru_locks osc
11697                 stime=$(date +%s)
11698                 time $lsx $DIR/$tdir | wc -l
11699                 etime=$(date +%s)
11700                 delta=$((etime - stime))
11701                 log "$lsx $i files without statahead: $delta sec"
11702                 lctl set_param llite.*.statahead_max=$max
11703
11704                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11705                         grep "statahead wrong:" | awk '{print $3}')
11706                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11707                 cancel_lru_locks mdc
11708                 cancel_lru_locks osc
11709                 stime=$(date +%s)
11710                 time $lsx $DIR/$tdir | wc -l
11711                 etime=$(date +%s)
11712                 delta_sa=$((etime - stime))
11713                 log "$lsx $i files with statahead: $delta_sa sec"
11714                 lctl get_param -n llite.*.statahead_stats
11715                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11716                         grep "statahead wrong:" | awk '{print $3}')
11717
11718                 [[ $swrong -lt $ewrong ]] &&
11719                         log "statahead was stopped, maybe too many locks held!"
11720                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11721
11722                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11723                         max=$(lctl get_param -n llite.*.statahead_max |
11724                                 head -n 1)
11725                         lctl set_param -n llite.*.statahead_max 0
11726                         lctl get_param llite.*.statahead_max
11727                         cancel_lru_locks mdc
11728                         cancel_lru_locks osc
11729                         stime=$(date +%s)
11730                         time $lsx $DIR/$tdir | wc -l
11731                         etime=$(date +%s)
11732                         delta=$((etime - stime))
11733                         log "$lsx $i files again without statahead: $delta sec"
11734                         lctl set_param llite.*.statahead_max=$max
11735                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11736                                 if [  $SLOWOK -eq 0 ]; then
11737                                         error "$lsx $i files is slower with statahead!"
11738                                 else
11739                                         log "$lsx $i files is slower with statahead!"
11740                                 fi
11741                                 break
11742                         fi
11743                 fi
11744
11745                 [ $delta -gt 20 ] && break
11746                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11747                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11748         done
11749         log "$lsx done"
11750
11751         stime=$(date +%s)
11752         rm -r $DIR/$tdir
11753         sync
11754         etime=$(date +%s)
11755         delta=$((etime - stime))
11756         log "rm -r $DIR/$tdir/: $delta seconds"
11757         log "rm done"
11758         lctl get_param -n llite.*.statahead_stats
11759 }
11760
11761 test_123aa() {
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763
11764         test_123a_base "ls -l"
11765 }
11766 run_test 123aa "verify statahead work"
11767
11768 test_123ab() {
11769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11770
11771         statx_supported || skip_env "Test must be statx() syscall supported"
11772
11773         test_123a_base "$STATX -l"
11774 }
11775 run_test 123ab "verify statahead work by using statx"
11776
11777 test_123ac() {
11778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11779
11780         statx_supported || skip_env "Test must be statx() syscall supported"
11781
11782         local rpcs_before
11783         local rpcs_after
11784         local agl_before
11785         local agl_after
11786
11787         cancel_lru_locks $OSC
11788         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11789         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11790                 awk '/agl.total:/ {print $3}')
11791         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11792         test_123a_base "$STATX --cached=always -D"
11793         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11794                 awk '/agl.total:/ {print $3}')
11795         [ $agl_before -eq $agl_after ] ||
11796                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11797         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11798         [ $rpcs_after -eq $rpcs_before ] ||
11799                 error "$STATX should not send glimpse RPCs to $OSC"
11800 }
11801 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11802
11803 test_123b () { # statahead(bug 15027)
11804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11805
11806         test_mkdir $DIR/$tdir
11807         createmany -o $DIR/$tdir/$tfile-%d 1000
11808
11809         cancel_lru_locks mdc
11810         cancel_lru_locks osc
11811
11812 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11813         lctl set_param fail_loc=0x80000803
11814         ls -lR $DIR/$tdir > /dev/null
11815         log "ls done"
11816         lctl set_param fail_loc=0x0
11817         lctl get_param -n llite.*.statahead_stats
11818         rm -r $DIR/$tdir
11819         sync
11820
11821 }
11822 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11823
11824 test_123c() {
11825         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11826
11827         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11828         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11829         touch $DIR/$tdir.1/{1..3}
11830         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11831
11832         remount_client $MOUNT
11833
11834         $MULTIOP $DIR/$tdir.0 Q
11835
11836         # let statahead to complete
11837         ls -l $DIR/$tdir.0 > /dev/null
11838
11839         testid=$(echo $TESTNAME | tr '_' ' ')
11840         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11841                 error "statahead warning" || true
11842 }
11843 run_test 123c "Can not initialize inode warning on DNE statahead"
11844
11845 test_124a() {
11846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11847         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11848                 skip_env "no lru resize on server"
11849
11850         local NR=2000
11851
11852         test_mkdir $DIR/$tdir
11853
11854         log "create $NR files at $DIR/$tdir"
11855         createmany -o $DIR/$tdir/f $NR ||
11856                 error "failed to create $NR files in $DIR/$tdir"
11857
11858         cancel_lru_locks mdc
11859         ls -l $DIR/$tdir > /dev/null
11860
11861         local NSDIR=""
11862         local LRU_SIZE=0
11863         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11864                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11865                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11866                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11867                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11868                         log "NSDIR=$NSDIR"
11869                         log "NS=$(basename $NSDIR)"
11870                         break
11871                 fi
11872         done
11873
11874         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11875                 skip "Not enough cached locks created!"
11876         fi
11877         log "LRU=$LRU_SIZE"
11878
11879         local SLEEP=30
11880
11881         # We know that lru resize allows one client to hold $LIMIT locks
11882         # for 10h. After that locks begin to be killed by client.
11883         local MAX_HRS=10
11884         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11885         log "LIMIT=$LIMIT"
11886         if [ $LIMIT -lt $LRU_SIZE ]; then
11887                 skip "Limit is too small $LIMIT"
11888         fi
11889
11890         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11891         # killing locks. Some time was spent for creating locks. This means
11892         # that up to the moment of sleep finish we must have killed some of
11893         # them (10-100 locks). This depends on how fast ther were created.
11894         # Many of them were touched in almost the same moment and thus will
11895         # be killed in groups.
11896         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11897
11898         # Use $LRU_SIZE_B here to take into account real number of locks
11899         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11900         local LRU_SIZE_B=$LRU_SIZE
11901         log "LVF=$LVF"
11902         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11903         log "OLD_LVF=$OLD_LVF"
11904         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11905
11906         # Let's make sure that we really have some margin. Client checks
11907         # cached locks every 10 sec.
11908         SLEEP=$((SLEEP+20))
11909         log "Sleep ${SLEEP} sec"
11910         local SEC=0
11911         while ((SEC<$SLEEP)); do
11912                 echo -n "..."
11913                 sleep 5
11914                 SEC=$((SEC+5))
11915                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11916                 echo -n "$LRU_SIZE"
11917         done
11918         echo ""
11919         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11920         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11921
11922         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11923                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11924                 unlinkmany $DIR/$tdir/f $NR
11925                 return
11926         }
11927
11928         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11929         log "unlink $NR files at $DIR/$tdir"
11930         unlinkmany $DIR/$tdir/f $NR
11931 }
11932 run_test 124a "lru resize ======================================="
11933
11934 get_max_pool_limit()
11935 {
11936         local limit=$($LCTL get_param \
11937                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11938         local max=0
11939         for l in $limit; do
11940                 if [[ $l -gt $max ]]; then
11941                         max=$l
11942                 fi
11943         done
11944         echo $max
11945 }
11946
11947 test_124b() {
11948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11949         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11950                 skip_env "no lru resize on server"
11951
11952         LIMIT=$(get_max_pool_limit)
11953
11954         NR=$(($(default_lru_size)*20))
11955         if [[ $NR -gt $LIMIT ]]; then
11956                 log "Limit lock number by $LIMIT locks"
11957                 NR=$LIMIT
11958         fi
11959
11960         IFree=$(mdsrate_inodes_available)
11961         if [ $IFree -lt $NR ]; then
11962                 log "Limit lock number by $IFree inodes"
11963                 NR=$IFree
11964         fi
11965
11966         lru_resize_disable mdc
11967         test_mkdir -p $DIR/$tdir/disable_lru_resize
11968
11969         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11970         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11971         cancel_lru_locks mdc
11972         stime=`date +%s`
11973         PID=""
11974         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11975         PID="$PID $!"
11976         sleep 2
11977         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11978         PID="$PID $!"
11979         sleep 2
11980         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11981         PID="$PID $!"
11982         wait $PID
11983         etime=`date +%s`
11984         nolruresize_delta=$((etime-stime))
11985         log "ls -la time: $nolruresize_delta seconds"
11986         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11987         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11988
11989         lru_resize_enable mdc
11990         test_mkdir -p $DIR/$tdir/enable_lru_resize
11991
11992         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11993         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11994         cancel_lru_locks mdc
11995         stime=`date +%s`
11996         PID=""
11997         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11998         PID="$PID $!"
11999         sleep 2
12000         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12001         PID="$PID $!"
12002         sleep 2
12003         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12004         PID="$PID $!"
12005         wait $PID
12006         etime=`date +%s`
12007         lruresize_delta=$((etime-stime))
12008         log "ls -la time: $lruresize_delta seconds"
12009         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12010
12011         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12012                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12013         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12014                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12015         else
12016                 log "lru resize performs the same with no lru resize"
12017         fi
12018         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12019 }
12020 run_test 124b "lru resize (performance test) ======================="
12021
12022 test_124c() {
12023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12024         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12025                 skip_env "no lru resize on server"
12026
12027         # cache ununsed locks on client
12028         local nr=100
12029         cancel_lru_locks mdc
12030         test_mkdir $DIR/$tdir
12031         createmany -o $DIR/$tdir/f $nr ||
12032                 error "failed to create $nr files in $DIR/$tdir"
12033         ls -l $DIR/$tdir > /dev/null
12034
12035         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12036         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12037         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12038         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12039         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12040
12041         # set lru_max_age to 1 sec
12042         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12043         echo "sleep $((recalc_p * 2)) seconds..."
12044         sleep $((recalc_p * 2))
12045
12046         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12047         # restore lru_max_age
12048         $LCTL set_param -n $nsdir.lru_max_age $max_age
12049         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12050         unlinkmany $DIR/$tdir/f $nr
12051 }
12052 run_test 124c "LRUR cancel very aged locks"
12053
12054 test_124d() {
12055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12056         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12057                 skip_env "no lru resize on server"
12058
12059         # cache ununsed locks on client
12060         local nr=100
12061
12062         lru_resize_disable mdc
12063         stack_trap "lru_resize_enable mdc" EXIT
12064
12065         cancel_lru_locks mdc
12066
12067         # asynchronous object destroy at MDT could cause bl ast to client
12068         test_mkdir $DIR/$tdir
12069         createmany -o $DIR/$tdir/f $nr ||
12070                 error "failed to create $nr files in $DIR/$tdir"
12071         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12072
12073         ls -l $DIR/$tdir > /dev/null
12074
12075         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12076         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12077         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12078         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12079
12080         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12081
12082         # set lru_max_age to 1 sec
12083         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12084         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12085
12086         echo "sleep $((recalc_p * 2)) seconds..."
12087         sleep $((recalc_p * 2))
12088
12089         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12090
12091         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12092 }
12093 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12094
12095 test_125() { # 13358
12096         $LCTL get_param -n llite.*.client_type | grep -q local ||
12097                 skip "must run as local client"
12098         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12099                 skip_env "must have acl enabled"
12100         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12101
12102         test_mkdir $DIR/$tdir
12103         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12104         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12105         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12106 }
12107 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12108
12109 test_126() { # bug 12829/13455
12110         $GSS && skip_env "must run as gss disabled"
12111         $LCTL get_param -n llite.*.client_type | grep -q local ||
12112                 skip "must run as local client"
12113         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12114
12115         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12116         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12117         rm -f $DIR/$tfile
12118         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12119 }
12120 run_test 126 "check that the fsgid provided by the client is taken into account"
12121
12122 test_127a() { # bug 15521
12123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12124         local name count samp unit min max sum sumsq
12125
12126         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12127         echo "stats before reset"
12128         $LCTL get_param osc.*.stats
12129         $LCTL set_param osc.*.stats=0
12130         local fsize=$((2048 * 1024))
12131
12132         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12133         cancel_lru_locks osc
12134         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12135
12136         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12137         stack_trap "rm -f $TMP/$tfile.tmp"
12138         while read name count samp unit min max sum sumsq; do
12139                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12140                 [ ! $min ] && error "Missing min value for $name proc entry"
12141                 eval $name=$count || error "Wrong proc format"
12142
12143                 case $name in
12144                 read_bytes|write_bytes)
12145                         [[ "$unit" =~ "bytes" ]] ||
12146                                 error "unit is not 'bytes': $unit"
12147                         (( $min >= 4096 )) || error "min is too small: $min"
12148                         (( $min <= $fsize )) || error "min is too big: $min"
12149                         (( $max >= 4096 )) || error "max is too small: $max"
12150                         (( $max <= $fsize )) || error "max is too big: $max"
12151                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12152                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12153                                 error "sumsquare is too small: $sumsq"
12154                         (( $sumsq <= $fsize * $fsize )) ||
12155                                 error "sumsquare is too big: $sumsq"
12156                         ;;
12157                 ost_read|ost_write)
12158                         [[ "$unit" =~ "usec" ]] ||
12159                                 error "unit is not 'usec': $unit"
12160                         ;;
12161                 *)      ;;
12162                 esac
12163         done < $DIR/$tfile.tmp
12164
12165         #check that we actually got some stats
12166         [ "$read_bytes" ] || error "Missing read_bytes stats"
12167         [ "$write_bytes" ] || error "Missing write_bytes stats"
12168         [ "$read_bytes" != 0 ] || error "no read done"
12169         [ "$write_bytes" != 0 ] || error "no write done"
12170 }
12171 run_test 127a "verify the client stats are sane"
12172
12173 test_127b() { # bug LU-333
12174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12175         local name count samp unit min max sum sumsq
12176
12177         echo "stats before reset"
12178         $LCTL get_param llite.*.stats
12179         $LCTL set_param llite.*.stats=0
12180
12181         # perform 2 reads and writes so MAX is different from SUM.
12182         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12183         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12184         cancel_lru_locks osc
12185         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12186         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12187
12188         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12189         stack_trap "rm -f $TMP/$tfile.tmp"
12190         while read name count samp unit min max sum sumsq; do
12191                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12192                 eval $name=$count || error "Wrong proc format"
12193
12194                 case $name in
12195                 read_bytes|write_bytes)
12196                         [[ "$unit" =~ "bytes" ]] ||
12197                                 error "unit is not 'bytes': $unit"
12198                         (( $count == 2 )) || error "count is not 2: $count"
12199                         (( $min == $PAGE_SIZE )) ||
12200                                 error "min is not $PAGE_SIZE: $min"
12201                         (( $max == $PAGE_SIZE )) ||
12202                                 error "max is not $PAGE_SIZE: $max"
12203                         (( $sum == $PAGE_SIZE * 2 )) ||
12204                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12205                         ;;
12206                 read|write)
12207                         [[ "$unit" =~ "usec" ]] ||
12208                                 error "unit is not 'usec': $unit"
12209                         ;;
12210                 *)      ;;
12211                 esac
12212         done < $TMP/$tfile.tmp
12213
12214         #check that we actually got some stats
12215         [ "$read_bytes" ] || error "Missing read_bytes stats"
12216         [ "$write_bytes" ] || error "Missing write_bytes stats"
12217         [ "$read_bytes" != 0 ] || error "no read done"
12218         [ "$write_bytes" != 0 ] || error "no write done"
12219 }
12220 run_test 127b "verify the llite client stats are sane"
12221
12222 test_127c() { # LU-12394
12223         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12224         local size
12225         local bsize
12226         local reads
12227         local writes
12228         local count
12229
12230         $LCTL set_param llite.*.extents_stats=1
12231         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12232
12233         # Use two stripes so there is enough space in default config
12234         $LFS setstripe -c 2 $DIR/$tfile
12235
12236         # Extent stats start at 0-4K and go in power of two buckets
12237         # LL_HIST_START = 12 --> 2^12 = 4K
12238         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12239         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12240         # small configs
12241         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12242                 do
12243                 # Write and read, 2x each, second time at a non-zero offset
12244                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12245                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12246                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12247                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12248                 rm -f $DIR/$tfile
12249         done
12250
12251         $LCTL get_param llite.*.extents_stats
12252
12253         count=2
12254         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12255                 do
12256                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12257                                 grep -m 1 $bsize)
12258                 reads=$(echo $bucket | awk '{print $5}')
12259                 writes=$(echo $bucket | awk '{print $9}')
12260                 [ "$reads" -eq $count ] ||
12261                         error "$reads reads in < $bsize bucket, expect $count"
12262                 [ "$writes" -eq $count ] ||
12263                         error "$writes writes in < $bsize bucket, expect $count"
12264         done
12265
12266         # Test mmap write and read
12267         $LCTL set_param llite.*.extents_stats=c
12268         size=512
12269         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12270         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12271         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12272
12273         $LCTL get_param llite.*.extents_stats
12274
12275         count=$(((size*1024) / PAGE_SIZE))
12276
12277         bsize=$((2 * PAGE_SIZE / 1024))K
12278
12279         bucket=$($LCTL get_param -n llite.*.extents_stats |
12280                         grep -m 1 $bsize)
12281         reads=$(echo $bucket | awk '{print $5}')
12282         writes=$(echo $bucket | awk '{print $9}')
12283         # mmap writes fault in the page first, creating an additonal read
12284         [ "$reads" -eq $((2 * count)) ] ||
12285                 error "$reads reads in < $bsize bucket, expect $count"
12286         [ "$writes" -eq $count ] ||
12287                 error "$writes writes in < $bsize bucket, expect $count"
12288 }
12289 run_test 127c "test llite extent stats with regular & mmap i/o"
12290
12291 test_128() { # bug 15212
12292         touch $DIR/$tfile
12293         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12294                 find $DIR/$tfile
12295                 find $DIR/$tfile
12296         EOF
12297
12298         result=$(grep error $TMP/$tfile.log)
12299         rm -f $DIR/$tfile $TMP/$tfile.log
12300         [ -z "$result" ] ||
12301                 error "consecutive find's under interactive lfs failed"
12302 }
12303 run_test 128 "interactive lfs for 2 consecutive find's"
12304
12305 set_dir_limits () {
12306         local mntdev
12307         local canondev
12308         local node
12309
12310         local ldproc=/proc/fs/ldiskfs
12311         local facets=$(get_facets MDS)
12312
12313         for facet in ${facets//,/ }; do
12314                 canondev=$(ldiskfs_canon \
12315                            *.$(convert_facet2label $facet).mntdev $facet)
12316                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12317                         ldproc=/sys/fs/ldiskfs
12318                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12319                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12320         done
12321 }
12322
12323 check_mds_dmesg() {
12324         local facets=$(get_facets MDS)
12325         for facet in ${facets//,/ }; do
12326                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12327         done
12328         return 1
12329 }
12330
12331 test_129() {
12332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12333         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12334                 skip "Need MDS version with at least 2.5.56"
12335         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12336                 skip_env "ldiskfs only test"
12337         fi
12338         remote_mds_nodsh && skip "remote MDS with nodsh"
12339
12340         local ENOSPC=28
12341         local has_warning=false
12342
12343         rm -rf $DIR/$tdir
12344         mkdir -p $DIR/$tdir
12345
12346         # block size of mds1
12347         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12348         set_dir_limits $maxsize $((maxsize * 6 / 8))
12349         stack_trap "set_dir_limits 0 0"
12350         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12351         local dirsize=$(stat -c%s "$DIR/$tdir")
12352         local nfiles=0
12353         while (( $dirsize <= $maxsize )); do
12354                 $MCREATE $DIR/$tdir/file_base_$nfiles
12355                 rc=$?
12356                 # check two errors:
12357                 # ENOSPC for ext4 max_dir_size, which has been used since
12358                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12359                 if (( rc == ENOSPC )); then
12360                         set_dir_limits 0 0
12361                         echo "rc=$rc returned as expected after $nfiles files"
12362
12363                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12364                                 error "create failed w/o dir size limit"
12365
12366                         # messages may be rate limited if test is run repeatedly
12367                         check_mds_dmesg '"is approaching max"' ||
12368                                 echo "warning message should be output"
12369                         check_mds_dmesg '"has reached max"' ||
12370                                 echo "reached message should be output"
12371
12372                         dirsize=$(stat -c%s "$DIR/$tdir")
12373
12374                         [[ $dirsize -ge $maxsize ]] && return 0
12375                         error "dirsize $dirsize < $maxsize after $nfiles files"
12376                 elif (( rc != 0 )); then
12377                         break
12378                 fi
12379                 nfiles=$((nfiles + 1))
12380                 dirsize=$(stat -c%s "$DIR/$tdir")
12381         done
12382
12383         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12384 }
12385 run_test 129 "test directory size limit ========================"
12386
12387 OLDIFS="$IFS"
12388 cleanup_130() {
12389         trap 0
12390         IFS="$OLDIFS"
12391 }
12392
12393 test_130a() {
12394         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12395         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12396
12397         trap cleanup_130 EXIT RETURN
12398
12399         local fm_file=$DIR/$tfile
12400         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12401         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12402                 error "dd failed for $fm_file"
12403
12404         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12405         filefrag -ves $fm_file
12406         RC=$?
12407         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12408                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12409         [ $RC != 0 ] && error "filefrag $fm_file failed"
12410
12411         filefrag_op=$(filefrag -ve -k $fm_file |
12412                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12413         lun=$($LFS getstripe -i $fm_file)
12414
12415         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12416         IFS=$'\n'
12417         tot_len=0
12418         for line in $filefrag_op
12419         do
12420                 frag_lun=`echo $line | cut -d: -f5`
12421                 ext_len=`echo $line | cut -d: -f4`
12422                 if (( $frag_lun != $lun )); then
12423                         cleanup_130
12424                         error "FIEMAP on 1-stripe file($fm_file) failed"
12425                         return
12426                 fi
12427                 (( tot_len += ext_len ))
12428         done
12429
12430         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12431                 cleanup_130
12432                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12433                 return
12434         fi
12435
12436         cleanup_130
12437
12438         echo "FIEMAP on single striped file succeeded"
12439 }
12440 run_test 130a "FIEMAP (1-stripe file)"
12441
12442 test_130b() {
12443         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12444
12445         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12446         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12447
12448         trap cleanup_130 EXIT RETURN
12449
12450         local fm_file=$DIR/$tfile
12451         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12452                         error "setstripe on $fm_file"
12453         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12454                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12455
12456         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12457                 error "dd failed on $fm_file"
12458
12459         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12460         filefrag_op=$(filefrag -ve -k $fm_file |
12461                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12462
12463         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12464                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12465
12466         IFS=$'\n'
12467         tot_len=0
12468         num_luns=1
12469         for line in $filefrag_op
12470         do
12471                 frag_lun=$(echo $line | cut -d: -f5 |
12472                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12473                 ext_len=$(echo $line | cut -d: -f4)
12474                 if (( $frag_lun != $last_lun )); then
12475                         if (( tot_len != 1024 )); then
12476                                 cleanup_130
12477                                 error "FIEMAP on $fm_file failed; returned " \
12478                                 "len $tot_len for OST $last_lun instead of 1024"
12479                                 return
12480                         else
12481                                 (( num_luns += 1 ))
12482                                 tot_len=0
12483                         fi
12484                 fi
12485                 (( tot_len += ext_len ))
12486                 last_lun=$frag_lun
12487         done
12488         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12489                 cleanup_130
12490                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12491                         "luns or wrong len for OST $last_lun"
12492                 return
12493         fi
12494
12495         cleanup_130
12496
12497         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12498 }
12499 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12500
12501 test_130c() {
12502         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12503
12504         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12505         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12506
12507         trap cleanup_130 EXIT RETURN
12508
12509         local fm_file=$DIR/$tfile
12510         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12511         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12512                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12513
12514         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12515                         error "dd failed on $fm_file"
12516
12517         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12518         filefrag_op=$(filefrag -ve -k $fm_file |
12519                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12520
12521         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12522                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12523
12524         IFS=$'\n'
12525         tot_len=0
12526         num_luns=1
12527         for line in $filefrag_op
12528         do
12529                 frag_lun=$(echo $line | cut -d: -f5 |
12530                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12531                 ext_len=$(echo $line | cut -d: -f4)
12532                 if (( $frag_lun != $last_lun )); then
12533                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12534                         if (( logical != 512 )); then
12535                                 cleanup_130
12536                                 error "FIEMAP on $fm_file failed; returned " \
12537                                 "logical start for lun $logical instead of 512"
12538                                 return
12539                         fi
12540                         if (( tot_len != 512 )); then
12541                                 cleanup_130
12542                                 error "FIEMAP on $fm_file failed; returned " \
12543                                 "len $tot_len for OST $last_lun instead of 1024"
12544                                 return
12545                         else
12546                                 (( num_luns += 1 ))
12547                                 tot_len=0
12548                         fi
12549                 fi
12550                 (( tot_len += ext_len ))
12551                 last_lun=$frag_lun
12552         done
12553         if (( num_luns != 2 || tot_len != 512 )); then
12554                 cleanup_130
12555                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12556                         "luns or wrong len for OST $last_lun"
12557                 return
12558         fi
12559
12560         cleanup_130
12561
12562         echo "FIEMAP on 2-stripe file with hole succeeded"
12563 }
12564 run_test 130c "FIEMAP (2-stripe file with hole)"
12565
12566 test_130d() {
12567         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12568
12569         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12570         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12571
12572         trap cleanup_130 EXIT RETURN
12573
12574         local fm_file=$DIR/$tfile
12575         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12576                         error "setstripe on $fm_file"
12577         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12578                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12579
12580         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12581         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12582                 error "dd failed on $fm_file"
12583
12584         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12585         filefrag_op=$(filefrag -ve -k $fm_file |
12586                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12587
12588         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12589                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12590
12591         IFS=$'\n'
12592         tot_len=0
12593         num_luns=1
12594         for line in $filefrag_op
12595         do
12596                 frag_lun=$(echo $line | cut -d: -f5 |
12597                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12598                 ext_len=$(echo $line | cut -d: -f4)
12599                 if (( $frag_lun != $last_lun )); then
12600                         if (( tot_len != 1024 )); then
12601                                 cleanup_130
12602                                 error "FIEMAP on $fm_file failed; returned " \
12603                                 "len $tot_len for OST $last_lun instead of 1024"
12604                                 return
12605                         else
12606                                 (( num_luns += 1 ))
12607                                 tot_len=0
12608                         fi
12609                 fi
12610                 (( tot_len += ext_len ))
12611                 last_lun=$frag_lun
12612         done
12613         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12614                 cleanup_130
12615                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12616                         "luns or wrong len for OST $last_lun"
12617                 return
12618         fi
12619
12620         cleanup_130
12621
12622         echo "FIEMAP on N-stripe file succeeded"
12623 }
12624 run_test 130d "FIEMAP (N-stripe file)"
12625
12626 test_130e() {
12627         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12628
12629         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12630         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12631
12632         trap cleanup_130 EXIT RETURN
12633
12634         local fm_file=$DIR/$tfile
12635         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12636         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12637                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12638
12639         NUM_BLKS=512
12640         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12641         for ((i = 0; i < $NUM_BLKS; i++))
12642         do
12643                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12644         done
12645
12646         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12647         filefrag_op=$(filefrag -ve -k $fm_file |
12648                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12649
12650         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12651                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12652
12653         IFS=$'\n'
12654         tot_len=0
12655         num_luns=1
12656         for line in $filefrag_op
12657         do
12658                 frag_lun=$(echo $line | cut -d: -f5 |
12659                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12660                 ext_len=$(echo $line | cut -d: -f4)
12661                 if (( $frag_lun != $last_lun )); then
12662                         if (( tot_len != $EXPECTED_LEN )); then
12663                                 cleanup_130
12664                                 error "FIEMAP on $fm_file failed; returned " \
12665                                 "len $tot_len for OST $last_lun instead " \
12666                                 "of $EXPECTED_LEN"
12667                                 return
12668                         else
12669                                 (( num_luns += 1 ))
12670                                 tot_len=0
12671                         fi
12672                 fi
12673                 (( tot_len += ext_len ))
12674                 last_lun=$frag_lun
12675         done
12676         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12677                 cleanup_130
12678                 error "FIEMAP on $fm_file failed; returned wrong number " \
12679                         "of luns or wrong len for OST $last_lun"
12680                 return
12681         fi
12682
12683         cleanup_130
12684
12685         echo "FIEMAP with continuation calls succeeded"
12686 }
12687 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12688
12689 test_130f() {
12690         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12691         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12692
12693         local fm_file=$DIR/$tfile
12694         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12695                 error "multiop create with lov_delay_create on $fm_file"
12696
12697         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12698         filefrag_extents=$(filefrag -vek $fm_file |
12699                            awk '/extents? found/ { print $2 }')
12700         if [[ "$filefrag_extents" != "0" ]]; then
12701                 error "FIEMAP on $fm_file failed; " \
12702                       "returned $filefrag_extents expected 0"
12703         fi
12704
12705         rm -f $fm_file
12706 }
12707 run_test 130f "FIEMAP (unstriped file)"
12708
12709 # Test for writev/readv
12710 test_131a() {
12711         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12712                 error "writev test failed"
12713         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12714                 error "readv failed"
12715         rm -f $DIR/$tfile
12716 }
12717 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12718
12719 test_131b() {
12720         local fsize=$((524288 + 1048576 + 1572864))
12721         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12722                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12723                         error "append writev test failed"
12724
12725         ((fsize += 1572864 + 1048576))
12726         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12727                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12728                         error "append writev test failed"
12729         rm -f $DIR/$tfile
12730 }
12731 run_test 131b "test append writev"
12732
12733 test_131c() {
12734         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12735         error "NOT PASS"
12736 }
12737 run_test 131c "test read/write on file w/o objects"
12738
12739 test_131d() {
12740         rwv -f $DIR/$tfile -w -n 1 1572864
12741         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12742         if [ "$NOB" != 1572864 ]; then
12743                 error "Short read filed: read $NOB bytes instead of 1572864"
12744         fi
12745         rm -f $DIR/$tfile
12746 }
12747 run_test 131d "test short read"
12748
12749 test_131e() {
12750         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12751         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12752         error "read hitting hole failed"
12753         rm -f $DIR/$tfile
12754 }
12755 run_test 131e "test read hitting hole"
12756
12757 check_stats() {
12758         local facet=$1
12759         local op=$2
12760         local want=${3:-0}
12761         local res
12762
12763         case $facet in
12764         mds*) res=$(do_facet $facet \
12765                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12766                  ;;
12767         ost*) res=$(do_facet $facet \
12768                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12769                  ;;
12770         *) error "Wrong facet '$facet'" ;;
12771         esac
12772         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12773         # if the argument $3 is zero, it means any stat increment is ok.
12774         if [[ $want -gt 0 ]]; then
12775                 local count=$(echo $res | awk '{ print $2 }')
12776                 [[ $count -ne $want ]] &&
12777                         error "The $op counter on $facet is $count, not $want"
12778         fi
12779 }
12780
12781 test_133a() {
12782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12783         remote_ost_nodsh && skip "remote OST with nodsh"
12784         remote_mds_nodsh && skip "remote MDS with nodsh"
12785         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12786                 skip_env "MDS doesn't support rename stats"
12787
12788         local testdir=$DIR/${tdir}/stats_testdir
12789
12790         mkdir -p $DIR/${tdir}
12791
12792         # clear stats.
12793         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12794         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12795
12796         # verify mdt stats first.
12797         mkdir ${testdir} || error "mkdir failed"
12798         check_stats $SINGLEMDS "mkdir" 1
12799         touch ${testdir}/${tfile} || error "touch failed"
12800         check_stats $SINGLEMDS "open" 1
12801         check_stats $SINGLEMDS "close" 1
12802         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12803                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12804                 check_stats $SINGLEMDS "mknod" 2
12805         }
12806         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12807         check_stats $SINGLEMDS "unlink" 1
12808         rm -f ${testdir}/${tfile} || error "file remove failed"
12809         check_stats $SINGLEMDS "unlink" 2
12810
12811         # remove working dir and check mdt stats again.
12812         rmdir ${testdir} || error "rmdir failed"
12813         check_stats $SINGLEMDS "rmdir" 1
12814
12815         local testdir1=$DIR/${tdir}/stats_testdir1
12816         mkdir -p ${testdir}
12817         mkdir -p ${testdir1}
12818         touch ${testdir1}/test1
12819         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12820         check_stats $SINGLEMDS "crossdir_rename" 1
12821
12822         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12823         check_stats $SINGLEMDS "samedir_rename" 1
12824
12825         rm -rf $DIR/${tdir}
12826 }
12827 run_test 133a "Verifying MDT stats ========================================"
12828
12829 test_133b() {
12830         local res
12831
12832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12833         remote_ost_nodsh && skip "remote OST with nodsh"
12834         remote_mds_nodsh && skip "remote MDS with nodsh"
12835
12836         local testdir=$DIR/${tdir}/stats_testdir
12837
12838         mkdir -p ${testdir} || error "mkdir failed"
12839         touch ${testdir}/${tfile} || error "touch failed"
12840         cancel_lru_locks mdc
12841
12842         # clear stats.
12843         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12844         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12845
12846         # extra mdt stats verification.
12847         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12848         check_stats $SINGLEMDS "setattr" 1
12849         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12850         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12851         then            # LU-1740
12852                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12853                 check_stats $SINGLEMDS "getattr" 1
12854         fi
12855         rm -rf $DIR/${tdir}
12856
12857         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12858         # so the check below is not reliable
12859         [ $MDSCOUNT -eq 1 ] || return 0
12860
12861         # Sleep to avoid a cached response.
12862         #define OBD_STATFS_CACHE_SECONDS 1
12863         sleep 2
12864         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12865         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12866         $LFS df || error "lfs failed"
12867         check_stats $SINGLEMDS "statfs" 1
12868
12869         # check aggregated statfs (LU-10018)
12870         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12871                 return 0
12872         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12873                 return 0
12874         sleep 2
12875         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12876         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12877         df $DIR
12878         check_stats $SINGLEMDS "statfs" 1
12879
12880         # We want to check that the client didn't send OST_STATFS to
12881         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12882         # extra care is needed here.
12883         if remote_mds; then
12884                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12885                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12886
12887                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12888                 [ "$res" ] && error "OST got STATFS"
12889         fi
12890
12891         return 0
12892 }
12893 run_test 133b "Verifying extra MDT stats =================================="
12894
12895 test_133c() {
12896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12897         remote_ost_nodsh && skip "remote OST with nodsh"
12898         remote_mds_nodsh && skip "remote MDS with nodsh"
12899
12900         local testdir=$DIR/$tdir/stats_testdir
12901
12902         test_mkdir -p $testdir
12903
12904         # verify obdfilter stats.
12905         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12906         sync
12907         cancel_lru_locks osc
12908         wait_delete_completed
12909
12910         # clear stats.
12911         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12912         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12913
12914         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12915                 error "dd failed"
12916         sync
12917         cancel_lru_locks osc
12918         check_stats ost1 "write" 1
12919
12920         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12921         check_stats ost1 "read" 1
12922
12923         > $testdir/$tfile || error "truncate failed"
12924         check_stats ost1 "punch" 1
12925
12926         rm -f $testdir/$tfile || error "file remove failed"
12927         wait_delete_completed
12928         check_stats ost1 "destroy" 1
12929
12930         rm -rf $DIR/$tdir
12931 }
12932 run_test 133c "Verifying OST stats ========================================"
12933
12934 order_2() {
12935         local value=$1
12936         local orig=$value
12937         local order=1
12938
12939         while [ $value -ge 2 ]; do
12940                 order=$((order*2))
12941                 value=$((value/2))
12942         done
12943
12944         if [ $orig -gt $order ]; then
12945                 order=$((order*2))
12946         fi
12947         echo $order
12948 }
12949
12950 size_in_KMGT() {
12951     local value=$1
12952     local size=('K' 'M' 'G' 'T');
12953     local i=0
12954     local size_string=$value
12955
12956     while [ $value -ge 1024 ]; do
12957         if [ $i -gt 3 ]; then
12958             #T is the biggest unit we get here, if that is bigger,
12959             #just return XXXT
12960             size_string=${value}T
12961             break
12962         fi
12963         value=$((value >> 10))
12964         if [ $value -lt 1024 ]; then
12965             size_string=${value}${size[$i]}
12966             break
12967         fi
12968         i=$((i + 1))
12969     done
12970
12971     echo $size_string
12972 }
12973
12974 get_rename_size() {
12975         local size=$1
12976         local context=${2:-.}
12977         local sample=$(do_facet $SINGLEMDS $LCTL \
12978                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12979                 grep -A1 $context |
12980                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12981         echo $sample
12982 }
12983
12984 test_133d() {
12985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12986         remote_ost_nodsh && skip "remote OST with nodsh"
12987         remote_mds_nodsh && skip "remote MDS with nodsh"
12988         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12989                 skip_env "MDS doesn't support rename stats"
12990
12991         local testdir1=$DIR/${tdir}/stats_testdir1
12992         local testdir2=$DIR/${tdir}/stats_testdir2
12993         mkdir -p $DIR/${tdir}
12994
12995         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12996
12997         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12998         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12999
13000         createmany -o $testdir1/test 512 || error "createmany failed"
13001
13002         # check samedir rename size
13003         mv ${testdir1}/test0 ${testdir1}/test_0
13004
13005         local testdir1_size=$(ls -l $DIR/${tdir} |
13006                 awk '/stats_testdir1/ {print $5}')
13007         local testdir2_size=$(ls -l $DIR/${tdir} |
13008                 awk '/stats_testdir2/ {print $5}')
13009
13010         testdir1_size=$(order_2 $testdir1_size)
13011         testdir2_size=$(order_2 $testdir2_size)
13012
13013         testdir1_size=$(size_in_KMGT $testdir1_size)
13014         testdir2_size=$(size_in_KMGT $testdir2_size)
13015
13016         echo "source rename dir size: ${testdir1_size}"
13017         echo "target rename dir size: ${testdir2_size}"
13018
13019         local cmd="do_facet $SINGLEMDS $LCTL "
13020         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13021
13022         eval $cmd || error "$cmd failed"
13023         local samedir=$($cmd | grep 'same_dir')
13024         local same_sample=$(get_rename_size $testdir1_size)
13025         [ -z "$samedir" ] && error "samedir_rename_size count error"
13026         [[ $same_sample -eq 1 ]] ||
13027                 error "samedir_rename_size error $same_sample"
13028         echo "Check same dir rename stats success"
13029
13030         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13031
13032         # check crossdir rename size
13033         mv ${testdir1}/test_0 ${testdir2}/test_0
13034
13035         testdir1_size=$(ls -l $DIR/${tdir} |
13036                 awk '/stats_testdir1/ {print $5}')
13037         testdir2_size=$(ls -l $DIR/${tdir} |
13038                 awk '/stats_testdir2/ {print $5}')
13039
13040         testdir1_size=$(order_2 $testdir1_size)
13041         testdir2_size=$(order_2 $testdir2_size)
13042
13043         testdir1_size=$(size_in_KMGT $testdir1_size)
13044         testdir2_size=$(size_in_KMGT $testdir2_size)
13045
13046         echo "source rename dir size: ${testdir1_size}"
13047         echo "target rename dir size: ${testdir2_size}"
13048
13049         eval $cmd || error "$cmd failed"
13050         local crossdir=$($cmd | grep 'crossdir')
13051         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13052         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13053         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13054         [[ $src_sample -eq 1 ]] ||
13055                 error "crossdir_rename_size error $src_sample"
13056         [[ $tgt_sample -eq 1 ]] ||
13057                 error "crossdir_rename_size error $tgt_sample"
13058         echo "Check cross dir rename stats success"
13059         rm -rf $DIR/${tdir}
13060 }
13061 run_test 133d "Verifying rename_stats ========================================"
13062
13063 test_133e() {
13064         remote_mds_nodsh && skip "remote MDS with nodsh"
13065         remote_ost_nodsh && skip "remote OST with nodsh"
13066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13067
13068         local testdir=$DIR/${tdir}/stats_testdir
13069         local ctr f0 f1 bs=32768 count=42 sum
13070
13071         mkdir -p ${testdir} || error "mkdir failed"
13072
13073         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13074
13075         for ctr in {write,read}_bytes; do
13076                 sync
13077                 cancel_lru_locks osc
13078
13079                 do_facet ost1 $LCTL set_param -n \
13080                         "obdfilter.*.exports.clear=clear"
13081
13082                 if [ $ctr = write_bytes ]; then
13083                         f0=/dev/zero
13084                         f1=${testdir}/${tfile}
13085                 else
13086                         f0=${testdir}/${tfile}
13087                         f1=/dev/null
13088                 fi
13089
13090                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13091                         error "dd failed"
13092                 sync
13093                 cancel_lru_locks osc
13094
13095                 sum=$(do_facet ost1 $LCTL get_param \
13096                         "obdfilter.*.exports.*.stats" |
13097                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13098                                 $1 == ctr { sum += $7 }
13099                                 END { printf("%0.0f", sum) }')
13100
13101                 if ((sum != bs * count)); then
13102                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13103                 fi
13104         done
13105
13106         rm -rf $DIR/${tdir}
13107 }
13108 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13109
13110 test_133f() {
13111         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13112                 skip "too old lustre for get_param -R ($facet_ver)"
13113
13114         # verifying readability.
13115         $LCTL get_param -R '*' &> /dev/null
13116
13117         # Verifing writability with badarea_io.
13118         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13119                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13120                 error "client badarea_io failed"
13121
13122         # remount the FS in case writes/reads /proc break the FS
13123         cleanup || error "failed to unmount"
13124         setup || error "failed to setup"
13125 }
13126 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13127
13128 test_133g() {
13129         remote_mds_nodsh && skip "remote MDS with nodsh"
13130         remote_ost_nodsh && skip "remote OST with nodsh"
13131
13132         local facet
13133         for facet in mds1 ost1; do
13134                 local facet_ver=$(lustre_version_code $facet)
13135                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13136                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13137                 else
13138                         log "$facet: too old lustre for get_param -R"
13139                 fi
13140                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13141                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13142                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13143                                 xargs badarea_io" ||
13144                                         error "$facet badarea_io failed"
13145                 else
13146                         skip_noexit "$facet: too old lustre for get_param -R"
13147                 fi
13148         done
13149
13150         # remount the FS in case writes/reads /proc break the FS
13151         cleanup || error "failed to unmount"
13152         setup || error "failed to setup"
13153 }
13154 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13155
13156 test_133h() {
13157         remote_mds_nodsh && skip "remote MDS with nodsh"
13158         remote_ost_nodsh && skip "remote OST with nodsh"
13159         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13160                 skip "Need MDS version at least 2.9.54"
13161
13162         local facet
13163         for facet in client mds1 ost1; do
13164                 # Get the list of files that are missing the terminating newline
13165                 local plist=$(do_facet $facet
13166                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13167                 local ent
13168                 for ent in $plist; do
13169                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13170                                 awk -v FS='\v' -v RS='\v\v' \
13171                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13172                                         print FILENAME}'" 2>/dev/null)
13173                         [ -z $missing ] || {
13174                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13175                                 error "file does not end with newline: $facet-$ent"
13176                         }
13177                 done
13178         done
13179 }
13180 run_test 133h "Proc files should end with newlines"
13181
13182 test_134a() {
13183         remote_mds_nodsh && skip "remote MDS with nodsh"
13184         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13185                 skip "Need MDS version at least 2.7.54"
13186
13187         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13188         cancel_lru_locks mdc
13189
13190         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13191         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13192         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13193
13194         local nr=1000
13195         createmany -o $DIR/$tdir/f $nr ||
13196                 error "failed to create $nr files in $DIR/$tdir"
13197         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13198
13199         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13200         do_facet mds1 $LCTL set_param fail_loc=0x327
13201         do_facet mds1 $LCTL set_param fail_val=500
13202         touch $DIR/$tdir/m
13203
13204         echo "sleep 10 seconds ..."
13205         sleep 10
13206         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13207
13208         do_facet mds1 $LCTL set_param fail_loc=0
13209         do_facet mds1 $LCTL set_param fail_val=0
13210         [ $lck_cnt -lt $unused ] ||
13211                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13212
13213         rm $DIR/$tdir/m
13214         unlinkmany $DIR/$tdir/f $nr
13215 }
13216 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13217
13218 test_134b() {
13219         remote_mds_nodsh && skip "remote MDS with nodsh"
13220         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13221                 skip "Need MDS version at least 2.7.54"
13222
13223         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13224         cancel_lru_locks mdc
13225
13226         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13227                         ldlm.lock_reclaim_threshold_mb)
13228         # disable reclaim temporarily
13229         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13230
13231         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13232         do_facet mds1 $LCTL set_param fail_loc=0x328
13233         do_facet mds1 $LCTL set_param fail_val=500
13234
13235         $LCTL set_param debug=+trace
13236
13237         local nr=600
13238         createmany -o $DIR/$tdir/f $nr &
13239         local create_pid=$!
13240
13241         echo "Sleep $TIMEOUT seconds ..."
13242         sleep $TIMEOUT
13243         if ! ps -p $create_pid  > /dev/null 2>&1; then
13244                 do_facet mds1 $LCTL set_param fail_loc=0
13245                 do_facet mds1 $LCTL set_param fail_val=0
13246                 do_facet mds1 $LCTL set_param \
13247                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13248                 error "createmany finished incorrectly!"
13249         fi
13250         do_facet mds1 $LCTL set_param fail_loc=0
13251         do_facet mds1 $LCTL set_param fail_val=0
13252         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13253         wait $create_pid || return 1
13254
13255         unlinkmany $DIR/$tdir/f $nr
13256 }
13257 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13258
13259 test_135() {
13260         remote_mds_nodsh && skip "remote MDS with nodsh"
13261         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13262                 skip "Need MDS version at least 2.13.50"
13263         local fname
13264
13265         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13266
13267 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13268         #set only one record at plain llog
13269         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13270
13271         #fill already existed plain llog each 64767
13272         #wrapping whole catalog
13273         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13274
13275         createmany -o $DIR/$tdir/$tfile_ 64700
13276         for (( i = 0; i < 64700; i = i + 2 ))
13277         do
13278                 rm $DIR/$tdir/$tfile_$i &
13279                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13280                 local pid=$!
13281                 wait $pid
13282         done
13283
13284         #waiting osp synchronization
13285         wait_delete_completed
13286 }
13287 run_test 135 "Race catalog processing"
13288
13289 test_136() {
13290         remote_mds_nodsh && skip "remote MDS with nodsh"
13291         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13292                 skip "Need MDS version at least 2.13.50"
13293         local fname
13294
13295         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13296         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13297         #set only one record at plain llog
13298 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13299         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13300
13301         #fill already existed 2 plain llogs each 64767
13302         #wrapping whole catalog
13303         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13304         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13305         wait_delete_completed
13306
13307         createmany -o $DIR/$tdir/$tfile_ 10
13308         sleep 25
13309
13310         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13311         for (( i = 0; i < 10; i = i + 3 ))
13312         do
13313                 rm $DIR/$tdir/$tfile_$i &
13314                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13315                 local pid=$!
13316                 wait $pid
13317                 sleep 7
13318                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13319         done
13320
13321         #waiting osp synchronization
13322         wait_delete_completed
13323 }
13324 run_test 136 "Race catalog processing 2"
13325
13326 test_140() { #bug-17379
13327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13328
13329         test_mkdir $DIR/$tdir
13330         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13331         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13332
13333         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13334         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13335         local i=0
13336         while i=$((i + 1)); do
13337                 test_mkdir $i
13338                 cd $i || error "Changing to $i"
13339                 ln -s ../stat stat || error "Creating stat symlink"
13340                 # Read the symlink until ELOOP present,
13341                 # not LBUGing the system is considered success,
13342                 # we didn't overrun the stack.
13343                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13344                 if [ $ret -ne 0 ]; then
13345                         if [ $ret -eq 40 ]; then
13346                                 break  # -ELOOP
13347                         else
13348                                 error "Open stat symlink"
13349                                         return
13350                         fi
13351                 fi
13352         done
13353         i=$((i - 1))
13354         echo "The symlink depth = $i"
13355         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13356                 error "Invalid symlink depth"
13357
13358         # Test recursive symlink
13359         ln -s symlink_self symlink_self
13360         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13361         echo "open symlink_self returns $ret"
13362         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13363 }
13364 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13365
13366 test_150a() {
13367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13368
13369         local TF="$TMP/$tfile"
13370
13371         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13372         cp $TF $DIR/$tfile
13373         cancel_lru_locks $OSC
13374         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13375         remount_client $MOUNT
13376         df -P $MOUNT
13377         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13378
13379         $TRUNCATE $TF 6000
13380         $TRUNCATE $DIR/$tfile 6000
13381         cancel_lru_locks $OSC
13382         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13383
13384         echo "12345" >>$TF
13385         echo "12345" >>$DIR/$tfile
13386         cancel_lru_locks $OSC
13387         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13388
13389         echo "12345" >>$TF
13390         echo "12345" >>$DIR/$tfile
13391         cancel_lru_locks $OSC
13392         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13393
13394         rm -f $TF
13395         true
13396 }
13397 run_test 150a "truncate/append tests"
13398
13399 test_150b() {
13400         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13401         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13402                 skip "Need OST version at least 2.13.53"
13403         touch $DIR/$tfile
13404         check_fallocate $DIR/$tfile || error "fallocate failed"
13405 }
13406 run_test 150b "Verify fallocate (prealloc) functionality"
13407
13408 test_150c() {
13409         local bytes
13410         local want
13411
13412         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13413         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13414                 skip "Need OST version at least 2.13.53"
13415
13416         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13417         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13418         sync; sync_all_data
13419         cancel_lru_locks $OSC
13420         sleep 5
13421         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13422         want=$((OSTCOUNT * 1048576))
13423
13424         # Must allocate all requested space, not more than 5% extra
13425         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13426                 error "bytes $bytes is not $want"
13427 }
13428 run_test 150c "Verify fallocate Size and Blocks"
13429
13430 test_150d() {
13431         local bytes
13432         local want
13433
13434         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13435         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13436                 skip "Need OST version at least 2.13.53"
13437
13438         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13439         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13440         sync; sync_all_data
13441         cancel_lru_locks $OSC
13442         sleep 5
13443         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13444         want=$((OSTCOUNT * 1048576))
13445
13446         # Must allocate all requested space, not more than 5% extra
13447         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13448                 error "bytes $bytes is not $want"
13449 }
13450 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13451
13452 test_150e() {
13453         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13454         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13455                 skip "Need OST version at least 2.13.55"
13456
13457         echo "df before:"
13458         $LFS df
13459         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13460                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13461
13462         # Find OST with Minimum Size
13463         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13464                        sort -un | head -1)
13465
13466         # Get 90% of the available space
13467         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13468
13469         fallocate -l${space}k $DIR/$tfile ||
13470                 error "fallocate ${space}k $DIR/$tfile failed"
13471         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13472
13473         # get size immediately after fallocate. This should be correctly
13474         # updated
13475         local size=$(stat -c '%s' $DIR/$tfile)
13476         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13477
13478         # Sleep for a while for statfs to get updated. And not pull from cache.
13479         sleep 2
13480
13481         echo "df after fallocate:"
13482         $LFS df
13483
13484         (( size / 1024 == space )) || error "size $size != requested $space"
13485         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13486                 error "used $used < space $space"
13487
13488         rm $DIR/$tfile || error "rm failed"
13489         sync
13490         wait_delete_completed
13491
13492         echo "df after unlink:"
13493         $LFS df
13494 }
13495 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13496
13497 #LU-2902 roc_hit was not able to read all values from lproc
13498 function roc_hit_init() {
13499         local list=$(comma_list $(osts_nodes))
13500         local dir=$DIR/$tdir-check
13501         local file=$dir/$tfile
13502         local BEFORE
13503         local AFTER
13504         local idx
13505
13506         test_mkdir $dir
13507         #use setstripe to do a write to every ost
13508         for i in $(seq 0 $((OSTCOUNT-1))); do
13509                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13510                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13511                 idx=$(printf %04x $i)
13512                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13513                         awk '$1 == "cache_access" {sum += $7}
13514                                 END { printf("%0.0f", sum) }')
13515
13516                 cancel_lru_locks osc
13517                 cat $file >/dev/null
13518
13519                 AFTER=$(get_osd_param $list *OST*$idx stats |
13520                         awk '$1 == "cache_access" {sum += $7}
13521                                 END { printf("%0.0f", sum) }')
13522
13523                 echo BEFORE:$BEFORE AFTER:$AFTER
13524                 if ! let "AFTER - BEFORE == 4"; then
13525                         rm -rf $dir
13526                         error "roc_hit is not safe to use"
13527                 fi
13528                 rm $file
13529         done
13530
13531         rm -rf $dir
13532 }
13533
13534 function roc_hit() {
13535         local list=$(comma_list $(osts_nodes))
13536         echo $(get_osd_param $list '' stats |
13537                 awk '$1 == "cache_hit" {sum += $7}
13538                         END { printf("%0.0f", sum) }')
13539 }
13540
13541 function set_cache() {
13542         local on=1
13543
13544         if [ "$2" == "off" ]; then
13545                 on=0;
13546         fi
13547         local list=$(comma_list $(osts_nodes))
13548         set_osd_param $list '' $1_cache_enable $on
13549
13550         cancel_lru_locks osc
13551 }
13552
13553 test_151() {
13554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13555         remote_ost_nodsh && skip "remote OST with nodsh"
13556
13557         local CPAGES=3
13558         local list=$(comma_list $(osts_nodes))
13559
13560         # check whether obdfilter is cache capable at all
13561         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13562                 skip "not cache-capable obdfilter"
13563         fi
13564
13565         # check cache is enabled on all obdfilters
13566         if get_osd_param $list '' read_cache_enable | grep 0; then
13567                 skip "oss cache is disabled"
13568         fi
13569
13570         set_osd_param $list '' writethrough_cache_enable 1
13571
13572         # check write cache is enabled on all obdfilters
13573         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13574                 skip "oss write cache is NOT enabled"
13575         fi
13576
13577         roc_hit_init
13578
13579         #define OBD_FAIL_OBD_NO_LRU  0x609
13580         do_nodes $list $LCTL set_param fail_loc=0x609
13581
13582         # pages should be in the case right after write
13583         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13584                 error "dd failed"
13585
13586         local BEFORE=$(roc_hit)
13587         cancel_lru_locks osc
13588         cat $DIR/$tfile >/dev/null
13589         local AFTER=$(roc_hit)
13590
13591         do_nodes $list $LCTL set_param fail_loc=0
13592
13593         if ! let "AFTER - BEFORE == CPAGES"; then
13594                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13595         fi
13596
13597         cancel_lru_locks osc
13598         # invalidates OST cache
13599         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13600         set_osd_param $list '' read_cache_enable 0
13601         cat $DIR/$tfile >/dev/null
13602
13603         # now data shouldn't be found in the cache
13604         BEFORE=$(roc_hit)
13605         cancel_lru_locks osc
13606         cat $DIR/$tfile >/dev/null
13607         AFTER=$(roc_hit)
13608         if let "AFTER - BEFORE != 0"; then
13609                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13610         fi
13611
13612         set_osd_param $list '' read_cache_enable 1
13613         rm -f $DIR/$tfile
13614 }
13615 run_test 151 "test cache on oss and controls ==============================="
13616
13617 test_152() {
13618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13619
13620         local TF="$TMP/$tfile"
13621
13622         # simulate ENOMEM during write
13623 #define OBD_FAIL_OST_NOMEM      0x226
13624         lctl set_param fail_loc=0x80000226
13625         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13626         cp $TF $DIR/$tfile
13627         sync || error "sync failed"
13628         lctl set_param fail_loc=0
13629
13630         # discard client's cache
13631         cancel_lru_locks osc
13632
13633         # simulate ENOMEM during read
13634         lctl set_param fail_loc=0x80000226
13635         cmp $TF $DIR/$tfile || error "cmp failed"
13636         lctl set_param fail_loc=0
13637
13638         rm -f $TF
13639 }
13640 run_test 152 "test read/write with enomem ============================"
13641
13642 test_153() {
13643         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13644 }
13645 run_test 153 "test if fdatasync does not crash ======================="
13646
13647 dot_lustre_fid_permission_check() {
13648         local fid=$1
13649         local ffid=$MOUNT/.lustre/fid/$fid
13650         local test_dir=$2
13651
13652         echo "stat fid $fid"
13653         stat $ffid > /dev/null || error "stat $ffid failed."
13654         echo "touch fid $fid"
13655         touch $ffid || error "touch $ffid failed."
13656         echo "write to fid $fid"
13657         cat /etc/hosts > $ffid || error "write $ffid failed."
13658         echo "read fid $fid"
13659         diff /etc/hosts $ffid || error "read $ffid failed."
13660         echo "append write to fid $fid"
13661         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13662         echo "rename fid $fid"
13663         mv $ffid $test_dir/$tfile.1 &&
13664                 error "rename $ffid to $tfile.1 should fail."
13665         touch $test_dir/$tfile.1
13666         mv $test_dir/$tfile.1 $ffid &&
13667                 error "rename $tfile.1 to $ffid should fail."
13668         rm -f $test_dir/$tfile.1
13669         echo "truncate fid $fid"
13670         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13671         echo "link fid $fid"
13672         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13673         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13674                 echo "setfacl fid $fid"
13675                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13676                 echo "getfacl fid $fid"
13677                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13678         fi
13679         echo "unlink fid $fid"
13680         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13681         echo "mknod fid $fid"
13682         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13683
13684         fid=[0xf00000400:0x1:0x0]
13685         ffid=$MOUNT/.lustre/fid/$fid
13686
13687         echo "stat non-exist fid $fid"
13688         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13689         echo "write to non-exist fid $fid"
13690         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13691         echo "link new fid $fid"
13692         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13693
13694         mkdir -p $test_dir/$tdir
13695         touch $test_dir/$tdir/$tfile
13696         fid=$($LFS path2fid $test_dir/$tdir)
13697         rc=$?
13698         [ $rc -ne 0 ] &&
13699                 error "error: could not get fid for $test_dir/$dir/$tfile."
13700
13701         ffid=$MOUNT/.lustre/fid/$fid
13702
13703         echo "ls $fid"
13704         ls $ffid > /dev/null || error "ls $ffid failed."
13705         echo "touch $fid/$tfile.1"
13706         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13707
13708         echo "touch $MOUNT/.lustre/fid/$tfile"
13709         touch $MOUNT/.lustre/fid/$tfile && \
13710                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13711
13712         echo "setxattr to $MOUNT/.lustre/fid"
13713         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13714
13715         echo "listxattr for $MOUNT/.lustre/fid"
13716         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13717
13718         echo "delxattr from $MOUNT/.lustre/fid"
13719         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13720
13721         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13722         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13723                 error "touch invalid fid should fail."
13724
13725         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13726         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13727                 error "touch non-normal fid should fail."
13728
13729         echo "rename $tdir to $MOUNT/.lustre/fid"
13730         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13731                 error "rename to $MOUNT/.lustre/fid should fail."
13732
13733         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13734         then            # LU-3547
13735                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13736                 local new_obf_mode=777
13737
13738                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13739                 chmod $new_obf_mode $DIR/.lustre/fid ||
13740                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13741
13742                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13743                 [ $obf_mode -eq $new_obf_mode ] ||
13744                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13745
13746                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13747                 chmod $old_obf_mode $DIR/.lustre/fid ||
13748                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13749         fi
13750
13751         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13752         fid=$($LFS path2fid $test_dir/$tfile-2)
13753
13754         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13755         then # LU-5424
13756                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13757                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13758                         error "create lov data thru .lustre failed"
13759         fi
13760         echo "cp /etc/passwd $test_dir/$tfile-2"
13761         cp /etc/passwd $test_dir/$tfile-2 ||
13762                 error "copy to $test_dir/$tfile-2 failed."
13763         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13764         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13765                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13766
13767         rm -rf $test_dir/tfile.lnk
13768         rm -rf $test_dir/$tfile-2
13769 }
13770
13771 test_154A() {
13772         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13773                 skip "Need MDS version at least 2.4.1"
13774
13775         local tf=$DIR/$tfile
13776         touch $tf
13777
13778         local fid=$($LFS path2fid $tf)
13779         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13780
13781         # check that we get the same pathname back
13782         local rootpath
13783         local found
13784         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13785                 echo "$rootpath $fid"
13786                 found=$($LFS fid2path $rootpath "$fid")
13787                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13788                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13789         done
13790
13791         # check wrong root path format
13792         rootpath=$MOUNT"_wrong"
13793         found=$($LFS fid2path $rootpath "$fid")
13794         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13795 }
13796 run_test 154A "lfs path2fid and fid2path basic checks"
13797
13798 test_154B() {
13799         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13800                 skip "Need MDS version at least 2.4.1"
13801
13802         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13803         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13804         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13805         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13806
13807         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13808         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13809
13810         # check that we get the same pathname
13811         echo "PFID: $PFID, name: $name"
13812         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13813         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13814         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13815                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13816
13817         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13818 }
13819 run_test 154B "verify the ll_decode_linkea tool"
13820
13821 test_154a() {
13822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13823         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13824         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13825                 skip "Need MDS version at least 2.2.51"
13826         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13827
13828         cp /etc/hosts $DIR/$tfile
13829
13830         fid=$($LFS path2fid $DIR/$tfile)
13831         rc=$?
13832         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13833
13834         dot_lustre_fid_permission_check "$fid" $DIR ||
13835                 error "dot lustre permission check $fid failed"
13836
13837         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13838
13839         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13840
13841         touch $MOUNT/.lustre/file &&
13842                 error "creation is not allowed under .lustre"
13843
13844         mkdir $MOUNT/.lustre/dir &&
13845                 error "mkdir is not allowed under .lustre"
13846
13847         rm -rf $DIR/$tfile
13848 }
13849 run_test 154a "Open-by-FID"
13850
13851 test_154b() {
13852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13853         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13855         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13856                 skip "Need MDS version at least 2.2.51"
13857
13858         local remote_dir=$DIR/$tdir/remote_dir
13859         local MDTIDX=1
13860         local rc=0
13861
13862         mkdir -p $DIR/$tdir
13863         $LFS mkdir -i $MDTIDX $remote_dir ||
13864                 error "create remote directory failed"
13865
13866         cp /etc/hosts $remote_dir/$tfile
13867
13868         fid=$($LFS path2fid $remote_dir/$tfile)
13869         rc=$?
13870         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13871
13872         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13873                 error "dot lustre permission check $fid failed"
13874         rm -rf $DIR/$tdir
13875 }
13876 run_test 154b "Open-by-FID for remote directory"
13877
13878 test_154c() {
13879         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13880                 skip "Need MDS version at least 2.4.1"
13881
13882         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13883         local FID1=$($LFS path2fid $DIR/$tfile.1)
13884         local FID2=$($LFS path2fid $DIR/$tfile.2)
13885         local FID3=$($LFS path2fid $DIR/$tfile.3)
13886
13887         local N=1
13888         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13889                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13890                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13891                 local want=FID$N
13892                 [ "$FID" = "${!want}" ] ||
13893                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13894                 N=$((N + 1))
13895         done
13896
13897         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13898         do
13899                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13900                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13901                 N=$((N + 1))
13902         done
13903 }
13904 run_test 154c "lfs path2fid and fid2path multiple arguments"
13905
13906 test_154d() {
13907         remote_mds_nodsh && skip "remote MDS with nodsh"
13908         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13909                 skip "Need MDS version at least 2.5.53"
13910
13911         if remote_mds; then
13912                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13913         else
13914                 nid="0@lo"
13915         fi
13916         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13917         local fd
13918         local cmd
13919
13920         rm -f $DIR/$tfile
13921         touch $DIR/$tfile
13922
13923         local fid=$($LFS path2fid $DIR/$tfile)
13924         # Open the file
13925         fd=$(free_fd)
13926         cmd="exec $fd<$DIR/$tfile"
13927         eval $cmd
13928         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13929         echo "$fid_list" | grep "$fid"
13930         rc=$?
13931
13932         cmd="exec $fd>/dev/null"
13933         eval $cmd
13934         if [ $rc -ne 0 ]; then
13935                 error "FID $fid not found in open files list $fid_list"
13936         fi
13937 }
13938 run_test 154d "Verify open file fid"
13939
13940 test_154e()
13941 {
13942         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13943                 skip "Need MDS version at least 2.6.50"
13944
13945         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13946                 error ".lustre returned by readdir"
13947         fi
13948 }
13949 run_test 154e ".lustre is not returned by readdir"
13950
13951 test_154f() {
13952         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13953
13954         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13955         test_mkdir -p -c1 $DIR/$tdir/d
13956         # test dirs inherit from its stripe
13957         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13958         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13959         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13960         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13961         touch $DIR/f
13962
13963         # get fid of parents
13964         local FID0=$($LFS path2fid $DIR/$tdir/d)
13965         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13966         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13967         local FID3=$($LFS path2fid $DIR)
13968
13969         # check that path2fid --parents returns expected <parent_fid>/name
13970         # 1) test for a directory (single parent)
13971         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13972         [ "$parent" == "$FID0/foo1" ] ||
13973                 error "expected parent: $FID0/foo1, got: $parent"
13974
13975         # 2) test for a file with nlink > 1 (multiple parents)
13976         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13977         echo "$parent" | grep -F "$FID1/$tfile" ||
13978                 error "$FID1/$tfile not returned in parent list"
13979         echo "$parent" | grep -F "$FID2/link" ||
13980                 error "$FID2/link not returned in parent list"
13981
13982         # 3) get parent by fid
13983         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13984         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13985         echo "$parent" | grep -F "$FID1/$tfile" ||
13986                 error "$FID1/$tfile not returned in parent list (by fid)"
13987         echo "$parent" | grep -F "$FID2/link" ||
13988                 error "$FID2/link not returned in parent list (by fid)"
13989
13990         # 4) test for entry in root directory
13991         parent=$($LFS path2fid --parents $DIR/f)
13992         echo "$parent" | grep -F "$FID3/f" ||
13993                 error "$FID3/f not returned in parent list"
13994
13995         # 5) test it on root directory
13996         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13997                 error "$MOUNT should not have parents"
13998
13999         # enable xattr caching and check that linkea is correctly updated
14000         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14001         save_lustre_params client "llite.*.xattr_cache" > $save
14002         lctl set_param llite.*.xattr_cache 1
14003
14004         # 6.1) linkea update on rename
14005         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14006
14007         # get parents by fid
14008         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14009         # foo1 should no longer be returned in parent list
14010         echo "$parent" | grep -F "$FID1" &&
14011                 error "$FID1 should no longer be in parent list"
14012         # the new path should appear
14013         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14014                 error "$FID2/$tfile.moved is not in parent list"
14015
14016         # 6.2) linkea update on unlink
14017         rm -f $DIR/$tdir/d/foo2/link
14018         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14019         # foo2/link should no longer be returned in parent list
14020         echo "$parent" | grep -F "$FID2/link" &&
14021                 error "$FID2/link should no longer be in parent list"
14022         true
14023
14024         rm -f $DIR/f
14025         restore_lustre_params < $save
14026         rm -f $save
14027 }
14028 run_test 154f "get parent fids by reading link ea"
14029
14030 test_154g()
14031 {
14032         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14033         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14034            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14035                 skip "Need MDS version at least 2.6.92"
14036
14037         mkdir -p $DIR/$tdir
14038         llapi_fid_test -d $DIR/$tdir
14039 }
14040 run_test 154g "various llapi FID tests"
14041
14042 test_155_small_load() {
14043     local temp=$TMP/$tfile
14044     local file=$DIR/$tfile
14045
14046     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14047         error "dd of=$temp bs=6096 count=1 failed"
14048     cp $temp $file
14049     cancel_lru_locks $OSC
14050     cmp $temp $file || error "$temp $file differ"
14051
14052     $TRUNCATE $temp 6000
14053     $TRUNCATE $file 6000
14054     cmp $temp $file || error "$temp $file differ (truncate1)"
14055
14056     echo "12345" >>$temp
14057     echo "12345" >>$file
14058     cmp $temp $file || error "$temp $file differ (append1)"
14059
14060     echo "12345" >>$temp
14061     echo "12345" >>$file
14062     cmp $temp $file || error "$temp $file differ (append2)"
14063
14064     rm -f $temp $file
14065     true
14066 }
14067
14068 test_155_big_load() {
14069         remote_ost_nodsh && skip "remote OST with nodsh"
14070
14071         local temp=$TMP/$tfile
14072         local file=$DIR/$tfile
14073
14074         free_min_max
14075         local cache_size=$(do_facet ost$((MAXI+1)) \
14076                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14077         local large_file_size=$((cache_size * 2))
14078
14079         echo "OSS cache size: $cache_size KB"
14080         echo "Large file size: $large_file_size KB"
14081
14082         [ $MAXV -le $large_file_size ] &&
14083                 skip_env "max available OST size needs > $large_file_size KB"
14084
14085         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14086
14087         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14088                 error "dd of=$temp bs=$large_file_size count=1k failed"
14089         cp $temp $file
14090         ls -lh $temp $file
14091         cancel_lru_locks osc
14092         cmp $temp $file || error "$temp $file differ"
14093
14094         rm -f $temp $file
14095         true
14096 }
14097
14098 save_writethrough() {
14099         local facets=$(get_facets OST)
14100
14101         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14102 }
14103
14104 test_155a() {
14105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14106
14107         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14108
14109         save_writethrough $p
14110
14111         set_cache read on
14112         set_cache writethrough on
14113         test_155_small_load
14114         restore_lustre_params < $p
14115         rm -f $p
14116 }
14117 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14118
14119 test_155b() {
14120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14121
14122         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14123
14124         save_writethrough $p
14125
14126         set_cache read on
14127         set_cache writethrough off
14128         test_155_small_load
14129         restore_lustre_params < $p
14130         rm -f $p
14131 }
14132 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14133
14134 test_155c() {
14135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14136
14137         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14138
14139         save_writethrough $p
14140
14141         set_cache read off
14142         set_cache writethrough on
14143         test_155_small_load
14144         restore_lustre_params < $p
14145         rm -f $p
14146 }
14147 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14148
14149 test_155d() {
14150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14151
14152         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14153
14154         save_writethrough $p
14155
14156         set_cache read off
14157         set_cache writethrough off
14158         test_155_small_load
14159         restore_lustre_params < $p
14160         rm -f $p
14161 }
14162 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14163
14164 test_155e() {
14165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14166
14167         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14168
14169         save_writethrough $p
14170
14171         set_cache read on
14172         set_cache writethrough on
14173         test_155_big_load
14174         restore_lustre_params < $p
14175         rm -f $p
14176 }
14177 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14178
14179 test_155f() {
14180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14181
14182         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14183
14184         save_writethrough $p
14185
14186         set_cache read on
14187         set_cache writethrough off
14188         test_155_big_load
14189         restore_lustre_params < $p
14190         rm -f $p
14191 }
14192 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14193
14194 test_155g() {
14195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14196
14197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14198
14199         save_writethrough $p
14200
14201         set_cache read off
14202         set_cache writethrough on
14203         test_155_big_load
14204         restore_lustre_params < $p
14205         rm -f $p
14206 }
14207 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14208
14209 test_155h() {
14210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14211
14212         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14213
14214         save_writethrough $p
14215
14216         set_cache read off
14217         set_cache writethrough off
14218         test_155_big_load
14219         restore_lustre_params < $p
14220         rm -f $p
14221 }
14222 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14223
14224 test_156() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226         remote_ost_nodsh && skip "remote OST with nodsh"
14227         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14228                 skip "stats not implemented on old servers"
14229         [ "$ost1_FSTYPE" = "zfs" ] &&
14230                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14231
14232         local CPAGES=3
14233         local BEFORE
14234         local AFTER
14235         local file="$DIR/$tfile"
14236         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14237
14238         save_writethrough $p
14239         roc_hit_init
14240
14241         log "Turn on read and write cache"
14242         set_cache read on
14243         set_cache writethrough on
14244
14245         log "Write data and read it back."
14246         log "Read should be satisfied from the cache."
14247         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14248         BEFORE=$(roc_hit)
14249         cancel_lru_locks osc
14250         cat $file >/dev/null
14251         AFTER=$(roc_hit)
14252         if ! let "AFTER - BEFORE == CPAGES"; then
14253                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14254         else
14255                 log "cache hits: before: $BEFORE, after: $AFTER"
14256         fi
14257
14258         log "Read again; it should be satisfied from the cache."
14259         BEFORE=$AFTER
14260         cancel_lru_locks osc
14261         cat $file >/dev/null
14262         AFTER=$(roc_hit)
14263         if ! let "AFTER - BEFORE == CPAGES"; then
14264                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14265         else
14266                 log "cache hits:: before: $BEFORE, after: $AFTER"
14267         fi
14268
14269         log "Turn off the read cache and turn on the write cache"
14270         set_cache read off
14271         set_cache writethrough on
14272
14273         log "Read again; it should be satisfied from the cache."
14274         BEFORE=$(roc_hit)
14275         cancel_lru_locks osc
14276         cat $file >/dev/null
14277         AFTER=$(roc_hit)
14278         if ! let "AFTER - BEFORE == CPAGES"; then
14279                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14280         else
14281                 log "cache hits:: before: $BEFORE, after: $AFTER"
14282         fi
14283
14284         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14285                 # > 2.12.56 uses pagecache if cached
14286                 log "Read again; it should not be satisfied from the cache."
14287                 BEFORE=$AFTER
14288                 cancel_lru_locks osc
14289                 cat $file >/dev/null
14290                 AFTER=$(roc_hit)
14291                 if ! let "AFTER - BEFORE == 0"; then
14292                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14293                 else
14294                         log "cache hits:: before: $BEFORE, after: $AFTER"
14295                 fi
14296         fi
14297
14298         log "Write data and read it back."
14299         log "Read should be satisfied from the cache."
14300         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14301         BEFORE=$(roc_hit)
14302         cancel_lru_locks osc
14303         cat $file >/dev/null
14304         AFTER=$(roc_hit)
14305         if ! let "AFTER - BEFORE == CPAGES"; then
14306                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14307         else
14308                 log "cache hits:: before: $BEFORE, after: $AFTER"
14309         fi
14310
14311         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14312                 # > 2.12.56 uses pagecache if cached
14313                 log "Read again; it should not be satisfied from the cache."
14314                 BEFORE=$AFTER
14315                 cancel_lru_locks osc
14316                 cat $file >/dev/null
14317                 AFTER=$(roc_hit)
14318                 if ! let "AFTER - BEFORE == 0"; then
14319                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14320                 else
14321                         log "cache hits:: before: $BEFORE, after: $AFTER"
14322                 fi
14323         fi
14324
14325         log "Turn off read and write cache"
14326         set_cache read off
14327         set_cache writethrough off
14328
14329         log "Write data and read it back"
14330         log "It should not be satisfied from the cache."
14331         rm -f $file
14332         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14333         cancel_lru_locks osc
14334         BEFORE=$(roc_hit)
14335         cat $file >/dev/null
14336         AFTER=$(roc_hit)
14337         if ! let "AFTER - BEFORE == 0"; then
14338                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14339         else
14340                 log "cache hits:: before: $BEFORE, after: $AFTER"
14341         fi
14342
14343         log "Turn on the read cache and turn off the write cache"
14344         set_cache read on
14345         set_cache writethrough off
14346
14347         log "Write data and read it back"
14348         log "It should not be satisfied from the cache."
14349         rm -f $file
14350         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14351         BEFORE=$(roc_hit)
14352         cancel_lru_locks osc
14353         cat $file >/dev/null
14354         AFTER=$(roc_hit)
14355         if ! let "AFTER - BEFORE == 0"; then
14356                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14357         else
14358                 log "cache hits:: before: $BEFORE, after: $AFTER"
14359         fi
14360
14361         log "Read again; it should be satisfied from the cache."
14362         BEFORE=$(roc_hit)
14363         cancel_lru_locks osc
14364         cat $file >/dev/null
14365         AFTER=$(roc_hit)
14366         if ! let "AFTER - BEFORE == CPAGES"; then
14367                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14368         else
14369                 log "cache hits:: before: $BEFORE, after: $AFTER"
14370         fi
14371
14372         restore_lustre_params < $p
14373         rm -f $p $file
14374 }
14375 run_test 156 "Verification of tunables"
14376
14377 test_160a() {
14378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14379         remote_mds_nodsh && skip "remote MDS with nodsh"
14380         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14381                 skip "Need MDS version at least 2.2.0"
14382
14383         changelog_register || error "changelog_register failed"
14384         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14385         changelog_users $SINGLEMDS | grep -q $cl_user ||
14386                 error "User $cl_user not found in changelog_users"
14387
14388         # change something
14389         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14390         changelog_clear 0 || error "changelog_clear failed"
14391         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14392         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14393         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14394         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14395         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14396         rm $DIR/$tdir/pics/desktop.jpg
14397
14398         changelog_dump | tail -10
14399
14400         echo "verifying changelog mask"
14401         changelog_chmask "-MKDIR"
14402         changelog_chmask "-CLOSE"
14403
14404         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14405         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14406
14407         changelog_chmask "+MKDIR"
14408         changelog_chmask "+CLOSE"
14409
14410         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14411         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14412
14413         changelog_dump | tail -10
14414         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14415         CLOSES=$(changelog_dump | grep -c "CLOSE")
14416         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14417         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14418
14419         # verify contents
14420         echo "verifying target fid"
14421         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14422         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14423         [ "$fidc" == "$fidf" ] ||
14424                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14425         echo "verifying parent fid"
14426         # The FID returned from the Changelog may be the directory shard on
14427         # a different MDT, and not the FID returned by path2fid on the parent.
14428         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14429         # since this is what will matter when recreating this file in the tree.
14430         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14431         local pathp=$($LFS fid2path $MOUNT "$fidp")
14432         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14433                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14434
14435         echo "getting records for $cl_user"
14436         changelog_users $SINGLEMDS
14437         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14438         local nclr=3
14439         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14440                 error "changelog_clear failed"
14441         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14442         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14443         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14444                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14445
14446         local min0_rec=$(changelog_users $SINGLEMDS |
14447                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14448         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14449                           awk '{ print $1; exit; }')
14450
14451         changelog_dump | tail -n 5
14452         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14453         [ $first_rec == $((min0_rec + 1)) ] ||
14454                 error "first index should be $min0_rec + 1 not $first_rec"
14455
14456         # LU-3446 changelog index reset on MDT restart
14457         local cur_rec1=$(changelog_users $SINGLEMDS |
14458                          awk '/^current.index:/ { print $NF }')
14459         changelog_clear 0 ||
14460                 error "clear all changelog records for $cl_user failed"
14461         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14462         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14463                 error "Fail to start $SINGLEMDS"
14464         local cur_rec2=$(changelog_users $SINGLEMDS |
14465                          awk '/^current.index:/ { print $NF }')
14466         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14467         [ $cur_rec1 == $cur_rec2 ] ||
14468                 error "current index should be $cur_rec1 not $cur_rec2"
14469
14470         echo "verifying users from this test are deregistered"
14471         changelog_deregister || error "changelog_deregister failed"
14472         changelog_users $SINGLEMDS | grep -q $cl_user &&
14473                 error "User '$cl_user' still in changelog_users"
14474
14475         # lctl get_param -n mdd.*.changelog_users
14476         # current index: 144
14477         # ID    index (idle seconds)
14478         # cl3   144 (2)
14479         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14480                 # this is the normal case where all users were deregistered
14481                 # make sure no new records are added when no users are present
14482                 local last_rec1=$(changelog_users $SINGLEMDS |
14483                                   awk '/^current.index:/ { print $NF }')
14484                 touch $DIR/$tdir/chloe
14485                 local last_rec2=$(changelog_users $SINGLEMDS |
14486                                   awk '/^current.index:/ { print $NF }')
14487                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14488                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14489         else
14490                 # any changelog users must be leftovers from a previous test
14491                 changelog_users $SINGLEMDS
14492                 echo "other changelog users; can't verify off"
14493         fi
14494 }
14495 run_test 160a "changelog sanity"
14496
14497 test_160b() { # LU-3587
14498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14499         remote_mds_nodsh && skip "remote MDS with nodsh"
14500         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14501                 skip "Need MDS version at least 2.2.0"
14502
14503         changelog_register || error "changelog_register failed"
14504         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14505         changelog_users $SINGLEMDS | grep -q $cl_user ||
14506                 error "User '$cl_user' not found in changelog_users"
14507
14508         local longname1=$(str_repeat a 255)
14509         local longname2=$(str_repeat b 255)
14510
14511         cd $DIR
14512         echo "creating very long named file"
14513         touch $longname1 || error "create of '$longname1' failed"
14514         echo "renaming very long named file"
14515         mv $longname1 $longname2
14516
14517         changelog_dump | grep RENME | tail -n 5
14518         rm -f $longname2
14519 }
14520 run_test 160b "Verify that very long rename doesn't crash in changelog"
14521
14522 test_160c() {
14523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14524         remote_mds_nodsh && skip "remote MDS with nodsh"
14525
14526         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14527                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14528                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14529                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14530
14531         local rc=0
14532
14533         # Registration step
14534         changelog_register || error "changelog_register failed"
14535
14536         rm -rf $DIR/$tdir
14537         mkdir -p $DIR/$tdir
14538         $MCREATE $DIR/$tdir/foo_160c
14539         changelog_chmask "-TRUNC"
14540         $TRUNCATE $DIR/$tdir/foo_160c 200
14541         changelog_chmask "+TRUNC"
14542         $TRUNCATE $DIR/$tdir/foo_160c 199
14543         changelog_dump | tail -n 5
14544         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14545         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14546 }
14547 run_test 160c "verify that changelog log catch the truncate event"
14548
14549 test_160d() {
14550         remote_mds_nodsh && skip "remote MDS with nodsh"
14551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14553         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14554                 skip "Need MDS version at least 2.7.60"
14555
14556         # Registration step
14557         changelog_register || error "changelog_register failed"
14558
14559         mkdir -p $DIR/$tdir/migrate_dir
14560         changelog_clear 0 || error "changelog_clear failed"
14561
14562         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14563         changelog_dump | tail -n 5
14564         local migrates=$(changelog_dump | grep -c "MIGRT")
14565         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14566 }
14567 run_test 160d "verify that changelog log catch the migrate event"
14568
14569 test_160e() {
14570         remote_mds_nodsh && skip "remote MDS with nodsh"
14571
14572         # Create a user
14573         changelog_register || error "changelog_register failed"
14574
14575         # Delete a future user (expect fail)
14576         local MDT0=$(facet_svc $SINGLEMDS)
14577         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14578         local rc=$?
14579
14580         if [ $rc -eq 0 ]; then
14581                 error "Deleted non-existant user cl77"
14582         elif [ $rc -ne 2 ]; then
14583                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14584         fi
14585
14586         # Clear to a bad index (1 billion should be safe)
14587         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14588         rc=$?
14589
14590         if [ $rc -eq 0 ]; then
14591                 error "Successfully cleared to invalid CL index"
14592         elif [ $rc -ne 22 ]; then
14593                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14594         fi
14595 }
14596 run_test 160e "changelog negative testing (should return errors)"
14597
14598 test_160f() {
14599         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14600         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14601                 skip "Need MDS version at least 2.10.56"
14602
14603         local mdts=$(comma_list $(mdts_nodes))
14604
14605         # Create a user
14606         changelog_register || error "first changelog_register failed"
14607         changelog_register || error "second changelog_register failed"
14608         local cl_users
14609         declare -A cl_user1
14610         declare -A cl_user2
14611         local user_rec1
14612         local user_rec2
14613         local i
14614
14615         # generate some changelog records to accumulate on each MDT
14616         # use fnv1a because created files should be evenly distributed
14617         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14618                 error "test_mkdir $tdir failed"
14619         log "$(date +%s): creating first files"
14620         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14621                 error "create $DIR/$tdir/$tfile failed"
14622
14623         # check changelogs have been generated
14624         local start=$SECONDS
14625         local idle_time=$((MDSCOUNT * 5 + 5))
14626         local nbcl=$(changelog_dump | wc -l)
14627         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14628
14629         for param in "changelog_max_idle_time=$idle_time" \
14630                      "changelog_gc=1" \
14631                      "changelog_min_gc_interval=2" \
14632                      "changelog_min_free_cat_entries=3"; do
14633                 local MDT0=$(facet_svc $SINGLEMDS)
14634                 local var="${param%=*}"
14635                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14636
14637                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14638                 do_nodes $mdts $LCTL set_param mdd.*.$param
14639         done
14640
14641         # force cl_user2 to be idle (1st part), but also cancel the
14642         # cl_user1 records so that it is not evicted later in the test.
14643         local sleep1=$((idle_time / 2))
14644         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14645         sleep $sleep1
14646
14647         # simulate changelog catalog almost full
14648         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14649         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14650
14651         for i in $(seq $MDSCOUNT); do
14652                 cl_users=(${CL_USERS[mds$i]})
14653                 cl_user1[mds$i]="${cl_users[0]}"
14654                 cl_user2[mds$i]="${cl_users[1]}"
14655
14656                 [ -n "${cl_user1[mds$i]}" ] ||
14657                         error "mds$i: no user registered"
14658                 [ -n "${cl_user2[mds$i]}" ] ||
14659                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14660
14661                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14662                 [ -n "$user_rec1" ] ||
14663                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14664                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14665                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14666                 [ -n "$user_rec2" ] ||
14667                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14668                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14669                      "$user_rec1 + 2 == $user_rec2"
14670                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14671                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14672                               "$user_rec1 + 2, but is $user_rec2"
14673                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14674                 [ -n "$user_rec2" ] ||
14675                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14676                 [ $user_rec1 == $user_rec2 ] ||
14677                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14678                               "$user_rec1, but is $user_rec2"
14679         done
14680
14681         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14682         local sleep2=$((idle_time - (SECONDS - start) + 1))
14683         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14684         sleep $sleep2
14685
14686         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14687         # cl_user1 should be OK because it recently processed records.
14688         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14689         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14690                 error "create $DIR/$tdir/${tfile}b failed"
14691
14692         # ensure gc thread is done
14693         for i in $(mdts_nodes); do
14694                 wait_update $i \
14695                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14696                         error "$i: GC-thread not done"
14697         done
14698
14699         local first_rec
14700         for i in $(seq $MDSCOUNT); do
14701                 # check cl_user1 still registered
14702                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14703                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14704                 # check cl_user2 unregistered
14705                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14706                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14707
14708                 # check changelogs are present and starting at $user_rec1 + 1
14709                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14710                 [ -n "$user_rec1" ] ||
14711                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14712                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14713                             awk '{ print $1; exit; }')
14714
14715                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14716                 [ $((user_rec1 + 1)) == $first_rec ] ||
14717                         error "mds$i: first index should be $user_rec1 + 1, " \
14718                               "but is $first_rec"
14719         done
14720 }
14721 run_test 160f "changelog garbage collect (timestamped users)"
14722
14723 test_160g() {
14724         remote_mds_nodsh && skip "remote MDS with nodsh"
14725         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14726                 skip "Need MDS version at least 2.10.56"
14727
14728         local mdts=$(comma_list $(mdts_nodes))
14729
14730         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14731         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14732
14733         # Create a user
14734         changelog_register || error "first changelog_register failed"
14735         changelog_register || error "second changelog_register failed"
14736         local cl_users
14737         declare -A cl_user1
14738         declare -A cl_user2
14739         local user_rec1
14740         local user_rec2
14741         local i
14742
14743         # generate some changelog records to accumulate on each MDT
14744         # use fnv1a because created files should be evenly distributed
14745         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14746                 error "mkdir $tdir failed"
14747         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14748                 error "create $DIR/$tdir/$tfile failed"
14749
14750         # check changelogs have been generated
14751         local nbcl=$(changelog_dump | wc -l)
14752         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14753
14754         # reduce the max_idle_indexes value to make sure we exceed it
14755         max_ndx=$((nbcl / 2 - 1))
14756
14757         for param in "changelog_max_idle_indexes=$max_ndx" \
14758                      "changelog_gc=1" \
14759                      "changelog_min_gc_interval=2" \
14760                      "changelog_min_free_cat_entries=3"; do
14761                 local MDT0=$(facet_svc $SINGLEMDS)
14762                 local var="${param%=*}"
14763                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14764
14765                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14766                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14767                         error "unable to set mdd.*.$param"
14768         done
14769
14770         # simulate changelog catalog almost full
14771         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14772         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14773
14774         for i in $(seq $MDSCOUNT); do
14775                 cl_users=(${CL_USERS[mds$i]})
14776                 cl_user1[mds$i]="${cl_users[0]}"
14777                 cl_user2[mds$i]="${cl_users[1]}"
14778
14779                 [ -n "${cl_user1[mds$i]}" ] ||
14780                         error "mds$i: no user registered"
14781                 [ -n "${cl_user2[mds$i]}" ] ||
14782                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14783
14784                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14785                 [ -n "$user_rec1" ] ||
14786                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14787                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14788                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14789                 [ -n "$user_rec2" ] ||
14790                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14791                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14792                      "$user_rec1 + 2 == $user_rec2"
14793                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14794                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14795                               "$user_rec1 + 2, but is $user_rec2"
14796                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14797                 [ -n "$user_rec2" ] ||
14798                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14799                 [ $user_rec1 == $user_rec2 ] ||
14800                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14801                               "$user_rec1, but is $user_rec2"
14802         done
14803
14804         # ensure we are past the previous changelog_min_gc_interval set above
14805         sleep 2
14806
14807         # generate one more changelog to trigger fail_loc
14808         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14809                 error "create $DIR/$tdir/${tfile}bis failed"
14810
14811         # ensure gc thread is done
14812         for i in $(mdts_nodes); do
14813                 wait_update $i \
14814                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14815                         error "$i: GC-thread not done"
14816         done
14817
14818         local first_rec
14819         for i in $(seq $MDSCOUNT); do
14820                 # check cl_user1 still registered
14821                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14822                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14823                 # check cl_user2 unregistered
14824                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14825                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14826
14827                 # check changelogs are present and starting at $user_rec1 + 1
14828                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14829                 [ -n "$user_rec1" ] ||
14830                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14831                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14832                             awk '{ print $1; exit; }')
14833
14834                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14835                 [ $((user_rec1 + 1)) == $first_rec ] ||
14836                         error "mds$i: first index should be $user_rec1 + 1, " \
14837                               "but is $first_rec"
14838         done
14839 }
14840 run_test 160g "changelog garbage collect (old users)"
14841
14842 test_160h() {
14843         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14844         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14845                 skip "Need MDS version at least 2.10.56"
14846
14847         local mdts=$(comma_list $(mdts_nodes))
14848
14849         # Create a user
14850         changelog_register || error "first changelog_register failed"
14851         changelog_register || error "second changelog_register failed"
14852         local cl_users
14853         declare -A cl_user1
14854         declare -A cl_user2
14855         local user_rec1
14856         local user_rec2
14857         local i
14858
14859         # generate some changelog records to accumulate on each MDT
14860         # use fnv1a because created files should be evenly distributed
14861         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14862                 error "test_mkdir $tdir failed"
14863         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14864                 error "create $DIR/$tdir/$tfile failed"
14865
14866         # check changelogs have been generated
14867         local nbcl=$(changelog_dump | wc -l)
14868         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14869
14870         for param in "changelog_max_idle_time=10" \
14871                      "changelog_gc=1" \
14872                      "changelog_min_gc_interval=2"; do
14873                 local MDT0=$(facet_svc $SINGLEMDS)
14874                 local var="${param%=*}"
14875                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14876
14877                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14878                 do_nodes $mdts $LCTL set_param mdd.*.$param
14879         done
14880
14881         # force cl_user2 to be idle (1st part)
14882         sleep 9
14883
14884         for i in $(seq $MDSCOUNT); do
14885                 cl_users=(${CL_USERS[mds$i]})
14886                 cl_user1[mds$i]="${cl_users[0]}"
14887                 cl_user2[mds$i]="${cl_users[1]}"
14888
14889                 [ -n "${cl_user1[mds$i]}" ] ||
14890                         error "mds$i: no user registered"
14891                 [ -n "${cl_user2[mds$i]}" ] ||
14892                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14893
14894                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14895                 [ -n "$user_rec1" ] ||
14896                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14897                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14898                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14899                 [ -n "$user_rec2" ] ||
14900                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14901                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14902                      "$user_rec1 + 2 == $user_rec2"
14903                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14904                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14905                               "$user_rec1 + 2, but is $user_rec2"
14906                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14907                 [ -n "$user_rec2" ] ||
14908                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14909                 [ $user_rec1 == $user_rec2 ] ||
14910                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14911                               "$user_rec1, but is $user_rec2"
14912         done
14913
14914         # force cl_user2 to be idle (2nd part) and to reach
14915         # changelog_max_idle_time
14916         sleep 2
14917
14918         # force each GC-thread start and block then
14919         # one per MDT/MDD, set fail_val accordingly
14920         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14921         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14922
14923         # generate more changelogs to trigger fail_loc
14924         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14925                 error "create $DIR/$tdir/${tfile}bis failed"
14926
14927         # stop MDT to stop GC-thread, should be done in back-ground as it will
14928         # block waiting for the thread to be released and exit
14929         declare -A stop_pids
14930         for i in $(seq $MDSCOUNT); do
14931                 stop mds$i &
14932                 stop_pids[mds$i]=$!
14933         done
14934
14935         for i in $(mdts_nodes); do
14936                 local facet
14937                 local nb=0
14938                 local facets=$(facets_up_on_host $i)
14939
14940                 for facet in ${facets//,/ }; do
14941                         if [[ $facet == mds* ]]; then
14942                                 nb=$((nb + 1))
14943                         fi
14944                 done
14945                 # ensure each MDS's gc threads are still present and all in "R"
14946                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14947                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14948                         error "$i: expected $nb GC-thread"
14949                 wait_update $i \
14950                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14951                         "R" 20 ||
14952                         error "$i: GC-thread not found in R-state"
14953                 # check umounts of each MDT on MDS have reached kthread_stop()
14954                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14955                         error "$i: expected $nb umount"
14956                 wait_update $i \
14957                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14958                         error "$i: umount not found in D-state"
14959         done
14960
14961         # release all GC-threads
14962         do_nodes $mdts $LCTL set_param fail_loc=0
14963
14964         # wait for MDT stop to complete
14965         for i in $(seq $MDSCOUNT); do
14966                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14967         done
14968
14969         # XXX
14970         # may try to check if any orphan changelog records are present
14971         # via ldiskfs/zfs and llog_reader...
14972
14973         # re-start/mount MDTs
14974         for i in $(seq $MDSCOUNT); do
14975                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14976                         error "Fail to start mds$i"
14977         done
14978
14979         local first_rec
14980         for i in $(seq $MDSCOUNT); do
14981                 # check cl_user1 still registered
14982                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14983                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14984                 # check cl_user2 unregistered
14985                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14986                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14987
14988                 # check changelogs are present and starting at $user_rec1 + 1
14989                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14990                 [ -n "$user_rec1" ] ||
14991                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14992                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14993                             awk '{ print $1; exit; }')
14994
14995                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14996                 [ $((user_rec1 + 1)) == $first_rec ] ||
14997                         error "mds$i: first index should be $user_rec1 + 1, " \
14998                               "but is $first_rec"
14999         done
15000 }
15001 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15002               "during mount"
15003
15004 test_160i() {
15005
15006         local mdts=$(comma_list $(mdts_nodes))
15007
15008         changelog_register || error "first changelog_register failed"
15009
15010         # generate some changelog records to accumulate on each MDT
15011         # use fnv1a because created files should be evenly distributed
15012         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15013                 error "mkdir $tdir failed"
15014         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15015                 error "create $DIR/$tdir/$tfile failed"
15016
15017         # check changelogs have been generated
15018         local nbcl=$(changelog_dump | wc -l)
15019         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15020
15021         # simulate race between register and unregister
15022         # XXX as fail_loc is set per-MDS, with DNE configs the race
15023         # simulation will only occur for one MDT per MDS and for the
15024         # others the normal race scenario will take place
15025         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15026         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15027         do_nodes $mdts $LCTL set_param fail_val=1
15028
15029         # unregister 1st user
15030         changelog_deregister &
15031         local pid1=$!
15032         # wait some time for deregister work to reach race rdv
15033         sleep 2
15034         # register 2nd user
15035         changelog_register || error "2nd user register failed"
15036
15037         wait $pid1 || error "1st user deregister failed"
15038
15039         local i
15040         local last_rec
15041         declare -A LAST_REC
15042         for i in $(seq $MDSCOUNT); do
15043                 if changelog_users mds$i | grep "^cl"; then
15044                         # make sure new records are added with one user present
15045                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15046                                           awk '/^current.index:/ { print $NF }')
15047                 else
15048                         error "mds$i has no user registered"
15049                 fi
15050         done
15051
15052         # generate more changelog records to accumulate on each MDT
15053         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15054                 error "create $DIR/$tdir/${tfile}bis failed"
15055
15056         for i in $(seq $MDSCOUNT); do
15057                 last_rec=$(changelog_users $SINGLEMDS |
15058                            awk '/^current.index:/ { print $NF }')
15059                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15060                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15061                         error "changelogs are off on mds$i"
15062         done
15063 }
15064 run_test 160i "changelog user register/unregister race"
15065
15066 test_160j() {
15067         remote_mds_nodsh && skip "remote MDS with nodsh"
15068         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15069                 skip "Need MDS version at least 2.12.56"
15070
15071         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15072         stack_trap "umount $MOUNT2" EXIT
15073
15074         changelog_register || error "first changelog_register failed"
15075         stack_trap "changelog_deregister" EXIT
15076
15077         # generate some changelog
15078         # use fnv1a because created files should be evenly distributed
15079         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15080                 error "mkdir $tdir failed"
15081         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15082                 error "create $DIR/$tdir/${tfile}bis failed"
15083
15084         # open the changelog device
15085         exec 3>/dev/changelog-$FSNAME-MDT0000
15086         stack_trap "exec 3>&-" EXIT
15087         exec 4</dev/changelog-$FSNAME-MDT0000
15088         stack_trap "exec 4<&-" EXIT
15089
15090         # umount the first lustre mount
15091         umount $MOUNT
15092         stack_trap "mount_client $MOUNT" EXIT
15093
15094         # read changelog
15095         cat <&4 >/dev/null || error "read changelog failed"
15096
15097         # clear changelog
15098         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15099         changelog_users $SINGLEMDS | grep -q $cl_user ||
15100                 error "User $cl_user not found in changelog_users"
15101
15102         printf 'clear:'$cl_user':0' >&3
15103 }
15104 run_test 160j "client can be umounted  while its chanangelog is being used"
15105
15106 test_160k() {
15107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15108         remote_mds_nodsh && skip "remote MDS with nodsh"
15109
15110         mkdir -p $DIR/$tdir/1/1
15111
15112         changelog_register || error "changelog_register failed"
15113         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15114
15115         changelog_users $SINGLEMDS | grep -q $cl_user ||
15116                 error "User '$cl_user' not found in changelog_users"
15117 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15118         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15119         rmdir $DIR/$tdir/1/1 & sleep 1
15120         mkdir $DIR/$tdir/2
15121         touch $DIR/$tdir/2/2
15122         rm -rf $DIR/$tdir/2
15123
15124         wait
15125         sleep 4
15126
15127         changelog_dump | grep rmdir || error "rmdir not recorded"
15128
15129         rm -rf $DIR/$tdir
15130         changelog_deregister
15131 }
15132 run_test 160k "Verify that changelog records are not lost"
15133
15134 # Verifies that a file passed as a parameter has recently had an operation
15135 # performed on it that has generated an MTIME changelog which contains the
15136 # correct parent FID. As files might reside on a different MDT from the
15137 # parent directory in DNE configurations, the FIDs are translated to paths
15138 # before being compared, which should be identical
15139 compare_mtime_changelog() {
15140         local file="${1}"
15141         local mdtidx
15142         local mtime
15143         local cl_fid
15144         local pdir
15145         local dir
15146
15147         mdtidx=$($LFS getstripe --mdt-index $file)
15148         mdtidx=$(printf "%04x" $mdtidx)
15149
15150         # Obtain the parent FID from the MTIME changelog
15151         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15152         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15153
15154         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15155         [ -z "$cl_fid" ] && error "parent FID not present"
15156
15157         # Verify that the path for the parent FID is the same as the path for
15158         # the test directory
15159         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15160
15161         dir=$(dirname $1)
15162
15163         [[ "${pdir%/}" == "$dir" ]] ||
15164                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15165 }
15166
15167 test_160l() {
15168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15169
15170         remote_mds_nodsh && skip "remote MDS with nodsh"
15171         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15172                 skip "Need MDS version at least 2.13.55"
15173
15174         local cl_user
15175
15176         changelog_register || error "changelog_register failed"
15177         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15178
15179         changelog_users $SINGLEMDS | grep -q $cl_user ||
15180                 error "User '$cl_user' not found in changelog_users"
15181
15182         # Clear some types so that MTIME changelogs are generated
15183         changelog_chmask "-CREAT"
15184         changelog_chmask "-CLOSE"
15185
15186         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15187
15188         # Test CL_MTIME during setattr
15189         touch $DIR/$tdir/$tfile
15190         compare_mtime_changelog $DIR/$tdir/$tfile
15191
15192         # Test CL_MTIME during close
15193         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15194         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15195 }
15196 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15197
15198 test_161a() {
15199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15200
15201         test_mkdir -c1 $DIR/$tdir
15202         cp /etc/hosts $DIR/$tdir/$tfile
15203         test_mkdir -c1 $DIR/$tdir/foo1
15204         test_mkdir -c1 $DIR/$tdir/foo2
15205         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15206         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15207         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15208         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15209         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15210         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15211                 $LFS fid2path $DIR $FID
15212                 error "bad link ea"
15213         fi
15214         # middle
15215         rm $DIR/$tdir/foo2/zachary
15216         # last
15217         rm $DIR/$tdir/foo2/thor
15218         # first
15219         rm $DIR/$tdir/$tfile
15220         # rename
15221         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15222         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15223                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15224         rm $DIR/$tdir/foo2/maggie
15225
15226         # overflow the EA
15227         local longname=$tfile.avg_len_is_thirty_two_
15228         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15229                 error_noexit 'failed to unlink many hardlinks'" EXIT
15230         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15231                 error "failed to hardlink many files"
15232         links=$($LFS fid2path $DIR $FID | wc -l)
15233         echo -n "${links}/1000 links in link EA"
15234         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15235 }
15236 run_test 161a "link ea sanity"
15237
15238 test_161b() {
15239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15240         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15241
15242         local MDTIDX=1
15243         local remote_dir=$DIR/$tdir/remote_dir
15244
15245         mkdir -p $DIR/$tdir
15246         $LFS mkdir -i $MDTIDX $remote_dir ||
15247                 error "create remote directory failed"
15248
15249         cp /etc/hosts $remote_dir/$tfile
15250         mkdir -p $remote_dir/foo1
15251         mkdir -p $remote_dir/foo2
15252         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15253         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15254         ln $remote_dir/$tfile $remote_dir/foo1/luna
15255         ln $remote_dir/$tfile $remote_dir/foo2/thor
15256
15257         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15258                      tr -d ']')
15259         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15260                 $LFS fid2path $DIR $FID
15261                 error "bad link ea"
15262         fi
15263         # middle
15264         rm $remote_dir/foo2/zachary
15265         # last
15266         rm $remote_dir/foo2/thor
15267         # first
15268         rm $remote_dir/$tfile
15269         # rename
15270         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15271         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15272         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15273                 $LFS fid2path $DIR $FID
15274                 error "bad link rename"
15275         fi
15276         rm $remote_dir/foo2/maggie
15277
15278         # overflow the EA
15279         local longname=filename_avg_len_is_thirty_two_
15280         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15281                 error "failed to hardlink many files"
15282         links=$($LFS fid2path $DIR $FID | wc -l)
15283         echo -n "${links}/1000 links in link EA"
15284         [[ ${links} -gt 60 ]] ||
15285                 error "expected at least 60 links in link EA"
15286         unlinkmany $remote_dir/foo2/$longname 1000 ||
15287         error "failed to unlink many hardlinks"
15288 }
15289 run_test 161b "link ea sanity under remote directory"
15290
15291 test_161c() {
15292         remote_mds_nodsh && skip "remote MDS with nodsh"
15293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15294         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15295                 skip "Need MDS version at least 2.1.5"
15296
15297         # define CLF_RENAME_LAST 0x0001
15298         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15299         changelog_register || error "changelog_register failed"
15300
15301         rm -rf $DIR/$tdir
15302         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15303         touch $DIR/$tdir/foo_161c
15304         touch $DIR/$tdir/bar_161c
15305         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15306         changelog_dump | grep RENME | tail -n 5
15307         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15308         changelog_clear 0 || error "changelog_clear failed"
15309         if [ x$flags != "x0x1" ]; then
15310                 error "flag $flags is not 0x1"
15311         fi
15312
15313         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15314         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15315         touch $DIR/$tdir/foo_161c
15316         touch $DIR/$tdir/bar_161c
15317         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15318         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15319         changelog_dump | grep RENME | tail -n 5
15320         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15321         changelog_clear 0 || error "changelog_clear failed"
15322         if [ x$flags != "x0x0" ]; then
15323                 error "flag $flags is not 0x0"
15324         fi
15325         echo "rename overwrite a target having nlink > 1," \
15326                 "changelog record has flags of $flags"
15327
15328         # rename doesn't overwrite a target (changelog flag 0x0)
15329         touch $DIR/$tdir/foo_161c
15330         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15331         changelog_dump | grep RENME | tail -n 5
15332         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15333         changelog_clear 0 || error "changelog_clear failed"
15334         if [ x$flags != "x0x0" ]; then
15335                 error "flag $flags is not 0x0"
15336         fi
15337         echo "rename doesn't overwrite a target," \
15338                 "changelog record has flags of $flags"
15339
15340         # define CLF_UNLINK_LAST 0x0001
15341         # unlink a file having nlink = 1 (changelog flag 0x1)
15342         rm -f $DIR/$tdir/foo2_161c
15343         changelog_dump | grep UNLNK | tail -n 5
15344         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15345         changelog_clear 0 || error "changelog_clear failed"
15346         if [ x$flags != "x0x1" ]; then
15347                 error "flag $flags is not 0x1"
15348         fi
15349         echo "unlink a file having nlink = 1," \
15350                 "changelog record has flags of $flags"
15351
15352         # unlink a file having nlink > 1 (changelog flag 0x0)
15353         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15354         rm -f $DIR/$tdir/foobar_161c
15355         changelog_dump | grep UNLNK | tail -n 5
15356         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15357         changelog_clear 0 || error "changelog_clear failed"
15358         if [ x$flags != "x0x0" ]; then
15359                 error "flag $flags is not 0x0"
15360         fi
15361         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15362 }
15363 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15364
15365 test_161d() {
15366         remote_mds_nodsh && skip "remote MDS with nodsh"
15367         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15368
15369         local pid
15370         local fid
15371
15372         changelog_register || error "changelog_register failed"
15373
15374         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15375         # interfer with $MOUNT/.lustre/fid/ access
15376         mkdir $DIR/$tdir
15377         [[ $? -eq 0 ]] || error "mkdir failed"
15378
15379         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15380         $LCTL set_param fail_loc=0x8000140c
15381         # 5s pause
15382         $LCTL set_param fail_val=5
15383
15384         # create file
15385         echo foofoo > $DIR/$tdir/$tfile &
15386         pid=$!
15387
15388         # wait for create to be delayed
15389         sleep 2
15390
15391         ps -p $pid
15392         [[ $? -eq 0 ]] || error "create should be blocked"
15393
15394         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15395         stack_trap "rm -f $tempfile"
15396         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15397         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15398         # some delay may occur during ChangeLog publishing and file read just
15399         # above, that could allow file write to happen finally
15400         [[ -s $tempfile ]] && echo "file should be empty"
15401
15402         $LCTL set_param fail_loc=0
15403
15404         wait $pid
15405         [[ $? -eq 0 ]] || error "create failed"
15406 }
15407 run_test 161d "create with concurrent .lustre/fid access"
15408
15409 check_path() {
15410         local expected="$1"
15411         shift
15412         local fid="$2"
15413
15414         local path
15415         path=$($LFS fid2path "$@")
15416         local rc=$?
15417
15418         if [ $rc -ne 0 ]; then
15419                 error "path looked up of '$expected' failed: rc=$rc"
15420         elif [ "$path" != "$expected" ]; then
15421                 error "path looked up '$path' instead of '$expected'"
15422         else
15423                 echo "FID '$fid' resolves to path '$path' as expected"
15424         fi
15425 }
15426
15427 test_162a() { # was test_162
15428         test_mkdir -p -c1 $DIR/$tdir/d2
15429         touch $DIR/$tdir/d2/$tfile
15430         touch $DIR/$tdir/d2/x1
15431         touch $DIR/$tdir/d2/x2
15432         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15433         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15434         # regular file
15435         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15436         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15437
15438         # softlink
15439         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15440         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15441         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15442
15443         # softlink to wrong file
15444         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15445         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15446         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15447
15448         # hardlink
15449         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15450         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15451         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15452         # fid2path dir/fsname should both work
15453         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15454         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15455
15456         # hardlink count: check that there are 2 links
15457         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15458         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15459
15460         # hardlink indexing: remove the first link
15461         rm $DIR/$tdir/d2/p/q/r/hlink
15462         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15463 }
15464 run_test 162a "path lookup sanity"
15465
15466 test_162b() {
15467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15469
15470         mkdir $DIR/$tdir
15471         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15472                                 error "create striped dir failed"
15473
15474         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15475                                         tail -n 1 | awk '{print $2}')
15476         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15477
15478         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15479         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15480
15481         # regular file
15482         for ((i=0;i<5;i++)); do
15483                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15484                         error "get fid for f$i failed"
15485                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15486
15487                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15488                         error "get fid for d$i failed"
15489                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15490         done
15491
15492         return 0
15493 }
15494 run_test 162b "striped directory path lookup sanity"
15495
15496 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15497 test_162c() {
15498         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15499                 skip "Need MDS version at least 2.7.51"
15500
15501         local lpath=$tdir.local
15502         local rpath=$tdir.remote
15503
15504         test_mkdir $DIR/$lpath
15505         test_mkdir $DIR/$rpath
15506
15507         for ((i = 0; i <= 101; i++)); do
15508                 lpath="$lpath/$i"
15509                 mkdir $DIR/$lpath
15510                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15511                         error "get fid for local directory $DIR/$lpath failed"
15512                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15513
15514                 rpath="$rpath/$i"
15515                 test_mkdir $DIR/$rpath
15516                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15517                         error "get fid for remote directory $DIR/$rpath failed"
15518                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15519         done
15520
15521         return 0
15522 }
15523 run_test 162c "fid2path works with paths 100 or more directories deep"
15524
15525 oalr_event_count() {
15526         local event="${1}"
15527         local trace="${2}"
15528
15529         awk -v name="${FSNAME}-OST0000" \
15530             -v event="${event}" \
15531             '$1 == "TRACE" && $2 == event && $3 == name' \
15532             "${trace}" |
15533         wc -l
15534 }
15535
15536 oalr_expect_event_count() {
15537         local event="${1}"
15538         local trace="${2}"
15539         local expect="${3}"
15540         local count
15541
15542         count=$(oalr_event_count "${event}" "${trace}")
15543         if ((count == expect)); then
15544                 return 0
15545         fi
15546
15547         error_noexit "${event} event count was '${count}', expected ${expect}"
15548         cat "${trace}" >&2
15549         exit 1
15550 }
15551
15552 cleanup_165() {
15553         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15554         stop ost1
15555         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15556 }
15557
15558 setup_165() {
15559         sync # Flush previous IOs so we can count log entries.
15560         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15561         stack_trap cleanup_165 EXIT
15562 }
15563
15564 test_165a() {
15565         local trace="/tmp/${tfile}.trace"
15566         local rc
15567         local count
15568
15569         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15570                 skip "OFD access log unsupported"
15571
15572         setup_165
15573         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15574         sleep 5
15575
15576         do_facet ost1 ofd_access_log_reader --list
15577         stop ost1
15578
15579         do_facet ost1 killall -TERM ofd_access_log_reader
15580         wait
15581         rc=$?
15582
15583         if ((rc != 0)); then
15584                 error "ofd_access_log_reader exited with rc = '${rc}'"
15585         fi
15586
15587         # Parse trace file for discovery events:
15588         oalr_expect_event_count alr_log_add "${trace}" 1
15589         oalr_expect_event_count alr_log_eof "${trace}" 1
15590         oalr_expect_event_count alr_log_free "${trace}" 1
15591 }
15592 run_test 165a "ofd access log discovery"
15593
15594 test_165b() {
15595         local trace="/tmp/${tfile}.trace"
15596         local file="${DIR}/${tfile}"
15597         local pfid1
15598         local pfid2
15599         local -a entry
15600         local rc
15601         local count
15602         local size
15603         local flags
15604
15605         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15606                 skip "OFD access log unsupported"
15607
15608         setup_165
15609         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15610         sleep 5
15611
15612         do_facet ost1 ofd_access_log_reader --list
15613
15614         lfs setstripe -c 1 -i 0 "${file}"
15615         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15616                 error "cannot create '${file}'"
15617
15618         sleep 5
15619         do_facet ost1 killall -TERM ofd_access_log_reader
15620         wait
15621         rc=$?
15622
15623         if ((rc != 0)); then
15624                 error "ofd_access_log_reader exited with rc = '${rc}'"
15625         fi
15626
15627         oalr_expect_event_count alr_log_entry "${trace}" 1
15628
15629         pfid1=$($LFS path2fid "${file}")
15630
15631         # 1     2             3   4    5     6   7    8    9     10
15632         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15633         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15634
15635         echo "entry = '${entry[*]}'" >&2
15636
15637         pfid2=${entry[4]}
15638         if [[ "${pfid1}" != "${pfid2}" ]]; then
15639                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15640         fi
15641
15642         size=${entry[8]}
15643         if ((size != 1048576)); then
15644                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15645         fi
15646
15647         flags=${entry[10]}
15648         if [[ "${flags}" != "w" ]]; then
15649                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15650         fi
15651
15652         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15653         sleep 5
15654
15655         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15656                 error "cannot read '${file}'"
15657         sleep 5
15658
15659         do_facet ost1 killall -TERM ofd_access_log_reader
15660         wait
15661         rc=$?
15662
15663         if ((rc != 0)); then
15664                 error "ofd_access_log_reader exited with rc = '${rc}'"
15665         fi
15666
15667         oalr_expect_event_count alr_log_entry "${trace}" 1
15668
15669         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15670         echo "entry = '${entry[*]}'" >&2
15671
15672         pfid2=${entry[4]}
15673         if [[ "${pfid1}" != "${pfid2}" ]]; then
15674                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15675         fi
15676
15677         size=${entry[8]}
15678         if ((size != 524288)); then
15679                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15680         fi
15681
15682         flags=${entry[10]}
15683         if [[ "${flags}" != "r" ]]; then
15684                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15685         fi
15686 }
15687 run_test 165b "ofd access log entries are produced and consumed"
15688
15689 test_165c() {
15690         local trace="/tmp/${tfile}.trace"
15691         local file="${DIR}/${tdir}/${tfile}"
15692
15693         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15694                 skip "OFD access log unsupported"
15695
15696         test_mkdir "${DIR}/${tdir}"
15697
15698         setup_165
15699         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15700         sleep 5
15701
15702         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15703
15704         # 4096 / 64 = 64. Create twice as many entries.
15705         for ((i = 0; i < 128; i++)); do
15706                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15707                         error "cannot create file"
15708         done
15709
15710         sync
15711
15712         do_facet ost1 killall -TERM ofd_access_log_reader
15713         wait
15714         rc=$?
15715         if ((rc != 0)); then
15716                 error "ofd_access_log_reader exited with rc = '${rc}'"
15717         fi
15718
15719         unlinkmany  "${file}-%d" 128
15720 }
15721 run_test 165c "full ofd access logs do not block IOs"
15722
15723 oal_get_read_count() {
15724         local stats="$1"
15725
15726         # STATS lustre-OST0001 alr_read_count 1
15727
15728         do_facet ost1 cat "${stats}" |
15729         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15730              END { print count; }'
15731 }
15732
15733 oal_expect_read_count() {
15734         local stats="$1"
15735         local count
15736         local expect="$2"
15737
15738         # Ask ofd_access_log_reader to write stats.
15739         do_facet ost1 killall -USR1 ofd_access_log_reader
15740
15741         # Allow some time for things to happen.
15742         sleep 1
15743
15744         count=$(oal_get_read_count "${stats}")
15745         if ((count == expect)); then
15746                 return 0
15747         fi
15748
15749         error_noexit "bad read count, got ${count}, expected ${expect}"
15750         do_facet ost1 cat "${stats}" >&2
15751         exit 1
15752 }
15753
15754 test_165d() {
15755         local stats="/tmp/${tfile}.stats"
15756         local file="${DIR}/${tdir}/${tfile}"
15757         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15758
15759         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15760                 skip "OFD access log unsupported"
15761
15762         test_mkdir "${DIR}/${tdir}"
15763
15764         setup_165
15765         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15766         sleep 5
15767
15768         lfs setstripe -c 1 -i 0 "${file}"
15769
15770         do_facet ost1 lctl set_param "${param}=rw"
15771         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15772                 error "cannot create '${file}'"
15773         oal_expect_read_count "${stats}" 1
15774
15775         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15776                 error "cannot read '${file}'"
15777         oal_expect_read_count "${stats}" 2
15778
15779         do_facet ost1 lctl set_param "${param}=r"
15780         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15781                 error "cannot create '${file}'"
15782         oal_expect_read_count "${stats}" 2
15783
15784         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15785                 error "cannot read '${file}'"
15786         oal_expect_read_count "${stats}" 3
15787
15788         do_facet ost1 lctl set_param "${param}=w"
15789         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15790                 error "cannot create '${file}'"
15791         oal_expect_read_count "${stats}" 4
15792
15793         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15794                 error "cannot read '${file}'"
15795         oal_expect_read_count "${stats}" 4
15796
15797         do_facet ost1 lctl set_param "${param}=0"
15798         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15799                 error "cannot create '${file}'"
15800         oal_expect_read_count "${stats}" 4
15801
15802         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15803                 error "cannot read '${file}'"
15804         oal_expect_read_count "${stats}" 4
15805
15806         do_facet ost1 killall -TERM ofd_access_log_reader
15807         wait
15808         rc=$?
15809         if ((rc != 0)); then
15810                 error "ofd_access_log_reader exited with rc = '${rc}'"
15811         fi
15812 }
15813 run_test 165d "ofd_access_log mask works"
15814
15815 test_165e() {
15816         local stats="/tmp/${tfile}.stats"
15817         local file0="${DIR}/${tdir}-0/${tfile}"
15818         local file1="${DIR}/${tdir}-1/${tfile}"
15819
15820         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15821                 skip "OFD access log unsupported"
15822
15823         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15824
15825         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15826         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15827
15828         lfs setstripe -c 1 -i 0 "${file0}"
15829         lfs setstripe -c 1 -i 0 "${file1}"
15830
15831         setup_165
15832         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15833         sleep 5
15834
15835         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15836                 error "cannot create '${file0}'"
15837         sync
15838         oal_expect_read_count "${stats}" 0
15839
15840         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15841                 error "cannot create '${file1}'"
15842         sync
15843         oal_expect_read_count "${stats}" 1
15844
15845         do_facet ost1 killall -TERM ofd_access_log_reader
15846         wait
15847         rc=$?
15848         if ((rc != 0)); then
15849                 error "ofd_access_log_reader exited with rc = '${rc}'"
15850         fi
15851 }
15852 run_test 165e "ofd_access_log MDT index filter works"
15853
15854 test_165f() {
15855         local trace="/tmp/${tfile}.trace"
15856         local rc
15857         local count
15858
15859         setup_165
15860         do_facet ost1 timeout 60 ofd_access_log_reader \
15861                 --exit-on-close --debug=- --trace=- > "${trace}" &
15862         sleep 5
15863         stop ost1
15864
15865         wait
15866         rc=$?
15867
15868         if ((rc != 0)); then
15869                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15870                 cat "${trace}"
15871                 exit 1
15872         fi
15873 }
15874 run_test 165f "ofd_access_log_reader --exit-on-close works"
15875
15876 test_169() {
15877         # do directio so as not to populate the page cache
15878         log "creating a 10 Mb file"
15879         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15880                 error "multiop failed while creating a file"
15881         log "starting reads"
15882         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15883         log "truncating the file"
15884         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15885                 error "multiop failed while truncating the file"
15886         log "killing dd"
15887         kill %+ || true # reads might have finished
15888         echo "wait until dd is finished"
15889         wait
15890         log "removing the temporary file"
15891         rm -rf $DIR/$tfile || error "tmp file removal failed"
15892 }
15893 run_test 169 "parallel read and truncate should not deadlock"
15894
15895 test_170() {
15896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15897
15898         $LCTL clear     # bug 18514
15899         $LCTL debug_daemon start $TMP/${tfile}_log_good
15900         touch $DIR/$tfile
15901         $LCTL debug_daemon stop
15902         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15903                 error "sed failed to read log_good"
15904
15905         $LCTL debug_daemon start $TMP/${tfile}_log_good
15906         rm -rf $DIR/$tfile
15907         $LCTL debug_daemon stop
15908
15909         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15910                error "lctl df log_bad failed"
15911
15912         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15913         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15914
15915         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15916         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15917
15918         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15919                 error "bad_line good_line1 good_line2 are empty"
15920
15921         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15922         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15923         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15924
15925         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15926         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15927         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15928
15929         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15930                 error "bad_line_new good_line_new are empty"
15931
15932         local expected_good=$((good_line1 + good_line2*2))
15933
15934         rm -f $TMP/${tfile}*
15935         # LU-231, short malformed line may not be counted into bad lines
15936         if [ $bad_line -ne $bad_line_new ] &&
15937                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15938                 error "expected $bad_line bad lines, but got $bad_line_new"
15939                 return 1
15940         fi
15941
15942         if [ $expected_good -ne $good_line_new ]; then
15943                 error "expected $expected_good good lines, but got $good_line_new"
15944                 return 2
15945         fi
15946         true
15947 }
15948 run_test 170 "test lctl df to handle corrupted log ====================="
15949
15950 test_171() { # bug20592
15951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15952
15953         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15954         $LCTL set_param fail_loc=0x50e
15955         $LCTL set_param fail_val=3000
15956         multiop_bg_pause $DIR/$tfile O_s || true
15957         local MULTIPID=$!
15958         kill -USR1 $MULTIPID
15959         # cause log dump
15960         sleep 3
15961         wait $MULTIPID
15962         if dmesg | grep "recursive fault"; then
15963                 error "caught a recursive fault"
15964         fi
15965         $LCTL set_param fail_loc=0
15966         true
15967 }
15968 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15969
15970 # it would be good to share it with obdfilter-survey/iokit-libecho code
15971 setup_obdecho_osc () {
15972         local rc=0
15973         local ost_nid=$1
15974         local obdfilter_name=$2
15975         echo "Creating new osc for $obdfilter_name on $ost_nid"
15976         # make sure we can find loopback nid
15977         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15978
15979         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15980                            ${obdfilter_name}_osc_UUID || rc=2; }
15981         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15982                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15983         return $rc
15984 }
15985
15986 cleanup_obdecho_osc () {
15987         local obdfilter_name=$1
15988         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15989         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15990         return 0
15991 }
15992
15993 obdecho_test() {
15994         local OBD=$1
15995         local node=$2
15996         local pages=${3:-64}
15997         local rc=0
15998         local id
15999
16000         local count=10
16001         local obd_size=$(get_obd_size $node $OBD)
16002         local page_size=$(get_page_size $node)
16003         if [[ -n "$obd_size" ]]; then
16004                 local new_count=$((obd_size / (pages * page_size / 1024)))
16005                 [[ $new_count -ge $count ]] || count=$new_count
16006         fi
16007
16008         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16009         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16010                            rc=2; }
16011         if [ $rc -eq 0 ]; then
16012             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16013             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16014         fi
16015         echo "New object id is $id"
16016         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16017                            rc=4; }
16018         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16019                            "test_brw $count w v $pages $id" || rc=4; }
16020         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16021                            rc=4; }
16022         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16023                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16024         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16025                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16026         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16027         return $rc
16028 }
16029
16030 test_180a() {
16031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16032
16033         if ! [ -d /sys/fs/lustre/echo_client ] &&
16034            ! module_loaded obdecho; then
16035                 load_module obdecho/obdecho &&
16036                         stack_trap "rmmod obdecho" EXIT ||
16037                         error "unable to load obdecho on client"
16038         fi
16039
16040         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16041         local host=$($LCTL get_param -n osc.$osc.import |
16042                      awk '/current_connection:/ { print $2 }' )
16043         local target=$($LCTL get_param -n osc.$osc.import |
16044                        awk '/target:/ { print $2 }' )
16045         target=${target%_UUID}
16046
16047         if [ -n "$target" ]; then
16048                 setup_obdecho_osc $host $target &&
16049                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16050                         { error "obdecho setup failed with $?"; return; }
16051
16052                 obdecho_test ${target}_osc client ||
16053                         error "obdecho_test failed on ${target}_osc"
16054         else
16055                 $LCTL get_param osc.$osc.import
16056                 error "there is no osc.$osc.import target"
16057         fi
16058 }
16059 run_test 180a "test obdecho on osc"
16060
16061 test_180b() {
16062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16063         remote_ost_nodsh && skip "remote OST with nodsh"
16064
16065         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16066                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16067                 error "failed to load module obdecho"
16068
16069         local target=$(do_facet ost1 $LCTL dl |
16070                        awk '/obdfilter/ { print $4; exit; }')
16071
16072         if [ -n "$target" ]; then
16073                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16074         else
16075                 do_facet ost1 $LCTL dl
16076                 error "there is no obdfilter target on ost1"
16077         fi
16078 }
16079 run_test 180b "test obdecho directly on obdfilter"
16080
16081 test_180c() { # LU-2598
16082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16083         remote_ost_nodsh && skip "remote OST with nodsh"
16084         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16085                 skip "Need MDS version at least 2.4.0"
16086
16087         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16088                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16089                 error "failed to load module obdecho"
16090
16091         local target=$(do_facet ost1 $LCTL dl |
16092                        awk '/obdfilter/ { print $4; exit; }')
16093
16094         if [ -n "$target" ]; then
16095                 local pages=16384 # 64MB bulk I/O RPC size
16096
16097                 obdecho_test "$target" ost1 "$pages" ||
16098                         error "obdecho_test with pages=$pages failed with $?"
16099         else
16100                 do_facet ost1 $LCTL dl
16101                 error "there is no obdfilter target on ost1"
16102         fi
16103 }
16104 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16105
16106 test_181() { # bug 22177
16107         test_mkdir $DIR/$tdir
16108         # create enough files to index the directory
16109         createmany -o $DIR/$tdir/foobar 4000
16110         # print attributes for debug purpose
16111         lsattr -d .
16112         # open dir
16113         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16114         MULTIPID=$!
16115         # remove the files & current working dir
16116         unlinkmany $DIR/$tdir/foobar 4000
16117         rmdir $DIR/$tdir
16118         kill -USR1 $MULTIPID
16119         wait $MULTIPID
16120         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16121         return 0
16122 }
16123 run_test 181 "Test open-unlinked dir ========================"
16124
16125 test_182() {
16126         local fcount=1000
16127         local tcount=10
16128
16129         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16130
16131         $LCTL set_param mdc.*.rpc_stats=clear
16132
16133         for (( i = 0; i < $tcount; i++ )) ; do
16134                 mkdir $DIR/$tdir/$i
16135         done
16136
16137         for (( i = 0; i < $tcount; i++ )) ; do
16138                 createmany -o $DIR/$tdir/$i/f- $fcount &
16139         done
16140         wait
16141
16142         for (( i = 0; i < $tcount; i++ )) ; do
16143                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16144         done
16145         wait
16146
16147         $LCTL get_param mdc.*.rpc_stats
16148
16149         rm -rf $DIR/$tdir
16150 }
16151 run_test 182 "Test parallel modify metadata operations ================"
16152
16153 test_183() { # LU-2275
16154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16155         remote_mds_nodsh && skip "remote MDS with nodsh"
16156         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16157                 skip "Need MDS version at least 2.3.56"
16158
16159         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16160         echo aaa > $DIR/$tdir/$tfile
16161
16162 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16163         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16164
16165         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16166         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16167
16168         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16169
16170         # Flush negative dentry cache
16171         touch $DIR/$tdir/$tfile
16172
16173         # We are not checking for any leaked references here, they'll
16174         # become evident next time we do cleanup with module unload.
16175         rm -rf $DIR/$tdir
16176 }
16177 run_test 183 "No crash or request leak in case of strange dispositions ========"
16178
16179 # test suite 184 is for LU-2016, LU-2017
16180 test_184a() {
16181         check_swap_layouts_support
16182
16183         dir0=$DIR/$tdir/$testnum
16184         test_mkdir -p -c1 $dir0
16185         ref1=/etc/passwd
16186         ref2=/etc/group
16187         file1=$dir0/f1
16188         file2=$dir0/f2
16189         $LFS setstripe -c1 $file1
16190         cp $ref1 $file1
16191         $LFS setstripe -c2 $file2
16192         cp $ref2 $file2
16193         gen1=$($LFS getstripe -g $file1)
16194         gen2=$($LFS getstripe -g $file2)
16195
16196         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16197         gen=$($LFS getstripe -g $file1)
16198         [[ $gen1 != $gen ]] ||
16199                 "Layout generation on $file1 does not change"
16200         gen=$($LFS getstripe -g $file2)
16201         [[ $gen2 != $gen ]] ||
16202                 "Layout generation on $file2 does not change"
16203
16204         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16205         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16206
16207         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16208 }
16209 run_test 184a "Basic layout swap"
16210
16211 test_184b() {
16212         check_swap_layouts_support
16213
16214         dir0=$DIR/$tdir/$testnum
16215         mkdir -p $dir0 || error "creating dir $dir0"
16216         file1=$dir0/f1
16217         file2=$dir0/f2
16218         file3=$dir0/f3
16219         dir1=$dir0/d1
16220         dir2=$dir0/d2
16221         mkdir $dir1 $dir2
16222         $LFS setstripe -c1 $file1
16223         $LFS setstripe -c2 $file2
16224         $LFS setstripe -c1 $file3
16225         chown $RUNAS_ID $file3
16226         gen1=$($LFS getstripe -g $file1)
16227         gen2=$($LFS getstripe -g $file2)
16228
16229         $LFS swap_layouts $dir1 $dir2 &&
16230                 error "swap of directories layouts should fail"
16231         $LFS swap_layouts $dir1 $file1 &&
16232                 error "swap of directory and file layouts should fail"
16233         $RUNAS $LFS swap_layouts $file1 $file2 &&
16234                 error "swap of file we cannot write should fail"
16235         $LFS swap_layouts $file1 $file3 &&
16236                 error "swap of file with different owner should fail"
16237         /bin/true # to clear error code
16238 }
16239 run_test 184b "Forbidden layout swap (will generate errors)"
16240
16241 test_184c() {
16242         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16243         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16244         check_swap_layouts_support
16245         check_swap_layout_no_dom $DIR
16246
16247         local dir0=$DIR/$tdir/$testnum
16248         mkdir -p $dir0 || error "creating dir $dir0"
16249
16250         local ref1=$dir0/ref1
16251         local ref2=$dir0/ref2
16252         local file1=$dir0/file1
16253         local file2=$dir0/file2
16254         # create a file large enough for the concurrent test
16255         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16256         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16257         echo "ref file size: ref1($(stat -c %s $ref1))," \
16258              "ref2($(stat -c %s $ref2))"
16259
16260         cp $ref2 $file2
16261         dd if=$ref1 of=$file1 bs=16k &
16262         local DD_PID=$!
16263
16264         # Make sure dd starts to copy file, but wait at most 5 seconds
16265         local loops=0
16266         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16267
16268         $LFS swap_layouts $file1 $file2
16269         local rc=$?
16270         wait $DD_PID
16271         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16272         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16273
16274         # how many bytes copied before swapping layout
16275         local copied=$(stat -c %s $file2)
16276         local remaining=$(stat -c %s $ref1)
16277         remaining=$((remaining - copied))
16278         echo "Copied $copied bytes before swapping layout..."
16279
16280         cmp -n $copied $file1 $ref2 | grep differ &&
16281                 error "Content mismatch [0, $copied) of ref2 and file1"
16282         cmp -n $copied $file2 $ref1 ||
16283                 error "Content mismatch [0, $copied) of ref1 and file2"
16284         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16285                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16286
16287         # clean up
16288         rm -f $ref1 $ref2 $file1 $file2
16289 }
16290 run_test 184c "Concurrent write and layout swap"
16291
16292 test_184d() {
16293         check_swap_layouts_support
16294         check_swap_layout_no_dom $DIR
16295         [ -z "$(which getfattr 2>/dev/null)" ] &&
16296                 skip_env "no getfattr command"
16297
16298         local file1=$DIR/$tdir/$tfile-1
16299         local file2=$DIR/$tdir/$tfile-2
16300         local file3=$DIR/$tdir/$tfile-3
16301         local lovea1
16302         local lovea2
16303
16304         mkdir -p $DIR/$tdir
16305         touch $file1 || error "create $file1 failed"
16306         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16307                 error "create $file2 failed"
16308         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16309                 error "create $file3 failed"
16310         lovea1=$(get_layout_param $file1)
16311
16312         $LFS swap_layouts $file2 $file3 ||
16313                 error "swap $file2 $file3 layouts failed"
16314         $LFS swap_layouts $file1 $file2 ||
16315                 error "swap $file1 $file2 layouts failed"
16316
16317         lovea2=$(get_layout_param $file2)
16318         echo "$lovea1"
16319         echo "$lovea2"
16320         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16321
16322         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16323         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16324 }
16325 run_test 184d "allow stripeless layouts swap"
16326
16327 test_184e() {
16328         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16329                 skip "Need MDS version at least 2.6.94"
16330         check_swap_layouts_support
16331         check_swap_layout_no_dom $DIR
16332         [ -z "$(which getfattr 2>/dev/null)" ] &&
16333                 skip_env "no getfattr command"
16334
16335         local file1=$DIR/$tdir/$tfile-1
16336         local file2=$DIR/$tdir/$tfile-2
16337         local file3=$DIR/$tdir/$tfile-3
16338         local lovea
16339
16340         mkdir -p $DIR/$tdir
16341         touch $file1 || error "create $file1 failed"
16342         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16343                 error "create $file2 failed"
16344         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16345                 error "create $file3 failed"
16346
16347         $LFS swap_layouts $file1 $file2 ||
16348                 error "swap $file1 $file2 layouts failed"
16349
16350         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16351         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16352
16353         echo 123 > $file1 || error "Should be able to write into $file1"
16354
16355         $LFS swap_layouts $file1 $file3 ||
16356                 error "swap $file1 $file3 layouts failed"
16357
16358         echo 123 > $file1 || error "Should be able to write into $file1"
16359
16360         rm -rf $file1 $file2 $file3
16361 }
16362 run_test 184e "Recreate layout after stripeless layout swaps"
16363
16364 test_184f() {
16365         # Create a file with name longer than sizeof(struct stat) ==
16366         # 144 to see if we can get chars from the file name to appear
16367         # in the returned striping. Note that 'f' == 0x66.
16368         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16369
16370         mkdir -p $DIR/$tdir
16371         mcreate $DIR/$tdir/$file
16372         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16373                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16374         fi
16375 }
16376 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16377
16378 test_185() { # LU-2441
16379         # LU-3553 - no volatile file support in old servers
16380         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16381                 skip "Need MDS version at least 2.3.60"
16382
16383         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16384         touch $DIR/$tdir/spoo
16385         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16386         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16387                 error "cannot create/write a volatile file"
16388         [ "$FILESET" == "" ] &&
16389         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16390                 error "FID is still valid after close"
16391
16392         multiop_bg_pause $DIR/$tdir vVw4096_c
16393         local multi_pid=$!
16394
16395         local OLD_IFS=$IFS
16396         IFS=":"
16397         local fidv=($fid)
16398         IFS=$OLD_IFS
16399         # assume that the next FID for this client is sequential, since stdout
16400         # is unfortunately eaten by multiop_bg_pause
16401         local n=$((${fidv[1]} + 1))
16402         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16403         if [ "$FILESET" == "" ]; then
16404                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16405                         error "FID is missing before close"
16406         fi
16407         kill -USR1 $multi_pid
16408         # 1 second delay, so if mtime change we will see it
16409         sleep 1
16410         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16411         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16412 }
16413 run_test 185 "Volatile file support"
16414
16415 function create_check_volatile() {
16416         local idx=$1
16417         local tgt
16418
16419         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16420         local PID=$!
16421         sleep 1
16422         local FID=$(cat /tmp/${tfile}.fid)
16423         [ "$FID" == "" ] && error "can't get FID for volatile"
16424         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16425         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16426         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16427         kill -USR1 $PID
16428         wait
16429         sleep 1
16430         cancel_lru_locks mdc # flush opencache
16431         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16432         return 0
16433 }
16434
16435 test_185a(){
16436         # LU-12516 - volatile creation via .lustre
16437         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16438                 skip "Need MDS version at least 2.3.55"
16439
16440         create_check_volatile 0
16441         [ $MDSCOUNT -lt 2 ] && return 0
16442
16443         # DNE case
16444         create_check_volatile 1
16445
16446         return 0
16447 }
16448 run_test 185a "Volatile file creation in .lustre/fid/"
16449
16450 test_187a() {
16451         remote_mds_nodsh && skip "remote MDS with nodsh"
16452         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16453                 skip "Need MDS version at least 2.3.0"
16454
16455         local dir0=$DIR/$tdir/$testnum
16456         mkdir -p $dir0 || error "creating dir $dir0"
16457
16458         local file=$dir0/file1
16459         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16460         local dv1=$($LFS data_version $file)
16461         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16462         local dv2=$($LFS data_version $file)
16463         [[ $dv1 != $dv2 ]] ||
16464                 error "data version did not change on write $dv1 == $dv2"
16465
16466         # clean up
16467         rm -f $file1
16468 }
16469 run_test 187a "Test data version change"
16470
16471 test_187b() {
16472         remote_mds_nodsh && skip "remote MDS with nodsh"
16473         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16474                 skip "Need MDS version at least 2.3.0"
16475
16476         local dir0=$DIR/$tdir/$testnum
16477         mkdir -p $dir0 || error "creating dir $dir0"
16478
16479         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16480         [[ ${DV[0]} != ${DV[1]} ]] ||
16481                 error "data version did not change on write"\
16482                       " ${DV[0]} == ${DV[1]}"
16483
16484         # clean up
16485         rm -f $file1
16486 }
16487 run_test 187b "Test data version change on volatile file"
16488
16489 test_200() {
16490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16491         remote_mgs_nodsh && skip "remote MGS with nodsh"
16492         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16493
16494         local POOL=${POOL:-cea1}
16495         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16496         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16497         # Pool OST targets
16498         local first_ost=0
16499         local last_ost=$(($OSTCOUNT - 1))
16500         local ost_step=2
16501         local ost_list=$(seq $first_ost $ost_step $last_ost)
16502         local ost_range="$first_ost $last_ost $ost_step"
16503         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16504         local file_dir=$POOL_ROOT/file_tst
16505         local subdir=$test_path/subdir
16506         local rc=0
16507
16508         while : ; do
16509                 # former test_200a test_200b
16510                 pool_add $POOL                          || { rc=$? ; break; }
16511                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16512                 # former test_200c test_200d
16513                 mkdir -p $test_path
16514                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16515                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16516                 mkdir -p $subdir
16517                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16518                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16519                                                         || { rc=$? ; break; }
16520                 # former test_200e test_200f
16521                 local files=$((OSTCOUNT*3))
16522                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16523                                                         || { rc=$? ; break; }
16524                 pool_create_files $POOL $file_dir $files "$ost_list" \
16525                                                         || { rc=$? ; break; }
16526                 # former test_200g test_200h
16527                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16528                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16529
16530                 # former test_201a test_201b test_201c
16531                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16532
16533                 local f=$test_path/$tfile
16534                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16535                 pool_remove $POOL $f                    || { rc=$? ; break; }
16536                 break
16537         done
16538
16539         destroy_test_pools
16540
16541         return $rc
16542 }
16543 run_test 200 "OST pools"
16544
16545 # usage: default_attr <count | size | offset>
16546 default_attr() {
16547         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16548 }
16549
16550 # usage: check_default_stripe_attr
16551 check_default_stripe_attr() {
16552         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16553         case $1 in
16554         --stripe-count|-c)
16555                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16556         --stripe-size|-S)
16557                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16558         --stripe-index|-i)
16559                 EXPECTED=-1;;
16560         *)
16561                 error "unknown getstripe attr '$1'"
16562         esac
16563
16564         [ $ACTUAL == $EXPECTED ] ||
16565                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16566 }
16567
16568 test_204a() {
16569         test_mkdir $DIR/$tdir
16570         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16571
16572         check_default_stripe_attr --stripe-count
16573         check_default_stripe_attr --stripe-size
16574         check_default_stripe_attr --stripe-index
16575 }
16576 run_test 204a "Print default stripe attributes"
16577
16578 test_204b() {
16579         test_mkdir $DIR/$tdir
16580         $LFS setstripe --stripe-count 1 $DIR/$tdir
16581
16582         check_default_stripe_attr --stripe-size
16583         check_default_stripe_attr --stripe-index
16584 }
16585 run_test 204b "Print default stripe size and offset"
16586
16587 test_204c() {
16588         test_mkdir $DIR/$tdir
16589         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16590
16591         check_default_stripe_attr --stripe-count
16592         check_default_stripe_attr --stripe-index
16593 }
16594 run_test 204c "Print default stripe count and offset"
16595
16596 test_204d() {
16597         test_mkdir $DIR/$tdir
16598         $LFS setstripe --stripe-index 0 $DIR/$tdir
16599
16600         check_default_stripe_attr --stripe-count
16601         check_default_stripe_attr --stripe-size
16602 }
16603 run_test 204d "Print default stripe count and size"
16604
16605 test_204e() {
16606         test_mkdir $DIR/$tdir
16607         $LFS setstripe -d $DIR/$tdir
16608
16609         check_default_stripe_attr --stripe-count --raw
16610         check_default_stripe_attr --stripe-size --raw
16611         check_default_stripe_attr --stripe-index --raw
16612 }
16613 run_test 204e "Print raw stripe attributes"
16614
16615 test_204f() {
16616         test_mkdir $DIR/$tdir
16617         $LFS setstripe --stripe-count 1 $DIR/$tdir
16618
16619         check_default_stripe_attr --stripe-size --raw
16620         check_default_stripe_attr --stripe-index --raw
16621 }
16622 run_test 204f "Print raw stripe size and offset"
16623
16624 test_204g() {
16625         test_mkdir $DIR/$tdir
16626         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16627
16628         check_default_stripe_attr --stripe-count --raw
16629         check_default_stripe_attr --stripe-index --raw
16630 }
16631 run_test 204g "Print raw stripe count and offset"
16632
16633 test_204h() {
16634         test_mkdir $DIR/$tdir
16635         $LFS setstripe --stripe-index 0 $DIR/$tdir
16636
16637         check_default_stripe_attr --stripe-count --raw
16638         check_default_stripe_attr --stripe-size --raw
16639 }
16640 run_test 204h "Print raw stripe count and size"
16641
16642 # Figure out which job scheduler is being used, if any,
16643 # or use a fake one
16644 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16645         JOBENV=SLURM_JOB_ID
16646 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16647         JOBENV=LSB_JOBID
16648 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16649         JOBENV=PBS_JOBID
16650 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16651         JOBENV=LOADL_STEP_ID
16652 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16653         JOBENV=JOB_ID
16654 else
16655         $LCTL list_param jobid_name > /dev/null 2>&1
16656         if [ $? -eq 0 ]; then
16657                 JOBENV=nodelocal
16658         else
16659                 JOBENV=FAKE_JOBID
16660         fi
16661 fi
16662 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16663
16664 verify_jobstats() {
16665         local cmd=($1)
16666         shift
16667         local facets="$@"
16668
16669 # we don't really need to clear the stats for this test to work, since each
16670 # command has a unique jobid, but it makes debugging easier if needed.
16671 #       for facet in $facets; do
16672 #               local dev=$(convert_facet2label $facet)
16673 #               # clear old jobstats
16674 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16675 #       done
16676
16677         # use a new JobID for each test, or we might see an old one
16678         [ "$JOBENV" = "FAKE_JOBID" ] &&
16679                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16680
16681         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16682
16683         [ "$JOBENV" = "nodelocal" ] && {
16684                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16685                 $LCTL set_param jobid_name=$FAKE_JOBID
16686                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16687         }
16688
16689         log "Test: ${cmd[*]}"
16690         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16691
16692         if [ $JOBENV = "FAKE_JOBID" ]; then
16693                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16694         else
16695                 ${cmd[*]}
16696         fi
16697
16698         # all files are created on OST0000
16699         for facet in $facets; do
16700                 local stats="*.$(convert_facet2label $facet).job_stats"
16701
16702                 # strip out libtool wrappers for in-tree executables
16703                 if [ $(do_facet $facet lctl get_param $stats |
16704                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16705                         do_facet $facet lctl get_param $stats
16706                         error "No jobstats for $JOBVAL found on $facet::$stats"
16707                 fi
16708         done
16709 }
16710
16711 jobstats_set() {
16712         local new_jobenv=$1
16713
16714         set_persistent_param_and_check client "jobid_var" \
16715                 "$FSNAME.sys.jobid_var" $new_jobenv
16716 }
16717
16718 test_205a() { # Job stats
16719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16720         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16721                 skip "Need MDS version with at least 2.7.1"
16722         remote_mgs_nodsh && skip "remote MGS with nodsh"
16723         remote_mds_nodsh && skip "remote MDS with nodsh"
16724         remote_ost_nodsh && skip "remote OST with nodsh"
16725         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16726                 skip "Server doesn't support jobstats"
16727         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16728
16729         local old_jobenv=$($LCTL get_param -n jobid_var)
16730         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16731
16732         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16733                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16734         else
16735                 stack_trap "do_facet mgs $PERM_CMD \
16736                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16737         fi
16738         changelog_register
16739
16740         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16741                                 mdt.*.job_cleanup_interval | head -n 1)
16742         local new_interval=5
16743         do_facet $SINGLEMDS \
16744                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16745         stack_trap "do_facet $SINGLEMDS \
16746                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16747         local start=$SECONDS
16748
16749         local cmd
16750         # mkdir
16751         cmd="mkdir $DIR/$tdir"
16752         verify_jobstats "$cmd" "$SINGLEMDS"
16753         # rmdir
16754         cmd="rmdir $DIR/$tdir"
16755         verify_jobstats "$cmd" "$SINGLEMDS"
16756         # mkdir on secondary MDT
16757         if [ $MDSCOUNT -gt 1 ]; then
16758                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16759                 verify_jobstats "$cmd" "mds2"
16760         fi
16761         # mknod
16762         cmd="mknod $DIR/$tfile c 1 3"
16763         verify_jobstats "$cmd" "$SINGLEMDS"
16764         # unlink
16765         cmd="rm -f $DIR/$tfile"
16766         verify_jobstats "$cmd" "$SINGLEMDS"
16767         # create all files on OST0000 so verify_jobstats can find OST stats
16768         # open & close
16769         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16770         verify_jobstats "$cmd" "$SINGLEMDS"
16771         # setattr
16772         cmd="touch $DIR/$tfile"
16773         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16774         # write
16775         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16776         verify_jobstats "$cmd" "ost1"
16777         # read
16778         cancel_lru_locks osc
16779         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16780         verify_jobstats "$cmd" "ost1"
16781         # truncate
16782         cmd="$TRUNCATE $DIR/$tfile 0"
16783         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16784         # rename
16785         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16786         verify_jobstats "$cmd" "$SINGLEMDS"
16787         # jobstats expiry - sleep until old stats should be expired
16788         local left=$((new_interval + 5 - (SECONDS - start)))
16789         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16790                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16791                         "0" $left
16792         cmd="mkdir $DIR/$tdir.expire"
16793         verify_jobstats "$cmd" "$SINGLEMDS"
16794         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16795             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16796
16797         # Ensure that jobid are present in changelog (if supported by MDS)
16798         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16799                 changelog_dump | tail -10
16800                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16801                 [ $jobids -eq 9 ] ||
16802                         error "Wrong changelog jobid count $jobids != 9"
16803
16804                 # LU-5862
16805                 JOBENV="disable"
16806                 jobstats_set $JOBENV
16807                 touch $DIR/$tfile
16808                 changelog_dump | grep $tfile
16809                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16810                 [ $jobids -eq 0 ] ||
16811                         error "Unexpected jobids when jobid_var=$JOBENV"
16812         fi
16813
16814         # test '%j' access to environment variable - if supported
16815         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16816                 JOBENV="JOBCOMPLEX"
16817                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16818
16819                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16820         fi
16821
16822         # test '%j' access to per-session jobid - if supported
16823         if lctl list_param jobid_this_session > /dev/null 2>&1
16824         then
16825                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16826                 lctl set_param jobid_this_session=$USER
16827
16828                 JOBENV="JOBCOMPLEX"
16829                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16830
16831                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16832         fi
16833 }
16834 run_test 205a "Verify job stats"
16835
16836 # LU-13117, LU-13597
16837 test_205b() {
16838         job_stats="mdt.*.job_stats"
16839         $LCTL set_param $job_stats=clear
16840         # Setting jobid_var to USER might not be supported
16841         $LCTL set_param jobid_var=USER || true
16842         $LCTL set_param jobid_name="%e.%u"
16843         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16844         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16845                 grep "job_id:.*foolish" &&
16846                         error "Unexpected jobid found"
16847         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16848                 grep "open:.*min.*max.*sum" ||
16849                         error "wrong job_stats format found"
16850 }
16851 run_test 205b "Verify job stats jobid and output format"
16852
16853 # LU-13733
16854 test_205c() {
16855         $LCTL set_param llite.*.stats=0
16856         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16857         $LCTL get_param llite.*.stats
16858         $LCTL get_param llite.*.stats | grep \
16859                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16860                         error "wrong client stats format found"
16861 }
16862 run_test 205c "Verify client stats format"
16863
16864 # LU-1480, LU-1773 and LU-1657
16865 test_206() {
16866         mkdir -p $DIR/$tdir
16867         $LFS setstripe -c -1 $DIR/$tdir
16868 #define OBD_FAIL_LOV_INIT 0x1403
16869         $LCTL set_param fail_loc=0xa0001403
16870         $LCTL set_param fail_val=1
16871         touch $DIR/$tdir/$tfile || true
16872 }
16873 run_test 206 "fail lov_init_raid0() doesn't lbug"
16874
16875 test_207a() {
16876         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16877         local fsz=`stat -c %s $DIR/$tfile`
16878         cancel_lru_locks mdc
16879
16880         # do not return layout in getattr intent
16881 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16882         $LCTL set_param fail_loc=0x170
16883         local sz=`stat -c %s $DIR/$tfile`
16884
16885         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16886
16887         rm -rf $DIR/$tfile
16888 }
16889 run_test 207a "can refresh layout at glimpse"
16890
16891 test_207b() {
16892         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16893         local cksum=`md5sum $DIR/$tfile`
16894         local fsz=`stat -c %s $DIR/$tfile`
16895         cancel_lru_locks mdc
16896         cancel_lru_locks osc
16897
16898         # do not return layout in getattr intent
16899 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16900         $LCTL set_param fail_loc=0x171
16901
16902         # it will refresh layout after the file is opened but before read issues
16903         echo checksum is "$cksum"
16904         echo "$cksum" |md5sum -c --quiet || error "file differs"
16905
16906         rm -rf $DIR/$tfile
16907 }
16908 run_test 207b "can refresh layout at open"
16909
16910 test_208() {
16911         # FIXME: in this test suite, only RD lease is used. This is okay
16912         # for now as only exclusive open is supported. After generic lease
16913         # is done, this test suite should be revised. - Jinshan
16914
16915         remote_mds_nodsh && skip "remote MDS with nodsh"
16916         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16917                 skip "Need MDS version at least 2.4.52"
16918
16919         echo "==== test 1: verify get lease work"
16920         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16921
16922         echo "==== test 2: verify lease can be broken by upcoming open"
16923         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16924         local PID=$!
16925         sleep 1
16926
16927         $MULTIOP $DIR/$tfile oO_RDONLY:c
16928         kill -USR1 $PID && wait $PID || error "break lease error"
16929
16930         echo "==== test 3: verify lease can't be granted if an open already exists"
16931         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16932         local PID=$!
16933         sleep 1
16934
16935         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16936         kill -USR1 $PID && wait $PID || error "open file error"
16937
16938         echo "==== test 4: lease can sustain over recovery"
16939         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16940         PID=$!
16941         sleep 1
16942
16943         fail mds1
16944
16945         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16946
16947         echo "==== test 5: lease broken can't be regained by replay"
16948         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16949         PID=$!
16950         sleep 1
16951
16952         # open file to break lease and then recovery
16953         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16954         fail mds1
16955
16956         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16957
16958         rm -f $DIR/$tfile
16959 }
16960 run_test 208 "Exclusive open"
16961
16962 test_209() {
16963         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16964                 skip_env "must have disp_stripe"
16965
16966         touch $DIR/$tfile
16967         sync; sleep 5; sync;
16968
16969         echo 3 > /proc/sys/vm/drop_caches
16970         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16971                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16972         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16973
16974         # open/close 500 times
16975         for i in $(seq 500); do
16976                 cat $DIR/$tfile
16977         done
16978
16979         echo 3 > /proc/sys/vm/drop_caches
16980         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16981                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16982         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16983
16984         echo "before: $req_before, after: $req_after"
16985         [ $((req_after - req_before)) -ge 300 ] &&
16986                 error "open/close requests are not freed"
16987         return 0
16988 }
16989 run_test 209 "read-only open/close requests should be freed promptly"
16990
16991 test_210() {
16992         local pid
16993
16994         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16995         pid=$!
16996         sleep 1
16997
16998         $LFS getstripe $DIR/$tfile
16999         kill -USR1 $pid
17000         wait $pid || error "multiop failed"
17001
17002         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17003         pid=$!
17004         sleep 1
17005
17006         $LFS getstripe $DIR/$tfile
17007         kill -USR1 $pid
17008         wait $pid || error "multiop failed"
17009 }
17010 run_test 210 "lfs getstripe does not break leases"
17011
17012 test_212() {
17013         size=`date +%s`
17014         size=$((size % 8192 + 1))
17015         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17016         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17017         rm -f $DIR/f212 $DIR/f212.xyz
17018 }
17019 run_test 212 "Sendfile test ============================================"
17020
17021 test_213() {
17022         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17023         cancel_lru_locks osc
17024         lctl set_param fail_loc=0x8000040f
17025         # generate a read lock
17026         cat $DIR/$tfile > /dev/null
17027         # write to the file, it will try to cancel the above read lock.
17028         cat /etc/hosts >> $DIR/$tfile
17029 }
17030 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17031
17032 test_214() { # for bug 20133
17033         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17034         for (( i=0; i < 340; i++ )) ; do
17035                 touch $DIR/$tdir/d214c/a$i
17036         done
17037
17038         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17039         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17040         ls $DIR/d214c || error "ls $DIR/d214c failed"
17041         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17042         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17043 }
17044 run_test 214 "hash-indexed directory test - bug 20133"
17045
17046 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17047 create_lnet_proc_files() {
17048         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17049 }
17050
17051 # counterpart of create_lnet_proc_files
17052 remove_lnet_proc_files() {
17053         rm -f $TMP/lnet_$1.sys
17054 }
17055
17056 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17057 # 3rd arg as regexp for body
17058 check_lnet_proc_stats() {
17059         local l=$(cat "$TMP/lnet_$1" |wc -l)
17060         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17061
17062         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17063 }
17064
17065 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17066 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17067 # optional and can be regexp for 2nd line (lnet.routes case)
17068 check_lnet_proc_entry() {
17069         local blp=2          # blp stands for 'position of 1st line of body'
17070         [ -z "$5" ] || blp=3 # lnet.routes case
17071
17072         local l=$(cat "$TMP/lnet_$1" |wc -l)
17073         # subtracting one from $blp because the body can be empty
17074         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17075
17076         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17077                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17078
17079         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17080                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17081
17082         # bail out if any unexpected line happened
17083         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17084         [ "$?" != 0 ] || error "$2 misformatted"
17085 }
17086
17087 test_215() { # for bugs 18102, 21079, 21517
17088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17089
17090         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17091         local P='[1-9][0-9]*'           # positive numeric
17092         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17093         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17094         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17095         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17096
17097         local L1 # regexp for 1st line
17098         local L2 # regexp for 2nd line (optional)
17099         local BR # regexp for the rest (body)
17100
17101         # lnet.stats should look as 11 space-separated non-negative numerics
17102         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17103         create_lnet_proc_files "stats"
17104         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17105         remove_lnet_proc_files "stats"
17106
17107         # lnet.routes should look like this:
17108         # Routing disabled/enabled
17109         # net hops priority state router
17110         # where net is a string like tcp0, hops > 0, priority >= 0,
17111         # state is up/down,
17112         # router is a string like 192.168.1.1@tcp2
17113         L1="^Routing (disabled|enabled)$"
17114         L2="^net +hops +priority +state +router$"
17115         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17116         create_lnet_proc_files "routes"
17117         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17118         remove_lnet_proc_files "routes"
17119
17120         # lnet.routers should look like this:
17121         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17122         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17123         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17124         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17125         L1="^ref +rtr_ref +alive +router$"
17126         BR="^$P +$P +(up|down) +$NID$"
17127         create_lnet_proc_files "routers"
17128         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17129         remove_lnet_proc_files "routers"
17130
17131         # lnet.peers should look like this:
17132         # nid refs state last max rtr min tx min queue
17133         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17134         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17135         # numeric (0 or >0 or <0), queue >= 0.
17136         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17137         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17138         create_lnet_proc_files "peers"
17139         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17140         remove_lnet_proc_files "peers"
17141
17142         # lnet.buffers  should look like this:
17143         # pages count credits min
17144         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17145         L1="^pages +count +credits +min$"
17146         BR="^ +$N +$N +$I +$I$"
17147         create_lnet_proc_files "buffers"
17148         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17149         remove_lnet_proc_files "buffers"
17150
17151         # lnet.nis should look like this:
17152         # nid status alive refs peer rtr max tx min
17153         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17154         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17155         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17156         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17157         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17158         create_lnet_proc_files "nis"
17159         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17160         remove_lnet_proc_files "nis"
17161
17162         # can we successfully write to lnet.stats?
17163         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17164 }
17165 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17166
17167 test_216() { # bug 20317
17168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17169         remote_ost_nodsh && skip "remote OST with nodsh"
17170
17171         local node
17172         local facets=$(get_facets OST)
17173         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17174
17175         save_lustre_params client "osc.*.contention_seconds" > $p
17176         save_lustre_params $facets \
17177                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17178         save_lustre_params $facets \
17179                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17180         save_lustre_params $facets \
17181                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17182         clear_stats osc.*.osc_stats
17183
17184         # agressive lockless i/o settings
17185         do_nodes $(comma_list $(osts_nodes)) \
17186                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17187                         ldlm.namespaces.filter-*.contended_locks=0 \
17188                         ldlm.namespaces.filter-*.contention_seconds=60"
17189         lctl set_param -n osc.*.contention_seconds=60
17190
17191         $DIRECTIO write $DIR/$tfile 0 10 4096
17192         $CHECKSTAT -s 40960 $DIR/$tfile
17193
17194         # disable lockless i/o
17195         do_nodes $(comma_list $(osts_nodes)) \
17196                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17197                         ldlm.namespaces.filter-*.contended_locks=32 \
17198                         ldlm.namespaces.filter-*.contention_seconds=0"
17199         lctl set_param -n osc.*.contention_seconds=0
17200         clear_stats osc.*.osc_stats
17201
17202         dd if=/dev/zero of=$DIR/$tfile count=0
17203         $CHECKSTAT -s 0 $DIR/$tfile
17204
17205         restore_lustre_params <$p
17206         rm -f $p
17207         rm $DIR/$tfile
17208 }
17209 run_test 216 "check lockless direct write updates file size and kms correctly"
17210
17211 test_217() { # bug 22430
17212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17213
17214         local node
17215         local nid
17216
17217         for node in $(nodes_list); do
17218                 nid=$(host_nids_address $node $NETTYPE)
17219                 if [[ $nid = *-* ]] ; then
17220                         echo "lctl ping $(h2nettype $nid)"
17221                         lctl ping $(h2nettype $nid)
17222                 else
17223                         echo "skipping $node (no hyphen detected)"
17224                 fi
17225         done
17226 }
17227 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17228
17229 test_218() {
17230        # do directio so as not to populate the page cache
17231        log "creating a 10 Mb file"
17232        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17233        log "starting reads"
17234        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17235        log "truncating the file"
17236        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17237        log "killing dd"
17238        kill %+ || true # reads might have finished
17239        echo "wait until dd is finished"
17240        wait
17241        log "removing the temporary file"
17242        rm -rf $DIR/$tfile || error "tmp file removal failed"
17243 }
17244 run_test 218 "parallel read and truncate should not deadlock"
17245
17246 test_219() {
17247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17248
17249         # write one partial page
17250         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17251         # set no grant so vvp_io_commit_write will do sync write
17252         $LCTL set_param fail_loc=0x411
17253         # write a full page at the end of file
17254         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17255
17256         $LCTL set_param fail_loc=0
17257         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17258         $LCTL set_param fail_loc=0x411
17259         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17260
17261         # LU-4201
17262         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17263         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17264 }
17265 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17266
17267 test_220() { #LU-325
17268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17269         remote_ost_nodsh && skip "remote OST with nodsh"
17270         remote_mds_nodsh && skip "remote MDS with nodsh"
17271         remote_mgs_nodsh && skip "remote MGS with nodsh"
17272
17273         local OSTIDX=0
17274
17275         # create on MDT0000 so the last_id and next_id are correct
17276         mkdir $DIR/$tdir
17277         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17278         OST=${OST%_UUID}
17279
17280         # on the mdt's osc
17281         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17282         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17283                         osp.$mdtosc_proc1.prealloc_last_id)
17284         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17285                         osp.$mdtosc_proc1.prealloc_next_id)
17286
17287         $LFS df -i
17288
17289         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17290         #define OBD_FAIL_OST_ENOINO              0x229
17291         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17292         create_pool $FSNAME.$TESTNAME || return 1
17293         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17294
17295         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17296
17297         MDSOBJS=$((last_id - next_id))
17298         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17299
17300         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17301         echo "OST still has $count kbytes free"
17302
17303         echo "create $MDSOBJS files @next_id..."
17304         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17305
17306         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17307                         osp.$mdtosc_proc1.prealloc_last_id)
17308         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17309                         osp.$mdtosc_proc1.prealloc_next_id)
17310
17311         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17312         $LFS df -i
17313
17314         echo "cleanup..."
17315
17316         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17317         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17318
17319         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17320                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17321         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17322                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17323         echo "unlink $MDSOBJS files @$next_id..."
17324         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17325 }
17326 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17327
17328 test_221() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330
17331         dd if=`which date` of=$MOUNT/date oflag=sync
17332         chmod +x $MOUNT/date
17333
17334         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17335         $LCTL set_param fail_loc=0x80001401
17336
17337         $MOUNT/date > /dev/null
17338         rm -f $MOUNT/date
17339 }
17340 run_test 221 "make sure fault and truncate race to not cause OOM"
17341
17342 test_222a () {
17343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17344
17345         rm -rf $DIR/$tdir
17346         test_mkdir $DIR/$tdir
17347         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17348         createmany -o $DIR/$tdir/$tfile 10
17349         cancel_lru_locks mdc
17350         cancel_lru_locks osc
17351         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17352         $LCTL set_param fail_loc=0x31a
17353         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17354         $LCTL set_param fail_loc=0
17355         rm -r $DIR/$tdir
17356 }
17357 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17358
17359 test_222b () {
17360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17361
17362         rm -rf $DIR/$tdir
17363         test_mkdir $DIR/$tdir
17364         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17365         createmany -o $DIR/$tdir/$tfile 10
17366         cancel_lru_locks mdc
17367         cancel_lru_locks osc
17368         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17369         $LCTL set_param fail_loc=0x31a
17370         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17371         $LCTL set_param fail_loc=0
17372 }
17373 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17374
17375 test_223 () {
17376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17377
17378         rm -rf $DIR/$tdir
17379         test_mkdir $DIR/$tdir
17380         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17381         createmany -o $DIR/$tdir/$tfile 10
17382         cancel_lru_locks mdc
17383         cancel_lru_locks osc
17384         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17385         $LCTL set_param fail_loc=0x31b
17386         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17387         $LCTL set_param fail_loc=0
17388         rm -r $DIR/$tdir
17389 }
17390 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17391
17392 test_224a() { # LU-1039, MRP-303
17393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17394
17395         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17396         $LCTL set_param fail_loc=0x508
17397         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17398         $LCTL set_param fail_loc=0
17399         df $DIR
17400 }
17401 run_test 224a "Don't panic on bulk IO failure"
17402
17403 test_224b() { # LU-1039, MRP-303
17404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17405
17406         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17407         cancel_lru_locks osc
17408         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17409         $LCTL set_param fail_loc=0x515
17410         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17411         $LCTL set_param fail_loc=0
17412         df $DIR
17413 }
17414 run_test 224b "Don't panic on bulk IO failure"
17415
17416 test_224c() { # LU-6441
17417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17418         remote_mds_nodsh && skip "remote MDS with nodsh"
17419
17420         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17421         save_writethrough $p
17422         set_cache writethrough on
17423
17424         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17425         local at_max=$($LCTL get_param -n at_max)
17426         local timeout=$($LCTL get_param -n timeout)
17427         local test_at="at_max"
17428         local param_at="$FSNAME.sys.at_max"
17429         local test_timeout="timeout"
17430         local param_timeout="$FSNAME.sys.timeout"
17431
17432         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17433
17434         set_persistent_param_and_check client "$test_at" "$param_at" 0
17435         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17436
17437         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17438         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17439         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17440         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17441         sync
17442         do_facet ost1 "$LCTL set_param fail_loc=0"
17443
17444         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17445         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17446                 $timeout
17447
17448         $LCTL set_param -n $pages_per_rpc
17449         restore_lustre_params < $p
17450         rm -f $p
17451 }
17452 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17453
17454 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17455 test_225a () {
17456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17457         if [ -z ${MDSSURVEY} ]; then
17458                 skip_env "mds-survey not found"
17459         fi
17460         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17461                 skip "Need MDS version at least 2.2.51"
17462
17463         local mds=$(facet_host $SINGLEMDS)
17464         local target=$(do_nodes $mds 'lctl dl' |
17465                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17466
17467         local cmd1="file_count=1000 thrhi=4"
17468         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17469         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17470         local cmd="$cmd1 $cmd2 $cmd3"
17471
17472         rm -f ${TMP}/mds_survey*
17473         echo + $cmd
17474         eval $cmd || error "mds-survey with zero-stripe failed"
17475         cat ${TMP}/mds_survey*
17476         rm -f ${TMP}/mds_survey*
17477 }
17478 run_test 225a "Metadata survey sanity with zero-stripe"
17479
17480 test_225b () {
17481         if [ -z ${MDSSURVEY} ]; then
17482                 skip_env "mds-survey not found"
17483         fi
17484         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17485                 skip "Need MDS version at least 2.2.51"
17486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17487         remote_mds_nodsh && skip "remote MDS with nodsh"
17488         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17489                 skip_env "Need to mount OST to test"
17490         fi
17491
17492         local mds=$(facet_host $SINGLEMDS)
17493         local target=$(do_nodes $mds 'lctl dl' |
17494                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17495
17496         local cmd1="file_count=1000 thrhi=4"
17497         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17498         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17499         local cmd="$cmd1 $cmd2 $cmd3"
17500
17501         rm -f ${TMP}/mds_survey*
17502         echo + $cmd
17503         eval $cmd || error "mds-survey with stripe_count failed"
17504         cat ${TMP}/mds_survey*
17505         rm -f ${TMP}/mds_survey*
17506 }
17507 run_test 225b "Metadata survey sanity with stripe_count = 1"
17508
17509 mcreate_path2fid () {
17510         local mode=$1
17511         local major=$2
17512         local minor=$3
17513         local name=$4
17514         local desc=$5
17515         local path=$DIR/$tdir/$name
17516         local fid
17517         local rc
17518         local fid_path
17519
17520         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17521                 error "cannot create $desc"
17522
17523         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17524         rc=$?
17525         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17526
17527         fid_path=$($LFS fid2path $MOUNT $fid)
17528         rc=$?
17529         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17530
17531         [ "$path" == "$fid_path" ] ||
17532                 error "fid2path returned $fid_path, expected $path"
17533
17534         echo "pass with $path and $fid"
17535 }
17536
17537 test_226a () {
17538         rm -rf $DIR/$tdir
17539         mkdir -p $DIR/$tdir
17540
17541         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17542         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17543         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17544         mcreate_path2fid 0040666 0 0 dir "directory"
17545         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17546         mcreate_path2fid 0100666 0 0 file "regular file"
17547         mcreate_path2fid 0120666 0 0 link "symbolic link"
17548         mcreate_path2fid 0140666 0 0 sock "socket"
17549 }
17550 run_test 226a "call path2fid and fid2path on files of all type"
17551
17552 test_226b () {
17553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17554
17555         local MDTIDX=1
17556
17557         rm -rf $DIR/$tdir
17558         mkdir -p $DIR/$tdir
17559         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17560                 error "create remote directory failed"
17561         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17562         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17563                                 "character special file (null)"
17564         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17565                                 "character special file (no device)"
17566         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17567         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17568                                 "block special file (loop)"
17569         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17570         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17571         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17572 }
17573 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17574
17575 test_226c () {
17576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17577         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17578                 skip "Need MDS version at least 2.13.55"
17579
17580         local submnt=/mnt/submnt
17581         local srcfile=/etc/passwd
17582         local dstfile=$submnt/passwd
17583         local path
17584         local fid
17585
17586         rm -rf $DIR/$tdir
17587         rm -rf $submnt
17588         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17589                 error "create remote directory failed"
17590         mkdir -p $submnt || error "create $submnt failed"
17591         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17592                 error "mount $submnt failed"
17593         stack_trap "umount $submnt" EXIT
17594
17595         cp $srcfile $dstfile
17596         fid=$($LFS path2fid $dstfile)
17597         path=$($LFS fid2path $submnt "$fid")
17598         [ "$path" = "$dstfile" ] ||
17599                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17600 }
17601 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17602
17603 # LU-1299 Executing or running ldd on a truncated executable does not
17604 # cause an out-of-memory condition.
17605 test_227() {
17606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17607         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17608
17609         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17610         chmod +x $MOUNT/date
17611
17612         $MOUNT/date > /dev/null
17613         ldd $MOUNT/date > /dev/null
17614         rm -f $MOUNT/date
17615 }
17616 run_test 227 "running truncated executable does not cause OOM"
17617
17618 # LU-1512 try to reuse idle OI blocks
17619 test_228a() {
17620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17621         remote_mds_nodsh && skip "remote MDS with nodsh"
17622         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17623
17624         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17625         local myDIR=$DIR/$tdir
17626
17627         mkdir -p $myDIR
17628         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17629         $LCTL set_param fail_loc=0x80001002
17630         createmany -o $myDIR/t- 10000
17631         $LCTL set_param fail_loc=0
17632         # The guard is current the largest FID holder
17633         touch $myDIR/guard
17634         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17635                     tr -d '[')
17636         local IDX=$(($SEQ % 64))
17637
17638         do_facet $SINGLEMDS sync
17639         # Make sure journal flushed.
17640         sleep 6
17641         local blk1=$(do_facet $SINGLEMDS \
17642                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17643                      grep Blockcount | awk '{print $4}')
17644
17645         # Remove old files, some OI blocks will become idle.
17646         unlinkmany $myDIR/t- 10000
17647         # Create new files, idle OI blocks should be reused.
17648         createmany -o $myDIR/t- 2000
17649         do_facet $SINGLEMDS sync
17650         # Make sure journal flushed.
17651         sleep 6
17652         local blk2=$(do_facet $SINGLEMDS \
17653                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17654                      grep Blockcount | awk '{print $4}')
17655
17656         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17657 }
17658 run_test 228a "try to reuse idle OI blocks"
17659
17660 test_228b() {
17661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17662         remote_mds_nodsh && skip "remote MDS with nodsh"
17663         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17664
17665         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17666         local myDIR=$DIR/$tdir
17667
17668         mkdir -p $myDIR
17669         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17670         $LCTL set_param fail_loc=0x80001002
17671         createmany -o $myDIR/t- 10000
17672         $LCTL set_param fail_loc=0
17673         # The guard is current the largest FID holder
17674         touch $myDIR/guard
17675         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17676                     tr -d '[')
17677         local IDX=$(($SEQ % 64))
17678
17679         do_facet $SINGLEMDS sync
17680         # Make sure journal flushed.
17681         sleep 6
17682         local blk1=$(do_facet $SINGLEMDS \
17683                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17684                      grep Blockcount | awk '{print $4}')
17685
17686         # Remove old files, some OI blocks will become idle.
17687         unlinkmany $myDIR/t- 10000
17688
17689         # stop the MDT
17690         stop $SINGLEMDS || error "Fail to stop MDT."
17691         # remount the MDT
17692         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17693
17694         df $MOUNT || error "Fail to df."
17695         # Create new files, idle OI blocks should be reused.
17696         createmany -o $myDIR/t- 2000
17697         do_facet $SINGLEMDS sync
17698         # Make sure journal flushed.
17699         sleep 6
17700         local blk2=$(do_facet $SINGLEMDS \
17701                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17702                      grep Blockcount | awk '{print $4}')
17703
17704         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17705 }
17706 run_test 228b "idle OI blocks can be reused after MDT restart"
17707
17708 #LU-1881
17709 test_228c() {
17710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17711         remote_mds_nodsh && skip "remote MDS with nodsh"
17712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17713
17714         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17715         local myDIR=$DIR/$tdir
17716
17717         mkdir -p $myDIR
17718         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17719         $LCTL set_param fail_loc=0x80001002
17720         # 20000 files can guarantee there are index nodes in the OI file
17721         createmany -o $myDIR/t- 20000
17722         $LCTL set_param fail_loc=0
17723         # The guard is current the largest FID holder
17724         touch $myDIR/guard
17725         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17726                     tr -d '[')
17727         local IDX=$(($SEQ % 64))
17728
17729         do_facet $SINGLEMDS sync
17730         # Make sure journal flushed.
17731         sleep 6
17732         local blk1=$(do_facet $SINGLEMDS \
17733                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17734                      grep Blockcount | awk '{print $4}')
17735
17736         # Remove old files, some OI blocks will become idle.
17737         unlinkmany $myDIR/t- 20000
17738         rm -f $myDIR/guard
17739         # The OI file should become empty now
17740
17741         # Create new files, idle OI blocks should be reused.
17742         createmany -o $myDIR/t- 2000
17743         do_facet $SINGLEMDS sync
17744         # Make sure journal flushed.
17745         sleep 6
17746         local blk2=$(do_facet $SINGLEMDS \
17747                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17748                      grep Blockcount | awk '{print $4}')
17749
17750         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17751 }
17752 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17753
17754 test_229() { # LU-2482, LU-3448
17755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17756         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17757         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17758                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17759
17760         rm -f $DIR/$tfile
17761
17762         # Create a file with a released layout and stripe count 2.
17763         $MULTIOP $DIR/$tfile H2c ||
17764                 error "failed to create file with released layout"
17765
17766         $LFS getstripe -v $DIR/$tfile
17767
17768         local pattern=$($LFS getstripe -L $DIR/$tfile)
17769         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17770
17771         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17772                 error "getstripe"
17773         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17774         stat $DIR/$tfile || error "failed to stat released file"
17775
17776         chown $RUNAS_ID $DIR/$tfile ||
17777                 error "chown $RUNAS_ID $DIR/$tfile failed"
17778
17779         chgrp $RUNAS_ID $DIR/$tfile ||
17780                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17781
17782         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17783         rm $DIR/$tfile || error "failed to remove released file"
17784 }
17785 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17786
17787 test_230a() {
17788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17790         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17791                 skip "Need MDS version at least 2.11.52"
17792
17793         local MDTIDX=1
17794
17795         test_mkdir $DIR/$tdir
17796         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17797         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17798         [ $mdt_idx -ne 0 ] &&
17799                 error "create local directory on wrong MDT $mdt_idx"
17800
17801         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17802                         error "create remote directory failed"
17803         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17804         [ $mdt_idx -ne $MDTIDX ] &&
17805                 error "create remote directory on wrong MDT $mdt_idx"
17806
17807         createmany -o $DIR/$tdir/test_230/t- 10 ||
17808                 error "create files on remote directory failed"
17809         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17810         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17811         rm -r $DIR/$tdir || error "unlink remote directory failed"
17812 }
17813 run_test 230a "Create remote directory and files under the remote directory"
17814
17815 test_230b() {
17816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17818         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17819                 skip "Need MDS version at least 2.11.52"
17820
17821         local MDTIDX=1
17822         local mdt_index
17823         local i
17824         local file
17825         local pid
17826         local stripe_count
17827         local migrate_dir=$DIR/$tdir/migrate_dir
17828         local other_dir=$DIR/$tdir/other_dir
17829
17830         test_mkdir $DIR/$tdir
17831         test_mkdir -i0 -c1 $migrate_dir
17832         test_mkdir -i0 -c1 $other_dir
17833         for ((i=0; i<10; i++)); do
17834                 mkdir -p $migrate_dir/dir_${i}
17835                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17836                         error "create files under remote dir failed $i"
17837         done
17838
17839         cp /etc/passwd $migrate_dir/$tfile
17840         cp /etc/passwd $other_dir/$tfile
17841         chattr +SAD $migrate_dir
17842         chattr +SAD $migrate_dir/$tfile
17843
17844         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17845         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17846         local old_dir_mode=$(stat -c%f $migrate_dir)
17847         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17848
17849         mkdir -p $migrate_dir/dir_default_stripe2
17850         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17851         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17852
17853         mkdir -p $other_dir
17854         ln $migrate_dir/$tfile $other_dir/luna
17855         ln $migrate_dir/$tfile $migrate_dir/sofia
17856         ln $other_dir/$tfile $migrate_dir/david
17857         ln -s $migrate_dir/$tfile $other_dir/zachary
17858         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17859         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17860
17861         local len
17862         local lnktgt
17863
17864         # inline symlink
17865         for len in 58 59 60; do
17866                 lnktgt=$(str_repeat 'l' $len)
17867                 touch $migrate_dir/$lnktgt
17868                 ln -s $lnktgt $migrate_dir/${len}char_ln
17869         done
17870
17871         # PATH_MAX
17872         for len in 4094 4095; do
17873                 lnktgt=$(str_repeat 'l' $len)
17874                 ln -s $lnktgt $migrate_dir/${len}char_ln
17875         done
17876
17877         # NAME_MAX
17878         for len in 254 255; do
17879                 touch $migrate_dir/$(str_repeat 'l' $len)
17880         done
17881
17882         $LFS migrate -m $MDTIDX $migrate_dir ||
17883                 error "fails on migrating remote dir to MDT1"
17884
17885         echo "migratate to MDT1, then checking.."
17886         for ((i = 0; i < 10; i++)); do
17887                 for file in $(find $migrate_dir/dir_${i}); do
17888                         mdt_index=$($LFS getstripe -m $file)
17889                         # broken symlink getstripe will fail
17890                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17891                                 error "$file is not on MDT${MDTIDX}"
17892                 done
17893         done
17894
17895         # the multiple link file should still in MDT0
17896         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17897         [ $mdt_index == 0 ] ||
17898                 error "$file is not on MDT${MDTIDX}"
17899
17900         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17901         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17902                 error " expect $old_dir_flag get $new_dir_flag"
17903
17904         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17905         [ "$old_file_flag" = "$new_file_flag" ] ||
17906                 error " expect $old_file_flag get $new_file_flag"
17907
17908         local new_dir_mode=$(stat -c%f $migrate_dir)
17909         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17910                 error "expect mode $old_dir_mode get $new_dir_mode"
17911
17912         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17913         [ "$old_file_mode" = "$new_file_mode" ] ||
17914                 error "expect mode $old_file_mode get $new_file_mode"
17915
17916         diff /etc/passwd $migrate_dir/$tfile ||
17917                 error "$tfile different after migration"
17918
17919         diff /etc/passwd $other_dir/luna ||
17920                 error "luna different after migration"
17921
17922         diff /etc/passwd $migrate_dir/sofia ||
17923                 error "sofia different after migration"
17924
17925         diff /etc/passwd $migrate_dir/david ||
17926                 error "david different after migration"
17927
17928         diff /etc/passwd $other_dir/zachary ||
17929                 error "zachary different after migration"
17930
17931         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17932                 error "${tfile}_ln different after migration"
17933
17934         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17935                 error "${tfile}_ln_other different after migration"
17936
17937         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17938         [ $stripe_count = 2 ] ||
17939                 error "dir strpe_count $d != 2 after migration."
17940
17941         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17942         [ $stripe_count = 2 ] ||
17943                 error "file strpe_count $d != 2 after migration."
17944
17945         #migrate back to MDT0
17946         MDTIDX=0
17947
17948         $LFS migrate -m $MDTIDX $migrate_dir ||
17949                 error "fails on migrating remote dir to MDT0"
17950
17951         echo "migrate back to MDT0, checking.."
17952         for file in $(find $migrate_dir); do
17953                 mdt_index=$($LFS getstripe -m $file)
17954                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17955                         error "$file is not on MDT${MDTIDX}"
17956         done
17957
17958         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17959         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17960                 error " expect $old_dir_flag get $new_dir_flag"
17961
17962         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17963         [ "$old_file_flag" = "$new_file_flag" ] ||
17964                 error " expect $old_file_flag get $new_file_flag"
17965
17966         local new_dir_mode=$(stat -c%f $migrate_dir)
17967         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17968                 error "expect mode $old_dir_mode get $new_dir_mode"
17969
17970         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17971         [ "$old_file_mode" = "$new_file_mode" ] ||
17972                 error "expect mode $old_file_mode get $new_file_mode"
17973
17974         diff /etc/passwd ${migrate_dir}/$tfile ||
17975                 error "$tfile different after migration"
17976
17977         diff /etc/passwd ${other_dir}/luna ||
17978                 error "luna different after migration"
17979
17980         diff /etc/passwd ${migrate_dir}/sofia ||
17981                 error "sofia different after migration"
17982
17983         diff /etc/passwd ${other_dir}/zachary ||
17984                 error "zachary different after migration"
17985
17986         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17987                 error "${tfile}_ln different after migration"
17988
17989         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17990                 error "${tfile}_ln_other different after migration"
17991
17992         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17993         [ $stripe_count = 2 ] ||
17994                 error "dir strpe_count $d != 2 after migration."
17995
17996         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17997         [ $stripe_count = 2 ] ||
17998                 error "file strpe_count $d != 2 after migration."
17999
18000         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18001 }
18002 run_test 230b "migrate directory"
18003
18004 test_230c() {
18005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18007         remote_mds_nodsh && skip "remote MDS with nodsh"
18008         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18009                 skip "Need MDS version at least 2.11.52"
18010
18011         local MDTIDX=1
18012         local total=3
18013         local mdt_index
18014         local file
18015         local migrate_dir=$DIR/$tdir/migrate_dir
18016
18017         #If migrating directory fails in the middle, all entries of
18018         #the directory is still accessiable.
18019         test_mkdir $DIR/$tdir
18020         test_mkdir -i0 -c1 $migrate_dir
18021         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18022         stat $migrate_dir
18023         createmany -o $migrate_dir/f $total ||
18024                 error "create files under ${migrate_dir} failed"
18025
18026         # fail after migrating top dir, and this will fail only once, so the
18027         # first sub file migration will fail (currently f3), others succeed.
18028         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18029         do_facet mds1 lctl set_param fail_loc=0x1801
18030         local t=$(ls $migrate_dir | wc -l)
18031         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18032                 error "migrate should fail"
18033         local u=$(ls $migrate_dir | wc -l)
18034         [ "$u" == "$t" ] || error "$u != $t during migration"
18035
18036         # add new dir/file should succeed
18037         mkdir $migrate_dir/dir ||
18038                 error "mkdir failed under migrating directory"
18039         touch $migrate_dir/file ||
18040                 error "create file failed under migrating directory"
18041
18042         # add file with existing name should fail
18043         for file in $migrate_dir/f*; do
18044                 stat $file > /dev/null || error "stat $file failed"
18045                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18046                         error "open(O_CREAT|O_EXCL) $file should fail"
18047                 $MULTIOP $file m && error "create $file should fail"
18048                 touch $DIR/$tdir/remote_dir/$tfile ||
18049                         error "touch $tfile failed"
18050                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18051                         error "link $file should fail"
18052                 mdt_index=$($LFS getstripe -m $file)
18053                 if [ $mdt_index == 0 ]; then
18054                         # file failed to migrate is not allowed to rename to
18055                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18056                                 error "rename to $file should fail"
18057                 else
18058                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18059                                 error "rename to $file failed"
18060                 fi
18061                 echo hello >> $file || error "write $file failed"
18062         done
18063
18064         # resume migration with different options should fail
18065         $LFS migrate -m 0 $migrate_dir &&
18066                 error "migrate -m 0 $migrate_dir should fail"
18067
18068         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18069                 error "migrate -c 2 $migrate_dir should fail"
18070
18071         # resume migration should succeed
18072         $LFS migrate -m $MDTIDX $migrate_dir ||
18073                 error "migrate $migrate_dir failed"
18074
18075         echo "Finish migration, then checking.."
18076         for file in $(find $migrate_dir); do
18077                 mdt_index=$($LFS getstripe -m $file)
18078                 [ $mdt_index == $MDTIDX ] ||
18079                         error "$file is not on MDT${MDTIDX}"
18080         done
18081
18082         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18083 }
18084 run_test 230c "check directory accessiblity if migration failed"
18085
18086 test_230d() {
18087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18089         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18090                 skip "Need MDS version at least 2.11.52"
18091         # LU-11235
18092         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18093
18094         local migrate_dir=$DIR/$tdir/migrate_dir
18095         local old_index
18096         local new_index
18097         local old_count
18098         local new_count
18099         local new_hash
18100         local mdt_index
18101         local i
18102         local j
18103
18104         old_index=$((RANDOM % MDSCOUNT))
18105         old_count=$((MDSCOUNT - old_index))
18106         new_index=$((RANDOM % MDSCOUNT))
18107         new_count=$((MDSCOUNT - new_index))
18108         new_hash=1 # for all_char
18109
18110         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18111         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18112
18113         test_mkdir $DIR/$tdir
18114         test_mkdir -i $old_index -c $old_count $migrate_dir
18115
18116         for ((i=0; i<100; i++)); do
18117                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18118                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18119                         error "create files under remote dir failed $i"
18120         done
18121
18122         echo -n "Migrate from MDT$old_index "
18123         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18124         echo -n "to MDT$new_index"
18125         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18126         echo
18127
18128         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18129         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18130                 error "migrate remote dir error"
18131
18132         echo "Finish migration, then checking.."
18133         for file in $(find $migrate_dir); do
18134                 mdt_index=$($LFS getstripe -m $file)
18135                 if [ $mdt_index -lt $new_index ] ||
18136                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18137                         error "$file is on MDT$mdt_index"
18138                 fi
18139         done
18140
18141         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18142 }
18143 run_test 230d "check migrate big directory"
18144
18145 test_230e() {
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 i
18152         local j
18153         local a_fid
18154         local b_fid
18155
18156         mkdir -p $DIR/$tdir
18157         mkdir $DIR/$tdir/migrate_dir
18158         mkdir $DIR/$tdir/other_dir
18159         touch $DIR/$tdir/migrate_dir/a
18160         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18161         ls $DIR/$tdir/other_dir
18162
18163         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18164                 error "migrate dir fails"
18165
18166         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18167         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18168
18169         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18170         [ $mdt_index == 0 ] || error "a is not on MDT0"
18171
18172         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18173                 error "migrate dir fails"
18174
18175         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18176         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18177
18178         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18179         [ $mdt_index == 1 ] || error "a is not on MDT1"
18180
18181         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18182         [ $mdt_index == 1 ] || error "b is not on MDT1"
18183
18184         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18185         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18186
18187         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18188
18189         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18190 }
18191 run_test 230e "migrate mulitple local link files"
18192
18193 test_230f() {
18194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18196         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18197                 skip "Need MDS version at least 2.11.52"
18198
18199         local a_fid
18200         local ln_fid
18201
18202         mkdir -p $DIR/$tdir
18203         mkdir $DIR/$tdir/migrate_dir
18204         $LFS mkdir -i1 $DIR/$tdir/other_dir
18205         touch $DIR/$tdir/migrate_dir/a
18206         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18207         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18208         ls $DIR/$tdir/other_dir
18209
18210         # a should be migrated to MDT1, since no other links on MDT0
18211         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18212                 error "#1 migrate dir fails"
18213         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18214         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18215         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18216         [ $mdt_index == 1 ] || error "a is not on MDT1"
18217
18218         # a should stay on MDT1, because it is a mulitple link file
18219         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18220                 error "#2 migrate dir fails"
18221         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18222         [ $mdt_index == 1 ] || error "a is not on MDT1"
18223
18224         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18225                 error "#3 migrate dir fails"
18226
18227         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18228         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18229         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18230
18231         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18232         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18233
18234         # a should be migrated to MDT0, since no other links on MDT1
18235         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18236                 error "#4 migrate dir fails"
18237         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18238         [ $mdt_index == 0 ] || error "a is not on MDT0"
18239
18240         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18241 }
18242 run_test 230f "migrate mulitple remote link files"
18243
18244 test_230g() {
18245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18247         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18248                 skip "Need MDS version at least 2.11.52"
18249
18250         mkdir -p $DIR/$tdir/migrate_dir
18251
18252         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18253                 error "migrating dir to non-exist MDT succeeds"
18254         true
18255 }
18256 run_test 230g "migrate dir to non-exist MDT"
18257
18258 test_230h() {
18259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18261         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18262                 skip "Need MDS version at least 2.11.52"
18263
18264         local mdt_index
18265
18266         mkdir -p $DIR/$tdir/migrate_dir
18267
18268         $LFS migrate -m1 $DIR &&
18269                 error "migrating mountpoint1 should fail"
18270
18271         $LFS migrate -m1 $DIR/$tdir/.. &&
18272                 error "migrating mountpoint2 should fail"
18273
18274         # same as mv
18275         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18276                 error "migrating $tdir/migrate_dir/.. should fail"
18277
18278         true
18279 }
18280 run_test 230h "migrate .. and root"
18281
18282 test_230i() {
18283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18285         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18286                 skip "Need MDS version at least 2.11.52"
18287
18288         mkdir -p $DIR/$tdir/migrate_dir
18289
18290         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18291                 error "migration fails with a tailing slash"
18292
18293         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18294                 error "migration fails with two tailing slashes"
18295 }
18296 run_test 230i "lfs migrate -m tolerates trailing slashes"
18297
18298 test_230j() {
18299         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18300         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18301                 skip "Need MDS version at least 2.11.52"
18302
18303         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18304         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18305                 error "create $tfile failed"
18306         cat /etc/passwd > $DIR/$tdir/$tfile
18307
18308         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18309
18310         cmp /etc/passwd $DIR/$tdir/$tfile ||
18311                 error "DoM file mismatch after migration"
18312 }
18313 run_test 230j "DoM file data not changed after dir migration"
18314
18315 test_230k() {
18316         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18317         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18318                 skip "Need MDS version at least 2.11.56"
18319
18320         local total=20
18321         local files_on_starting_mdt=0
18322
18323         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18324         $LFS getdirstripe $DIR/$tdir
18325         for i in $(seq $total); do
18326                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18327                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18328                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18329         done
18330
18331         echo "$files_on_starting_mdt files on MDT0"
18332
18333         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18334         $LFS getdirstripe $DIR/$tdir
18335
18336         files_on_starting_mdt=0
18337         for i in $(seq $total); do
18338                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18339                         error "file $tfile.$i mismatch after migration"
18340                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18341                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18342         done
18343
18344         echo "$files_on_starting_mdt files on MDT1 after migration"
18345         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18346
18347         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18348         $LFS getdirstripe $DIR/$tdir
18349
18350         files_on_starting_mdt=0
18351         for i in $(seq $total); do
18352                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18353                         error "file $tfile.$i mismatch after 2nd migration"
18354                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18355                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18356         done
18357
18358         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18359         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18360
18361         true
18362 }
18363 run_test 230k "file data not changed after dir migration"
18364
18365 test_230l() {
18366         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18367         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18368                 skip "Need MDS version at least 2.11.56"
18369
18370         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18371         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18372                 error "create files under remote dir failed $i"
18373         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18374 }
18375 run_test 230l "readdir between MDTs won't crash"
18376
18377 test_230m() {
18378         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18379         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18380                 skip "Need MDS version at least 2.11.56"
18381
18382         local MDTIDX=1
18383         local mig_dir=$DIR/$tdir/migrate_dir
18384         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18385         local shortstr="b"
18386         local val
18387
18388         echo "Creating files and dirs with xattrs"
18389         test_mkdir $DIR/$tdir
18390         test_mkdir -i0 -c1 $mig_dir
18391         mkdir $mig_dir/dir
18392         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18393                 error "cannot set xattr attr1 on dir"
18394         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18395                 error "cannot set xattr attr2 on dir"
18396         touch $mig_dir/dir/f0
18397         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18398                 error "cannot set xattr attr1 on file"
18399         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18400                 error "cannot set xattr attr2 on file"
18401         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18402         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18403         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18404         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18405         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18406         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18407         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18408         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18409         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18410
18411         echo "Migrating to MDT1"
18412         $LFS migrate -m $MDTIDX $mig_dir ||
18413                 error "fails on migrating dir to MDT1"
18414
18415         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18416         echo "Checking xattrs"
18417         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18418         [ "$val" = $longstr ] ||
18419                 error "expecting xattr1 $longstr on dir, found $val"
18420         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18421         [ "$val" = $shortstr ] ||
18422                 error "expecting xattr2 $shortstr on dir, found $val"
18423         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18424         [ "$val" = $longstr ] ||
18425                 error "expecting xattr1 $longstr on file, found $val"
18426         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18427         [ "$val" = $shortstr ] ||
18428                 error "expecting xattr2 $shortstr on file, found $val"
18429 }
18430 run_test 230m "xattrs not changed after dir migration"
18431
18432 test_230n() {
18433         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18434         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18435                 skip "Need MDS version at least 2.13.53"
18436
18437         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18438         cat /etc/hosts > $DIR/$tdir/$tfile
18439         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18440         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18441
18442         cmp /etc/hosts $DIR/$tdir/$tfile ||
18443                 error "File data mismatch after migration"
18444 }
18445 run_test 230n "Dir migration with mirrored file"
18446
18447 test_230o() {
18448         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18449         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18450                 skip "Need MDS version at least 2.13.52"
18451
18452         local mdts=$(comma_list $(mdts_nodes))
18453         local timeout=100
18454
18455         local restripe_status
18456         local delta
18457         local i
18458         local j
18459
18460         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18461
18462         # in case "crush" hash type is not set
18463         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18464
18465         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18466                            mdt.*MDT0000.enable_dir_restripe)
18467         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18468         stack_trap "do_nodes $mdts $LCTL set_param \
18469                     mdt.*.enable_dir_restripe=$restripe_status"
18470
18471         mkdir $DIR/$tdir
18472         createmany -m $DIR/$tdir/f 100 ||
18473                 error "create files under remote dir failed $i"
18474         createmany -d $DIR/$tdir/d 100 ||
18475                 error "create dirs under remote dir failed $i"
18476
18477         for i in $(seq 2 $MDSCOUNT); do
18478                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18479                 $LFS setdirstripe -c $i $DIR/$tdir ||
18480                         error "split -c $i $tdir failed"
18481                 wait_update $HOSTNAME \
18482                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18483                         error "dir split not finished"
18484                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18485                         awk '/migrate/ {sum += $2} END { print sum }')
18486                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18487                 # delta is around total_files/stripe_count
18488                 [ $delta -lt $((200 /(i - 1))) ] ||
18489                         error "$delta files migrated"
18490         done
18491 }
18492 run_test 230o "dir split"
18493
18494 test_230p() {
18495         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18496         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18497                 skip "Need MDS version at least 2.13.52"
18498
18499         local mdts=$(comma_list $(mdts_nodes))
18500         local timeout=100
18501
18502         local restripe_status
18503         local delta
18504         local i
18505         local j
18506
18507         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18508
18509         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18510
18511         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18512                            mdt.*MDT0000.enable_dir_restripe)
18513         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18514         stack_trap "do_nodes $mdts $LCTL set_param \
18515                     mdt.*.enable_dir_restripe=$restripe_status"
18516
18517         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18518         createmany -m $DIR/$tdir/f 100 ||
18519                 error "create files under remote dir failed $i"
18520         createmany -d $DIR/$tdir/d 100 ||
18521                 error "create dirs under remote dir failed $i"
18522
18523         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18524                 local mdt_hash="crush"
18525
18526                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18527                 $LFS setdirstripe -c $i $DIR/$tdir ||
18528                         error "split -c $i $tdir failed"
18529                 [ $i -eq 1 ] && mdt_hash="none"
18530                 wait_update $HOSTNAME \
18531                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18532                         error "dir merge not finished"
18533                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18534                         awk '/migrate/ {sum += $2} END { print sum }')
18535                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18536                 # delta is around total_files/stripe_count
18537                 [ $delta -lt $((200 / i)) ] ||
18538                         error "$delta files migrated"
18539         done
18540 }
18541 run_test 230p "dir merge"
18542
18543 test_230q() {
18544         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18545         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18546                 skip "Need MDS version at least 2.13.52"
18547
18548         local mdts=$(comma_list $(mdts_nodes))
18549         local saved_threshold=$(do_facet mds1 \
18550                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18551         local saved_delta=$(do_facet mds1 \
18552                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18553         local threshold=100
18554         local delta=2
18555         local total=0
18556         local stripe_count=0
18557         local stripe_index
18558         local nr_files
18559
18560         # test with fewer files on ZFS
18561         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18562
18563         stack_trap "do_nodes $mdts $LCTL set_param \
18564                     mdt.*.dir_split_count=$saved_threshold"
18565         stack_trap "do_nodes $mdts $LCTL set_param \
18566                     mdt.*.dir_split_delta=$saved_delta"
18567         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18568         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18569         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18570         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18571         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18572         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18573
18574         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18575         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18576
18577         while [ $stripe_count -lt $MDSCOUNT ]; do
18578                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18579                         error "create sub files failed"
18580                 stat $DIR/$tdir > /dev/null
18581                 total=$((total + threshold * 3 / 2))
18582                 stripe_count=$((stripe_count + delta))
18583                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18584
18585                 wait_update $HOSTNAME \
18586                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18587                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18588
18589                 wait_update $HOSTNAME \
18590                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18591                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18592
18593                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18594                            grep -w $stripe_index | wc -l)
18595                 echo "$nr_files files on MDT$stripe_index after split"
18596                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18597                         error "$nr_files files on MDT$stripe_index after split"
18598
18599                 nr_files=$(ls $DIR/$tdir | wc -w)
18600                 [ $nr_files -eq $total ] ||
18601                         error "total sub files $nr_files != $total"
18602         done
18603 }
18604 run_test 230q "dir auto split"
18605
18606 test_230r() {
18607         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18608         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18609         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18610                 skip "Need MDS version at least 2.13.54"
18611
18612         # maximum amount of local locks:
18613         # parent striped dir - 2 locks
18614         # new stripe in parent to migrate to - 1 lock
18615         # source and target - 2 locks
18616         # Total 5 locks for regular file
18617         mkdir -p $DIR/$tdir
18618         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18619         touch $DIR/$tdir/dir1/eee
18620
18621         # create 4 hardlink for 4 more locks
18622         # Total: 9 locks > RS_MAX_LOCKS (8)
18623         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18624         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18625         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18626         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18627         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18628         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18629         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18630         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18631
18632         cancel_lru_locks mdc
18633
18634         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18635                 error "migrate dir fails"
18636
18637         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18638 }
18639 run_test 230r "migrate with too many local locks"
18640
18641 test_231a()
18642 {
18643         # For simplicity this test assumes that max_pages_per_rpc
18644         # is the same across all OSCs
18645         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18646         local bulk_size=$((max_pages * PAGE_SIZE))
18647         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18648                                        head -n 1)
18649
18650         mkdir -p $DIR/$tdir
18651         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18652                 error "failed to set stripe with -S ${brw_size}M option"
18653
18654         # clear the OSC stats
18655         $LCTL set_param osc.*.stats=0 &>/dev/null
18656         stop_writeback
18657
18658         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18659         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18660                 oflag=direct &>/dev/null || error "dd failed"
18661
18662         sync; sleep 1; sync # just to be safe
18663         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18664         if [ x$nrpcs != "x1" ]; then
18665                 $LCTL get_param osc.*.stats
18666                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18667         fi
18668
18669         start_writeback
18670         # Drop the OSC cache, otherwise we will read from it
18671         cancel_lru_locks osc
18672
18673         # clear the OSC stats
18674         $LCTL set_param osc.*.stats=0 &>/dev/null
18675
18676         # Client reads $bulk_size.
18677         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18678                 iflag=direct &>/dev/null || error "dd failed"
18679
18680         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18681         if [ x$nrpcs != "x1" ]; then
18682                 $LCTL get_param osc.*.stats
18683                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18684         fi
18685 }
18686 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18687
18688 test_231b() {
18689         mkdir -p $DIR/$tdir
18690         local i
18691         for i in {0..1023}; do
18692                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18693                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18694                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18695         done
18696         sync
18697 }
18698 run_test 231b "must not assert on fully utilized OST request buffer"
18699
18700 test_232a() {
18701         mkdir -p $DIR/$tdir
18702         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18703
18704         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18705         do_facet ost1 $LCTL set_param fail_loc=0x31c
18706
18707         # ignore dd failure
18708         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18709
18710         do_facet ost1 $LCTL set_param fail_loc=0
18711         umount_client $MOUNT || error "umount failed"
18712         mount_client $MOUNT || error "mount failed"
18713         stop ost1 || error "cannot stop ost1"
18714         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18715 }
18716 run_test 232a "failed lock should not block umount"
18717
18718 test_232b() {
18719         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18720                 skip "Need MDS version at least 2.10.58"
18721
18722         mkdir -p $DIR/$tdir
18723         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18724         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18725         sync
18726         cancel_lru_locks osc
18727
18728         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18729         do_facet ost1 $LCTL set_param fail_loc=0x31c
18730
18731         # ignore failure
18732         $LFS data_version $DIR/$tdir/$tfile || true
18733
18734         do_facet ost1 $LCTL set_param fail_loc=0
18735         umount_client $MOUNT || error "umount failed"
18736         mount_client $MOUNT || error "mount failed"
18737         stop ost1 || error "cannot stop ost1"
18738         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18739 }
18740 run_test 232b "failed data version lock should not block umount"
18741
18742 test_233a() {
18743         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18744                 skip "Need MDS version at least 2.3.64"
18745         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18746
18747         local fid=$($LFS path2fid $MOUNT)
18748
18749         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18750                 error "cannot access $MOUNT using its FID '$fid'"
18751 }
18752 run_test 233a "checking that OBF of the FS root succeeds"
18753
18754 test_233b() {
18755         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18756                 skip "Need MDS version at least 2.5.90"
18757         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18758
18759         local fid=$($LFS path2fid $MOUNT/.lustre)
18760
18761         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18762                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18763
18764         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18765         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18766                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18767 }
18768 run_test 233b "checking that OBF of the FS .lustre succeeds"
18769
18770 test_234() {
18771         local p="$TMP/sanityN-$TESTNAME.parameters"
18772         save_lustre_params client "llite.*.xattr_cache" > $p
18773         lctl set_param llite.*.xattr_cache 1 ||
18774                 skip_env "xattr cache is not supported"
18775
18776         mkdir -p $DIR/$tdir || error "mkdir failed"
18777         touch $DIR/$tdir/$tfile || error "touch failed"
18778         # OBD_FAIL_LLITE_XATTR_ENOMEM
18779         $LCTL set_param fail_loc=0x1405
18780         getfattr -n user.attr $DIR/$tdir/$tfile &&
18781                 error "getfattr should have failed with ENOMEM"
18782         $LCTL set_param fail_loc=0x0
18783         rm -rf $DIR/$tdir
18784
18785         restore_lustre_params < $p
18786         rm -f $p
18787 }
18788 run_test 234 "xattr cache should not crash on ENOMEM"
18789
18790 test_235() {
18791         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18792                 skip "Need MDS version at least 2.4.52"
18793
18794         flock_deadlock $DIR/$tfile
18795         local RC=$?
18796         case $RC in
18797                 0)
18798                 ;;
18799                 124) error "process hangs on a deadlock"
18800                 ;;
18801                 *) error "error executing flock_deadlock $DIR/$tfile"
18802                 ;;
18803         esac
18804 }
18805 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18806
18807 #LU-2935
18808 test_236() {
18809         check_swap_layouts_support
18810
18811         local ref1=/etc/passwd
18812         local ref2=/etc/group
18813         local file1=$DIR/$tdir/f1
18814         local file2=$DIR/$tdir/f2
18815
18816         test_mkdir -c1 $DIR/$tdir
18817         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18818         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18819         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18820         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18821         local fd=$(free_fd)
18822         local cmd="exec $fd<>$file2"
18823         eval $cmd
18824         rm $file2
18825         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18826                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18827         cmd="exec $fd>&-"
18828         eval $cmd
18829         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18830
18831         #cleanup
18832         rm -rf $DIR/$tdir
18833 }
18834 run_test 236 "Layout swap on open unlinked file"
18835
18836 # LU-4659 linkea consistency
18837 test_238() {
18838         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18839                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18840                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18841                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18842
18843         touch $DIR/$tfile
18844         ln $DIR/$tfile $DIR/$tfile.lnk
18845         touch $DIR/$tfile.new
18846         mv $DIR/$tfile.new $DIR/$tfile
18847         local fid1=$($LFS path2fid $DIR/$tfile)
18848         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18849         local path1=$($LFS fid2path $FSNAME "$fid1")
18850         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18851         local path2=$($LFS fid2path $FSNAME "$fid2")
18852         [ $tfile.lnk == $path2 ] ||
18853                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18854         rm -f $DIR/$tfile*
18855 }
18856 run_test 238 "Verify linkea consistency"
18857
18858 test_239A() { # was test_239
18859         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18860                 skip "Need MDS version at least 2.5.60"
18861
18862         local list=$(comma_list $(mdts_nodes))
18863
18864         mkdir -p $DIR/$tdir
18865         createmany -o $DIR/$tdir/f- 5000
18866         unlinkmany $DIR/$tdir/f- 5000
18867         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18868                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18869         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18870                         osp.*MDT*.sync_in_flight" | calc_sum)
18871         [ "$changes" -eq 0 ] || error "$changes not synced"
18872 }
18873 run_test 239A "osp_sync test"
18874
18875 test_239a() { #LU-5297
18876         remote_mds_nodsh && skip "remote MDS with nodsh"
18877
18878         touch $DIR/$tfile
18879         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18880         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18881         chgrp $RUNAS_GID $DIR/$tfile
18882         wait_delete_completed
18883 }
18884 run_test 239a "process invalid osp sync record correctly"
18885
18886 test_239b() { #LU-5297
18887         remote_mds_nodsh && skip "remote MDS with nodsh"
18888
18889         touch $DIR/$tfile1
18890         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18891         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18892         chgrp $RUNAS_GID $DIR/$tfile1
18893         wait_delete_completed
18894         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18895         touch $DIR/$tfile2
18896         chgrp $RUNAS_GID $DIR/$tfile2
18897         wait_delete_completed
18898 }
18899 run_test 239b "process osp sync record with ENOMEM error correctly"
18900
18901 test_240() {
18902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18903         remote_mds_nodsh && skip "remote MDS with nodsh"
18904
18905         mkdir -p $DIR/$tdir
18906
18907         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18908                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18909         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18910                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18911
18912         umount_client $MOUNT || error "umount failed"
18913         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18914         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18915         mount_client $MOUNT || error "failed to mount client"
18916
18917         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18918         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18919 }
18920 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18921
18922 test_241_bio() {
18923         local count=$1
18924         local bsize=$2
18925
18926         for LOOP in $(seq $count); do
18927                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18928                 cancel_lru_locks $OSC || true
18929         done
18930 }
18931
18932 test_241_dio() {
18933         local count=$1
18934         local bsize=$2
18935
18936         for LOOP in $(seq $1); do
18937                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18938                         2>/dev/null
18939         done
18940 }
18941
18942 test_241a() { # was test_241
18943         local bsize=$PAGE_SIZE
18944
18945         (( bsize < 40960 )) && bsize=40960
18946         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18947         ls -la $DIR/$tfile
18948         cancel_lru_locks $OSC
18949         test_241_bio 1000 $bsize &
18950         PID=$!
18951         test_241_dio 1000 $bsize
18952         wait $PID
18953 }
18954 run_test 241a "bio vs dio"
18955
18956 test_241b() {
18957         local bsize=$PAGE_SIZE
18958
18959         (( bsize < 40960 )) && bsize=40960
18960         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18961         ls -la $DIR/$tfile
18962         test_241_dio 1000 $bsize &
18963         PID=$!
18964         test_241_dio 1000 $bsize
18965         wait $PID
18966 }
18967 run_test 241b "dio vs dio"
18968
18969 test_242() {
18970         remote_mds_nodsh && skip "remote MDS with nodsh"
18971
18972         mkdir -p $DIR/$tdir
18973         touch $DIR/$tdir/$tfile
18974
18975         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18976         do_facet mds1 lctl set_param fail_loc=0x105
18977         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18978
18979         do_facet mds1 lctl set_param fail_loc=0
18980         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18981 }
18982 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18983
18984 test_243()
18985 {
18986         test_mkdir $DIR/$tdir
18987         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18988 }
18989 run_test 243 "various group lock tests"
18990
18991 test_244a()
18992 {
18993         test_mkdir $DIR/$tdir
18994         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18995         sendfile_grouplock $DIR/$tdir/$tfile || \
18996                 error "sendfile+grouplock failed"
18997         rm -rf $DIR/$tdir
18998 }
18999 run_test 244a "sendfile with group lock tests"
19000
19001 test_244b()
19002 {
19003         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19004
19005         local threads=50
19006         local size=$((1024*1024))
19007
19008         test_mkdir $DIR/$tdir
19009         for i in $(seq 1 $threads); do
19010                 local file=$DIR/$tdir/file_$((i / 10))
19011                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19012                 local pids[$i]=$!
19013         done
19014         for i in $(seq 1 $threads); do
19015                 wait ${pids[$i]}
19016         done
19017 }
19018 run_test 244b "multi-threaded write with group lock"
19019
19020 test_245() {
19021         local flagname="multi_mod_rpcs"
19022         local connect_data_name="max_mod_rpcs"
19023         local out
19024
19025         # check if multiple modify RPCs flag is set
19026         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19027                 grep "connect_flags:")
19028         echo "$out"
19029
19030         echo "$out" | grep -qw $flagname
19031         if [ $? -ne 0 ]; then
19032                 echo "connect flag $flagname is not set"
19033                 return
19034         fi
19035
19036         # check if multiple modify RPCs data is set
19037         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19038         echo "$out"
19039
19040         echo "$out" | grep -qw $connect_data_name ||
19041                 error "import should have connect data $connect_data_name"
19042 }
19043 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19044
19045 cleanup_247() {
19046         local submount=$1
19047
19048         trap 0
19049         umount_client $submount
19050         rmdir $submount
19051 }
19052
19053 test_247a() {
19054         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19055                 grep -q subtree ||
19056                 skip_env "Fileset feature is not supported"
19057
19058         local submount=${MOUNT}_$tdir
19059
19060         mkdir $MOUNT/$tdir
19061         mkdir -p $submount || error "mkdir $submount failed"
19062         FILESET="$FILESET/$tdir" mount_client $submount ||
19063                 error "mount $submount failed"
19064         trap "cleanup_247 $submount" EXIT
19065         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19066         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19067                 error "read $MOUNT/$tdir/$tfile failed"
19068         cleanup_247 $submount
19069 }
19070 run_test 247a "mount subdir as fileset"
19071
19072 test_247b() {
19073         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19074                 skip_env "Fileset feature is not supported"
19075
19076         local submount=${MOUNT}_$tdir
19077
19078         rm -rf $MOUNT/$tdir
19079         mkdir -p $submount || error "mkdir $submount failed"
19080         SKIP_FILESET=1
19081         FILESET="$FILESET/$tdir" mount_client $submount &&
19082                 error "mount $submount should fail"
19083         rmdir $submount
19084 }
19085 run_test 247b "mount subdir that dose not exist"
19086
19087 test_247c() {
19088         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19089                 skip_env "Fileset feature is not supported"
19090
19091         local submount=${MOUNT}_$tdir
19092
19093         mkdir -p $MOUNT/$tdir/dir1
19094         mkdir -p $submount || error "mkdir $submount failed"
19095         trap "cleanup_247 $submount" EXIT
19096         FILESET="$FILESET/$tdir" mount_client $submount ||
19097                 error "mount $submount failed"
19098         local fid=$($LFS path2fid $MOUNT/)
19099         $LFS fid2path $submount $fid && error "fid2path should fail"
19100         cleanup_247 $submount
19101 }
19102 run_test 247c "running fid2path outside subdirectory root"
19103
19104 test_247d() {
19105         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19106                 skip "Fileset feature is not supported"
19107
19108         local submount=${MOUNT}_$tdir
19109
19110         mkdir -p $MOUNT/$tdir/dir1
19111         mkdir -p $submount || error "mkdir $submount failed"
19112         FILESET="$FILESET/$tdir" mount_client $submount ||
19113                 error "mount $submount failed"
19114         trap "cleanup_247 $submount" EXIT
19115
19116         local td=$submount/dir1
19117         local fid=$($LFS path2fid $td)
19118         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19119
19120         # check that we get the same pathname back
19121         local rootpath
19122         local found
19123         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19124                 echo "$rootpath $fid"
19125                 found=$($LFS fid2path $rootpath "$fid")
19126                 [ -n "found" ] || error "fid2path should succeed"
19127                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19128         done
19129         # check wrong root path format
19130         rootpath=$submount"_wrong"
19131         found=$($LFS fid2path $rootpath "$fid")
19132         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19133
19134         cleanup_247 $submount
19135 }
19136 run_test 247d "running fid2path inside subdirectory root"
19137
19138 # LU-8037
19139 test_247e() {
19140         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19141                 grep -q subtree ||
19142                 skip "Fileset feature is not supported"
19143
19144         local submount=${MOUNT}_$tdir
19145
19146         mkdir $MOUNT/$tdir
19147         mkdir -p $submount || error "mkdir $submount failed"
19148         FILESET="$FILESET/.." mount_client $submount &&
19149                 error "mount $submount should fail"
19150         rmdir $submount
19151 }
19152 run_test 247e "mount .. as fileset"
19153
19154 test_247f() {
19155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19156         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19157                 skip "Need at least version 2.13.52"
19158         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19159                 grep -q subtree ||
19160                 skip "Fileset feature is not supported"
19161
19162         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19163         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19164                 error "mkdir remote failed"
19165         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19166         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19167                 error "mkdir striped failed"
19168         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19169
19170         local submount=${MOUNT}_$tdir
19171
19172         mkdir -p $submount || error "mkdir $submount failed"
19173
19174         local dir
19175         local fileset=$FILESET
19176
19177         for dir in $tdir/remote $tdir/remote/subdir \
19178                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19179                 FILESET="$fileset/$dir" mount_client $submount ||
19180                         error "mount $dir failed"
19181                 umount_client $submount
19182         done
19183 }
19184 run_test 247f "mount striped or remote directory as fileset"
19185
19186 test_248a() {
19187         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19188         [ -z "$fast_read_sav" ] && skip "no fast read support"
19189
19190         # create a large file for fast read verification
19191         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19192
19193         # make sure the file is created correctly
19194         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19195                 { rm -f $DIR/$tfile; skip "file creation error"; }
19196
19197         echo "Test 1: verify that fast read is 4 times faster on cache read"
19198
19199         # small read with fast read enabled
19200         $LCTL set_param -n llite.*.fast_read=1
19201         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19202                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19203                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19204         # small read with fast read disabled
19205         $LCTL set_param -n llite.*.fast_read=0
19206         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19207                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19208                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19209
19210         # verify that fast read is 4 times faster for cache read
19211         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19212                 error_not_in_vm "fast read was not 4 times faster: " \
19213                            "$t_fast vs $t_slow"
19214
19215         echo "Test 2: verify the performance between big and small read"
19216         $LCTL set_param -n llite.*.fast_read=1
19217
19218         # 1k non-cache read
19219         cancel_lru_locks osc
19220         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19221                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19222                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19223
19224         # 1M non-cache read
19225         cancel_lru_locks osc
19226         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19227                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19228                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19229
19230         # verify that big IO is not 4 times faster than small IO
19231         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19232                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19233
19234         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19235         rm -f $DIR/$tfile
19236 }
19237 run_test 248a "fast read verification"
19238
19239 test_248b() {
19240         # Default short_io_bytes=16384, try both smaller and larger sizes.
19241         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19242         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19243         echo "bs=53248 count=113 normal buffered write"
19244         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19245                 error "dd of initial data file failed"
19246         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19247
19248         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19249         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19250                 error "dd with sync normal writes failed"
19251         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19252
19253         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19254         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19255                 error "dd with sync small writes failed"
19256         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19257
19258         cancel_lru_locks osc
19259
19260         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19261         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19262         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19263         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19264                 iflag=direct || error "dd with O_DIRECT small read failed"
19265         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19266         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19267                 error "compare $TMP/$tfile.1 failed"
19268
19269         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19270         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19271
19272         # just to see what the maximum tunable value is, and test parsing
19273         echo "test invalid parameter 2MB"
19274         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19275                 error "too-large short_io_bytes allowed"
19276         echo "test maximum parameter 512KB"
19277         # if we can set a larger short_io_bytes, run test regardless of version
19278         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19279                 # older clients may not allow setting it this large, that's OK
19280                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19281                         skip "Need at least client version 2.13.50"
19282                 error "medium short_io_bytes failed"
19283         fi
19284         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19285         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19286
19287         echo "test large parameter 64KB"
19288         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19289         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19290
19291         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19292         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19293                 error "dd with sync large writes failed"
19294         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19295
19296         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19297         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19298         num=$((113 * 4096 / PAGE_SIZE))
19299         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19300         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19301                 error "dd with O_DIRECT large writes failed"
19302         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19303                 error "compare $DIR/$tfile.3 failed"
19304
19305         cancel_lru_locks osc
19306
19307         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19308         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19309                 error "dd with O_DIRECT large read failed"
19310         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19311                 error "compare $TMP/$tfile.2 failed"
19312
19313         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19314         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19315                 error "dd with O_DIRECT large read failed"
19316         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19317                 error "compare $TMP/$tfile.3 failed"
19318 }
19319 run_test 248b "test short_io read and write for both small and large sizes"
19320
19321 test_249() { # LU-7890
19322         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19323                 skip "Need at least version 2.8.54"
19324
19325         rm -f $DIR/$tfile
19326         $LFS setstripe -c 1 $DIR/$tfile
19327         # Offset 2T == 4k * 512M
19328         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19329                 error "dd to 2T offset failed"
19330 }
19331 run_test 249 "Write above 2T file size"
19332
19333 test_250() {
19334         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19335          && skip "no 16TB file size limit on ZFS"
19336
19337         $LFS setstripe -c 1 $DIR/$tfile
19338         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19339         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19340         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19341         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19342                 conv=notrunc,fsync && error "append succeeded"
19343         return 0
19344 }
19345 run_test 250 "Write above 16T limit"
19346
19347 test_251() {
19348         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19349
19350         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19351         #Skip once - writing the first stripe will succeed
19352         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19353         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19354                 error "short write happened"
19355
19356         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19357         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19358                 error "short read happened"
19359
19360         rm -f $DIR/$tfile
19361 }
19362 run_test 251 "Handling short read and write correctly"
19363
19364 test_252() {
19365         remote_mds_nodsh && skip "remote MDS with nodsh"
19366         remote_ost_nodsh && skip "remote OST with nodsh"
19367         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19368                 skip_env "ldiskfs only test"
19369         fi
19370
19371         local tgt
19372         local dev
19373         local out
19374         local uuid
19375         local num
19376         local gen
19377
19378         # check lr_reader on OST0000
19379         tgt=ost1
19380         dev=$(facet_device $tgt)
19381         out=$(do_facet $tgt $LR_READER $dev)
19382         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19383         echo "$out"
19384         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19385         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19386                 error "Invalid uuid returned by $LR_READER on target $tgt"
19387         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19388
19389         # check lr_reader -c on MDT0000
19390         tgt=mds1
19391         dev=$(facet_device $tgt)
19392         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19393                 skip "$LR_READER does not support additional options"
19394         fi
19395         out=$(do_facet $tgt $LR_READER -c $dev)
19396         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19397         echo "$out"
19398         num=$(echo "$out" | grep -c "mdtlov")
19399         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19400                 error "Invalid number of mdtlov clients returned by $LR_READER"
19401         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19402
19403         # check lr_reader -cr on MDT0000
19404         out=$(do_facet $tgt $LR_READER -cr $dev)
19405         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19406         echo "$out"
19407         echo "$out" | grep -q "^reply_data:$" ||
19408                 error "$LR_READER should have returned 'reply_data' section"
19409         num=$(echo "$out" | grep -c "client_generation")
19410         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19411 }
19412 run_test 252 "check lr_reader tool"
19413
19414 test_253() {
19415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19416         remote_mds_nodsh && skip "remote MDS with nodsh"
19417         remote_mgs_nodsh && skip "remote MGS with nodsh"
19418
19419         local ostidx=0
19420         local rc=0
19421         local ost_name=$(ostname_from_index $ostidx)
19422
19423         # on the mdt's osc
19424         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19425         do_facet $SINGLEMDS $LCTL get_param -n \
19426                 osp.$mdtosc_proc1.reserved_mb_high ||
19427                 skip  "remote MDS does not support reserved_mb_high"
19428
19429         rm -rf $DIR/$tdir
19430         wait_mds_ost_sync
19431         wait_delete_completed
19432         mkdir $DIR/$tdir
19433
19434         pool_add $TESTNAME || error "Pool creation failed"
19435         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19436
19437         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19438                 error "Setstripe failed"
19439
19440         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19441
19442         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19443                     grep "watermarks")
19444         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19445
19446         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19447                         osp.$mdtosc_proc1.prealloc_status)
19448         echo "prealloc_status $oa_status"
19449
19450         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19451                 error "File creation should fail"
19452
19453         #object allocation was stopped, but we still able to append files
19454         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19455                 oflag=append || error "Append failed"
19456
19457         rm -f $DIR/$tdir/$tfile.0
19458
19459         # For this test, we want to delete the files we created to go out of
19460         # space but leave the watermark, so we remain nearly out of space
19461         ost_watermarks_enospc_delete_files $tfile $ostidx
19462
19463         wait_delete_completed
19464
19465         sleep_maxage
19466
19467         for i in $(seq 10 12); do
19468                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19469                         2>/dev/null || error "File creation failed after rm"
19470         done
19471
19472         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19473                         osp.$mdtosc_proc1.prealloc_status)
19474         echo "prealloc_status $oa_status"
19475
19476         if (( oa_status != 0 )); then
19477                 error "Object allocation still disable after rm"
19478         fi
19479 }
19480 run_test 253 "Check object allocation limit"
19481
19482 test_254() {
19483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19484         remote_mds_nodsh && skip "remote MDS with nodsh"
19485         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19486                 skip "MDS does not support changelog_size"
19487
19488         local cl_user
19489         local MDT0=$(facet_svc $SINGLEMDS)
19490
19491         changelog_register || error "changelog_register failed"
19492
19493         changelog_clear 0 || error "changelog_clear failed"
19494
19495         local size1=$(do_facet $SINGLEMDS \
19496                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19497         echo "Changelog size $size1"
19498
19499         rm -rf $DIR/$tdir
19500         $LFS mkdir -i 0 $DIR/$tdir
19501         # change something
19502         mkdir -p $DIR/$tdir/pics/2008/zachy
19503         touch $DIR/$tdir/pics/2008/zachy/timestamp
19504         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19505         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19506         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19507         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19508         rm $DIR/$tdir/pics/desktop.jpg
19509
19510         local size2=$(do_facet $SINGLEMDS \
19511                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19512         echo "Changelog size after work $size2"
19513
19514         (( $size2 > $size1 )) ||
19515                 error "new Changelog size=$size2 less than old size=$size1"
19516 }
19517 run_test 254 "Check changelog size"
19518
19519 ladvise_no_type()
19520 {
19521         local type=$1
19522         local file=$2
19523
19524         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19525                 awk -F: '{print $2}' | grep $type > /dev/null
19526         if [ $? -ne 0 ]; then
19527                 return 0
19528         fi
19529         return 1
19530 }
19531
19532 ladvise_no_ioctl()
19533 {
19534         local file=$1
19535
19536         lfs ladvise -a willread $file > /dev/null 2>&1
19537         if [ $? -eq 0 ]; then
19538                 return 1
19539         fi
19540
19541         lfs ladvise -a willread $file 2>&1 |
19542                 grep "Inappropriate ioctl for device" > /dev/null
19543         if [ $? -eq 0 ]; then
19544                 return 0
19545         fi
19546         return 1
19547 }
19548
19549 percent() {
19550         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19551 }
19552
19553 # run a random read IO workload
19554 # usage: random_read_iops <filename> <filesize> <iosize>
19555 random_read_iops() {
19556         local file=$1
19557         local fsize=$2
19558         local iosize=${3:-4096}
19559
19560         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19561                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19562 }
19563
19564 drop_file_oss_cache() {
19565         local file="$1"
19566         local nodes="$2"
19567
19568         $LFS ladvise -a dontneed $file 2>/dev/null ||
19569                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19570 }
19571
19572 ladvise_willread_performance()
19573 {
19574         local repeat=10
19575         local average_origin=0
19576         local average_cache=0
19577         local average_ladvise=0
19578
19579         for ((i = 1; i <= $repeat; i++)); do
19580                 echo "Iter $i/$repeat: reading without willread hint"
19581                 cancel_lru_locks osc
19582                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19583                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19584                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19585                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19586
19587                 cancel_lru_locks osc
19588                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19589                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19590                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19591
19592                 cancel_lru_locks osc
19593                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19594                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19595                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19596                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19597                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19598         done
19599         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19600         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19601         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19602
19603         speedup_cache=$(percent $average_cache $average_origin)
19604         speedup_ladvise=$(percent $average_ladvise $average_origin)
19605
19606         echo "Average uncached read: $average_origin"
19607         echo "Average speedup with OSS cached read: " \
19608                 "$average_cache = +$speedup_cache%"
19609         echo "Average speedup with ladvise willread: " \
19610                 "$average_ladvise = +$speedup_ladvise%"
19611
19612         local lowest_speedup=20
19613         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19614                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19615                         "got $average_cache%. Skipping ladvise willread check."
19616                 return 0
19617         fi
19618
19619         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19620         # it is still good to run until then to exercise 'ladvise willread'
19621         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19622                 [ "$ost1_FSTYPE" = "zfs" ] &&
19623                 echo "osd-zfs does not support dontneed or drop_caches" &&
19624                 return 0
19625
19626         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19627         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19628                 error_not_in_vm "Speedup with willread is less than " \
19629                         "$lowest_speedup%, got $average_ladvise%"
19630 }
19631
19632 test_255a() {
19633         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19634                 skip "lustre < 2.8.54 does not support ladvise "
19635         remote_ost_nodsh && skip "remote OST with nodsh"
19636
19637         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19638
19639         ladvise_no_type willread $DIR/$tfile &&
19640                 skip "willread ladvise is not supported"
19641
19642         ladvise_no_ioctl $DIR/$tfile &&
19643                 skip "ladvise ioctl is not supported"
19644
19645         local size_mb=100
19646         local size=$((size_mb * 1048576))
19647         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19648                 error "dd to $DIR/$tfile failed"
19649
19650         lfs ladvise -a willread $DIR/$tfile ||
19651                 error "Ladvise failed with no range argument"
19652
19653         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19654                 error "Ladvise failed with no -l or -e argument"
19655
19656         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19657                 error "Ladvise failed with only -e argument"
19658
19659         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19660                 error "Ladvise failed with only -l argument"
19661
19662         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19663                 error "End offset should not be smaller than start offset"
19664
19665         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19666                 error "End offset should not be equal to start offset"
19667
19668         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19669                 error "Ladvise failed with overflowing -s argument"
19670
19671         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19672                 error "Ladvise failed with overflowing -e argument"
19673
19674         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19675                 error "Ladvise failed with overflowing -l argument"
19676
19677         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19678                 error "Ladvise succeeded with conflicting -l and -e arguments"
19679
19680         echo "Synchronous ladvise should wait"
19681         local delay=4
19682 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19683         do_nodes $(comma_list $(osts_nodes)) \
19684                 $LCTL set_param fail_val=$delay fail_loc=0x237
19685
19686         local start_ts=$SECONDS
19687         lfs ladvise -a willread $DIR/$tfile ||
19688                 error "Ladvise failed with no range argument"
19689         local end_ts=$SECONDS
19690         local inteval_ts=$((end_ts - start_ts))
19691
19692         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19693                 error "Synchronous advice didn't wait reply"
19694         fi
19695
19696         echo "Asynchronous ladvise shouldn't wait"
19697         local start_ts=$SECONDS
19698         lfs ladvise -a willread -b $DIR/$tfile ||
19699                 error "Ladvise failed with no range argument"
19700         local end_ts=$SECONDS
19701         local inteval_ts=$((end_ts - start_ts))
19702
19703         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19704                 error "Asynchronous advice blocked"
19705         fi
19706
19707         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19708         ladvise_willread_performance
19709 }
19710 run_test 255a "check 'lfs ladvise -a willread'"
19711
19712 facet_meminfo() {
19713         local facet=$1
19714         local info=$2
19715
19716         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19717 }
19718
19719 test_255b() {
19720         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19721                 skip "lustre < 2.8.54 does not support ladvise "
19722         remote_ost_nodsh && skip "remote OST with nodsh"
19723
19724         lfs setstripe -c 1 -i 0 $DIR/$tfile
19725
19726         ladvise_no_type dontneed $DIR/$tfile &&
19727                 skip "dontneed ladvise is not supported"
19728
19729         ladvise_no_ioctl $DIR/$tfile &&
19730                 skip "ladvise ioctl is not supported"
19731
19732         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19733                 [ "$ost1_FSTYPE" = "zfs" ] &&
19734                 skip "zfs-osd does not support 'ladvise dontneed'"
19735
19736         local size_mb=100
19737         local size=$((size_mb * 1048576))
19738         # In order to prevent disturbance of other processes, only check 3/4
19739         # of the memory usage
19740         local kibibytes=$((size_mb * 1024 * 3 / 4))
19741
19742         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19743                 error "dd to $DIR/$tfile failed"
19744
19745         #force write to complete before dropping OST cache & checking memory
19746         sync
19747
19748         local total=$(facet_meminfo ost1 MemTotal)
19749         echo "Total memory: $total KiB"
19750
19751         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19752         local before_read=$(facet_meminfo ost1 Cached)
19753         echo "Cache used before read: $before_read KiB"
19754
19755         lfs ladvise -a willread $DIR/$tfile ||
19756                 error "Ladvise willread failed"
19757         local after_read=$(facet_meminfo ost1 Cached)
19758         echo "Cache used after read: $after_read KiB"
19759
19760         lfs ladvise -a dontneed $DIR/$tfile ||
19761                 error "Ladvise dontneed again failed"
19762         local no_read=$(facet_meminfo ost1 Cached)
19763         echo "Cache used after dontneed ladvise: $no_read KiB"
19764
19765         if [ $total -lt $((before_read + kibibytes)) ]; then
19766                 echo "Memory is too small, abort checking"
19767                 return 0
19768         fi
19769
19770         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19771                 error "Ladvise willread should use more memory" \
19772                         "than $kibibytes KiB"
19773         fi
19774
19775         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19776                 error "Ladvise dontneed should release more memory" \
19777                         "than $kibibytes KiB"
19778         fi
19779 }
19780 run_test 255b "check 'lfs ladvise -a dontneed'"
19781
19782 test_255c() {
19783         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19784                 skip "lustre < 2.10.50 does not support lockahead"
19785
19786         local count
19787         local new_count
19788         local difference
19789         local i
19790         local rc
19791
19792         test_mkdir -p $DIR/$tdir
19793         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19794
19795         #test 10 returns only success/failure
19796         i=10
19797         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19798         rc=$?
19799         if [ $rc -eq 255 ]; then
19800                 error "Ladvise test${i} failed, ${rc}"
19801         fi
19802
19803         #test 11 counts lock enqueue requests, all others count new locks
19804         i=11
19805         count=$(do_facet ost1 \
19806                 $LCTL get_param -n ost.OSS.ost.stats)
19807         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19808
19809         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19810         rc=$?
19811         if [ $rc -eq 255 ]; then
19812                 error "Ladvise test${i} failed, ${rc}"
19813         fi
19814
19815         new_count=$(do_facet ost1 \
19816                 $LCTL get_param -n ost.OSS.ost.stats)
19817         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19818                    awk '{ print $2 }')
19819
19820         difference="$((new_count - count))"
19821         if [ $difference -ne $rc ]; then
19822                 error "Ladvise test${i}, bad enqueue count, returned " \
19823                       "${rc}, actual ${difference}"
19824         fi
19825
19826         for i in $(seq 12 21); do
19827                 # If we do not do this, we run the risk of having too many
19828                 # locks and starting lock cancellation while we are checking
19829                 # lock counts.
19830                 cancel_lru_locks osc
19831
19832                 count=$($LCTL get_param -n \
19833                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19834
19835                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19836                 rc=$?
19837                 if [ $rc -eq 255 ]; then
19838                         error "Ladvise test ${i} failed, ${rc}"
19839                 fi
19840
19841                 new_count=$($LCTL get_param -n \
19842                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19843                 difference="$((new_count - count))"
19844
19845                 # Test 15 output is divided by 100 to map down to valid return
19846                 if [ $i -eq 15 ]; then
19847                         rc="$((rc * 100))"
19848                 fi
19849
19850                 if [ $difference -ne $rc ]; then
19851                         error "Ladvise test ${i}, bad lock count, returned " \
19852                               "${rc}, actual ${difference}"
19853                 fi
19854         done
19855
19856         #test 22 returns only success/failure
19857         i=22
19858         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19859         rc=$?
19860         if [ $rc -eq 255 ]; then
19861                 error "Ladvise test${i} failed, ${rc}"
19862         fi
19863 }
19864 run_test 255c "suite of ladvise lockahead tests"
19865
19866 test_256() {
19867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19868         remote_mds_nodsh && skip "remote MDS with nodsh"
19869         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19870         changelog_users $SINGLEMDS | grep "^cl" &&
19871                 skip "active changelog user"
19872
19873         local cl_user
19874         local cat_sl
19875         local mdt_dev
19876
19877         mdt_dev=$(mdsdevname 1)
19878         echo $mdt_dev
19879
19880         changelog_register || error "changelog_register failed"
19881
19882         rm -rf $DIR/$tdir
19883         mkdir -p $DIR/$tdir
19884
19885         changelog_clear 0 || error "changelog_clear failed"
19886
19887         # change something
19888         touch $DIR/$tdir/{1..10}
19889
19890         # stop the MDT
19891         stop $SINGLEMDS || error "Fail to stop MDT"
19892
19893         # remount the MDT
19894
19895         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19896
19897         #after mount new plainllog is used
19898         touch $DIR/$tdir/{11..19}
19899         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19900         stack_trap "rm -f $tmpfile"
19901         cat_sl=$(do_facet $SINGLEMDS "sync; \
19902                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19903                  llog_reader $tmpfile | grep -c type=1064553b")
19904         do_facet $SINGLEMDS llog_reader $tmpfile
19905
19906         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19907
19908         changelog_clear 0 || error "changelog_clear failed"
19909
19910         cat_sl=$(do_facet $SINGLEMDS "sync; \
19911                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19912                  llog_reader $tmpfile | grep -c type=1064553b")
19913
19914         if (( cat_sl == 2 )); then
19915                 error "Empty plain llog was not deleted from changelog catalog"
19916         elif (( cat_sl != 1 )); then
19917                 error "Active plain llog shouldn't be deleted from catalog"
19918         fi
19919 }
19920 run_test 256 "Check llog delete for empty and not full state"
19921
19922 test_257() {
19923         remote_mds_nodsh && skip "remote MDS with nodsh"
19924         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19925                 skip "Need MDS version at least 2.8.55"
19926
19927         test_mkdir $DIR/$tdir
19928
19929         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19930                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19931         stat $DIR/$tdir
19932
19933 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19934         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19935         local facet=mds$((mdtidx + 1))
19936         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19937         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19938
19939         stop $facet || error "stop MDS failed"
19940         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19941                 error "start MDS fail"
19942         wait_recovery_complete $facet
19943 }
19944 run_test 257 "xattr locks are not lost"
19945
19946 # Verify we take the i_mutex when security requires it
19947 test_258a() {
19948 #define OBD_FAIL_IMUTEX_SEC 0x141c
19949         $LCTL set_param fail_loc=0x141c
19950         touch $DIR/$tfile
19951         chmod u+s $DIR/$tfile
19952         chmod a+rwx $DIR/$tfile
19953         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19954         RC=$?
19955         if [ $RC -ne 0 ]; then
19956                 error "error, failed to take i_mutex, rc=$?"
19957         fi
19958         rm -f $DIR/$tfile
19959 }
19960 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19961
19962 # Verify we do NOT take the i_mutex in the normal case
19963 test_258b() {
19964 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19965         $LCTL set_param fail_loc=0x141d
19966         touch $DIR/$tfile
19967         chmod a+rwx $DIR
19968         chmod a+rw $DIR/$tfile
19969         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19970         RC=$?
19971         if [ $RC -ne 0 ]; then
19972                 error "error, took i_mutex unnecessarily, rc=$?"
19973         fi
19974         rm -f $DIR/$tfile
19975
19976 }
19977 run_test 258b "verify i_mutex security behavior"
19978
19979 test_259() {
19980         local file=$DIR/$tfile
19981         local before
19982         local after
19983
19984         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19985
19986         stack_trap "rm -f $file" EXIT
19987
19988         wait_delete_completed
19989         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19990         echo "before: $before"
19991
19992         $LFS setstripe -i 0 -c 1 $file
19993         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19994         sync_all_data
19995         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19996         echo "after write: $after"
19997
19998 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19999         do_facet ost1 $LCTL set_param fail_loc=0x2301
20000         $TRUNCATE $file 0
20001         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20002         echo "after truncate: $after"
20003
20004         stop ost1
20005         do_facet ost1 $LCTL set_param fail_loc=0
20006         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20007         sleep 2
20008         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20009         echo "after restart: $after"
20010         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20011                 error "missing truncate?"
20012
20013         return 0
20014 }
20015 run_test 259 "crash at delayed truncate"
20016
20017 test_260() {
20018 #define OBD_FAIL_MDC_CLOSE               0x806
20019         $LCTL set_param fail_loc=0x80000806
20020         touch $DIR/$tfile
20021
20022 }
20023 run_test 260 "Check mdc_close fail"
20024
20025 ### Data-on-MDT sanity tests ###
20026 test_270a() {
20027         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20028                 skip "Need MDS version at least 2.10.55 for DoM"
20029
20030         # create DoM file
20031         local dom=$DIR/$tdir/dom_file
20032         local tmp=$DIR/$tdir/tmp_file
20033
20034         mkdir -p $DIR/$tdir
20035
20036         # basic checks for DoM component creation
20037         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20038                 error "Can set MDT layout to non-first entry"
20039
20040         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20041                 error "Can define multiple entries as MDT layout"
20042
20043         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20044
20045         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20046         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20047         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20048
20049         local mdtidx=$($LFS getstripe -m $dom)
20050         local mdtname=MDT$(printf %04x $mdtidx)
20051         local facet=mds$((mdtidx + 1))
20052         local space_check=1
20053
20054         # Skip free space checks with ZFS
20055         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20056
20057         # write
20058         sync
20059         local size_tmp=$((65536 * 3))
20060         local mdtfree1=$(do_facet $facet \
20061                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20062
20063         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20064         # check also direct IO along write
20065         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20066         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20067         sync
20068         cmp $tmp $dom || error "file data is different"
20069         [ $(stat -c%s $dom) == $size_tmp ] ||
20070                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20071         if [ $space_check == 1 ]; then
20072                 local mdtfree2=$(do_facet $facet \
20073                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20074
20075                 # increase in usage from by $size_tmp
20076                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20077                         error "MDT free space wrong after write: " \
20078                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20079         fi
20080
20081         # truncate
20082         local size_dom=10000
20083
20084         $TRUNCATE $dom $size_dom
20085         [ $(stat -c%s $dom) == $size_dom ] ||
20086                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20087         if [ $space_check == 1 ]; then
20088                 mdtfree1=$(do_facet $facet \
20089                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20090                 # decrease in usage from $size_tmp to new $size_dom
20091                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20092                   $(((size_tmp - size_dom) / 1024)) ] ||
20093                         error "MDT free space is wrong after truncate: " \
20094                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20095         fi
20096
20097         # append
20098         cat $tmp >> $dom
20099         sync
20100         size_dom=$((size_dom + size_tmp))
20101         [ $(stat -c%s $dom) == $size_dom ] ||
20102                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20103         if [ $space_check == 1 ]; then
20104                 mdtfree2=$(do_facet $facet \
20105                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20106                 # increase in usage by $size_tmp from previous
20107                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20108                         error "MDT free space is wrong after append: " \
20109                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20110         fi
20111
20112         # delete
20113         rm $dom
20114         if [ $space_check == 1 ]; then
20115                 mdtfree1=$(do_facet $facet \
20116                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20117                 # decrease in usage by $size_dom from previous
20118                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20119                         error "MDT free space is wrong after removal: " \
20120                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20121         fi
20122
20123         # combined striping
20124         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20125                 error "Can't create DoM + OST striping"
20126
20127         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20128         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20129         # check also direct IO along write
20130         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20131         sync
20132         cmp $tmp $dom || error "file data is different"
20133         [ $(stat -c%s $dom) == $size_tmp ] ||
20134                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20135         rm $dom $tmp
20136
20137         return 0
20138 }
20139 run_test 270a "DoM: basic functionality tests"
20140
20141 test_270b() {
20142         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20143                 skip "Need MDS version at least 2.10.55"
20144
20145         local dom=$DIR/$tdir/dom_file
20146         local max_size=1048576
20147
20148         mkdir -p $DIR/$tdir
20149         $LFS setstripe -E $max_size -L mdt $dom
20150
20151         # truncate over the limit
20152         $TRUNCATE $dom $(($max_size + 1)) &&
20153                 error "successful truncate over the maximum size"
20154         # write over the limit
20155         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20156                 error "successful write over the maximum size"
20157         # append over the limit
20158         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20159         echo "12345" >> $dom && error "successful append over the maximum size"
20160         rm $dom
20161
20162         return 0
20163 }
20164 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20165
20166 test_270c() {
20167         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20168                 skip "Need MDS version at least 2.10.55"
20169
20170         mkdir -p $DIR/$tdir
20171         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20172
20173         # check files inherit DoM EA
20174         touch $DIR/$tdir/first
20175         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20176                 error "bad pattern"
20177         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20178                 error "bad stripe count"
20179         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20180                 error "bad stripe size"
20181
20182         # check directory inherits DoM EA and uses it as default
20183         mkdir $DIR/$tdir/subdir
20184         touch $DIR/$tdir/subdir/second
20185         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20186                 error "bad pattern in sub-directory"
20187         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20188                 error "bad stripe count in sub-directory"
20189         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20190                 error "bad stripe size in sub-directory"
20191         return 0
20192 }
20193 run_test 270c "DoM: DoM EA inheritance tests"
20194
20195 test_270d() {
20196         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20197                 skip "Need MDS version at least 2.10.55"
20198
20199         mkdir -p $DIR/$tdir
20200         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20201
20202         # inherit default DoM striping
20203         mkdir $DIR/$tdir/subdir
20204         touch $DIR/$tdir/subdir/f1
20205
20206         # change default directory striping
20207         $LFS setstripe -c 1 $DIR/$tdir/subdir
20208         touch $DIR/$tdir/subdir/f2
20209         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20210                 error "wrong default striping in file 2"
20211         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20212                 error "bad pattern in file 2"
20213         return 0
20214 }
20215 run_test 270d "DoM: change striping from DoM to RAID0"
20216
20217 test_270e() {
20218         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20219                 skip "Need MDS version at least 2.10.55"
20220
20221         mkdir -p $DIR/$tdir/dom
20222         mkdir -p $DIR/$tdir/norm
20223         DOMFILES=20
20224         NORMFILES=10
20225         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20226         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20227
20228         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20229         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20230
20231         # find DoM files by layout
20232         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20233         [ $NUM -eq  $DOMFILES ] ||
20234                 error "lfs find -L: found $NUM, expected $DOMFILES"
20235         echo "Test 1: lfs find 20 DOM files by layout: OK"
20236
20237         # there should be 1 dir with default DOM striping
20238         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20239         [ $NUM -eq  1 ] ||
20240                 error "lfs find -L: found $NUM, expected 1 dir"
20241         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20242
20243         # find DoM files by stripe size
20244         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20245         [ $NUM -eq  $DOMFILES ] ||
20246                 error "lfs find -S: found $NUM, expected $DOMFILES"
20247         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20248
20249         # find files by stripe offset except DoM files
20250         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20251         [ $NUM -eq  $NORMFILES ] ||
20252                 error "lfs find -i: found $NUM, expected $NORMFILES"
20253         echo "Test 5: lfs find no DOM files by stripe index: OK"
20254         return 0
20255 }
20256 run_test 270e "DoM: lfs find with DoM files test"
20257
20258 test_270f() {
20259         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20260                 skip "Need MDS version at least 2.10.55"
20261
20262         local mdtname=${FSNAME}-MDT0000-mdtlov
20263         local dom=$DIR/$tdir/dom_file
20264         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20265                                                 lod.$mdtname.dom_stripesize)
20266         local dom_limit=131072
20267
20268         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20269         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20270                                                 lod.$mdtname.dom_stripesize)
20271         [ ${dom_limit} -eq ${dom_current} ] ||
20272                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20273
20274         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20275         $LFS setstripe -d $DIR/$tdir
20276         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20277                 error "Can't set directory default striping"
20278
20279         # exceed maximum stripe size
20280         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20281                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20282         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20283                 error "Able to create DoM component size more than LOD limit"
20284
20285         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20286         dom_current=$(do_facet mds1 $LCTL get_param -n \
20287                                                 lod.$mdtname.dom_stripesize)
20288         [ 0 -eq ${dom_current} ] ||
20289                 error "Can't set zero DoM stripe limit"
20290         rm $dom
20291
20292         # attempt to create DoM file on server with disabled DoM should
20293         # remove DoM entry from layout and be succeed
20294         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20295                 error "Can't create DoM file (DoM is disabled)"
20296         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20297                 error "File has DoM component while DoM is disabled"
20298         rm $dom
20299
20300         # attempt to create DoM file with only DoM stripe should return error
20301         $LFS setstripe -E $dom_limit -L mdt $dom &&
20302                 error "Able to create DoM-only file while DoM is disabled"
20303
20304         # too low values to be aligned with smallest stripe size 64K
20305         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20306         dom_current=$(do_facet mds1 $LCTL get_param -n \
20307                                                 lod.$mdtname.dom_stripesize)
20308         [ 30000 -eq ${dom_current} ] &&
20309                 error "Can set too small DoM stripe limit"
20310
20311         # 64K is a minimal stripe size in Lustre, expect limit of that size
20312         [ 65536 -eq ${dom_current} ] ||
20313                 error "Limit is not set to 64K but ${dom_current}"
20314
20315         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20316         dom_current=$(do_facet mds1 $LCTL get_param -n \
20317                                                 lod.$mdtname.dom_stripesize)
20318         echo $dom_current
20319         [ 2147483648 -eq ${dom_current} ] &&
20320                 error "Can set too large DoM stripe limit"
20321
20322         do_facet mds1 $LCTL set_param -n \
20323                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20324         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20325                 error "Can't create DoM component size after limit change"
20326         do_facet mds1 $LCTL set_param -n \
20327                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20328         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20329                 error "Can't create DoM file after limit decrease"
20330         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20331                 error "Can create big DoM component after limit decrease"
20332         touch ${dom}_def ||
20333                 error "Can't create file with old default layout"
20334
20335         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20336         return 0
20337 }
20338 run_test 270f "DoM: maximum DoM stripe size checks"
20339
20340 test_270g() {
20341         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20342                 skip "Need MDS version at least 2.13.52"
20343         local dom=$DIR/$tdir/$tfile
20344
20345         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20346         local lodname=${FSNAME}-MDT0000-mdtlov
20347
20348         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20349         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20350         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20351         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20352
20353         local dom_limit=1024
20354         local dom_threshold="50%"
20355
20356         $LFS setstripe -d $DIR/$tdir
20357         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20358                 error "Can't set directory default striping"
20359
20360         do_facet mds1 $LCTL set_param -n \
20361                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20362         # set 0 threshold and create DOM file to change tunable stripesize
20363         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20364         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20365                 error "Failed to create $dom file"
20366         # now tunable dom_cur_stripesize should reach maximum
20367         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20368                                         lod.${lodname}.dom_stripesize_cur_kb)
20369         [[ $dom_current == $dom_limit ]] ||
20370                 error "Current DOM stripesize is not maximum"
20371         rm $dom
20372
20373         # set threshold for further tests
20374         do_facet mds1 $LCTL set_param -n \
20375                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20376         echo "DOM threshold is $dom_threshold free space"
20377         local dom_def
20378         local dom_set
20379         # Spoof bfree to exceed threshold
20380         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20381         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20382         for spfree in 40 20 0 15 30 55; do
20383                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20384                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20385                         error "Failed to create $dom file"
20386                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20387                                         lod.${lodname}.dom_stripesize_cur_kb)
20388                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20389                 [[ $dom_def != $dom_current ]] ||
20390                         error "Default stripe size was not changed"
20391                 if [[ $spfree > 0 ]] ; then
20392                         dom_set=$($LFS getstripe -S $dom)
20393                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20394                                 error "DOM component size is still old"
20395                 else
20396                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20397                                 error "DoM component is set with no free space"
20398                 fi
20399                 rm $dom
20400                 dom_current=$dom_def
20401         done
20402 }
20403 run_test 270g "DoM: default DoM stripe size depends on free space"
20404
20405 test_270h() {
20406         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20407                 skip "Need MDS version at least 2.13.53"
20408
20409         local mdtname=${FSNAME}-MDT0000-mdtlov
20410         local dom=$DIR/$tdir/$tfile
20411         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20412
20413         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20414         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20415
20416         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20417         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20418                 error "can't create OST file"
20419         # mirrored file with DOM entry in the second mirror
20420         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20421                 error "can't create mirror with DoM component"
20422
20423         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20424
20425         # DOM component in the middle and has other enries in the same mirror,
20426         # should succeed but lost DoM component
20427         $LFS setstripe --copy=${dom}_1 $dom ||
20428                 error "Can't create file from OST|DOM mirror layout"
20429         # check new file has no DoM layout after all
20430         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20431                 error "File has DoM component while DoM is disabled"
20432 }
20433 run_test 270h "DoM: DoM stripe removal when disabled on server"
20434
20435 test_271a() {
20436         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20437                 skip "Need MDS version at least 2.10.55"
20438
20439         local dom=$DIR/$tdir/dom
20440
20441         mkdir -p $DIR/$tdir
20442
20443         $LFS setstripe -E 1024K -L mdt $dom
20444
20445         lctl set_param -n mdc.*.stats=clear
20446         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20447         cat $dom > /dev/null
20448         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20449         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20450         ls $dom
20451         rm -f $dom
20452 }
20453 run_test 271a "DoM: data is cached for read after write"
20454
20455 test_271b() {
20456         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20457                 skip "Need MDS version at least 2.10.55"
20458
20459         local dom=$DIR/$tdir/dom
20460
20461         mkdir -p $DIR/$tdir
20462
20463         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20464
20465         lctl set_param -n mdc.*.stats=clear
20466         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20467         cancel_lru_locks mdc
20468         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20469         # second stat to check size is cached on client
20470         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20471         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20472         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20473         rm -f $dom
20474 }
20475 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20476
20477 test_271ba() {
20478         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20479                 skip "Need MDS version at least 2.10.55"
20480
20481         local dom=$DIR/$tdir/dom
20482
20483         mkdir -p $DIR/$tdir
20484
20485         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20486
20487         lctl set_param -n mdc.*.stats=clear
20488         lctl set_param -n osc.*.stats=clear
20489         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20490         cancel_lru_locks mdc
20491         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20492         # second stat to check size is cached on client
20493         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20494         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20495         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20496         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20497         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20498         rm -f $dom
20499 }
20500 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20501
20502
20503 get_mdc_stats() {
20504         local mdtidx=$1
20505         local param=$2
20506         local mdt=MDT$(printf %04x $mdtidx)
20507
20508         if [ -z $param ]; then
20509                 lctl get_param -n mdc.*$mdt*.stats
20510         else
20511                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20512         fi
20513 }
20514
20515 test_271c() {
20516         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20517                 skip "Need MDS version at least 2.10.55"
20518
20519         local dom=$DIR/$tdir/dom
20520
20521         mkdir -p $DIR/$tdir
20522
20523         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20524
20525         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20526         local facet=mds$((mdtidx + 1))
20527
20528         cancel_lru_locks mdc
20529         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20530         createmany -o $dom 1000
20531         lctl set_param -n mdc.*.stats=clear
20532         smalliomany -w $dom 1000 200
20533         get_mdc_stats $mdtidx
20534         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20535         # Each file has 1 open, 1 IO enqueues, total 2000
20536         # but now we have also +1 getxattr for security.capability, total 3000
20537         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20538         unlinkmany $dom 1000
20539
20540         cancel_lru_locks mdc
20541         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20542         createmany -o $dom 1000
20543         lctl set_param -n mdc.*.stats=clear
20544         smalliomany -w $dom 1000 200
20545         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20546         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20547         # for OPEN and IO lock.
20548         [ $((enq - enq_2)) -ge 1000 ] ||
20549                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20550         unlinkmany $dom 1000
20551         return 0
20552 }
20553 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20554
20555 cleanup_271def_tests() {
20556         trap 0
20557         rm -f $1
20558 }
20559
20560 test_271d() {
20561         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20562                 skip "Need MDS version at least 2.10.57"
20563
20564         local dom=$DIR/$tdir/dom
20565         local tmp=$TMP/$tfile
20566         trap "cleanup_271def_tests $tmp" EXIT
20567
20568         mkdir -p $DIR/$tdir
20569
20570         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20571
20572         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20573
20574         cancel_lru_locks mdc
20575         dd if=/dev/urandom of=$tmp bs=1000 count=1
20576         dd if=$tmp of=$dom bs=1000 count=1
20577         cancel_lru_locks mdc
20578
20579         cat /etc/hosts >> $tmp
20580         lctl set_param -n mdc.*.stats=clear
20581
20582         # append data to the same file it should update local page
20583         echo "Append to the same page"
20584         cat /etc/hosts >> $dom
20585         local num=$(get_mdc_stats $mdtidx ost_read)
20586         local ra=$(get_mdc_stats $mdtidx req_active)
20587         local rw=$(get_mdc_stats $mdtidx req_waittime)
20588
20589         [ -z $num ] || error "$num READ RPC occured"
20590         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20591         echo "... DONE"
20592
20593         # compare content
20594         cmp $tmp $dom || error "file miscompare"
20595
20596         cancel_lru_locks mdc
20597         lctl set_param -n mdc.*.stats=clear
20598
20599         echo "Open and read file"
20600         cat $dom > /dev/null
20601         local num=$(get_mdc_stats $mdtidx ost_read)
20602         local ra=$(get_mdc_stats $mdtidx req_active)
20603         local rw=$(get_mdc_stats $mdtidx req_waittime)
20604
20605         [ -z $num ] || error "$num READ RPC occured"
20606         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20607         echo "... DONE"
20608
20609         # compare content
20610         cmp $tmp $dom || error "file miscompare"
20611
20612         return 0
20613 }
20614 run_test 271d "DoM: read on open (1K file in reply buffer)"
20615
20616 test_271f() {
20617         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20618                 skip "Need MDS version at least 2.10.57"
20619
20620         local dom=$DIR/$tdir/dom
20621         local tmp=$TMP/$tfile
20622         trap "cleanup_271def_tests $tmp" EXIT
20623
20624         mkdir -p $DIR/$tdir
20625
20626         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20627
20628         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20629
20630         cancel_lru_locks mdc
20631         dd if=/dev/urandom of=$tmp bs=265000 count=1
20632         dd if=$tmp of=$dom bs=265000 count=1
20633         cancel_lru_locks mdc
20634         cat /etc/hosts >> $tmp
20635         lctl set_param -n mdc.*.stats=clear
20636
20637         echo "Append to the same page"
20638         cat /etc/hosts >> $dom
20639         local num=$(get_mdc_stats $mdtidx ost_read)
20640         local ra=$(get_mdc_stats $mdtidx req_active)
20641         local rw=$(get_mdc_stats $mdtidx req_waittime)
20642
20643         [ -z $num ] || error "$num READ RPC occured"
20644         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20645         echo "... DONE"
20646
20647         # compare content
20648         cmp $tmp $dom || error "file miscompare"
20649
20650         cancel_lru_locks mdc
20651         lctl set_param -n mdc.*.stats=clear
20652
20653         echo "Open and read file"
20654         cat $dom > /dev/null
20655         local num=$(get_mdc_stats $mdtidx ost_read)
20656         local ra=$(get_mdc_stats $mdtidx req_active)
20657         local rw=$(get_mdc_stats $mdtidx req_waittime)
20658
20659         [ -z $num ] && num=0
20660         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20661         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20662         echo "... DONE"
20663
20664         # compare content
20665         cmp $tmp $dom || error "file miscompare"
20666
20667         return 0
20668 }
20669 run_test 271f "DoM: read on open (200K file and read tail)"
20670
20671 test_271g() {
20672         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20673                 skip "Skipping due to old client or server version"
20674
20675         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20676         # to get layout
20677         $CHECKSTAT -t file $DIR1/$tfile
20678
20679         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20680         MULTIOP_PID=$!
20681         sleep 1
20682         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20683         $LCTL set_param fail_loc=0x80000314
20684         rm $DIR1/$tfile || error "Unlink fails"
20685         RC=$?
20686         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20687         [ $RC -eq 0 ] || error "Failed write to stale object"
20688 }
20689 run_test 271g "Discard DoM data vs client flush race"
20690
20691 test_272a() {
20692         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20693                 skip "Need MDS version at least 2.11.50"
20694
20695         local dom=$DIR/$tdir/dom
20696         mkdir -p $DIR/$tdir
20697
20698         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20699         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20700                 error "failed to write data into $dom"
20701         local old_md5=$(md5sum $dom)
20702
20703         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20704                 error "failed to migrate to the same DoM component"
20705
20706         local new_md5=$(md5sum $dom)
20707
20708         [ "$old_md5" == "$new_md5" ] ||
20709                 error "md5sum differ: $old_md5, $new_md5"
20710
20711         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20712                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20713 }
20714 run_test 272a "DoM migration: new layout with the same DOM component"
20715
20716 test_272b() {
20717         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20718                 skip "Need MDS version at least 2.11.50"
20719
20720         local dom=$DIR/$tdir/dom
20721         mkdir -p $DIR/$tdir
20722         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20723
20724         local mdtidx=$($LFS getstripe -m $dom)
20725         local mdtname=MDT$(printf %04x $mdtidx)
20726         local facet=mds$((mdtidx + 1))
20727
20728         local mdtfree1=$(do_facet $facet \
20729                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20730         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20731                 error "failed to write data into $dom"
20732         local old_md5=$(md5sum $dom)
20733         cancel_lru_locks mdc
20734         local mdtfree1=$(do_facet $facet \
20735                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20736
20737         $LFS migrate -c2 $dom ||
20738                 error "failed to migrate to the new composite layout"
20739         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20740                 error "MDT stripe was not removed"
20741
20742         cancel_lru_locks mdc
20743         local new_md5=$(md5sum $dom)
20744         [ "$old_md5" == "$new_md5" ] ||
20745                 error "$old_md5 != $new_md5"
20746
20747         # Skip free space checks with ZFS
20748         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20749                 local mdtfree2=$(do_facet $facet \
20750                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20751                 [ $mdtfree2 -gt $mdtfree1 ] ||
20752                         error "MDT space is not freed after migration"
20753         fi
20754         return 0
20755 }
20756 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20757
20758 test_272c() {
20759         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20760                 skip "Need MDS version at least 2.11.50"
20761
20762         local dom=$DIR/$tdir/$tfile
20763         mkdir -p $DIR/$tdir
20764         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20765
20766         local mdtidx=$($LFS getstripe -m $dom)
20767         local mdtname=MDT$(printf %04x $mdtidx)
20768         local facet=mds$((mdtidx + 1))
20769
20770         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20771                 error "failed to write data into $dom"
20772         local old_md5=$(md5sum $dom)
20773         cancel_lru_locks mdc
20774         local mdtfree1=$(do_facet $facet \
20775                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20776
20777         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20778                 error "failed to migrate to the new composite layout"
20779         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20780                 error "MDT stripe was not removed"
20781
20782         cancel_lru_locks mdc
20783         local new_md5=$(md5sum $dom)
20784         [ "$old_md5" == "$new_md5" ] ||
20785                 error "$old_md5 != $new_md5"
20786
20787         # Skip free space checks with ZFS
20788         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20789                 local mdtfree2=$(do_facet $facet \
20790                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20791                 [ $mdtfree2 -gt $mdtfree1 ] ||
20792                         error "MDS space is not freed after migration"
20793         fi
20794         return 0
20795 }
20796 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20797
20798 test_272d() {
20799         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20800                 skip "Need MDS version at least 2.12.55"
20801
20802         local dom=$DIR/$tdir/$tfile
20803         mkdir -p $DIR/$tdir
20804         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20805
20806         local mdtidx=$($LFS getstripe -m $dom)
20807         local mdtname=MDT$(printf %04x $mdtidx)
20808         local facet=mds$((mdtidx + 1))
20809
20810         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20811                 error "failed to write data into $dom"
20812         local old_md5=$(md5sum $dom)
20813         cancel_lru_locks mdc
20814         local mdtfree1=$(do_facet $facet \
20815                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20816
20817         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20818                 error "failed mirroring to the new composite layout"
20819         $LFS mirror resync $dom ||
20820                 error "failed mirror resync"
20821         $LFS mirror split --mirror-id 1 -d $dom ||
20822                 error "failed mirror split"
20823
20824         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20825                 error "MDT stripe was not removed"
20826
20827         cancel_lru_locks mdc
20828         local new_md5=$(md5sum $dom)
20829         [ "$old_md5" == "$new_md5" ] ||
20830                 error "$old_md5 != $new_md5"
20831
20832         # Skip free space checks with ZFS
20833         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20834                 local mdtfree2=$(do_facet $facet \
20835                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20836                 [ $mdtfree2 -gt $mdtfree1 ] ||
20837                         error "MDS space is not freed after DOM mirror deletion"
20838         fi
20839         return 0
20840 }
20841 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20842
20843 test_272e() {
20844         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20845                 skip "Need MDS version at least 2.12.55"
20846
20847         local dom=$DIR/$tdir/$tfile
20848         mkdir -p $DIR/$tdir
20849         $LFS setstripe -c 2 $dom
20850
20851         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20852                 error "failed to write data into $dom"
20853         local old_md5=$(md5sum $dom)
20854         cancel_lru_locks mdc
20855
20856         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20857                 error "failed mirroring to the DOM layout"
20858         $LFS mirror resync $dom ||
20859                 error "failed mirror resync"
20860         $LFS mirror split --mirror-id 1 -d $dom ||
20861                 error "failed mirror split"
20862
20863         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20864                 error "MDT stripe was not removed"
20865
20866         cancel_lru_locks mdc
20867         local new_md5=$(md5sum $dom)
20868         [ "$old_md5" == "$new_md5" ] ||
20869                 error "$old_md5 != $new_md5"
20870
20871         return 0
20872 }
20873 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20874
20875 test_272f() {
20876         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20877                 skip "Need MDS version at least 2.12.55"
20878
20879         local dom=$DIR/$tdir/$tfile
20880         mkdir -p $DIR/$tdir
20881         $LFS setstripe -c 2 $dom
20882
20883         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20884                 error "failed to write data into $dom"
20885         local old_md5=$(md5sum $dom)
20886         cancel_lru_locks mdc
20887
20888         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20889                 error "failed migrating to the DOM file"
20890
20891         cancel_lru_locks mdc
20892         local new_md5=$(md5sum $dom)
20893         [ "$old_md5" != "$new_md5" ] &&
20894                 error "$old_md5 != $new_md5"
20895
20896         return 0
20897 }
20898 run_test 272f "DoM migration: OST-striped file to DOM file"
20899
20900 test_273a() {
20901         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20902                 skip "Need MDS version at least 2.11.50"
20903
20904         # Layout swap cannot be done if either file has DOM component,
20905         # this will never be supported, migration should be used instead
20906
20907         local dom=$DIR/$tdir/$tfile
20908         mkdir -p $DIR/$tdir
20909
20910         $LFS setstripe -c2 ${dom}_plain
20911         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20912         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20913                 error "can swap layout with DoM component"
20914         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20915                 error "can swap layout with DoM component"
20916
20917         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20918         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20919                 error "can swap layout with DoM component"
20920         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20921                 error "can swap layout with DoM component"
20922         return 0
20923 }
20924 run_test 273a "DoM: layout swapping should fail with DOM"
20925
20926 test_275() {
20927         remote_ost_nodsh && skip "remote OST with nodsh"
20928         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20929                 skip "Need OST version >= 2.10.57"
20930
20931         local file=$DIR/$tfile
20932         local oss
20933
20934         oss=$(comma_list $(osts_nodes))
20935
20936         dd if=/dev/urandom of=$file bs=1M count=2 ||
20937                 error "failed to create a file"
20938         cancel_lru_locks osc
20939
20940         #lock 1
20941         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20942                 error "failed to read a file"
20943
20944 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20945         $LCTL set_param fail_loc=0x8000031f
20946
20947         cancel_lru_locks osc &
20948         sleep 1
20949
20950 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20951         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20952         #IO takes another lock, but matches the PENDING one
20953         #and places it to the IO RPC
20954         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20955                 error "failed to read a file with PENDING lock"
20956 }
20957 run_test 275 "Read on a canceled duplicate lock"
20958
20959 test_276() {
20960         remote_ost_nodsh && skip "remote OST with nodsh"
20961         local pid
20962
20963         do_facet ost1 "(while true; do \
20964                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20965                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20966         pid=$!
20967
20968         for LOOP in $(seq 20); do
20969                 stop ost1
20970                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20971         done
20972         kill -9 $pid
20973         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20974                 rm $TMP/sanity_276_pid"
20975 }
20976 run_test 276 "Race between mount and obd_statfs"
20977
20978 test_277() {
20979         $LCTL set_param ldlm.namespaces.*.lru_size=0
20980         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20981         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20982                         grep ^used_mb | awk '{print $2}')
20983         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20984         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20985                 oflag=direct conv=notrunc
20986         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20987                         grep ^used_mb | awk '{print $2}')
20988         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20989 }
20990 run_test 277 "Direct IO shall drop page cache"
20991
20992 test_278() {
20993         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20994         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20995         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20996                 skip "needs the same host for mdt1 mdt2" && return
20997
20998         local pid1
20999         local pid2
21000
21001 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21002         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21003         stop mds2 &
21004         pid2=$!
21005
21006         stop mds1
21007
21008         echo "Starting MDTs"
21009         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21010         wait $pid2
21011 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21012 #will return NULL
21013         do_facet mds2 $LCTL set_param fail_loc=0
21014
21015         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21016         wait_recovery_complete mds2
21017 }
21018 run_test 278 "Race starting MDS between MDTs stop/start"
21019
21020 test_280() {
21021         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21022                 skip "Need MGS version at least 2.13.52"
21023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21024         combined_mgs_mds || skip "needs combined MGS/MDT"
21025
21026         umount_client $MOUNT
21027 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21028         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21029
21030         mount_client $MOUNT &
21031         sleep 1
21032         stop mgs || error "stop mgs failed"
21033         #for a race mgs would crash
21034         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21035         mount_client $MOUNT || error "mount client failed"
21036 }
21037 run_test 280 "Race between MGS umount and client llog processing"
21038
21039 cleanup_test_300() {
21040         trap 0
21041         umask $SAVE_UMASK
21042 }
21043 test_striped_dir() {
21044         local mdt_index=$1
21045         local stripe_count
21046         local stripe_index
21047
21048         mkdir -p $DIR/$tdir
21049
21050         SAVE_UMASK=$(umask)
21051         trap cleanup_test_300 RETURN EXIT
21052
21053         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21054                                                 $DIR/$tdir/striped_dir ||
21055                 error "set striped dir error"
21056
21057         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21058         [ "$mode" = "755" ] || error "expect 755 got $mode"
21059
21060         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21061                 error "getdirstripe failed"
21062         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21063         if [ "$stripe_count" != "2" ]; then
21064                 error "1:stripe_count is $stripe_count, expect 2"
21065         fi
21066         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21067         if [ "$stripe_count" != "2" ]; then
21068                 error "2:stripe_count is $stripe_count, expect 2"
21069         fi
21070
21071         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21072         if [ "$stripe_index" != "$mdt_index" ]; then
21073                 error "stripe_index is $stripe_index, expect $mdt_index"
21074         fi
21075
21076         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21077                 error "nlink error after create striped dir"
21078
21079         mkdir $DIR/$tdir/striped_dir/a
21080         mkdir $DIR/$tdir/striped_dir/b
21081
21082         stat $DIR/$tdir/striped_dir/a ||
21083                 error "create dir under striped dir failed"
21084         stat $DIR/$tdir/striped_dir/b ||
21085                 error "create dir under striped dir failed"
21086
21087         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21088                 error "nlink error after mkdir"
21089
21090         rmdir $DIR/$tdir/striped_dir/a
21091         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21092                 error "nlink error after rmdir"
21093
21094         rmdir $DIR/$tdir/striped_dir/b
21095         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21096                 error "nlink error after rmdir"
21097
21098         chattr +i $DIR/$tdir/striped_dir
21099         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21100                 error "immutable flags not working under striped dir!"
21101         chattr -i $DIR/$tdir/striped_dir
21102
21103         rmdir $DIR/$tdir/striped_dir ||
21104                 error "rmdir striped dir error"
21105
21106         cleanup_test_300
21107
21108         true
21109 }
21110
21111 test_300a() {
21112         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21113                 skip "skipped for lustre < 2.7.0"
21114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21116
21117         test_striped_dir 0 || error "failed on striped dir on MDT0"
21118         test_striped_dir 1 || error "failed on striped dir on MDT0"
21119 }
21120 run_test 300a "basic striped dir sanity test"
21121
21122 test_300b() {
21123         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21124                 skip "skipped for lustre < 2.7.0"
21125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21126         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21127
21128         local i
21129         local mtime1
21130         local mtime2
21131         local mtime3
21132
21133         test_mkdir $DIR/$tdir || error "mkdir fail"
21134         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21135                 error "set striped dir error"
21136         for i in {0..9}; do
21137                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21138                 sleep 1
21139                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21140                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21141                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21142                 sleep 1
21143                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21144                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21145                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21146         done
21147         true
21148 }
21149 run_test 300b "check ctime/mtime for striped dir"
21150
21151 test_300c() {
21152         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21153                 skip "skipped for lustre < 2.7.0"
21154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21156
21157         local file_count
21158
21159         mkdir -p $DIR/$tdir
21160         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21161                 error "set striped dir error"
21162
21163         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21164                 error "chown striped dir failed"
21165
21166         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21167                 error "create 5k files failed"
21168
21169         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21170
21171         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21172
21173         rm -rf $DIR/$tdir
21174 }
21175 run_test 300c "chown && check ls under striped directory"
21176
21177 test_300d() {
21178         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21179                 skip "skipped for lustre < 2.7.0"
21180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21181         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21182
21183         local stripe_count
21184         local file
21185
21186         mkdir -p $DIR/$tdir
21187         $LFS setstripe -c 2 $DIR/$tdir
21188
21189         #local striped directory
21190         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21191                 error "set striped dir error"
21192         #look at the directories for debug purposes
21193         ls -l $DIR/$tdir
21194         $LFS getdirstripe $DIR/$tdir
21195         ls -l $DIR/$tdir/striped_dir
21196         $LFS getdirstripe $DIR/$tdir/striped_dir
21197         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21198                 error "create 10 files failed"
21199
21200         #remote striped directory
21201         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21202                 error "set striped dir error"
21203         #look at the directories for debug purposes
21204         ls -l $DIR/$tdir
21205         $LFS getdirstripe $DIR/$tdir
21206         ls -l $DIR/$tdir/remote_striped_dir
21207         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21208         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21209                 error "create 10 files failed"
21210
21211         for file in $(find $DIR/$tdir); do
21212                 stripe_count=$($LFS getstripe -c $file)
21213                 [ $stripe_count -eq 2 ] ||
21214                         error "wrong stripe $stripe_count for $file"
21215         done
21216
21217         rm -rf $DIR/$tdir
21218 }
21219 run_test 300d "check default stripe under striped directory"
21220
21221 test_300e() {
21222         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21223                 skip "Need MDS version at least 2.7.55"
21224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21226
21227         local stripe_count
21228         local file
21229
21230         mkdir -p $DIR/$tdir
21231
21232         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21233                 error "set striped dir error"
21234
21235         touch $DIR/$tdir/striped_dir/a
21236         touch $DIR/$tdir/striped_dir/b
21237         touch $DIR/$tdir/striped_dir/c
21238
21239         mkdir $DIR/$tdir/striped_dir/dir_a
21240         mkdir $DIR/$tdir/striped_dir/dir_b
21241         mkdir $DIR/$tdir/striped_dir/dir_c
21242
21243         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21244                 error "set striped adir under striped dir error"
21245
21246         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21247                 error "set striped bdir under striped dir error"
21248
21249         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21250                 error "set striped cdir under striped dir error"
21251
21252         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21253                 error "rename dir under striped dir fails"
21254
21255         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21256                 error "rename dir under different stripes fails"
21257
21258         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21259                 error "rename file under striped dir should succeed"
21260
21261         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21262                 error "rename dir under striped dir should succeed"
21263
21264         rm -rf $DIR/$tdir
21265 }
21266 run_test 300e "check rename under striped directory"
21267
21268 test_300f() {
21269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21270         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21271         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21272                 skip "Need MDS version at least 2.7.55"
21273
21274         local stripe_count
21275         local file
21276
21277         rm -rf $DIR/$tdir
21278         mkdir -p $DIR/$tdir
21279
21280         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21281                 error "set striped dir error"
21282
21283         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21284                 error "set striped dir error"
21285
21286         touch $DIR/$tdir/striped_dir/a
21287         mkdir $DIR/$tdir/striped_dir/dir_a
21288         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21289                 error "create striped dir under striped dir fails"
21290
21291         touch $DIR/$tdir/striped_dir1/b
21292         mkdir $DIR/$tdir/striped_dir1/dir_b
21293         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21294                 error "create striped dir under striped dir fails"
21295
21296         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21297                 error "rename dir under different striped dir should fail"
21298
21299         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21300                 error "rename striped dir under diff striped dir should fail"
21301
21302         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21303                 error "rename file under diff striped dirs fails"
21304
21305         rm -rf $DIR/$tdir
21306 }
21307 run_test 300f "check rename cross striped directory"
21308
21309 test_300_check_default_striped_dir()
21310 {
21311         local dirname=$1
21312         local default_count=$2
21313         local default_index=$3
21314         local stripe_count
21315         local stripe_index
21316         local dir_stripe_index
21317         local dir
21318
21319         echo "checking $dirname $default_count $default_index"
21320         $LFS setdirstripe -D -c $default_count -i $default_index \
21321                                 -t all_char $DIR/$tdir/$dirname ||
21322                 error "set default stripe on striped dir error"
21323         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21324         [ $stripe_count -eq $default_count ] ||
21325                 error "expect $default_count get $stripe_count for $dirname"
21326
21327         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21328         [ $stripe_index -eq $default_index ] ||
21329                 error "expect $default_index get $stripe_index for $dirname"
21330
21331         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21332                                                 error "create dirs failed"
21333
21334         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21335         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21336         for dir in $(find $DIR/$tdir/$dirname/*); do
21337                 stripe_count=$($LFS getdirstripe -c $dir)
21338                 [ $stripe_count -eq $default_count ] ||
21339                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21340                 error "stripe count $default_count != $stripe_count for $dir"
21341
21342                 stripe_index=$($LFS getdirstripe -i $dir)
21343                 [ $default_index -eq -1 ] ||
21344                         [ $stripe_index -eq $default_index ] ||
21345                         error "$stripe_index != $default_index for $dir"
21346
21347                 #check default stripe
21348                 stripe_count=$($LFS getdirstripe -D -c $dir)
21349                 [ $stripe_count -eq $default_count ] ||
21350                 error "default count $default_count != $stripe_count for $dir"
21351
21352                 stripe_index=$($LFS getdirstripe -D -i $dir)
21353                 [ $stripe_index -eq $default_index ] ||
21354                 error "default index $default_index != $stripe_index for $dir"
21355         done
21356         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21357 }
21358
21359 test_300g() {
21360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21361         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21362                 skip "Need MDS version at least 2.7.55"
21363
21364         local dir
21365         local stripe_count
21366         local stripe_index
21367
21368         mkdir $DIR/$tdir
21369         mkdir $DIR/$tdir/normal_dir
21370
21371         #Checking when client cache stripe index
21372         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21373         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21374                 error "create striped_dir failed"
21375
21376         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21377                 error "create dir0 fails"
21378         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21379         [ $stripe_index -eq 0 ] ||
21380                 error "dir0 expect index 0 got $stripe_index"
21381
21382         mkdir $DIR/$tdir/striped_dir/dir1 ||
21383                 error "create dir1 fails"
21384         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21385         [ $stripe_index -eq 1 ] ||
21386                 error "dir1 expect index 1 got $stripe_index"
21387
21388         #check default stripe count/stripe index
21389         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21390         test_300_check_default_striped_dir normal_dir 1 0
21391         test_300_check_default_striped_dir normal_dir 2 1
21392         test_300_check_default_striped_dir normal_dir 2 -1
21393
21394         #delete default stripe information
21395         echo "delete default stripeEA"
21396         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21397                 error "set default stripe on striped dir error"
21398
21399         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21400         for dir in $(find $DIR/$tdir/normal_dir/*); do
21401                 stripe_count=$($LFS getdirstripe -c $dir)
21402                 [ $stripe_count -eq 0 ] ||
21403                         error "expect 1 get $stripe_count for $dir"
21404                 stripe_index=$($LFS getdirstripe -i $dir)
21405                 [ $stripe_index -eq 0 ] ||
21406                         error "expect 0 get $stripe_index for $dir"
21407         done
21408 }
21409 run_test 300g "check default striped directory for normal directory"
21410
21411 test_300h() {
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         local dir
21417         local stripe_count
21418
21419         mkdir $DIR/$tdir
21420         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21421                 error "set striped dir error"
21422
21423         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21424         test_300_check_default_striped_dir striped_dir 1 0
21425         test_300_check_default_striped_dir striped_dir 2 1
21426         test_300_check_default_striped_dir striped_dir 2 -1
21427
21428         #delete default stripe information
21429         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21430                 error "set default stripe on striped dir error"
21431
21432         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21433         for dir in $(find $DIR/$tdir/striped_dir/*); do
21434                 stripe_count=$($LFS getdirstripe -c $dir)
21435                 [ $stripe_count -eq 0 ] ||
21436                         error "expect 1 get $stripe_count for $dir"
21437         done
21438 }
21439 run_test 300h "check default striped directory for striped directory"
21440
21441 test_300i() {
21442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21444         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21445                 skip "Need MDS version at least 2.7.55"
21446
21447         local stripe_count
21448         local file
21449
21450         mkdir $DIR/$tdir
21451
21452         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21453                 error "set striped dir error"
21454
21455         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21456                 error "create files under striped dir failed"
21457
21458         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21459                 error "set striped hashdir error"
21460
21461         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21462                 error "create dir0 under hash dir failed"
21463         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21464                 error "create dir1 under hash dir failed"
21465
21466         # unfortunately, we need to umount to clear dir layout cache for now
21467         # once we fully implement dir layout, we can drop this
21468         umount_client $MOUNT || error "umount failed"
21469         mount_client $MOUNT || error "mount failed"
21470
21471         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21472         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21473         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21474
21475         #set the stripe to be unknown hash type
21476         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21477         $LCTL set_param fail_loc=0x1901
21478         for ((i = 0; i < 10; i++)); do
21479                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21480                         error "stat f-$i failed"
21481                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21482         done
21483
21484         touch $DIR/$tdir/striped_dir/f0 &&
21485                 error "create under striped dir with unknown hash should fail"
21486
21487         $LCTL set_param fail_loc=0
21488
21489         umount_client $MOUNT || error "umount failed"
21490         mount_client $MOUNT || error "mount failed"
21491
21492         return 0
21493 }
21494 run_test 300i "client handle unknown hash type striped directory"
21495
21496 test_300j() {
21497         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21499         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21500                 skip "Need MDS version at least 2.7.55"
21501
21502         local stripe_count
21503         local file
21504
21505         mkdir $DIR/$tdir
21506
21507         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21508         $LCTL set_param fail_loc=0x1702
21509         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21510                 error "set striped dir error"
21511
21512         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21513                 error "create files under striped dir failed"
21514
21515         $LCTL set_param fail_loc=0
21516
21517         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21518
21519         return 0
21520 }
21521 run_test 300j "test large update record"
21522
21523 test_300k() {
21524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21526         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21527                 skip "Need MDS version at least 2.7.55"
21528
21529         # this test needs a huge transaction
21530         local kb
21531         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21532              osd*.$FSNAME-MDT0000.kbytestotal")
21533         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21534
21535         local stripe_count
21536         local file
21537
21538         mkdir $DIR/$tdir
21539
21540         #define OBD_FAIL_LARGE_STRIPE   0x1703
21541         $LCTL set_param fail_loc=0x1703
21542         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21543                 error "set striped dir error"
21544         $LCTL set_param fail_loc=0
21545
21546         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21547                 error "getstripeddir fails"
21548         rm -rf $DIR/$tdir/striped_dir ||
21549                 error "unlink striped dir fails"
21550
21551         return 0
21552 }
21553 run_test 300k "test large striped directory"
21554
21555 test_300l() {
21556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21558         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21559                 skip "Need MDS version at least 2.7.55"
21560
21561         local stripe_index
21562
21563         test_mkdir -p $DIR/$tdir/striped_dir
21564         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21565                         error "chown $RUNAS_ID failed"
21566         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21567                 error "set default striped dir failed"
21568
21569         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21570         $LCTL set_param fail_loc=0x80000158
21571         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21572
21573         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21574         [ $stripe_index -eq 1 ] ||
21575                 error "expect 1 get $stripe_index for $dir"
21576 }
21577 run_test 300l "non-root user to create dir under striped dir with stale layout"
21578
21579 test_300m() {
21580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21581         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21582         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21583                 skip "Need MDS version at least 2.7.55"
21584
21585         mkdir -p $DIR/$tdir/striped_dir
21586         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21587                 error "set default stripes dir error"
21588
21589         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21590
21591         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21592         [ $stripe_count -eq 0 ] ||
21593                         error "expect 0 get $stripe_count for a"
21594
21595         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21596                 error "set default stripes dir error"
21597
21598         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21599
21600         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21601         [ $stripe_count -eq 0 ] ||
21602                         error "expect 0 get $stripe_count for b"
21603
21604         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21605                 error "set default stripes dir error"
21606
21607         mkdir $DIR/$tdir/striped_dir/c &&
21608                 error "default stripe_index is invalid, mkdir c should fails"
21609
21610         rm -rf $DIR/$tdir || error "rmdir fails"
21611 }
21612 run_test 300m "setstriped directory on single MDT FS"
21613
21614 cleanup_300n() {
21615         local list=$(comma_list $(mdts_nodes))
21616
21617         trap 0
21618         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21619 }
21620
21621 test_300n() {
21622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21623         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21624         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21625                 skip "Need MDS version at least 2.7.55"
21626         remote_mds_nodsh && skip "remote MDS with nodsh"
21627
21628         local stripe_index
21629         local list=$(comma_list $(mdts_nodes))
21630
21631         trap cleanup_300n RETURN EXIT
21632         mkdir -p $DIR/$tdir
21633         chmod 777 $DIR/$tdir
21634         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21635                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21636                 error "create striped dir succeeds with gid=0"
21637
21638         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21639         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21640                 error "create striped dir fails with gid=-1"
21641
21642         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21643         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21644                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21645                 error "set default striped dir succeeds with gid=0"
21646
21647
21648         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21649         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21650                 error "set default striped dir fails with gid=-1"
21651
21652
21653         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21654         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21655                                         error "create test_dir fails"
21656         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21657                                         error "create test_dir1 fails"
21658         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21659                                         error "create test_dir2 fails"
21660         cleanup_300n
21661 }
21662 run_test 300n "non-root user to create dir under striped dir with default EA"
21663
21664 test_300o() {
21665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21667         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21668                 skip "Need MDS version at least 2.7.55"
21669
21670         local numfree1
21671         local numfree2
21672
21673         mkdir -p $DIR/$tdir
21674
21675         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21676         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21677         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21678                 skip "not enough free inodes $numfree1 $numfree2"
21679         fi
21680
21681         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21682         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21683         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21684                 skip "not enough free space $numfree1 $numfree2"
21685         fi
21686
21687         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21688                 error "setdirstripe fails"
21689
21690         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21691                 error "create dirs fails"
21692
21693         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21694         ls $DIR/$tdir/striped_dir > /dev/null ||
21695                 error "ls striped dir fails"
21696         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21697                 error "unlink big striped dir fails"
21698 }
21699 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21700
21701 test_300p() {
21702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21704         remote_mds_nodsh && skip "remote MDS with nodsh"
21705
21706         mkdir -p $DIR/$tdir
21707
21708         #define OBD_FAIL_OUT_ENOSPC     0x1704
21709         do_facet mds2 lctl set_param fail_loc=0x80001704
21710         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21711                  && error "create striped directory should fail"
21712
21713         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21714
21715         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21716         true
21717 }
21718 run_test 300p "create striped directory without space"
21719
21720 test_300q() {
21721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21723
21724         local fd=$(free_fd)
21725         local cmd="exec $fd<$tdir"
21726         cd $DIR
21727         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21728         eval $cmd
21729         cmd="exec $fd<&-"
21730         trap "eval $cmd" EXIT
21731         cd $tdir || error "cd $tdir fails"
21732         rmdir  ../$tdir || error "rmdir $tdir fails"
21733         mkdir local_dir && error "create dir succeeds"
21734         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21735         eval $cmd
21736         return 0
21737 }
21738 run_test 300q "create remote directory under orphan directory"
21739
21740 test_300r() {
21741         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21742                 skip "Need MDS version at least 2.7.55" && return
21743         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21744
21745         mkdir $DIR/$tdir
21746
21747         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21748                 error "set striped dir error"
21749
21750         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21751                 error "getstripeddir fails"
21752
21753         local stripe_count
21754         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21755                       awk '/lmv_stripe_count:/ { print $2 }')
21756
21757         [ $MDSCOUNT -ne $stripe_count ] &&
21758                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21759
21760         rm -rf $DIR/$tdir/striped_dir ||
21761                 error "unlink striped dir fails"
21762 }
21763 run_test 300r "test -1 striped directory"
21764
21765 test_300s_helper() {
21766         local count=$1
21767
21768         local stripe_dir=$DIR/$tdir/striped_dir.$count
21769
21770         $LFS mkdir -c $count $stripe_dir ||
21771                 error "lfs mkdir -c error"
21772
21773         $LFS getdirstripe $stripe_dir ||
21774                 error "lfs getdirstripe fails"
21775
21776         local stripe_count
21777         stripe_count=$($LFS getdirstripe $stripe_dir |
21778                       awk '/lmv_stripe_count:/ { print $2 }')
21779
21780         [ $count -ne $stripe_count ] &&
21781                 error_noexit "bad stripe count $stripe_count expected $count"
21782
21783         local dupe_stripes
21784         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21785                 awk '/0x/ {count[$1] += 1}; END {
21786                         for (idx in count) {
21787                                 if (count[idx]>1) {
21788                                         print "index " idx " count " count[idx]
21789                                 }
21790                         }
21791                 }')
21792
21793         if [[ -n "$dupe_stripes" ]] ; then
21794                 lfs getdirstripe $stripe_dir
21795                 error_noexit "Dupe MDT above: $dupe_stripes "
21796         fi
21797
21798         rm -rf $stripe_dir ||
21799                 error_noexit "unlink $stripe_dir fails"
21800 }
21801
21802 test_300s() {
21803         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21804                 skip "Need MDS version at least 2.7.55" && return
21805         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21806
21807         mkdir $DIR/$tdir
21808         for count in $(seq 2 $MDSCOUNT); do
21809                 test_300s_helper $count
21810         done
21811 }
21812 run_test 300s "test lfs mkdir -c without -i"
21813
21814
21815 prepare_remote_file() {
21816         mkdir $DIR/$tdir/src_dir ||
21817                 error "create remote source failed"
21818
21819         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21820                  error "cp to remote source failed"
21821         touch $DIR/$tdir/src_dir/a
21822
21823         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21824                 error "create remote target dir failed"
21825
21826         touch $DIR/$tdir/tgt_dir/b
21827
21828         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21829                 error "rename dir cross MDT failed!"
21830
21831         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21832                 error "src_child still exists after rename"
21833
21834         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21835                 error "missing file(a) after rename"
21836
21837         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21838                 error "diff after rename"
21839 }
21840
21841 test_310a() {
21842         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21844
21845         local remote_file=$DIR/$tdir/tgt_dir/b
21846
21847         mkdir -p $DIR/$tdir
21848
21849         prepare_remote_file || error "prepare remote file failed"
21850
21851         #open-unlink file
21852         $OPENUNLINK $remote_file $remote_file ||
21853                 error "openunlink $remote_file failed"
21854         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21855 }
21856 run_test 310a "open unlink remote file"
21857
21858 test_310b() {
21859         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21861
21862         local remote_file=$DIR/$tdir/tgt_dir/b
21863
21864         mkdir -p $DIR/$tdir
21865
21866         prepare_remote_file || error "prepare remote file failed"
21867
21868         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21869         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21870         $CHECKSTAT -t file $remote_file || error "check file failed"
21871 }
21872 run_test 310b "unlink remote file with multiple links while open"
21873
21874 test_310c() {
21875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21876         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21877
21878         local remote_file=$DIR/$tdir/tgt_dir/b
21879
21880         mkdir -p $DIR/$tdir
21881
21882         prepare_remote_file || error "prepare remote file failed"
21883
21884         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21885         multiop_bg_pause $remote_file O_uc ||
21886                         error "mulitop failed for remote file"
21887         MULTIPID=$!
21888         $MULTIOP $DIR/$tfile Ouc
21889         kill -USR1 $MULTIPID
21890         wait $MULTIPID
21891 }
21892 run_test 310c "open-unlink remote file with multiple links"
21893
21894 #LU-4825
21895 test_311() {
21896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21897         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21898         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21899                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21900         remote_mds_nodsh && skip "remote MDS with nodsh"
21901
21902         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21903         local mdts=$(comma_list $(mdts_nodes))
21904
21905         mkdir -p $DIR/$tdir
21906         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21907         createmany -o $DIR/$tdir/$tfile. 1000
21908
21909         # statfs data is not real time, let's just calculate it
21910         old_iused=$((old_iused + 1000))
21911
21912         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21913                         osp.*OST0000*MDT0000.create_count")
21914         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21915                                 osp.*OST0000*MDT0000.max_create_count")
21916         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21917
21918         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21919         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21920         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21921
21922         unlinkmany $DIR/$tdir/$tfile. 1000
21923
21924         do_nodes $mdts "$LCTL set_param -n \
21925                         osp.*OST0000*.max_create_count=$max_count"
21926         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21927                 do_nodes $mdts "$LCTL set_param -n \
21928                                 osp.*OST0000*.create_count=$count"
21929         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21930                         grep "=0" && error "create_count is zero"
21931
21932         local new_iused
21933         for i in $(seq 120); do
21934                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21935                 # system may be too busy to destroy all objs in time, use
21936                 # a somewhat small value to not fail autotest
21937                 [ $((old_iused - new_iused)) -gt 400 ] && break
21938                 sleep 1
21939         done
21940
21941         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21942         [ $((old_iused - new_iused)) -gt 400 ] ||
21943                 error "objs not destroyed after unlink"
21944 }
21945 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21946
21947 zfs_oid_to_objid()
21948 {
21949         local ost=$1
21950         local objid=$2
21951
21952         local vdevdir=$(dirname $(facet_vdevice $ost))
21953         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21954         local zfs_zapid=$(do_facet $ost $cmd |
21955                           grep -w "/O/0/d$((objid%32))" -C 5 |
21956                           awk '/Object/{getline; print $1}')
21957         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21958                           awk "/$objid = /"'{printf $3}')
21959
21960         echo $zfs_objid
21961 }
21962
21963 zfs_object_blksz() {
21964         local ost=$1
21965         local objid=$2
21966
21967         local vdevdir=$(dirname $(facet_vdevice $ost))
21968         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21969         local blksz=$(do_facet $ost $cmd $objid |
21970                       awk '/dblk/{getline; printf $4}')
21971
21972         case "${blksz: -1}" in
21973                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21974                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21975                 *) ;;
21976         esac
21977
21978         echo $blksz
21979 }
21980
21981 test_312() { # LU-4856
21982         remote_ost_nodsh && skip "remote OST with nodsh"
21983         [ "$ost1_FSTYPE" = "zfs" ] ||
21984                 skip_env "the test only applies to zfs"
21985
21986         local max_blksz=$(do_facet ost1 \
21987                           $ZFS get -p recordsize $(facet_device ost1) |
21988                           awk '!/VALUE/{print $3}')
21989
21990         # to make life a little bit easier
21991         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21992         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21993
21994         local tf=$DIR/$tdir/$tfile
21995         touch $tf
21996         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21997
21998         # Get ZFS object id
21999         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22000         # block size change by sequential overwrite
22001         local bs
22002
22003         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22004                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22005
22006                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22007                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22008         done
22009         rm -f $tf
22010
22011         # block size change by sequential append write
22012         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22013         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22014         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22015         local count
22016
22017         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22018                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22019                         oflag=sync conv=notrunc
22020
22021                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22022                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22023                         error "blksz error, actual $blksz, " \
22024                                 "expected: 2 * $count * $PAGE_SIZE"
22025         done
22026         rm -f $tf
22027
22028         # random write
22029         touch $tf
22030         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22031         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22032
22033         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22034         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22035         [ $blksz -eq $PAGE_SIZE ] ||
22036                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22037
22038         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22039         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22040         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22041
22042         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22043         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22044         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22045 }
22046 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22047
22048 test_313() {
22049         remote_ost_nodsh && skip "remote OST with nodsh"
22050
22051         local file=$DIR/$tfile
22052
22053         rm -f $file
22054         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22055
22056         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22057         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22058         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22059                 error "write should failed"
22060         do_facet ost1 "$LCTL set_param fail_loc=0"
22061         rm -f $file
22062 }
22063 run_test 313 "io should fail after last_rcvd update fail"
22064
22065 test_314() {
22066         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22067
22068         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22069         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22070         rm -f $DIR/$tfile
22071         wait_delete_completed
22072         do_facet ost1 "$LCTL set_param fail_loc=0"
22073 }
22074 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22075
22076 test_315() { # LU-618
22077         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22078
22079         local file=$DIR/$tfile
22080         rm -f $file
22081
22082         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22083                 error "multiop file write failed"
22084         $MULTIOP $file oO_RDONLY:r4063232_c &
22085         PID=$!
22086
22087         sleep 2
22088
22089         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22090         kill -USR1 $PID
22091
22092         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22093         rm -f $file
22094 }
22095 run_test 315 "read should be accounted"
22096
22097 test_316() {
22098         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22099         large_xattr_enabled || skip_env "ea_inode feature disabled"
22100
22101         rm -rf $DIR/$tdir/d
22102         mkdir -p $DIR/$tdir/d
22103         chown nobody $DIR/$tdir/d
22104         touch $DIR/$tdir/d/file
22105
22106         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22107 }
22108 run_test 316 "lfs mv"
22109
22110 test_317() {
22111         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22112                 skip "Need MDS version at least 2.11.53"
22113         if [ "$ost1_FSTYPE" == "zfs" ]; then
22114                 skip "LU-10370: no implementation for ZFS"
22115         fi
22116
22117         local trunc_sz
22118         local grant_blk_size
22119
22120         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22121                         awk '/grant_block_size:/ { print $2; exit; }')
22122         #
22123         # Create File of size 5M. Truncate it to below size's and verify
22124         # blocks count.
22125         #
22126         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22127                 error "Create file $DIR/$tfile failed"
22128         stack_trap "rm -f $DIR/$tfile" EXIT
22129
22130         for trunc_sz in 2097152 4097 4000 509 0; do
22131                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22132                         error "truncate $tfile to $trunc_sz failed"
22133                 local sz=$(stat --format=%s $DIR/$tfile)
22134                 local blk=$(stat --format=%b $DIR/$tfile)
22135                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22136                                      grant_blk_size) * 8))
22137
22138                 if [[ $blk -ne $trunc_blk ]]; then
22139                         $(which stat) $DIR/$tfile
22140                         error "Expected Block $trunc_blk got $blk for $tfile"
22141                 fi
22142
22143                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22144                         error "Expected Size $trunc_sz got $sz for $tfile"
22145         done
22146
22147         #
22148         # sparse file test
22149         # Create file with a hole and write actual two blocks. Block count
22150         # must be 16.
22151         #
22152         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22153                 conv=fsync || error "Create file : $DIR/$tfile"
22154
22155         # Calculate the final truncate size.
22156         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22157
22158         #
22159         # truncate to size $trunc_sz bytes. Strip the last block
22160         # The block count must drop to 8
22161         #
22162         $TRUNCATE $DIR/$tfile $trunc_sz ||
22163                 error "truncate $tfile to $trunc_sz failed"
22164
22165         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22166         sz=$(stat --format=%s $DIR/$tfile)
22167         blk=$(stat --format=%b $DIR/$tfile)
22168
22169         if [[ $blk -ne $trunc_bsz ]]; then
22170                 $(which stat) $DIR/$tfile
22171                 error "Expected Block $trunc_bsz got $blk for $tfile"
22172         fi
22173
22174         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22175                 error "Expected Size $trunc_sz got $sz for $tfile"
22176 }
22177 run_test 317 "Verify blocks get correctly update after truncate"
22178
22179 test_318() {
22180         local old_max_active=$($LCTL get_param -n \
22181                             llite.*.max_read_ahead_async_active 2>/dev/null)
22182
22183         $LCTL set_param llite.*.max_read_ahead_async_active=256
22184         local max_active=$($LCTL get_param -n \
22185                            llite.*.max_read_ahead_async_active 2>/dev/null)
22186         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22187
22188         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22189                 error "set max_read_ahead_async_active should succeed"
22190
22191         $LCTL set_param llite.*.max_read_ahead_async_active=512
22192         max_active=$($LCTL get_param -n \
22193                      llite.*.max_read_ahead_async_active 2>/dev/null)
22194         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22195
22196         # restore @max_active
22197         [ $old_max_active -ne 0 ] && $LCTL set_param \
22198                 llite.*.max_read_ahead_async_active=$old_max_active
22199
22200         local old_threshold=$($LCTL get_param -n \
22201                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22202         local max_per_file_mb=$($LCTL get_param -n \
22203                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22204
22205         local invalid=$(($max_per_file_mb + 1))
22206         $LCTL set_param \
22207                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22208                         && error "set $invalid should fail"
22209
22210         local valid=$(($invalid - 1))
22211         $LCTL set_param \
22212                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22213                         error "set $valid should succeed"
22214         local threshold=$($LCTL get_param -n \
22215                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22216         [ $threshold -eq $valid ] || error \
22217                 "expect threshold $valid got $threshold"
22218         $LCTL set_param \
22219                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22220 }
22221 run_test 318 "Verify async readahead tunables"
22222
22223 test_319() {
22224         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22225
22226         local before=$(date +%s)
22227         local evict
22228         local mdir=$DIR/$tdir
22229         local file=$mdir/xxx
22230
22231         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22232         touch $file
22233
22234 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22235         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22236         $LFS mv -m1 $file &
22237
22238         sleep 1
22239         dd if=$file of=/dev/null
22240         wait
22241         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22242           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22243
22244         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22245 }
22246 run_test 319 "lost lease lock on migrate error"
22247
22248 test_398a() { # LU-4198
22249         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22250         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22251
22252         # request a new lock on client
22253         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22254
22255         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22256         local lock_count=$($LCTL get_param -n \
22257                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22258         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22259
22260         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22261
22262         # no lock cached, should use lockless IO and not enqueue new lock
22263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22264         lock_count=$($LCTL get_param -n \
22265                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22266         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22267 }
22268 run_test 398a "direct IO should cancel lock otherwise lockless"
22269
22270 test_398b() { # LU-4198
22271         which fio || skip_env "no fio installed"
22272         $LFS setstripe -c -1 $DIR/$tfile
22273
22274         local size=12
22275         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22276
22277         local njobs=4
22278         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22279         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22280                 --numjobs=$njobs --fallocate=none \
22281                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22282                 --filename=$DIR/$tfile &
22283         bg_pid=$!
22284
22285         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22286         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22287                 --numjobs=$njobs --fallocate=none \
22288                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22289                 --filename=$DIR/$tfile || true
22290         wait $bg_pid
22291
22292         rm -rf $DIR/$tfile
22293 }
22294 run_test 398b "DIO and buffer IO race"
22295
22296 test_398c() { # LU-4198
22297         which fio || skip_env "no fio installed"
22298
22299         saved_debug=$($LCTL get_param -n debug)
22300         $LCTL set_param debug=0
22301
22302         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22303         ((size /= 1024)) # by megabytes
22304         ((size /= 2)) # write half of the OST at most
22305         [ $size -gt 40 ] && size=40 #reduce test time anyway
22306
22307         $LFS setstripe -c 1 $DIR/$tfile
22308
22309         # it seems like ldiskfs reserves more space than necessary if the
22310         # writing blocks are not mapped, so it extends the file firstly
22311         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22312         cancel_lru_locks osc
22313
22314         # clear and verify rpc_stats later
22315         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22316
22317         local njobs=4
22318         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22319         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22320                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22321                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22322                 --filename=$DIR/$tfile
22323         [ $? -eq 0 ] || error "fio write error"
22324
22325         [ $($LCTL get_param -n \
22326          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22327                 error "Locks were requested while doing AIO"
22328
22329         # get the percentage of 1-page I/O
22330         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22331                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22332                 awk '{print $7}')
22333         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22334
22335         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22336         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22337                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22338                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22339                 --filename=$DIR/$tfile
22340         [ $? -eq 0 ] || error "fio mixed read write error"
22341
22342         echo "AIO with large block size ${size}M"
22343         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22344                 --numjobs=1 --fallocate=none --ioengine=libaio \
22345                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22346                 --filename=$DIR/$tfile
22347         [ $? -eq 0 ] || error "fio large block size failed"
22348
22349         rm -rf $DIR/$tfile
22350         $LCTL set_param debug="$saved_debug"
22351 }
22352 run_test 398c "run fio to test AIO"
22353
22354 test_398d() { #  LU-13846
22355         test -f aiocp || skip_env "no aiocp installed"
22356         local aio_file=$DIR/aio_file
22357
22358         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22359
22360         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22361         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22362
22363         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22364
22365         # make sure we don't crash and fail properly
22366         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22367                 error "aio not aligned with PAGE SIZE should fail"
22368
22369         rm -rf $DIR/$tfile $aio_file
22370 }
22371 run_test 398d "run aiocp to verify block size > stripe size"
22372
22373 test_fake_rw() {
22374         local read_write=$1
22375         if [ "$read_write" = "write" ]; then
22376                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22377         elif [ "$read_write" = "read" ]; then
22378                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22379         else
22380                 error "argument error"
22381         fi
22382
22383         # turn off debug for performance testing
22384         local saved_debug=$($LCTL get_param -n debug)
22385         $LCTL set_param debug=0
22386
22387         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22388
22389         # get ost1 size - $FSNAME-OST0000
22390         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22391         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22392         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22393
22394         if [ "$read_write" = "read" ]; then
22395                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22396         fi
22397
22398         local start_time=$(date +%s.%N)
22399         $dd_cmd bs=1M count=$blocks oflag=sync ||
22400                 error "real dd $read_write error"
22401         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22402
22403         if [ "$read_write" = "write" ]; then
22404                 rm -f $DIR/$tfile
22405         fi
22406
22407         # define OBD_FAIL_OST_FAKE_RW           0x238
22408         do_facet ost1 $LCTL set_param fail_loc=0x238
22409
22410         local start_time=$(date +%s.%N)
22411         $dd_cmd bs=1M count=$blocks oflag=sync ||
22412                 error "fake dd $read_write error"
22413         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22414
22415         if [ "$read_write" = "write" ]; then
22416                 # verify file size
22417                 cancel_lru_locks osc
22418                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22419                         error "$tfile size not $blocks MB"
22420         fi
22421         do_facet ost1 $LCTL set_param fail_loc=0
22422
22423         echo "fake $read_write $duration_fake vs. normal $read_write" \
22424                 "$duration in seconds"
22425         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22426                 error_not_in_vm "fake write is slower"
22427
22428         $LCTL set_param -n debug="$saved_debug"
22429         rm -f $DIR/$tfile
22430 }
22431 test_399a() { # LU-7655 for OST fake write
22432         remote_ost_nodsh && skip "remote OST with nodsh"
22433
22434         test_fake_rw write
22435 }
22436 run_test 399a "fake write should not be slower than normal write"
22437
22438 test_399b() { # LU-8726 for OST fake read
22439         remote_ost_nodsh && skip "remote OST with nodsh"
22440         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22441                 skip_env "ldiskfs only test"
22442         fi
22443
22444         test_fake_rw read
22445 }
22446 run_test 399b "fake read should not be slower than normal read"
22447
22448 test_400a() { # LU-1606, was conf-sanity test_74
22449         if ! which $CC > /dev/null 2>&1; then
22450                 skip_env "$CC is not installed"
22451         fi
22452
22453         local extra_flags=''
22454         local out=$TMP/$tfile
22455         local prefix=/usr/include/lustre
22456         local prog
22457
22458         # Oleg removes c files in his test rig so test if any c files exist
22459         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22460                 skip_env "Needed c test files are missing"
22461
22462         if ! [[ -d $prefix ]]; then
22463                 # Assume we're running in tree and fixup the include path.
22464                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22465                 extra_flags+=" -L$LUSTRE/utils/.lib"
22466         fi
22467
22468         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22469                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22470                         error "client api broken"
22471         done
22472         rm -f $out
22473 }
22474 run_test 400a "Lustre client api program can compile and link"
22475
22476 test_400b() { # LU-1606, LU-5011
22477         local header
22478         local out=$TMP/$tfile
22479         local prefix=/usr/include/linux/lustre
22480
22481         # We use a hard coded prefix so that this test will not fail
22482         # when run in tree. There are headers in lustre/include/lustre/
22483         # that are not packaged (like lustre_idl.h) and have more
22484         # complicated include dependencies (like config.h and lnet/types.h).
22485         # Since this test about correct packaging we just skip them when
22486         # they don't exist (see below) rather than try to fixup cppflags.
22487
22488         if ! which $CC > /dev/null 2>&1; then
22489                 skip_env "$CC is not installed"
22490         fi
22491
22492         for header in $prefix/*.h; do
22493                 if ! [[ -f "$header" ]]; then
22494                         continue
22495                 fi
22496
22497                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22498                         continue # lustre_ioctl.h is internal header
22499                 fi
22500
22501                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22502                         error "cannot compile '$header'"
22503         done
22504         rm -f $out
22505 }
22506 run_test 400b "packaged headers can be compiled"
22507
22508 test_401a() { #LU-7437
22509         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22510         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22511
22512         #count the number of parameters by "list_param -R"
22513         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22514         #count the number of parameters by listing proc files
22515         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22516         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22517         echo "proc_dirs='$proc_dirs'"
22518         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22519         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22520                       sort -u | wc -l)
22521
22522         [ $params -eq $procs ] ||
22523                 error "found $params parameters vs. $procs proc files"
22524
22525         # test the list_param -D option only returns directories
22526         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22527         #count the number of parameters by listing proc directories
22528         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22529                 sort -u | wc -l)
22530
22531         [ $params -eq $procs ] ||
22532                 error "found $params parameters vs. $procs proc files"
22533 }
22534 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22535
22536 test_401b() {
22537         # jobid_var may not allow arbitrary values, so use jobid_name
22538         # if available
22539         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22540                 local testname=jobid_name tmp='testing%p'
22541         else
22542                 local testname=jobid_var tmp=testing
22543         fi
22544
22545         local save=$($LCTL get_param -n $testname)
22546
22547         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22548                 error "no error returned when setting bad parameters"
22549
22550         local jobid_new=$($LCTL get_param -n foe $testname baz)
22551         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22552
22553         $LCTL set_param -n fog=bam $testname=$save bat=fog
22554         local jobid_old=$($LCTL get_param -n foe $testname bag)
22555         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22556 }
22557 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22558
22559 test_401c() {
22560         # jobid_var may not allow arbitrary values, so use jobid_name
22561         # if available
22562         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22563                 local testname=jobid_name
22564         else
22565                 local testname=jobid_var
22566         fi
22567
22568         local jobid_var_old=$($LCTL get_param -n $testname)
22569         local jobid_var_new
22570
22571         $LCTL set_param $testname= &&
22572                 error "no error returned for 'set_param a='"
22573
22574         jobid_var_new=$($LCTL get_param -n $testname)
22575         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22576                 error "$testname was changed by setting without value"
22577
22578         $LCTL set_param $testname &&
22579                 error "no error returned for 'set_param a'"
22580
22581         jobid_var_new=$($LCTL get_param -n $testname)
22582         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22583                 error "$testname was changed by setting without value"
22584 }
22585 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22586
22587 test_401d() {
22588         # jobid_var may not allow arbitrary values, so use jobid_name
22589         # if available
22590         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22591                 local testname=jobid_name new_value='foo=bar%p'
22592         else
22593                 local testname=jobid_var new_valuie=foo=bar
22594         fi
22595
22596         local jobid_var_old=$($LCTL get_param -n $testname)
22597         local jobid_var_new
22598
22599         $LCTL set_param $testname=$new_value ||
22600                 error "'set_param a=b' did not accept a value containing '='"
22601
22602         jobid_var_new=$($LCTL get_param -n $testname)
22603         [[ "$jobid_var_new" == "$new_value" ]] ||
22604                 error "'set_param a=b' failed on a value containing '='"
22605
22606         # Reset the $testname to test the other format
22607         $LCTL set_param $testname=$jobid_var_old
22608         jobid_var_new=$($LCTL get_param -n $testname)
22609         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22610                 error "failed to reset $testname"
22611
22612         $LCTL set_param $testname $new_value ||
22613                 error "'set_param a b' did not accept a value containing '='"
22614
22615         jobid_var_new=$($LCTL get_param -n $testname)
22616         [[ "$jobid_var_new" == "$new_value" ]] ||
22617                 error "'set_param a b' failed on a value containing '='"
22618
22619         $LCTL set_param $testname $jobid_var_old
22620         jobid_var_new=$($LCTL get_param -n $testname)
22621         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22622                 error "failed to reset $testname"
22623 }
22624 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22625
22626 test_402() {
22627         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22628         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22629                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22630         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22631                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22632                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22633         remote_mds_nodsh && skip "remote MDS with nodsh"
22634
22635         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22636 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22637         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22638         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22639                 echo "Touch failed - OK"
22640 }
22641 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22642
22643 test_403() {
22644         local file1=$DIR/$tfile.1
22645         local file2=$DIR/$tfile.2
22646         local tfile=$TMP/$tfile
22647
22648         rm -f $file1 $file2 $tfile
22649
22650         touch $file1
22651         ln $file1 $file2
22652
22653         # 30 sec OBD_TIMEOUT in ll_getattr()
22654         # right before populating st_nlink
22655         $LCTL set_param fail_loc=0x80001409
22656         stat -c %h $file1 > $tfile &
22657
22658         # create an alias, drop all locks and reclaim the dentry
22659         < $file2
22660         cancel_lru_locks mdc
22661         cancel_lru_locks osc
22662         sysctl -w vm.drop_caches=2
22663
22664         wait
22665
22666         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22667
22668         rm -f $tfile $file1 $file2
22669 }
22670 run_test 403 "i_nlink should not drop to zero due to aliasing"
22671
22672 test_404() { # LU-6601
22673         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22674                 skip "Need server version newer than 2.8.52"
22675         remote_mds_nodsh && skip "remote MDS with nodsh"
22676
22677         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22678                 awk '/osp .*-osc-MDT/ { print $4}')
22679
22680         local osp
22681         for osp in $mosps; do
22682                 echo "Deactivate: " $osp
22683                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22684                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22685                         awk -vp=$osp '$4 == p { print $2 }')
22686                 [ $stat = IN ] || {
22687                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22688                         error "deactivate error"
22689                 }
22690                 echo "Activate: " $osp
22691                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22692                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22693                         awk -vp=$osp '$4 == p { print $2 }')
22694                 [ $stat = UP ] || {
22695                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22696                         error "activate error"
22697                 }
22698         done
22699 }
22700 run_test 404 "validate manual {de}activated works properly for OSPs"
22701
22702 test_405() {
22703         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22704         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22705                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22706                         skip "Layout swap lock is not supported"
22707
22708         check_swap_layouts_support
22709         check_swap_layout_no_dom $DIR
22710
22711         test_mkdir $DIR/$tdir
22712         swap_lock_test -d $DIR/$tdir ||
22713                 error "One layout swap locked test failed"
22714 }
22715 run_test 405 "Various layout swap lock tests"
22716
22717 test_406() {
22718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22719         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22720         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22722         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22723                 skip "Need MDS version at least 2.8.50"
22724
22725         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22726         local test_pool=$TESTNAME
22727
22728         pool_add $test_pool || error "pool_add failed"
22729         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22730                 error "pool_add_targets failed"
22731
22732         save_layout_restore_at_exit $MOUNT
22733
22734         # parent set default stripe count only, child will stripe from both
22735         # parent and fs default
22736         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22737                 error "setstripe $MOUNT failed"
22738         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22739         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22740         for i in $(seq 10); do
22741                 local f=$DIR/$tdir/$tfile.$i
22742                 touch $f || error "touch failed"
22743                 local count=$($LFS getstripe -c $f)
22744                 [ $count -eq $OSTCOUNT ] ||
22745                         error "$f stripe count $count != $OSTCOUNT"
22746                 local offset=$($LFS getstripe -i $f)
22747                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22748                 local size=$($LFS getstripe -S $f)
22749                 [ $size -eq $((def_stripe_size * 2)) ] ||
22750                         error "$f stripe size $size != $((def_stripe_size * 2))"
22751                 local pool=$($LFS getstripe -p $f)
22752                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22753         done
22754
22755         # change fs default striping, delete parent default striping, now child
22756         # will stripe from new fs default striping only
22757         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22758                 error "change $MOUNT default stripe failed"
22759         $LFS setstripe -c 0 $DIR/$tdir ||
22760                 error "delete $tdir default stripe failed"
22761         for i in $(seq 11 20); do
22762                 local f=$DIR/$tdir/$tfile.$i
22763                 touch $f || error "touch $f failed"
22764                 local count=$($LFS getstripe -c $f)
22765                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22766                 local offset=$($LFS getstripe -i $f)
22767                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22768                 local size=$($LFS getstripe -S $f)
22769                 [ $size -eq $def_stripe_size ] ||
22770                         error "$f stripe size $size != $def_stripe_size"
22771                 local pool=$($LFS getstripe -p $f)
22772                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22773         done
22774
22775         unlinkmany $DIR/$tdir/$tfile. 1 20
22776
22777         local f=$DIR/$tdir/$tfile
22778         pool_remove_all_targets $test_pool $f
22779         pool_remove $test_pool $f
22780 }
22781 run_test 406 "DNE support fs default striping"
22782
22783 test_407() {
22784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22785         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22786                 skip "Need MDS version at least 2.8.55"
22787         remote_mds_nodsh && skip "remote MDS with nodsh"
22788
22789         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22790                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22791         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22792                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22793         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22794
22795         #define OBD_FAIL_DT_TXN_STOP    0x2019
22796         for idx in $(seq $MDSCOUNT); do
22797                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22798         done
22799         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22800         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22801                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22802         true
22803 }
22804 run_test 407 "transaction fail should cause operation fail"
22805
22806 test_408() {
22807         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22808
22809         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22810         lctl set_param fail_loc=0x8000040a
22811         # let ll_prepare_partial_page() fail
22812         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22813
22814         rm -f $DIR/$tfile
22815
22816         # create at least 100 unused inodes so that
22817         # shrink_icache_memory(0) should not return 0
22818         touch $DIR/$tfile-{0..100}
22819         rm -f $DIR/$tfile-{0..100}
22820         sync
22821
22822         echo 2 > /proc/sys/vm/drop_caches
22823 }
22824 run_test 408 "drop_caches should not hang due to page leaks"
22825
22826 test_409()
22827 {
22828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22829
22830         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22831         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22832         touch $DIR/$tdir/guard || error "(2) Fail to create"
22833
22834         local PREFIX=$(str_repeat 'A' 128)
22835         echo "Create 1K hard links start at $(date)"
22836         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22837                 error "(3) Fail to hard link"
22838
22839         echo "Links count should be right although linkEA overflow"
22840         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22841         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22842         [ $linkcount -eq 1001 ] ||
22843                 error "(5) Unexpected hard links count: $linkcount"
22844
22845         echo "List all links start at $(date)"
22846         ls -l $DIR/$tdir/foo > /dev/null ||
22847                 error "(6) Fail to list $DIR/$tdir/foo"
22848
22849         echo "Unlink hard links start at $(date)"
22850         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22851                 error "(7) Fail to unlink"
22852         echo "Unlink hard links finished at $(date)"
22853 }
22854 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22855
22856 test_410()
22857 {
22858         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22859                 skip "Need client version at least 2.9.59"
22860         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22861                 skip "Need MODULES build"
22862
22863         # Create a file, and stat it from the kernel
22864         local testfile=$DIR/$tfile
22865         touch $testfile
22866
22867         local run_id=$RANDOM
22868         local my_ino=$(stat --format "%i" $testfile)
22869
22870         # Try to insert the module. This will always fail as the
22871         # module is designed to not be inserted.
22872         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22873             &> /dev/null
22874
22875         # Anything but success is a test failure
22876         dmesg | grep -q \
22877             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22878             error "no inode match"
22879 }
22880 run_test 410 "Test inode number returned from kernel thread"
22881
22882 cleanup_test411_cgroup() {
22883         trap 0
22884         rmdir "$1"
22885 }
22886
22887 test_411() {
22888         local cg_basedir=/sys/fs/cgroup/memory
22889         # LU-9966
22890         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22891                 skip "no setup for cgroup"
22892
22893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22894                 error "test file creation failed"
22895         cancel_lru_locks osc
22896
22897         # Create a very small memory cgroup to force a slab allocation error
22898         local cgdir=$cg_basedir/osc_slab_alloc
22899         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22900         trap "cleanup_test411_cgroup $cgdir" EXIT
22901         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22902         echo 1M > $cgdir/memory.limit_in_bytes
22903
22904         # Should not LBUG, just be killed by oom-killer
22905         # dd will return 0 even allocation failure in some environment.
22906         # So don't check return value
22907         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22908         cleanup_test411_cgroup $cgdir
22909
22910         return 0
22911 }
22912 run_test 411 "Slab allocation error with cgroup does not LBUG"
22913
22914 test_412() {
22915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22916         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22917                 skip "Need server version at least 2.10.55"
22918         fi
22919
22920         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22921                 error "mkdir failed"
22922         $LFS getdirstripe $DIR/$tdir
22923         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22924         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22925                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22926         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22927         [ $stripe_count -eq 2 ] ||
22928                 error "expect 2 get $stripe_count"
22929 }
22930 run_test 412 "mkdir on specific MDTs"
22931
22932 test_qos_mkdir() {
22933         local mkdir_cmd=$1
22934         local stripe_count=$2
22935         local mdts=$(comma_list $(mdts_nodes))
22936
22937         local testdir
22938         local lmv_qos_prio_free
22939         local lmv_qos_threshold_rr
22940         local lmv_qos_maxage
22941         local lod_qos_prio_free
22942         local lod_qos_threshold_rr
22943         local lod_qos_maxage
22944         local count
22945         local i
22946
22947         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22948         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22949         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22950                 head -n1)
22951         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22952         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22953         stack_trap "$LCTL set_param \
22954                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22955         stack_trap "$LCTL set_param \
22956                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22957         stack_trap "$LCTL set_param \
22958                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22959
22960         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22961                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22962         lod_qos_prio_free=${lod_qos_prio_free%%%}
22963         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22964                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22965         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22966         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22967                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22968         stack_trap "do_nodes $mdts $LCTL set_param \
22969                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22970         stack_trap "do_nodes $mdts $LCTL set_param \
22971                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22972                 EXIT
22973         stack_trap "do_nodes $mdts $LCTL set_param \
22974                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22975
22976         echo
22977         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22978
22979         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22980         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22981
22982         testdir=$DIR/$tdir-s$stripe_count/rr
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/* |
22991                                 grep ^$((i - 1))$ | wc -l)
22992                 echo "$count directories created on MDT$((i - 1))"
22993                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22994
22995                 if [ $stripe_count -gt 1 ]; then
22996                         count=$($LFS getdirstripe $testdir/* |
22997                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22998                         echo "$count stripes created on MDT$((i - 1))"
22999                         # deviation should < 5% of average
23000                         [ $count -lt $((95 * stripe_count)) ] ||
23001                         [ $count -gt $((105 * stripe_count)) ] &&
23002                                 error "stripes are not evenly distributed"
23003                 fi
23004         done
23005
23006         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23007         do_nodes $mdts $LCTL set_param \
23008                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23009
23010         echo
23011         echo "Check for uneven MDTs: "
23012
23013         local ffree
23014         local bavail
23015         local max
23016         local min
23017         local max_index
23018         local min_index
23019         local tmp
23020
23021         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23022         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23023         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23024
23025         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23026         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23027         max_index=0
23028         min_index=0
23029         for ((i = 1; i < ${#ffree[@]}; i++)); do
23030                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23031                 if [ $tmp -gt $max ]; then
23032                         max=$tmp
23033                         max_index=$i
23034                 fi
23035                 if [ $tmp -lt $min ]; then
23036                         min=$tmp
23037                         min_index=$i
23038                 fi
23039         done
23040
23041         [ ${ffree[min_index]} -eq 0 ] &&
23042                 skip "no free files in MDT$min_index"
23043         [ ${ffree[min_index]} -gt 100000000 ] &&
23044                 skip "too much free files in MDT$min_index"
23045
23046         # Check if we need to generate uneven MDTs
23047         local threshold=50
23048         local diff=$(((max - min) * 100 / min))
23049         local value="$(generate_string 1024)"
23050
23051         while [ $diff -lt $threshold ]; do
23052                 # generate uneven MDTs, create till $threshold% diff
23053                 echo -n "weight diff=$diff% must be > $threshold% ..."
23054                 count=$((${ffree[min_index]} / 10))
23055                 # 50 sec per 10000 files in vm
23056                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23057                         skip "$count files to create"
23058                 echo "Fill MDT$min_index with $count files"
23059                 [ -d $DIR/$tdir-MDT$min_index ] ||
23060                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23061                         error "mkdir $tdir-MDT$min_index failed"
23062                 for i in $(seq $count); do
23063                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23064                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23065                                 error "create f$j_$i failed"
23066                         setfattr -n user.413b -v $value \
23067                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23068                                 error "setfattr f$j_$i failed"
23069                 done
23070
23071                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23072                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23073                 max=$(((${ffree[max_index]} >> 8) * \
23074                         (${bavail[max_index]} * bsize >> 16)))
23075                 min=$(((${ffree[min_index]} >> 8) * \
23076                         (${bavail[min_index]} * bsize >> 16)))
23077                 diff=$(((max - min) * 100 / min))
23078         done
23079
23080         echo "MDT filesfree available: ${ffree[@]}"
23081         echo "MDT blocks available: ${bavail[@]}"
23082         echo "weight diff=$diff%"
23083
23084         echo
23085         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23086
23087         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23088         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23089         # decrease statfs age, so that it can be updated in time
23090         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23091         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23092
23093         sleep 1
23094
23095         testdir=$DIR/$tdir-s$stripe_count/qos
23096
23097         for i in $(seq $((100 * MDSCOUNT))); do
23098                 eval $mkdir_cmd $testdir/subdir$i ||
23099                         error "$mkdir_cmd subdir$i failed"
23100         done
23101
23102         for i in $(seq $MDSCOUNT); do
23103                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23104                         wc -l)
23105                 echo "$count directories created on MDT$((i - 1))"
23106
23107                 if [ $stripe_count -gt 1 ]; then
23108                         count=$($LFS getdirstripe $testdir/* |
23109                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23110                         echo "$count stripes created on MDT$((i - 1))"
23111                 fi
23112         done
23113
23114         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23115         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23116
23117         # D-value should > 10% of averge
23118         [ $((max - min)) -lt 10 ] &&
23119                 error "subdirs shouldn't be evenly distributed"
23120
23121         # ditto
23122         if [ $stripe_count -gt 1 ]; then
23123                 max=$($LFS getdirstripe $testdir/* |
23124                         grep -P "^\s+$max_index\t" | wc -l)
23125                 min=$($LFS getdirstripe $testdir/* |
23126                         grep -P "^\s+$min_index\t" | wc -l)
23127                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23128                         error "stripes shouldn't be evenly distributed"|| true
23129         fi
23130 }
23131
23132 test_413a() {
23133         [ $MDSCOUNT -lt 2 ] &&
23134                 skip "We need at least 2 MDTs for this test"
23135
23136         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23137                 skip "Need server version at least 2.12.52"
23138
23139         local stripe_count
23140
23141         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23142                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23143                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23144                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23145                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23146         done
23147 }
23148 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23149
23150 test_413b() {
23151         [ $MDSCOUNT -lt 2 ] &&
23152                 skip "We need at least 2 MDTs for this test"
23153
23154         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23155                 skip "Need server version at least 2.12.52"
23156
23157         local stripe_count
23158
23159         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23160                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23161                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23162                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23163                 $LFS setdirstripe -D -c $stripe_count \
23164                         $DIR/$tdir-s$stripe_count/rr ||
23165                         error "setdirstripe failed"
23166                 $LFS setdirstripe -D -c $stripe_count \
23167                         $DIR/$tdir-s$stripe_count/qos ||
23168                         error "setdirstripe failed"
23169                 test_qos_mkdir "mkdir" $stripe_count
23170         done
23171 }
23172 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23173
23174 test_414() {
23175 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23176         $LCTL set_param fail_loc=0x80000521
23177         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23178         rm -f $DIR/$tfile
23179 }
23180 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23181
23182 test_415() {
23183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23184         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23185                 skip "Need server version at least 2.11.52"
23186
23187         # LU-11102
23188         local total
23189         local setattr_pid
23190         local start_time
23191         local end_time
23192         local duration
23193
23194         total=500
23195         # this test may be slow on ZFS
23196         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23197
23198         # though this test is designed for striped directory, let's test normal
23199         # directory too since lock is always saved as CoS lock.
23200         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23201         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23202
23203         (
23204                 while true; do
23205                         touch $DIR/$tdir
23206                 done
23207         ) &
23208         setattr_pid=$!
23209
23210         start_time=$(date +%s)
23211         for i in $(seq $total); do
23212                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23213                         > /dev/null
23214         done
23215         end_time=$(date +%s)
23216         duration=$((end_time - start_time))
23217
23218         kill -9 $setattr_pid
23219
23220         echo "rename $total files took $duration sec"
23221         [ $duration -lt 100 ] || error "rename took $duration sec"
23222 }
23223 run_test 415 "lock revoke is not missing"
23224
23225 test_416() {
23226         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23227                 skip "Need server version at least 2.11.55"
23228
23229         # define OBD_FAIL_OSD_TXN_START    0x19a
23230         do_facet mds1 lctl set_param fail_loc=0x19a
23231
23232         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23233
23234         true
23235 }
23236 run_test 416 "transaction start failure won't cause system hung"
23237
23238 cleanup_417() {
23239         trap 0
23240         do_nodes $(comma_list $(mdts_nodes)) \
23241                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23242         do_nodes $(comma_list $(mdts_nodes)) \
23243                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23244         do_nodes $(comma_list $(mdts_nodes)) \
23245                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23246 }
23247
23248 test_417() {
23249         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23250         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23251                 skip "Need MDS version at least 2.11.56"
23252
23253         trap cleanup_417 RETURN EXIT
23254
23255         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23256         do_nodes $(comma_list $(mdts_nodes)) \
23257                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23258         $LFS migrate -m 0 $DIR/$tdir.1 &&
23259                 error "migrate dir $tdir.1 should fail"
23260
23261         do_nodes $(comma_list $(mdts_nodes)) \
23262                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23263         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23264                 error "create remote dir $tdir.2 should fail"
23265
23266         do_nodes $(comma_list $(mdts_nodes)) \
23267                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23268         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23269                 error "create striped dir $tdir.3 should fail"
23270         true
23271 }
23272 run_test 417 "disable remote dir, striped dir and dir migration"
23273
23274 # Checks that the outputs of df [-i] and lfs df [-i] match
23275 #
23276 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23277 check_lfs_df() {
23278         local dir=$2
23279         local inodes
23280         local df_out
23281         local lfs_df_out
23282         local count
23283         local passed=false
23284
23285         # blocks or inodes
23286         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23287
23288         for count in {1..100}; do
23289                 cancel_lru_locks
23290                 sync; sleep 0.2
23291
23292                 # read the lines of interest
23293                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23294                         error "df $inodes $dir | tail -n +2 failed"
23295                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23296                         error "lfs df $inodes $dir | grep summary: failed"
23297
23298                 # skip first substrings of each output as they are different
23299                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23300                 # compare the two outputs
23301                 passed=true
23302                 for i in {1..5}; do
23303                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23304                 done
23305                 $passed && break
23306         done
23307
23308         if ! $passed; then
23309                 df -P $inodes $dir
23310                 echo
23311                 lfs df $inodes $dir
23312                 error "df and lfs df $1 output mismatch: "      \
23313                       "df ${inodes}: ${df_out[*]}, "            \
23314                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23315         fi
23316 }
23317
23318 test_418() {
23319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23320
23321         local dir=$DIR/$tdir
23322         local numfiles=$((RANDOM % 4096 + 2))
23323         local numblocks=$((RANDOM % 256 + 1))
23324
23325         wait_delete_completed
23326         test_mkdir $dir
23327
23328         # check block output
23329         check_lfs_df blocks $dir
23330         # check inode output
23331         check_lfs_df inodes $dir
23332
23333         # create a single file and retest
23334         echo "Creating a single file and testing"
23335         createmany -o $dir/$tfile- 1 &>/dev/null ||
23336                 error "creating 1 file in $dir failed"
23337         check_lfs_df blocks $dir
23338         check_lfs_df inodes $dir
23339
23340         # create a random number of files
23341         echo "Creating $((numfiles - 1)) files and testing"
23342         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23343                 error "creating $((numfiles - 1)) files in $dir failed"
23344
23345         # write a random number of blocks to the first test file
23346         echo "Writing $numblocks 4K blocks and testing"
23347         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23348                 count=$numblocks &>/dev/null ||
23349                 error "dd to $dir/${tfile}-0 failed"
23350
23351         # retest
23352         check_lfs_df blocks $dir
23353         check_lfs_df inodes $dir
23354
23355         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23356                 error "unlinking $numfiles files in $dir failed"
23357 }
23358 run_test 418 "df and lfs df outputs match"
23359
23360 test_419()
23361 {
23362         local dir=$DIR/$tdir
23363
23364         mkdir -p $dir
23365         touch $dir/file
23366
23367         cancel_lru_locks mdc
23368
23369         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23370         $LCTL set_param fail_loc=0x1410
23371         cat $dir/file
23372         $LCTL set_param fail_loc=0
23373         rm -rf $dir
23374 }
23375 run_test 419 "Verify open file by name doesn't crash kernel"
23376
23377 test_420()
23378 {
23379         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23380                 skip "Need MDS version at least 2.12.53"
23381
23382         local SAVE_UMASK=$(umask)
23383         local dir=$DIR/$tdir
23384         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23385
23386         mkdir -p $dir
23387         umask 0000
23388         mkdir -m03777 $dir/testdir
23389         ls -dn $dir/testdir
23390         # Need to remove trailing '.' when SELinux is enabled
23391         local dirperms=$(ls -dn $dir/testdir |
23392                          awk '{ sub(/\.$/, "", $1); print $1}')
23393         [ $dirperms == "drwxrwsrwt" ] ||
23394                 error "incorrect perms on $dir/testdir"
23395
23396         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23397                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23398         ls -n $dir/testdir/testfile
23399         local fileperms=$(ls -n $dir/testdir/testfile |
23400                           awk '{ sub(/\.$/, "", $1); print $1}')
23401         [ $fileperms == "-rwxr-xr-x" ] ||
23402                 error "incorrect perms on $dir/testdir/testfile"
23403
23404         umask $SAVE_UMASK
23405 }
23406 run_test 420 "clear SGID bit on non-directories for non-members"
23407
23408 test_421a() {
23409         local cnt
23410         local fid1
23411         local fid2
23412
23413         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23414                 skip "Need MDS version at least 2.12.54"
23415
23416         test_mkdir $DIR/$tdir
23417         createmany -o $DIR/$tdir/f 3
23418         cnt=$(ls -1 $DIR/$tdir | wc -l)
23419         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23420
23421         fid1=$(lfs path2fid $DIR/$tdir/f1)
23422         fid2=$(lfs path2fid $DIR/$tdir/f2)
23423         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23424
23425         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23426         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23427
23428         cnt=$(ls -1 $DIR/$tdir | wc -l)
23429         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23430
23431         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23432         createmany -o $DIR/$tdir/f 3
23433         cnt=$(ls -1 $DIR/$tdir | wc -l)
23434         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23435
23436         fid1=$(lfs path2fid $DIR/$tdir/f1)
23437         fid2=$(lfs path2fid $DIR/$tdir/f2)
23438         echo "remove using fsname $FSNAME"
23439         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23440
23441         cnt=$(ls -1 $DIR/$tdir | wc -l)
23442         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23443 }
23444 run_test 421a "simple rm by fid"
23445
23446 test_421b() {
23447         local cnt
23448         local FID1
23449         local FID2
23450
23451         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23452                 skip "Need MDS version at least 2.12.54"
23453
23454         test_mkdir $DIR/$tdir
23455         createmany -o $DIR/$tdir/f 3
23456         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23457         MULTIPID=$!
23458
23459         FID1=$(lfs path2fid $DIR/$tdir/f1)
23460         FID2=$(lfs path2fid $DIR/$tdir/f2)
23461         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23462
23463         kill -USR1 $MULTIPID
23464         wait
23465
23466         cnt=$(ls $DIR/$tdir | wc -l)
23467         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23468 }
23469 run_test 421b "rm by fid on open file"
23470
23471 test_421c() {
23472         local cnt
23473         local FIDS
23474
23475         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23476                 skip "Need MDS version at least 2.12.54"
23477
23478         test_mkdir $DIR/$tdir
23479         createmany -o $DIR/$tdir/f 3
23480         touch $DIR/$tdir/$tfile
23481         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23482         cnt=$(ls -1 $DIR/$tdir | wc -l)
23483         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23484
23485         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23486         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23487
23488         cnt=$(ls $DIR/$tdir | wc -l)
23489         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23490 }
23491 run_test 421c "rm by fid against hardlinked files"
23492
23493 test_421d() {
23494         local cnt
23495         local FIDS
23496
23497         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23498                 skip "Need MDS version at least 2.12.54"
23499
23500         test_mkdir $DIR/$tdir
23501         createmany -o $DIR/$tdir/f 4097
23502         cnt=$(ls -1 $DIR/$tdir | wc -l)
23503         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23504
23505         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23506         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23507
23508         cnt=$(ls $DIR/$tdir | wc -l)
23509         rm -rf $DIR/$tdir
23510         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23511 }
23512 run_test 421d "rmfid en masse"
23513
23514 test_421e() {
23515         local cnt
23516         local FID
23517
23518         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23519         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23520                 skip "Need MDS version at least 2.12.54"
23521
23522         mkdir -p $DIR/$tdir
23523         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23524         createmany -o $DIR/$tdir/striped_dir/f 512
23525         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23526         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23527
23528         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23529                 sed "s/[/][^:]*://g")
23530         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23531
23532         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23533         rm -rf $DIR/$tdir
23534         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23535 }
23536 run_test 421e "rmfid in DNE"
23537
23538 test_421f() {
23539         local cnt
23540         local FID
23541
23542         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23543                 skip "Need MDS version at least 2.12.54"
23544
23545         test_mkdir $DIR/$tdir
23546         touch $DIR/$tdir/f
23547         cnt=$(ls -1 $DIR/$tdir | wc -l)
23548         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23549
23550         FID=$(lfs path2fid $DIR/$tdir/f)
23551         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23552         # rmfid should fail
23553         cnt=$(ls -1 $DIR/$tdir | wc -l)
23554         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23555
23556         chmod a+rw $DIR/$tdir
23557         ls -la $DIR/$tdir
23558         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23559         # rmfid should fail
23560         cnt=$(ls -1 $DIR/$tdir | wc -l)
23561         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23562
23563         rm -f $DIR/$tdir/f
23564         $RUNAS touch $DIR/$tdir/f
23565         FID=$(lfs path2fid $DIR/$tdir/f)
23566         echo "rmfid as root"
23567         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23568         cnt=$(ls -1 $DIR/$tdir | wc -l)
23569         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23570
23571         rm -f $DIR/$tdir/f
23572         $RUNAS touch $DIR/$tdir/f
23573         cnt=$(ls -1 $DIR/$tdir | wc -l)
23574         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23575         FID=$(lfs path2fid $DIR/$tdir/f)
23576         # rmfid w/o user_fid2path mount option should fail
23577         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23578         cnt=$(ls -1 $DIR/$tdir | wc -l)
23579         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23580
23581         umount_client $MOUNT || error "failed to umount client"
23582         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23583                 error "failed to mount client'"
23584
23585         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23586         # rmfid should succeed
23587         cnt=$(ls -1 $DIR/$tdir | wc -l)
23588         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23589
23590         # rmfid shouldn't allow to remove files due to dir's permission
23591         chmod a+rwx $DIR/$tdir
23592         touch $DIR/$tdir/f
23593         ls -la $DIR/$tdir
23594         FID=$(lfs path2fid $DIR/$tdir/f)
23595         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23596
23597         umount_client $MOUNT || error "failed to umount client"
23598         mount_client $MOUNT "$MOUNT_OPTS" ||
23599                 error "failed to mount client'"
23600
23601 }
23602 run_test 421f "rmfid checks permissions"
23603
23604 test_421g() {
23605         local cnt
23606         local FIDS
23607
23608         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23609         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23610                 skip "Need MDS version at least 2.12.54"
23611
23612         mkdir -p $DIR/$tdir
23613         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23614         createmany -o $DIR/$tdir/striped_dir/f 512
23615         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23616         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23617
23618         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23619                 sed "s/[/][^:]*://g")
23620
23621         rm -f $DIR/$tdir/striped_dir/f1*
23622         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23623         removed=$((512 - cnt))
23624
23625         # few files have been just removed, so we expect
23626         # rmfid to fail on their fids
23627         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23628         [ $removed != $errors ] && error "$errors != $removed"
23629
23630         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23631         rm -rf $DIR/$tdir
23632         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23633 }
23634 run_test 421g "rmfid to return errors properly"
23635
23636 test_422() {
23637         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23638         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23639         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23640         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23641         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23642
23643         local amc=$(at_max_get client)
23644         local amo=$(at_max_get mds1)
23645         local timeout=`lctl get_param -n timeout`
23646
23647         at_max_set 0 client
23648         at_max_set 0 mds1
23649
23650 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23651         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23652                         fail_val=$(((2*timeout + 10)*1000))
23653         touch $DIR/$tdir/d3/file &
23654         sleep 2
23655 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23656         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23657                         fail_val=$((2*timeout + 5))
23658         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23659         local pid=$!
23660         sleep 1
23661         kill -9 $pid
23662         sleep $((2 * timeout))
23663         echo kill $pid
23664         kill -9 $pid
23665         lctl mark touch
23666         touch $DIR/$tdir/d2/file3
23667         touch $DIR/$tdir/d2/file4
23668         touch $DIR/$tdir/d2/file5
23669
23670         wait
23671         at_max_set $amc client
23672         at_max_set $amo mds1
23673
23674         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23675         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23676                 error "Watchdog is always throttled"
23677 }
23678 run_test 422 "kill a process with RPC in progress"
23679
23680 stat_test() {
23681     df -h $MOUNT &
23682     df -h $MOUNT &
23683     df -h $MOUNT &
23684     df -h $MOUNT &
23685     df -h $MOUNT &
23686     df -h $MOUNT &
23687 }
23688
23689 test_423() {
23690     local _stats
23691     # ensure statfs cache is expired
23692     sleep 2;
23693
23694     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23695     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23696
23697     return 0
23698 }
23699 run_test 423 "statfs should return a right data"
23700
23701 test_424() {
23702 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23703         $LCTL set_param fail_loc=0x80000522
23704         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23705         rm -f $DIR/$tfile
23706 }
23707 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23708
23709 test_425() {
23710         test_mkdir -c -1 $DIR/$tdir
23711         $LFS setstripe -c -1 $DIR/$tdir
23712
23713         lru_resize_disable "" 100
23714         stack_trap "lru_resize_enable" EXIT
23715
23716         sleep 5
23717
23718         for i in $(seq $((MDSCOUNT * 125))); do
23719                 local t=$DIR/$tdir/$tfile_$i
23720
23721                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23722                         error_noexit "Create file $t"
23723         done
23724         stack_trap "rm -rf $DIR/$tdir" EXIT
23725
23726         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23727                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23728                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23729
23730                 [ $lock_count -le $lru_size ] ||
23731                         error "osc lock count $lock_count > lru size $lru_size"
23732         done
23733
23734         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23735                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23736                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23737
23738                 [ $lock_count -le $lru_size ] ||
23739                         error "mdc lock count $lock_count > lru size $lru_size"
23740         done
23741 }
23742 run_test 425 "lock count should not exceed lru size"
23743
23744 test_426() {
23745         splice-test -r $DIR/$tfile
23746         splice-test -rd $DIR/$tfile
23747         splice-test $DIR/$tfile
23748         splice-test -d $DIR/$tfile
23749 }
23750 run_test 426 "splice test on Lustre"
23751
23752 lseek_test_430() {
23753         local offset
23754         local file=$1
23755
23756         # data at [200K, 400K)
23757         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23758                 error "256K->512K dd fails"
23759         # data at [2M, 3M)
23760         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23761                 error "2M->3M dd fails"
23762         # data at [4M, 5M)
23763         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23764                 error "4M->5M dd fails"
23765         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23766         # start at first component hole #1
23767         printf "Seeking hole from 1000 ... "
23768         offset=$(lseek_test -l 1000 $file)
23769         echo $offset
23770         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23771         printf "Seeking data from 1000 ... "
23772         offset=$(lseek_test -d 1000 $file)
23773         echo $offset
23774         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23775
23776         # start at first component data block
23777         printf "Seeking hole from 300000 ... "
23778         offset=$(lseek_test -l 300000 $file)
23779         echo $offset
23780         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23781         printf "Seeking data from 300000 ... "
23782         offset=$(lseek_test -d 300000 $file)
23783         echo $offset
23784         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23785
23786         # start at the first component but beyond end of object size
23787         printf "Seeking hole from 1000000 ... "
23788         offset=$(lseek_test -l 1000000 $file)
23789         echo $offset
23790         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23791         printf "Seeking data from 1000000 ... "
23792         offset=$(lseek_test -d 1000000 $file)
23793         echo $offset
23794         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23795
23796         # start at second component stripe 2 (empty file)
23797         printf "Seeking hole from 1500000 ... "
23798         offset=$(lseek_test -l 1500000 $file)
23799         echo $offset
23800         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23801         printf "Seeking data from 1500000 ... "
23802         offset=$(lseek_test -d 1500000 $file)
23803         echo $offset
23804         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23805
23806         # start at second component stripe 1 (all data)
23807         printf "Seeking hole from 3000000 ... "
23808         offset=$(lseek_test -l 3000000 $file)
23809         echo $offset
23810         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23811         printf "Seeking data from 3000000 ... "
23812         offset=$(lseek_test -d 3000000 $file)
23813         echo $offset
23814         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23815
23816         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23817                 error "2nd dd fails"
23818         echo "Add data block at 640K...1280K"
23819
23820         # start at before new data block, in hole
23821         printf "Seeking hole from 600000 ... "
23822         offset=$(lseek_test -l 600000 $file)
23823         echo $offset
23824         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23825         printf "Seeking data from 600000 ... "
23826         offset=$(lseek_test -d 600000 $file)
23827         echo $offset
23828         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23829
23830         # start at the first component new data block
23831         printf "Seeking hole from 1000000 ... "
23832         offset=$(lseek_test -l 1000000 $file)
23833         echo $offset
23834         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23835         printf "Seeking data from 1000000 ... "
23836         offset=$(lseek_test -d 1000000 $file)
23837         echo $offset
23838         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23839
23840         # start at second component stripe 2, new data
23841         printf "Seeking hole from 1200000 ... "
23842         offset=$(lseek_test -l 1200000 $file)
23843         echo $offset
23844         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23845         printf "Seeking data from 1200000 ... "
23846         offset=$(lseek_test -d 1200000 $file)
23847         echo $offset
23848         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23849
23850         # start beyond file end
23851         printf "Using offset > filesize ... "
23852         lseek_test -l 4000000 $file && error "lseek should fail"
23853         printf "Using offset > filesize ... "
23854         lseek_test -d 4000000 $file && error "lseek should fail"
23855
23856         printf "Done\n\n"
23857 }
23858
23859 test_430a() {
23860         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23861                 skip "MDT does not support SEEK_HOLE"
23862
23863         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23864                 skip "OST does not support SEEK_HOLE"
23865
23866         local file=$DIR/$tdir/$tfile
23867
23868         mkdir -p $DIR/$tdir
23869
23870         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23871         # OST stripe #1 will have continuous data at [1M, 3M)
23872         # OST stripe #2 is empty
23873         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23874         lseek_test_430 $file
23875         rm $file
23876         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23877         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23878         lseek_test_430 $file
23879         rm $file
23880         $LFS setstripe -c2 -S 512K $file
23881         echo "Two stripes, stripe size 512K"
23882         lseek_test_430 $file
23883         rm $file
23884         # FLR with stale mirror
23885         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23886                        -N -c2 -S 1M $file
23887         echo "Mirrored file:"
23888         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23889         echo "Plain 2 stripes 1M"
23890         lseek_test_430 $file
23891         rm $file
23892 }
23893 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23894
23895 test_430b() {
23896         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23897                 skip "OST does not support SEEK_HOLE"
23898
23899         local offset
23900         local file=$DIR/$tdir/$tfile
23901
23902         mkdir -p $DIR/$tdir
23903         # Empty layout lseek should fail
23904         $MCREATE $file
23905         # seek from 0
23906         printf "Seeking hole from 0 ... "
23907         lseek_test -l 0 $file && error "lseek should fail"
23908         printf "Seeking data from 0 ... "
23909         lseek_test -d 0 $file && error "lseek should fail"
23910         rm $file
23911
23912         # 1M-hole file
23913         $LFS setstripe -E 1M -c2 -E eof $file
23914         $TRUNCATE $file 1048576
23915         printf "Seeking hole from 1000000 ... "
23916         offset=$(lseek_test -l 1000000 $file)
23917         echo $offset
23918         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23919         printf "Seeking data from 1000000 ... "
23920         lseek_test -d 1000000 $file && error "lseek should fail"
23921         # full first component, non-inited second one
23922         dd if=/dev/urandom of=$file bs=1M count=1
23923         printf "Seeking hole from 1000000 ... "
23924         offset=$(lseek_test -l 1000000 $file)
23925         echo $offset
23926         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23927         printf "Seeking hole from 1048576 ... "
23928         lseek_test -l 1048576 $file && error "lseek should fail"
23929         # init second component and truncate back
23930         echo "123" >> $file
23931         $TRUNCATE $file 1048576
23932         ls -lia $file
23933         printf "Seeking hole from 1000000 ... "
23934         offset=$(lseek_test -l 1000000 $file)
23935         echo $offset
23936         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23937         printf "Seeking hole from 1048576 ... "
23938         lseek_test -l 1048576 $file && error "lseek should fail"
23939         # boundary checks for big values
23940         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
23941         offset=$(lseek_test -d 0 $file.10g)
23942         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
23943         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
23944         offset=$(lseek_test -d 0 $file.100g)
23945         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
23946         return 0
23947 }
23948 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
23949
23950 test_430c() {
23951         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23952                 skip "OST does not support SEEK_HOLE"
23953
23954         local file=$DIR/$tdir/$tfile
23955         local start
23956
23957         mkdir -p $DIR/$tdir
23958         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
23959
23960         # cp version 8.33+ prefers lseek over fiemap
23961         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
23962                 start=$SECONDS
23963                 time cp $file /dev/null
23964                 (( SECONDS - start < 5 )) ||
23965                         error "cp: too long runtime $((SECONDS - start))"
23966
23967         fi
23968         # tar version 1.29+ supports SEEK_HOLE/DATA
23969         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
23970                 start=$SECONDS
23971                 time tar cS $file - | cat > /dev/null
23972                 (( SECONDS - start < 5 )) ||
23973                         error "tar: too long runtime $((SECONDS - start))"
23974         fi
23975 }
23976 run_test 430c "lseek: external tools check"
23977
23978 prep_801() {
23979         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23980         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23981                 skip "Need server version at least 2.9.55"
23982
23983         start_full_debug_logging
23984 }
23985
23986 post_801() {
23987         stop_full_debug_logging
23988 }
23989
23990 barrier_stat() {
23991         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23992                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23993                            awk '/The barrier for/ { print $7 }')
23994                 echo $st
23995         else
23996                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23997                 echo \'$st\'
23998         fi
23999 }
24000
24001 barrier_expired() {
24002         local expired
24003
24004         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24005                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24006                           awk '/will be expired/ { print $7 }')
24007         else
24008                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24009         fi
24010
24011         echo $expired
24012 }
24013
24014 test_801a() {
24015         prep_801
24016
24017         echo "Start barrier_freeze at: $(date)"
24018         #define OBD_FAIL_BARRIER_DELAY          0x2202
24019         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24020         # Do not reduce barrier time - See LU-11873
24021         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24022
24023         sleep 2
24024         local b_status=$(barrier_stat)
24025         echo "Got barrier status at: $(date)"
24026         [ "$b_status" = "'freezing_p1'" ] ||
24027                 error "(1) unexpected barrier status $b_status"
24028
24029         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24030         wait
24031         b_status=$(barrier_stat)
24032         [ "$b_status" = "'frozen'" ] ||
24033                 error "(2) unexpected barrier status $b_status"
24034
24035         local expired=$(barrier_expired)
24036         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24037         sleep $((expired + 3))
24038
24039         b_status=$(barrier_stat)
24040         [ "$b_status" = "'expired'" ] ||
24041                 error "(3) unexpected barrier status $b_status"
24042
24043         # Do not reduce barrier time - See LU-11873
24044         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24045                 error "(4) fail to freeze barrier"
24046
24047         b_status=$(barrier_stat)
24048         [ "$b_status" = "'frozen'" ] ||
24049                 error "(5) unexpected barrier status $b_status"
24050
24051         echo "Start barrier_thaw at: $(date)"
24052         #define OBD_FAIL_BARRIER_DELAY          0x2202
24053         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24054         do_facet mgs $LCTL barrier_thaw $FSNAME &
24055
24056         sleep 2
24057         b_status=$(barrier_stat)
24058         echo "Got barrier status at: $(date)"
24059         [ "$b_status" = "'thawing'" ] ||
24060                 error "(6) unexpected barrier status $b_status"
24061
24062         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24063         wait
24064         b_status=$(barrier_stat)
24065         [ "$b_status" = "'thawed'" ] ||
24066                 error "(7) unexpected barrier status $b_status"
24067
24068         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24069         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24070         do_facet mgs $LCTL barrier_freeze $FSNAME
24071
24072         b_status=$(barrier_stat)
24073         [ "$b_status" = "'failed'" ] ||
24074                 error "(8) unexpected barrier status $b_status"
24075
24076         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24077         do_facet mgs $LCTL barrier_thaw $FSNAME
24078
24079         post_801
24080 }
24081 run_test 801a "write barrier user interfaces and stat machine"
24082
24083 test_801b() {
24084         prep_801
24085
24086         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24087         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24088         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24089         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24090         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24091
24092         cancel_lru_locks mdc
24093
24094         # 180 seconds should be long enough
24095         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24096
24097         local b_status=$(barrier_stat)
24098         [ "$b_status" = "'frozen'" ] ||
24099                 error "(6) unexpected barrier status $b_status"
24100
24101         mkdir $DIR/$tdir/d0/d10 &
24102         mkdir_pid=$!
24103
24104         touch $DIR/$tdir/d1/f13 &
24105         touch_pid=$!
24106
24107         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24108         ln_pid=$!
24109
24110         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24111         mv_pid=$!
24112
24113         rm -f $DIR/$tdir/d4/f12 &
24114         rm_pid=$!
24115
24116         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24117
24118         # To guarantee taht the 'stat' is not blocked
24119         b_status=$(barrier_stat)
24120         [ "$b_status" = "'frozen'" ] ||
24121                 error "(8) unexpected barrier status $b_status"
24122
24123         # let above commands to run at background
24124         sleep 5
24125
24126         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24127         ps -p $touch_pid || error "(10) touch should be blocked"
24128         ps -p $ln_pid || error "(11) link should be blocked"
24129         ps -p $mv_pid || error "(12) rename should be blocked"
24130         ps -p $rm_pid || error "(13) unlink should be blocked"
24131
24132         b_status=$(barrier_stat)
24133         [ "$b_status" = "'frozen'" ] ||
24134                 error "(14) unexpected barrier status $b_status"
24135
24136         do_facet mgs $LCTL barrier_thaw $FSNAME
24137         b_status=$(barrier_stat)
24138         [ "$b_status" = "'thawed'" ] ||
24139                 error "(15) unexpected barrier status $b_status"
24140
24141         wait $mkdir_pid || error "(16) mkdir should succeed"
24142         wait $touch_pid || error "(17) touch should succeed"
24143         wait $ln_pid || error "(18) link should succeed"
24144         wait $mv_pid || error "(19) rename should succeed"
24145         wait $rm_pid || error "(20) unlink should succeed"
24146
24147         post_801
24148 }
24149 run_test 801b "modification will be blocked by write barrier"
24150
24151 test_801c() {
24152         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24153
24154         prep_801
24155
24156         stop mds2 || error "(1) Fail to stop mds2"
24157
24158         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24159
24160         local b_status=$(barrier_stat)
24161         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24162                 do_facet mgs $LCTL barrier_thaw $FSNAME
24163                 error "(2) unexpected barrier status $b_status"
24164         }
24165
24166         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24167                 error "(3) Fail to rescan barrier bitmap"
24168
24169         # Do not reduce barrier time - See LU-11873
24170         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24171
24172         b_status=$(barrier_stat)
24173         [ "$b_status" = "'frozen'" ] ||
24174                 error "(4) unexpected barrier status $b_status"
24175
24176         do_facet mgs $LCTL barrier_thaw $FSNAME
24177         b_status=$(barrier_stat)
24178         [ "$b_status" = "'thawed'" ] ||
24179                 error "(5) unexpected barrier status $b_status"
24180
24181         local devname=$(mdsdevname 2)
24182
24183         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24184
24185         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24186                 error "(7) Fail to rescan barrier bitmap"
24187
24188         post_801
24189 }
24190 run_test 801c "rescan barrier bitmap"
24191
24192 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24193 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24194 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24195 saved_MOUNT_OPTS=$MOUNT_OPTS
24196
24197 cleanup_802a() {
24198         trap 0
24199
24200         stopall
24201         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24202         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24203         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24204         MOUNT_OPTS=$saved_MOUNT_OPTS
24205         setupall
24206 }
24207
24208 test_802a() {
24209         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24210         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24211         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24212                 skip "Need server version at least 2.9.55"
24213
24214         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24215
24216         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24217
24218         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24219                 error "(2) Fail to copy"
24220
24221         trap cleanup_802a EXIT
24222
24223         # sync by force before remount as readonly
24224         sync; sync_all_data; sleep 3; sync_all_data
24225
24226         stopall
24227
24228         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24229         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24230         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24231
24232         echo "Mount the server as read only"
24233         setupall server_only || error "(3) Fail to start servers"
24234
24235         echo "Mount client without ro should fail"
24236         mount_client $MOUNT &&
24237                 error "(4) Mount client without 'ro' should fail"
24238
24239         echo "Mount client with ro should succeed"
24240         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24241         mount_client $MOUNT ||
24242                 error "(5) Mount client with 'ro' should succeed"
24243
24244         echo "Modify should be refused"
24245         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24246
24247         echo "Read should be allowed"
24248         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24249                 error "(7) Read should succeed under ro mode"
24250
24251         cleanup_802a
24252 }
24253 run_test 802a "simulate readonly device"
24254
24255 test_802b() {
24256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24257         remote_mds_nodsh && skip "remote MDS with nodsh"
24258
24259         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24260                 skip "readonly option not available"
24261
24262         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24263
24264         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24265                 error "(2) Fail to copy"
24266
24267         # write back all cached data before setting MDT to readonly
24268         cancel_lru_locks
24269         sync_all_data
24270
24271         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24272         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24273
24274         echo "Modify should be refused"
24275         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24276
24277         echo "Read should be allowed"
24278         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24279                 error "(7) Read should succeed under ro mode"
24280
24281         # disable readonly
24282         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24283 }
24284 run_test 802b "be able to set MDTs to readonly"
24285
24286 test_803a() {
24287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24288         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24289                 skip "MDS needs to be newer than 2.10.54"
24290
24291         mkdir -p $DIR/$tdir
24292         # Create some objects on all MDTs to trigger related logs objects
24293         for idx in $(seq $MDSCOUNT); do
24294                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24295                         $DIR/$tdir/dir${idx} ||
24296                         error "Fail to create $DIR/$tdir/dir${idx}"
24297         done
24298
24299         sync; sleep 3
24300         wait_delete_completed # ensure old test cleanups are finished
24301         echo "before create:"
24302         $LFS df -i $MOUNT
24303         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24304
24305         for i in {1..10}; do
24306                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24307                         error "Fail to create $DIR/$tdir/foo$i"
24308         done
24309
24310         sync; sleep 3
24311         echo "after create:"
24312         $LFS df -i $MOUNT
24313         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24314
24315         # allow for an llog to be cleaned up during the test
24316         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24317                 error "before ($before_used) + 10 > after ($after_used)"
24318
24319         for i in {1..10}; do
24320                 rm -rf $DIR/$tdir/foo$i ||
24321                         error "Fail to remove $DIR/$tdir/foo$i"
24322         done
24323
24324         sleep 3 # avoid MDT return cached statfs
24325         wait_delete_completed
24326         echo "after unlink:"
24327         $LFS df -i $MOUNT
24328         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24329
24330         # allow for an llog to be created during the test
24331         [ $after_used -le $((before_used + 1)) ] ||
24332                 error "after ($after_used) > before ($before_used) + 1"
24333 }
24334 run_test 803a "verify agent object for remote object"
24335
24336 test_803b() {
24337         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24338         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24339                 skip "MDS needs to be newer than 2.13.56"
24340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24341
24342         for i in $(seq 0 $((MDSCOUNT - 1))); do
24343                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24344         done
24345
24346         local before=0
24347         local after=0
24348
24349         local tmp
24350
24351         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24352         for i in $(seq 0 $((MDSCOUNT - 1))); do
24353                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24354                         awk '/getattr/ { print $2 }')
24355                 before=$((before + tmp))
24356         done
24357         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24358         for i in $(seq 0 $((MDSCOUNT - 1))); do
24359                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24360                         awk '/getattr/ { print $2 }')
24361                 after=$((after + tmp))
24362         done
24363
24364         [ $before -eq $after ] || error "getattr count $before != $after"
24365 }
24366 run_test 803b "remote object can getattr from cache"
24367
24368 test_804() {
24369         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24370         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24371                 skip "MDS needs to be newer than 2.10.54"
24372         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24373
24374         mkdir -p $DIR/$tdir
24375         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24376                 error "Fail to create $DIR/$tdir/dir0"
24377
24378         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24379         local dev=$(mdsdevname 2)
24380
24381         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24382                 grep ${fid} || error "NOT found agent entry for dir0"
24383
24384         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24385                 error "Fail to create $DIR/$tdir/dir1"
24386
24387         touch $DIR/$tdir/dir1/foo0 ||
24388                 error "Fail to create $DIR/$tdir/dir1/foo0"
24389         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24390         local rc=0
24391
24392         for idx in $(seq $MDSCOUNT); do
24393                 dev=$(mdsdevname $idx)
24394                 do_facet mds${idx} \
24395                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24396                         grep ${fid} && rc=$idx
24397         done
24398
24399         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24400                 error "Fail to rename foo0 to foo1"
24401         if [ $rc -eq 0 ]; then
24402                 for idx in $(seq $MDSCOUNT); do
24403                         dev=$(mdsdevname $idx)
24404                         do_facet mds${idx} \
24405                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24406                         grep ${fid} && rc=$idx
24407                 done
24408         fi
24409
24410         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24411                 error "Fail to rename foo1 to foo2"
24412         if [ $rc -eq 0 ]; then
24413                 for idx in $(seq $MDSCOUNT); do
24414                         dev=$(mdsdevname $idx)
24415                         do_facet mds${idx} \
24416                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24417                         grep ${fid} && rc=$idx
24418                 done
24419         fi
24420
24421         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24422
24423         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24424                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24425         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24426                 error "Fail to rename foo2 to foo0"
24427         unlink $DIR/$tdir/dir1/foo0 ||
24428                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24429         rm -rf $DIR/$tdir/dir0 ||
24430                 error "Fail to rm $DIR/$tdir/dir0"
24431
24432         for idx in $(seq $MDSCOUNT); do
24433                 dev=$(mdsdevname $idx)
24434                 rc=0
24435
24436                 stop mds${idx}
24437                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24438                         rc=$?
24439                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24440                         error "mount mds$idx failed"
24441                 df $MOUNT > /dev/null 2>&1
24442
24443                 # e2fsck should not return error
24444                 [ $rc -eq 0 ] ||
24445                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24446         done
24447 }
24448 run_test 804 "verify agent entry for remote entry"
24449
24450 cleanup_805() {
24451         do_facet $SINGLEMDS zfs set quota=$old $fsset
24452         unlinkmany $DIR/$tdir/f- 1000000
24453         trap 0
24454 }
24455
24456 test_805() {
24457         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24458         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24459         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24460                 skip "netfree not implemented before 0.7"
24461         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24462                 skip "Need MDS version at least 2.10.57"
24463
24464         local fsset
24465         local freekb
24466         local usedkb
24467         local old
24468         local quota
24469         local pref="osd-zfs.$FSNAME-MDT0000."
24470
24471         # limit available space on MDS dataset to meet nospace issue
24472         # quickly. then ZFS 0.7.2 can use reserved space if asked
24473         # properly (using netfree flag in osd_declare_destroy()
24474         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24475         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24476                 gawk '{print $3}')
24477         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24478         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24479         let "usedkb=usedkb-freekb"
24480         let "freekb=freekb/2"
24481         if let "freekb > 5000"; then
24482                 let "freekb=5000"
24483         fi
24484         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24485         trap cleanup_805 EXIT
24486         mkdir $DIR/$tdir
24487         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24488                 error "Can't set PFL layout"
24489         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24490         rm -rf $DIR/$tdir || error "not able to remove"
24491         do_facet $SINGLEMDS zfs set quota=$old $fsset
24492         trap 0
24493 }
24494 run_test 805 "ZFS can remove from full fs"
24495
24496 # Size-on-MDS test
24497 check_lsom_data()
24498 {
24499         local file=$1
24500         local size=$($LFS getsom -s $file)
24501         local expect=$(stat -c %s $file)
24502
24503         [[ $size == $expect ]] ||
24504                 error "$file expected size: $expect, got: $size"
24505
24506         local blocks=$($LFS getsom -b $file)
24507         expect=$(stat -c %b $file)
24508         [[ $blocks == $expect ]] ||
24509                 error "$file expected blocks: $expect, got: $blocks"
24510 }
24511
24512 check_lsom_size()
24513 {
24514         local size=$($LFS getsom -s $1)
24515         local expect=$2
24516
24517         [[ $size == $expect ]] ||
24518                 error "$file expected size: $expect, got: $size"
24519 }
24520
24521 test_806() {
24522         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24523                 skip "Need MDS version at least 2.11.52"
24524
24525         local bs=1048576
24526
24527         touch $DIR/$tfile || error "touch $tfile failed"
24528
24529         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24530         save_lustre_params client "llite.*.xattr_cache" > $save
24531         lctl set_param llite.*.xattr_cache=0
24532         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24533
24534         # single-threaded write
24535         echo "Test SOM for single-threaded write"
24536         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24537                 error "write $tfile failed"
24538         check_lsom_size $DIR/$tfile $bs
24539
24540         local num=32
24541         local size=$(($num * $bs))
24542         local offset=0
24543         local i
24544
24545         echo "Test SOM for single client multi-threaded($num) write"
24546         $TRUNCATE $DIR/$tfile 0
24547         for ((i = 0; i < $num; i++)); do
24548                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24549                 local pids[$i]=$!
24550                 offset=$((offset + $bs))
24551         done
24552         for (( i=0; i < $num; i++ )); do
24553                 wait ${pids[$i]}
24554         done
24555         check_lsom_size $DIR/$tfile $size
24556
24557         $TRUNCATE $DIR/$tfile 0
24558         for ((i = 0; i < $num; i++)); do
24559                 offset=$((offset - $bs))
24560                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24561                 local pids[$i]=$!
24562         done
24563         for (( i=0; i < $num; i++ )); do
24564                 wait ${pids[$i]}
24565         done
24566         check_lsom_size $DIR/$tfile $size
24567
24568         # multi-client writes
24569         num=$(get_node_count ${CLIENTS//,/ })
24570         size=$(($num * $bs))
24571         offset=0
24572         i=0
24573
24574         echo "Test SOM for multi-client ($num) writes"
24575         $TRUNCATE $DIR/$tfile 0
24576         for client in ${CLIENTS//,/ }; do
24577                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24578                 local pids[$i]=$!
24579                 i=$((i + 1))
24580                 offset=$((offset + $bs))
24581         done
24582         for (( i=0; i < $num; i++ )); do
24583                 wait ${pids[$i]}
24584         done
24585         check_lsom_size $DIR/$tfile $offset
24586
24587         i=0
24588         $TRUNCATE $DIR/$tfile 0
24589         for client in ${CLIENTS//,/ }; do
24590                 offset=$((offset - $bs))
24591                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24592                 local pids[$i]=$!
24593                 i=$((i + 1))
24594         done
24595         for (( i=0; i < $num; i++ )); do
24596                 wait ${pids[$i]}
24597         done
24598         check_lsom_size $DIR/$tfile $size
24599
24600         # verify truncate
24601         echo "Test SOM for truncate"
24602         $TRUNCATE $DIR/$tfile 1048576
24603         check_lsom_size $DIR/$tfile 1048576
24604         $TRUNCATE $DIR/$tfile 1234
24605         check_lsom_size $DIR/$tfile 1234
24606
24607         # verify SOM blocks count
24608         echo "Verify SOM block count"
24609         $TRUNCATE $DIR/$tfile 0
24610         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24611                 error "failed to write file $tfile"
24612         check_lsom_data $DIR/$tfile
24613 }
24614 run_test 806 "Verify Lazy Size on MDS"
24615
24616 test_807() {
24617         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24618         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24619                 skip "Need MDS version at least 2.11.52"
24620
24621         # Registration step
24622         changelog_register || error "changelog_register failed"
24623         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24624         changelog_users $SINGLEMDS | grep -q $cl_user ||
24625                 error "User $cl_user not found in changelog_users"
24626
24627         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24628         save_lustre_params client "llite.*.xattr_cache" > $save
24629         lctl set_param llite.*.xattr_cache=0
24630         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24631
24632         rm -rf $DIR/$tdir || error "rm $tdir failed"
24633         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24634         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24635         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24636         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24637                 error "truncate $tdir/trunc failed"
24638
24639         local bs=1048576
24640         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24641                 error "write $tfile failed"
24642
24643         # multi-client wirtes
24644         local num=$(get_node_count ${CLIENTS//,/ })
24645         local offset=0
24646         local i=0
24647
24648         echo "Test SOM for multi-client ($num) writes"
24649         touch $DIR/$tfile || error "touch $tfile failed"
24650         $TRUNCATE $DIR/$tfile 0
24651         for client in ${CLIENTS//,/ }; do
24652                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24653                 local pids[$i]=$!
24654                 i=$((i + 1))
24655                 offset=$((offset + $bs))
24656         done
24657         for (( i=0; i < $num; i++ )); do
24658                 wait ${pids[$i]}
24659         done
24660
24661         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24662         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24663         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24664         check_lsom_data $DIR/$tdir/trunc
24665         check_lsom_data $DIR/$tdir/single_dd
24666         check_lsom_data $DIR/$tfile
24667
24668         rm -rf $DIR/$tdir
24669         # Deregistration step
24670         changelog_deregister || error "changelog_deregister failed"
24671 }
24672 run_test 807 "verify LSOM syncing tool"
24673
24674 check_som_nologged()
24675 {
24676         local lines=$($LFS changelog $FSNAME-MDT0000 |
24677                 grep 'x=trusted.som' | wc -l)
24678         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24679 }
24680
24681 test_808() {
24682         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24683                 skip "Need MDS version at least 2.11.55"
24684
24685         # Registration step
24686         changelog_register || error "changelog_register failed"
24687
24688         touch $DIR/$tfile || error "touch $tfile failed"
24689         check_som_nologged
24690
24691         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24692                 error "write $tfile failed"
24693         check_som_nologged
24694
24695         $TRUNCATE $DIR/$tfile 1234
24696         check_som_nologged
24697
24698         $TRUNCATE $DIR/$tfile 1048576
24699         check_som_nologged
24700
24701         # Deregistration step
24702         changelog_deregister || error "changelog_deregister failed"
24703 }
24704 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24705
24706 check_som_nodata()
24707 {
24708         $LFS getsom $1
24709         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24710 }
24711
24712 test_809() {
24713         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24714                 skip "Need MDS version at least 2.11.56"
24715
24716         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24717                 error "failed to create DoM-only file $DIR/$tfile"
24718         touch $DIR/$tfile || error "touch $tfile failed"
24719         check_som_nodata $DIR/$tfile
24720
24721         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24722                 error "write $tfile failed"
24723         check_som_nodata $DIR/$tfile
24724
24725         $TRUNCATE $DIR/$tfile 1234
24726         check_som_nodata $DIR/$tfile
24727
24728         $TRUNCATE $DIR/$tfile 4097
24729         check_som_nodata $DIR/$file
24730 }
24731 run_test 809 "Verify no SOM xattr store for DoM-only files"
24732
24733 test_810() {
24734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24735         $GSS && skip_env "could not run with gss"
24736         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24737                 skip "OST < 2.12.58 doesn't align checksum"
24738
24739         set_checksums 1
24740         stack_trap "set_checksums $ORIG_CSUM" EXIT
24741         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24742
24743         local csum
24744         local before
24745         local after
24746         for csum in $CKSUM_TYPES; do
24747                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24748                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24749                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24750                         eval set -- $i
24751                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24752                         before=$(md5sum $DIR/$tfile)
24753                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24754                         after=$(md5sum $DIR/$tfile)
24755                         [ "$before" == "$after" ] ||
24756                                 error "$csum: $before != $after bs=$1 seek=$2"
24757                 done
24758         done
24759 }
24760 run_test 810 "partial page writes on ZFS (LU-11663)"
24761
24762 test_812a() {
24763         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24764                 skip "OST < 2.12.51 doesn't support this fail_loc"
24765
24766         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24767         # ensure ost1 is connected
24768         stat $DIR/$tfile >/dev/null || error "can't stat"
24769         wait_osc_import_state client ost1 FULL
24770         # no locks, no reqs to let the connection idle
24771         cancel_lru_locks osc
24772
24773         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24774 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24775         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24776         wait_osc_import_state client ost1 CONNECTING
24777         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24778
24779         stat $DIR/$tfile >/dev/null || error "can't stat file"
24780 }
24781 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24782
24783 test_812b() { # LU-12378
24784         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24785                 skip "OST < 2.12.51 doesn't support this fail_loc"
24786
24787         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24788         # ensure ost1 is connected
24789         stat $DIR/$tfile >/dev/null || error "can't stat"
24790         wait_osc_import_state client ost1 FULL
24791         # no locks, no reqs to let the connection idle
24792         cancel_lru_locks osc
24793
24794         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24795 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24796         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24797         wait_osc_import_state client ost1 CONNECTING
24798         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24799
24800         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24801         wait_osc_import_state client ost1 IDLE
24802 }
24803 run_test 812b "do not drop no resend request for idle connect"
24804
24805 test_813() {
24806         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24807         [ -z "$file_heat_sav" ] && skip "no file heat support"
24808
24809         local readsample
24810         local writesample
24811         local readbyte
24812         local writebyte
24813         local readsample1
24814         local writesample1
24815         local readbyte1
24816         local writebyte1
24817
24818         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24819         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24820
24821         $LCTL set_param -n llite.*.file_heat=1
24822         echo "Turn on file heat"
24823         echo "Period second: $period_second, Decay percentage: $decay_pct"
24824
24825         echo "QQQQ" > $DIR/$tfile
24826         echo "QQQQ" > $DIR/$tfile
24827         echo "QQQQ" > $DIR/$tfile
24828         cat $DIR/$tfile > /dev/null
24829         cat $DIR/$tfile > /dev/null
24830         cat $DIR/$tfile > /dev/null
24831         cat $DIR/$tfile > /dev/null
24832
24833         local out=$($LFS heat_get $DIR/$tfile)
24834
24835         $LFS heat_get $DIR/$tfile
24836         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24837         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24838         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24839         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24840
24841         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24842         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24843         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24844         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24845
24846         sleep $((period_second + 3))
24847         echo "Sleep $((period_second + 3)) seconds..."
24848         # The recursion formula to calculate the heat of the file f is as
24849         # follow:
24850         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24851         # Where Hi is the heat value in the period between time points i*I and
24852         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24853         # to the weight of Ci.
24854         out=$($LFS heat_get $DIR/$tfile)
24855         $LFS heat_get $DIR/$tfile
24856         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24857         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24858         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24859         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24860
24861         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24862                 error "read sample ($readsample) is wrong"
24863         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24864                 error "write sample ($writesample) is wrong"
24865         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24866                 error "read bytes ($readbyte) is wrong"
24867         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24868                 error "write bytes ($writebyte) is wrong"
24869
24870         echo "QQQQ" > $DIR/$tfile
24871         echo "QQQQ" > $DIR/$tfile
24872         echo "QQQQ" > $DIR/$tfile
24873         cat $DIR/$tfile > /dev/null
24874         cat $DIR/$tfile > /dev/null
24875         cat $DIR/$tfile > /dev/null
24876         cat $DIR/$tfile > /dev/null
24877
24878         sleep $((period_second + 3))
24879         echo "Sleep $((period_second + 3)) seconds..."
24880
24881         out=$($LFS heat_get $DIR/$tfile)
24882         $LFS heat_get $DIR/$tfile
24883         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24884         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24885         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24886         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24887
24888         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24889                 4 * $decay_pct) / 100") -eq 1 ] ||
24890                 error "read sample ($readsample1) is wrong"
24891         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24892                 3 * $decay_pct) / 100") -eq 1 ] ||
24893                 error "write sample ($writesample1) is wrong"
24894         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24895                 20 * $decay_pct) / 100") -eq 1 ] ||
24896                 error "read bytes ($readbyte1) is wrong"
24897         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24898                 15 * $decay_pct) / 100") -eq 1 ] ||
24899                 error "write bytes ($writebyte1) is wrong"
24900
24901         echo "Turn off file heat for the file $DIR/$tfile"
24902         $LFS heat_set -o $DIR/$tfile
24903
24904         echo "QQQQ" > $DIR/$tfile
24905         echo "QQQQ" > $DIR/$tfile
24906         echo "QQQQ" > $DIR/$tfile
24907         cat $DIR/$tfile > /dev/null
24908         cat $DIR/$tfile > /dev/null
24909         cat $DIR/$tfile > /dev/null
24910         cat $DIR/$tfile > /dev/null
24911
24912         out=$($LFS heat_get $DIR/$tfile)
24913         $LFS heat_get $DIR/$tfile
24914         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24915         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24916         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24917         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24918
24919         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24920         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24921         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24922         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24923
24924         echo "Trun on file heat for the file $DIR/$tfile"
24925         $LFS heat_set -O $DIR/$tfile
24926
24927         echo "QQQQ" > $DIR/$tfile
24928         echo "QQQQ" > $DIR/$tfile
24929         echo "QQQQ" > $DIR/$tfile
24930         cat $DIR/$tfile > /dev/null
24931         cat $DIR/$tfile > /dev/null
24932         cat $DIR/$tfile > /dev/null
24933         cat $DIR/$tfile > /dev/null
24934
24935         out=$($LFS heat_get $DIR/$tfile)
24936         $LFS heat_get $DIR/$tfile
24937         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24938         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24939         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24940         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24941
24942         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24943         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24944         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24945         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24946
24947         $LFS heat_set -c $DIR/$tfile
24948         $LCTL set_param -n llite.*.file_heat=0
24949         echo "Turn off file heat support for the Lustre filesystem"
24950
24951         echo "QQQQ" > $DIR/$tfile
24952         echo "QQQQ" > $DIR/$tfile
24953         echo "QQQQ" > $DIR/$tfile
24954         cat $DIR/$tfile > /dev/null
24955         cat $DIR/$tfile > /dev/null
24956         cat $DIR/$tfile > /dev/null
24957         cat $DIR/$tfile > /dev/null
24958
24959         out=$($LFS heat_get $DIR/$tfile)
24960         $LFS heat_get $DIR/$tfile
24961         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24962         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24963         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24964         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24965
24966         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24967         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24968         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24969         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24970
24971         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24972         rm -f $DIR/$tfile
24973 }
24974 run_test 813 "File heat verfication"
24975
24976 test_814()
24977 {
24978         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24979         echo -n y >> $DIR/$tfile
24980         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24981         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24982 }
24983 run_test 814 "sparse cp works as expected (LU-12361)"
24984
24985 test_815()
24986 {
24987         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24988         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24989 }
24990 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24991
24992 test_816() {
24993         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24994         # ensure ost1 is connected
24995         stat $DIR/$tfile >/dev/null || error "can't stat"
24996         wait_osc_import_state client ost1 FULL
24997         # no locks, no reqs to let the connection idle
24998         cancel_lru_locks osc
24999         lru_resize_disable osc
25000         local before
25001         local now
25002         before=$($LCTL get_param -n \
25003                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25004
25005         wait_osc_import_state client ost1 IDLE
25006         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25007         now=$($LCTL get_param -n \
25008               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25009         [ $before == $now ] || error "lru_size changed $before != $now"
25010 }
25011 run_test 816 "do not reset lru_resize on idle reconnect"
25012
25013 cleanup_817() {
25014         umount $tmpdir
25015         exportfs -u localhost:$DIR/nfsexp
25016         rm -rf $DIR/nfsexp
25017 }
25018
25019 test_817() {
25020         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25021
25022         mkdir -p $DIR/nfsexp
25023         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25024                 error "failed to export nfs"
25025
25026         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25027         stack_trap cleanup_817 EXIT
25028
25029         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25030                 error "failed to mount nfs to $tmpdir"
25031
25032         cp /bin/true $tmpdir
25033         $DIR/nfsexp/true || error "failed to execute 'true' command"
25034 }
25035 run_test 817 "nfsd won't cache write lock for exec file"
25036
25037 test_818() {
25038         mkdir $DIR/$tdir
25039         $LFS setstripe -c1 -i0 $DIR/$tfile
25040         $LFS setstripe -c1 -i1 $DIR/$tfile
25041         stop $SINGLEMDS
25042         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25043         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25044         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25045                 error "start $SINGLEMDS failed"
25046         rm -rf $DIR/$tdir
25047 }
25048 run_test 818 "unlink with failed llog"
25049
25050 test_819a() {
25051         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25052         cancel_lru_locks osc
25053         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25054         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25055         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25056         rm -f $TDIR/$tfile
25057 }
25058 run_test 819a "too big niobuf in read"
25059
25060 test_819b() {
25061         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25062         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25063         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25064         cancel_lru_locks osc
25065         sleep 1
25066         rm -f $TDIR/$tfile
25067 }
25068 run_test 819b "too big niobuf in write"
25069
25070
25071 function test_820_start_ost() {
25072         sleep 5
25073
25074         for num in $(seq $OSTCOUNT); do
25075                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25076         done
25077 }
25078
25079 test_820() {
25080         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25081
25082         mkdir $DIR/$tdir
25083         umount_client $MOUNT || error "umount failed"
25084         for num in $(seq $OSTCOUNT); do
25085                 stop ost$num
25086         done
25087
25088         # mount client with no active OSTs
25089         # so that the client can't initialize max LOV EA size
25090         # from OSC notifications
25091         mount_client $MOUNT || error "mount failed"
25092         # delay OST starting to keep this 0 max EA size for a while
25093         test_820_start_ost &
25094
25095         # create a directory on MDS2
25096         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25097                 error "Failed to create directory"
25098         # open intent should update default EA size
25099         # see mdc_update_max_ea_from_body()
25100         # notice this is the very first RPC to MDS2
25101         cp /etc/services $DIR/$tdir/mds2 ||
25102                 error "Failed to copy files to mds$n"
25103 }
25104 run_test 820 "update max EA from open intent"
25105
25106 #
25107 # tests that do cleanup/setup should be run at the end
25108 #
25109
25110 test_900() {
25111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25112         local ls
25113
25114         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25115         $LCTL set_param fail_loc=0x903
25116
25117         cancel_lru_locks MGC
25118
25119         FAIL_ON_ERROR=true cleanup
25120         FAIL_ON_ERROR=true setup
25121 }
25122 run_test 900 "umount should not race with any mgc requeue thread"
25123
25124 # LUS-6253/LU-11185
25125 test_901() {
25126         local oldc
25127         local newc
25128         local olds
25129         local news
25130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25131
25132         # some get_param have a bug to handle dot in param name
25133         cancel_lru_locks MGC
25134         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25135         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25136         umount_client $MOUNT || error "umount failed"
25137         mount_client $MOUNT || error "mount failed"
25138         cancel_lru_locks MGC
25139         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25140         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25141
25142         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25143         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25144
25145         return 0
25146 }
25147 run_test 901 "don't leak a mgc lock on client umount"
25148
25149 # LU-13377
25150 test_902() {
25151         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25152                 skip "client does not have LU-13377 fix"
25153         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25154         $LCTL set_param fail_loc=0x1415
25155         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25156         cancel_lru_locks osc
25157         rm -f $DIR/$tfile
25158 }
25159 run_test 902 "test short write doesn't hang lustre"
25160
25161 complete $SECONDS
25162 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25163 check_and_cleanup_lustre
25164 if [ "$I_MOUNTED" != "yes" ]; then
25165         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25166 fi
25167 exit_status