Whamcloud - gitweb
44c02a33ac9f3ca7d8ad9771eefb201ae11c4548
[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
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 #                                  5              12     8   12  15   (min)"
66 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
67
68 if [ "$mds1_FSTYPE" = "zfs" ]; then
69         #                                               13    (min)"
70         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
71 fi
72
73 if [ "$ost1_FSTYPE" = "zfs" ]; then
74         always_except LU-1941 130b 130c 130d 130e 130f 130g
75 fi
76
77 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
78
79 # Get the SLES distro version
80 #
81 # Returns a version string that should only be used in comparing
82 # strings returned by version_code()
83 sles_version_code()
84 {
85         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
86
87         # All SuSE Linux versions have one decimal. version_code expects two
88         local sles_version=$version.0
89         version_code $sles_version
90 }
91
92 # Check if we are running on Ubuntu or SLES so we can make decisions on
93 # what tests to run
94 if [ -r /etc/SuSE-release ]; then
95         sles_version=$(sles_version_code)
96         [ $sles_version -lt $(version_code 11.4.0) ] &&
97                 always_except LU-4341 170
98
99         [ $sles_version -lt $(version_code 12.0.0) ] &&
100                 always_except LU-3703 234
101 elif [ -r /etc/os-release ]; then
102         if grep -qi ubuntu /etc/os-release; then
103                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
104                                                 -e 's/^VERSION=//p' \
105                                                 /etc/os-release |
106                                                 awk '{ print $1 }'))
107
108                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
109                         always_except LU-10366 410
110                 fi
111         fi
112 fi
113
114 build_test_filter
115 FAIL_ON_ERROR=false
116
117 cleanup() {
118         echo -n "cln.."
119         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
120         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
121 }
122 setup() {
123         echo -n "mnt.."
124         load_modules
125         setupall || exit 10
126         echo "done"
127 }
128
129 check_swap_layouts_support()
130 {
131         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
132                 skip "Does not support layout lock."
133 }
134
135 check_swap_layout_no_dom()
136 {
137         local FOLDER=$1
138         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
139         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
140 }
141
142 check_and_setup_lustre
143 DIR=${DIR:-$MOUNT}
144 assert_DIR
145
146 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
147
148 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
149 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
150 rm -rf $DIR/[Rdfs][0-9]*
151
152 # $RUNAS_ID may get set incorrectly somewhere else
153 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
154         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
155
156 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
157
158 if [ "${ONLY}" = "MOUNT" ] ; then
159         echo "Lustre is up, please go on"
160         exit
161 fi
162
163 echo "preparing for tests involving mounts"
164 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
165 touch $EXT2_DEV
166 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
167 echo # add a newline after mke2fs.
168
169 umask 077
170
171 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
172 lctl set_param debug=-1 2> /dev/null || true
173 test_0a() {
174         touch $DIR/$tfile
175         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
176         rm $DIR/$tfile
177         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
178 }
179 run_test 0a "touch; rm ====================="
180
181 test_0b() {
182         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
183         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
184 }
185 run_test 0b "chmod 0755 $DIR ============================="
186
187 test_0c() {
188         $LCTL get_param mdc.*.import | grep "state: FULL" ||
189                 error "import not FULL"
190         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
191                 error "bad target"
192 }
193 run_test 0c "check import proc"
194
195 test_0d() { # LU-3397
196         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
197                 skip "proc exports not supported before 2.10.57"
198
199         local mgs_exp="mgs.MGS.exports"
200         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
201         local exp_client_nid
202         local exp_client_version
203         local exp_val
204         local imp_val
205         local temp_imp=$DIR/$tfile.import
206         local temp_exp=$DIR/$tfile.export
207
208         # save mgc import file to $temp_imp
209         $LCTL get_param mgc.*.import | tee $temp_imp
210         # Check if client uuid is found in MGS export
211         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
212                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
213                         $client_uuid ] &&
214                         break;
215         done
216         # save mgs export file to $temp_exp
217         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
218
219         # Compare the value of field "connect_flags"
220         imp_val=$(grep "connect_flags" $temp_imp)
221         exp_val=$(grep "connect_flags" $temp_exp)
222         [ "$exp_val" == "$imp_val" ] ||
223                 error "export flags '$exp_val' != import flags '$imp_val'"
224
225         # Compare client versions.  Only compare top-3 fields for compatibility
226         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
227         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
228         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "exp version '$exp_client_version'($exp_val) != " \
231                         "'$(lustre_build_version client)'($imp_val)"
232 }
233 run_test 0d "check export proc ============================="
234
235 test_0e() { # LU-13417
236         (( $MDSCOUNT > 1 )) ||
237                 skip "We need at least 2 MDTs for this test"
238
239         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
240                 skip "Need server version at least 2.14.51"
241
242         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
243         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
244
245         [ $default_lmv_count -eq 1 ] ||
246                 error "$MOUNT default stripe count $default_lmv_count"
247
248         [ $default_lmv_index -eq -1 ] ||
249                 error "$MOUNT default stripe index $default_lmv_index"
250
251         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
252         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
253
254         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
255         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
256
257         [ $mdt_index1 -eq $mdt_index2 ] &&
258                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
259
260         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
261 }
262 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
263
264 test_1() {
265         test_mkdir $DIR/$tdir
266         test_mkdir $DIR/$tdir/d2
267         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
268         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
269         rmdir $DIR/$tdir/d2
270         rmdir $DIR/$tdir
271         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
272 }
273 run_test 1 "mkdir; remkdir; rmdir"
274
275 test_2() {
276         test_mkdir $DIR/$tdir
277         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
281 }
282 run_test 2 "mkdir; touch; rmdir; check file"
283
284 test_3() {
285         test_mkdir $DIR/$tdir
286         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
287         touch $DIR/$tdir/$tfile
288         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
289         rm -r $DIR/$tdir
290         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
291 }
292 run_test 3 "mkdir; touch; rmdir; check dir"
293
294 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
295 test_4() {
296         test_mkdir -i 1 $DIR/$tdir
297
298         touch $DIR/$tdir/$tfile ||
299                 error "Create file under remote directory failed"
300
301         rmdir $DIR/$tdir &&
302                 error "Expect error removing in-use dir $DIR/$tdir"
303
304         test -d $DIR/$tdir || error "Remote directory disappeared"
305
306         rm -rf $DIR/$tdir || error "remove remote dir error"
307 }
308 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
309
310 test_5() {
311         test_mkdir $DIR/$tdir
312         test_mkdir $DIR/$tdir/d2
313         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
314         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
315         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
316 }
317 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
318
319 test_6a() {
320         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
321         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
322         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
323                 error "$tfile does not have perm 0666 or UID $UID"
324         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
325         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
326                 error "$tfile should be 0666 and owned by UID $UID"
327 }
328 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
329
330 test_6c() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         touch $DIR/$tfile
334         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
335         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
336                 error "$tfile should be owned by UID $RUNAS_ID"
337         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
338         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by UID $RUNAS_ID"
340 }
341 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
342
343 test_6e() {
344         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
345
346         touch $DIR/$tfile
347         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
348         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
349                 error "$tfile should be owned by GID $UID"
350         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
351         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
352                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
353 }
354 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
355
356 test_6g() {
357         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
358
359         test_mkdir $DIR/$tdir
360         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
361         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
362         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
363         test_mkdir $DIR/$tdir/d/subdir
364         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
365                 error "$tdir/d/subdir should be GID $RUNAS_GID"
366         if [[ $MDSCOUNT -gt 1 ]]; then
367                 # check remote dir sgid inherite
368                 $LFS mkdir -i 0 $DIR/$tdir.local ||
369                         error "mkdir $tdir.local failed"
370                 chmod g+s $DIR/$tdir.local ||
371                         error "chmod $tdir.local failed"
372                 chgrp $RUNAS_GID $DIR/$tdir.local ||
373                         error "chgrp $tdir.local failed"
374                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
375                         error "mkdir $tdir.remote failed"
376                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
377                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
378                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
379                         error "$tdir.remote should be mode 02755"
380         fi
381 }
382 run_test 6g "verify new dir in sgid dir inherits group"
383
384 test_6h() { # bug 7331
385         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
386
387         touch $DIR/$tfile || error "touch failed"
388         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
389         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
390                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
391         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
392                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
393 }
394 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
395
396 test_7a() {
397         test_mkdir $DIR/$tdir
398         $MCREATE $DIR/$tdir/$tfile
399         chmod 0666 $DIR/$tdir/$tfile
400         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
401                 error "$tdir/$tfile should be mode 0666"
402 }
403 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
404
405 test_7b() {
406         if [ ! -d $DIR/$tdir ]; then
407                 test_mkdir $DIR/$tdir
408         fi
409         $MCREATE $DIR/$tdir/$tfile
410         echo -n foo > $DIR/$tdir/$tfile
411         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
412         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
413 }
414 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
415
416 test_8() {
417         test_mkdir $DIR/$tdir
418         touch $DIR/$tdir/$tfile
419         chmod 0666 $DIR/$tdir/$tfile
420         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
421                 error "$tfile mode not 0666"
422 }
423 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
424
425 test_9() {
426         test_mkdir $DIR/$tdir
427         test_mkdir $DIR/$tdir/d2
428         test_mkdir $DIR/$tdir/d2/d3
429         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
430 }
431 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
432
433 test_10() {
434         test_mkdir $DIR/$tdir
435         test_mkdir $DIR/$tdir/d2
436         touch $DIR/$tdir/d2/$tfile
437         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
438                 error "$tdir/d2/$tfile not a file"
439 }
440 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
441
442 test_11() {
443         test_mkdir $DIR/$tdir
444         test_mkdir $DIR/$tdir/d2
445         chmod 0666 $DIR/$tdir/d2
446         chmod 0705 $DIR/$tdir/d2
447         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
448                 error "$tdir/d2 mode not 0705"
449 }
450 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
451
452 test_12() {
453         test_mkdir $DIR/$tdir
454         touch $DIR/$tdir/$tfile
455         chmod 0666 $DIR/$tdir/$tfile
456         chmod 0654 $DIR/$tdir/$tfile
457         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
458                 error "$tdir/d2 mode not 0654"
459 }
460 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
461
462 test_13() {
463         test_mkdir $DIR/$tdir
464         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
465         >  $DIR/$tdir/$tfile
466         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
467                 error "$tdir/$tfile size not 0 after truncate"
468 }
469 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
470
471 test_14() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
478
479 test_15() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
483         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
484                 error "$tdir/${tfile_2} not a file after rename"
485         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
486 }
487 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
488
489 test_16() {
490         test_mkdir $DIR/$tdir
491         touch $DIR/$tdir/$tfile
492         rm -rf $DIR/$tdir/$tfile
493         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
494 }
495 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
496
497 test_17a() {
498         test_mkdir $DIR/$tdir
499         touch $DIR/$tdir/$tfile
500         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
501         ls -l $DIR/$tdir
502         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
503                 error "$tdir/l-exist not a symlink"
504         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
505                 error "$tdir/l-exist not referencing a file"
506         rm -f $DIR/$tdir/l-exist
507         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
508 }
509 run_test 17a "symlinks: create, remove (real)"
510
511 test_17b() {
512         test_mkdir $DIR/$tdir
513         ln -s no-such-file $DIR/$tdir/l-dangle
514         ls -l $DIR/$tdir
515         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
516                 error "$tdir/l-dangle not referencing no-such-file"
517         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
518                 error "$tdir/l-dangle not referencing non-existent file"
519         rm -f $DIR/$tdir/l-dangle
520         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
521 }
522 run_test 17b "symlinks: create, remove (dangling)"
523
524 test_17c() { # bug 3440 - don't save failed open RPC for replay
525         test_mkdir $DIR/$tdir
526         ln -s foo $DIR/$tdir/$tfile
527         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
528 }
529 run_test 17c "symlinks: open dangling (should return error)"
530
531 test_17d() {
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         touch $DIR/$tdir/$tfile || error "creating to new symlink"
535 }
536 run_test 17d "symlinks: create dangling"
537
538 test_17e() {
539         test_mkdir $DIR/$tdir
540         local foo=$DIR/$tdir/$tfile
541         ln -s $foo $foo || error "create symlink failed"
542         ls -l $foo || error "ls -l failed"
543         ls $foo && error "ls not failed" || true
544 }
545 run_test 17e "symlinks: create recursive symlink (should return error)"
546
547 test_17f() {
548         test_mkdir $DIR/$tdir
549         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
550         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
554         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
555         ls -l  $DIR/$tdir
556 }
557 run_test 17f "symlinks: long and very long symlink name"
558
559 # str_repeat(S, N) generate a string that is string S repeated N times
560 str_repeat() {
561         local s=$1
562         local n=$2
563         local ret=''
564         while [ $((n -= 1)) -ge 0 ]; do
565                 ret=$ret$s
566         done
567         echo $ret
568 }
569
570 # Long symlinks and LU-2241
571 test_17g() {
572         test_mkdir $DIR/$tdir
573         local TESTS="59 60 61 4094 4095"
574
575         # Fix for inode size boundary in 2.1.4
576         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
577                 TESTS="4094 4095"
578
579         # Patch not applied to 2.2 or 2.3 branches
580         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
581         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
582                 TESTS="4094 4095"
583
584         for i in $TESTS; do
585                 local SYMNAME=$(str_repeat 'x' $i)
586                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
587                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
588         done
589 }
590 run_test 17g "symlinks: really long symlink name and inode boundaries"
591
592 test_17h() { #bug 17378
593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
594         remote_mds_nodsh && skip "remote MDS with nodsh"
595
596         local mdt_idx
597
598         test_mkdir $DIR/$tdir
599         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
600         $LFS setstripe -c -1 $DIR/$tdir
601         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
602         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
603         touch $DIR/$tdir/$tfile || true
604 }
605 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
606
607 test_17i() { #bug 20018
608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
609         remote_mds_nodsh && skip "remote MDS with nodsh"
610
611         local foo=$DIR/$tdir/$tfile
612         local mdt_idx
613
614         test_mkdir -c1 $DIR/$tdir
615         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
616         ln -s $foo $foo || error "create symlink failed"
617 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
618         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
619         ls -l $foo && error "error not detected"
620         return 0
621 }
622 run_test 17i "don't panic on short symlink (should return error)"
623
624 test_17k() { #bug 22301
625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
626         [[ -z "$(which rsync 2>/dev/null)" ]] &&
627                 skip "no rsync command"
628         rsync --help | grep -q xattr ||
629                 skip_env "$(rsync --version | head -n1) does not support xattrs"
630         test_mkdir $DIR/$tdir
631         test_mkdir $DIR/$tdir.new
632         touch $DIR/$tdir/$tfile
633         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
634         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
635                 error "rsync failed with xattrs enabled"
636 }
637 run_test 17k "symlinks: rsync with xattrs enabled"
638
639 test_17l() { # LU-279
640         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
641                 skip "no getfattr command"
642
643         test_mkdir $DIR/$tdir
644         touch $DIR/$tdir/$tfile
645         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
646         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
647                 # -h to not follow symlinks. -m '' to list all the xattrs.
648                 # grep to remove first line: '# file: $path'.
649                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
650                 do
651                         lgetxattr_size_check $path $xattr ||
652                                 error "lgetxattr_size_check $path $xattr failed"
653                 done
654         done
655 }
656 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
657
658 # LU-1540
659 test_17m() {
660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
661         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
662         remote_mds_nodsh && skip "remote MDS with nodsh"
663         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
664         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
665                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
666
667         local short_sym="0123456789"
668         local wdir=$DIR/$tdir
669         local i
670
671         test_mkdir $wdir
672         long_sym=$short_sym
673         # create a long symlink file
674         for ((i = 0; i < 4; ++i)); do
675                 long_sym=${long_sym}${long_sym}
676         done
677
678         echo "create 512 short and long symlink files under $wdir"
679         for ((i = 0; i < 256; ++i)); do
680                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
681                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
682         done
683
684         echo "erase them"
685         rm -f $wdir/*
686         sync
687         wait_delete_completed
688
689         echo "recreate the 512 symlink files with a shorter string"
690         for ((i = 0; i < 512; ++i)); do
691                 # rewrite the symlink file with a shorter string
692                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
693                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
694         done
695
696         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
697
698         echo "stop and checking mds${mds_index}:"
699         # e2fsck should not return error
700         stop mds${mds_index}
701         local devname=$(mdsdevname $mds_index)
702         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
703         rc=$?
704
705         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
706                 error "start mds${mds_index} failed"
707         df $MOUNT > /dev/null 2>&1
708         [ $rc -eq 0 ] ||
709                 error "e2fsck detected error for short/long symlink: rc=$rc"
710         rm -f $wdir/*
711 }
712 run_test 17m "run e2fsck against MDT which contains short/long symlink"
713
714 check_fs_consistency_17n() {
715         local mdt_index
716         local rc=0
717
718         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
719         # so it only check MDT1/MDT2 instead of all of MDTs.
720         for mdt_index in 1 2; do
721                 # e2fsck should not return error
722                 stop mds${mdt_index}
723                 local devname=$(mdsdevname $mdt_index)
724                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
725                         rc=$((rc + $?))
726
727                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
728                         error "mount mds$mdt_index failed"
729                 df $MOUNT > /dev/null 2>&1
730         done
731         return $rc
732 }
733
734 test_17n() {
735         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
737         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
738         remote_mds_nodsh && skip "remote MDS with nodsh"
739         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
740         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
741                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
742
743         local i
744
745         test_mkdir $DIR/$tdir
746         for ((i=0; i<10; i++)); do
747                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
748                         error "create remote dir error $i"
749                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
750                         error "create files under remote dir failed $i"
751         done
752
753         check_fs_consistency_17n ||
754                 error "e2fsck report error after create files under remote dir"
755
756         for ((i = 0; i < 10; i++)); do
757                 rm -rf $DIR/$tdir/remote_dir_${i} ||
758                         error "destroy remote dir error $i"
759         done
760
761         check_fs_consistency_17n ||
762                 error "e2fsck report error after unlink files under remote dir"
763
764         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
765                 skip "lustre < 2.4.50 does not support migrate mv"
766
767         for ((i = 0; i < 10; i++)); do
768                 mkdir -p $DIR/$tdir/remote_dir_${i}
769                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
770                         error "create files under remote dir failed $i"
771                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
772                         error "migrate remote dir error $i"
773         done
774         check_fs_consistency_17n || error "e2fsck report error after migration"
775
776         for ((i = 0; i < 10; i++)); do
777                 rm -rf $DIR/$tdir/remote_dir_${i} ||
778                         error "destroy remote dir error $i"
779         done
780
781         check_fs_consistency_17n || error "e2fsck report error after unlink"
782 }
783 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
784
785 test_17o() {
786         remote_mds_nodsh && skip "remote MDS with nodsh"
787         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
788                 skip "Need MDS version at least 2.3.64"
789
790         local wdir=$DIR/${tdir}o
791         local mdt_index
792         local rc=0
793
794         test_mkdir $wdir
795         touch $wdir/$tfile
796         mdt_index=$($LFS getstripe -m $wdir/$tfile)
797         mdt_index=$((mdt_index + 1))
798
799         cancel_lru_locks mdc
800         #fail mds will wait the failover finish then set
801         #following fail_loc to avoid interfer the recovery process.
802         fail mds${mdt_index}
803
804         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
805         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
806         ls -l $wdir/$tfile && rc=1
807         do_facet mds${mdt_index} lctl set_param fail_loc=0
808         [[ $rc -eq 0 ]] || error "stat file should fail"
809 }
810 run_test 17o "stat file with incompat LMA feature"
811
812 test_18() {
813         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
814         ls $DIR || error "Failed to ls $DIR: $?"
815 }
816 run_test 18 "touch .../f ; ls ... =============================="
817
818 test_19a() {
819         touch $DIR/$tfile
820         ls -l $DIR
821         rm $DIR/$tfile
822         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
823 }
824 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
825
826 test_19b() {
827         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
828 }
829 run_test 19b "ls -l .../f19 (should return error) =============="
830
831 test_19c() {
832         [ $RUNAS_ID -eq $UID ] &&
833                 skip_env "RUNAS_ID = UID = $UID -- skipping"
834
835         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
836 }
837 run_test 19c "$RUNAS touch .../f19 (should return error) =="
838
839 test_19d() {
840         cat $DIR/f19 && error || true
841 }
842 run_test 19d "cat .../f19 (should return error) =============="
843
844 test_20() {
845         touch $DIR/$tfile
846         rm $DIR/$tfile
847         touch $DIR/$tfile
848         rm $DIR/$tfile
849         touch $DIR/$tfile
850         rm $DIR/$tfile
851         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
852 }
853 run_test 20 "touch .../f ; ls -l ..."
854
855 test_21() {
856         test_mkdir $DIR/$tdir
857         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
858         ln -s dangle $DIR/$tdir/link
859         echo foo >> $DIR/$tdir/link
860         cat $DIR/$tdir/dangle
861         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
862         $CHECKSTAT -f -t file $DIR/$tdir/link ||
863                 error "$tdir/link not linked to a file"
864 }
865 run_test 21 "write to dangling link"
866
867 test_22() {
868         local wdir=$DIR/$tdir
869         test_mkdir $wdir
870         chown $RUNAS_ID:$RUNAS_GID $wdir
871         (cd $wdir || error "cd $wdir failed";
872                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
873                 $RUNAS tar xf -)
874         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
875         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
876         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
877                 error "checkstat -u failed"
878 }
879 run_test 22 "unpack tar archive as non-root user"
880
881 # was test_23
882 test_23a() {
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
887         openfile -f O_CREAT:O_EXCL $file &&
888                 error "$file recreate succeeded" || true
889 }
890 run_test 23a "O_CREAT|O_EXCL in subdir"
891
892 test_23b() { # bug 18988
893         test_mkdir $DIR/$tdir
894         local file=$DIR/$tdir/$tfile
895
896         rm -f $file
897         echo foo > $file || error "write filed"
898         echo bar >> $file || error "append filed"
899         $CHECKSTAT -s 8 $file || error "wrong size"
900         rm $file
901 }
902 run_test 23b "O_APPEND check"
903
904 # LU-9409, size with O_APPEND and tiny writes
905 test_23c() {
906         local file=$DIR/$tfile
907
908         # single dd
909         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
910         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
911         rm -f $file
912
913         # racing tiny writes
914         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         wait
917         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
918         rm -f $file
919
920         #racing tiny & normal writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
923         wait
924         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
925         rm -f $file
926
927         #racing tiny & normal writes 2, ugly numbers
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
930         wait
931         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
932         rm -f $file
933 }
934 run_test 23c "O_APPEND size checks for tiny writes"
935
936 # LU-11069 file offset is correct after appending writes
937 test_23d() {
938         local file=$DIR/$tfile
939         local offset
940
941         echo CentaurHauls > $file
942         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
943         if ((offset != 26)); then
944                 error "wrong offset, expected 26, got '$offset'"
945         fi
946 }
947 run_test 23d "file offset is correct after appending writes"
948
949 # rename sanity
950 test_24a() {
951         echo '-- same directory rename'
952         test_mkdir $DIR/$tdir
953         touch $DIR/$tdir/$tfile.1
954         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
955         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
956 }
957 run_test 24a "rename file to non-existent target"
958
959 test_24b() {
960         test_mkdir $DIR/$tdir
961         touch $DIR/$tdir/$tfile.{1,2}
962         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
963         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
964         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
965 }
966 run_test 24b "rename file to existing target"
967
968 test_24c() {
969         test_mkdir $DIR/$tdir
970         test_mkdir $DIR/$tdir/d$testnum.1
971         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24c "rename directory to non-existent target"
976
977 test_24d() {
978         test_mkdir -c1 $DIR/$tdir
979         test_mkdir -c1 $DIR/$tdir/d$testnum.1
980         test_mkdir -c1 $DIR/$tdir/d$testnum.2
981         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
982         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
983         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
984 }
985 run_test 24d "rename directory to existing target"
986
987 test_24e() {
988         echo '-- cross directory renames --'
989         test_mkdir $DIR/R5a
990         test_mkdir $DIR/R5b
991         touch $DIR/R5a/f
992         mv $DIR/R5a/f $DIR/R5b/g
993         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
994         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
995 }
996 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
997
998 test_24f() {
999         test_mkdir $DIR/R6a
1000         test_mkdir $DIR/R6b
1001         touch $DIR/R6a/f $DIR/R6b/g
1002         mv $DIR/R6a/f $DIR/R6b/g
1003         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1004         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1005 }
1006 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1007
1008 test_24g() {
1009         test_mkdir $DIR/R7a
1010         test_mkdir $DIR/R7b
1011         test_mkdir $DIR/R7a/d
1012         mv $DIR/R7a/d $DIR/R7b/e
1013         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1014         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1015 }
1016 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1017
1018 test_24h() {
1019         test_mkdir -c1 $DIR/R8a
1020         test_mkdir -c1 $DIR/R8b
1021         test_mkdir -c1 $DIR/R8a/d
1022         test_mkdir -c1 $DIR/R8b/e
1023         mrename $DIR/R8a/d $DIR/R8b/e
1024         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1025         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1026 }
1027 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1028
1029 test_24i() {
1030         echo "-- rename error cases"
1031         test_mkdir $DIR/R9
1032         test_mkdir $DIR/R9/a
1033         touch $DIR/R9/f
1034         mrename $DIR/R9/f $DIR/R9/a
1035         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1036         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1037         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1038 }
1039 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1040
1041 test_24j() {
1042         test_mkdir $DIR/R10
1043         mrename $DIR/R10/f $DIR/R10/g
1044         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1045         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1046         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1047 }
1048 run_test 24j "source does not exist ============================"
1049
1050 test_24k() {
1051         test_mkdir $DIR/R11a
1052         test_mkdir $DIR/R11a/d
1053         touch $DIR/R11a/f
1054         mv $DIR/R11a/f $DIR/R11a/d
1055         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1056         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1057 }
1058 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1059
1060 # bug 2429 - rename foo foo foo creates invalid file
1061 test_24l() {
1062         f="$DIR/f24l"
1063         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1064 }
1065 run_test 24l "Renaming a file to itself ========================"
1066
1067 test_24m() {
1068         f="$DIR/f24m"
1069         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1070         # on ext3 this does not remove either the source or target files
1071         # though the "expected" operation would be to remove the source
1072         $CHECKSTAT -t file ${f} || error "${f} missing"
1073         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1074 }
1075 run_test 24m "Renaming a file to a hard link to itself ========="
1076
1077 test_24n() {
1078     f="$DIR/f24n"
1079     # this stats the old file after it was renamed, so it should fail
1080     touch ${f}
1081     $CHECKSTAT ${f} || error "${f} missing"
1082     mv ${f} ${f}.rename
1083     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1084     $CHECKSTAT -a ${f} || error "${f} exists"
1085 }
1086 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1087
1088 test_24o() {
1089         test_mkdir $DIR/$tdir
1090         rename_many -s random -v -n 10 $DIR/$tdir
1091 }
1092 run_test 24o "rename of files during htree split"
1093
1094 test_24p() {
1095         test_mkdir $DIR/R12a
1096         test_mkdir $DIR/R12b
1097         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1098         mrename $DIR/R12a $DIR/R12b
1099         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1100         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1101         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1102         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1103 }
1104 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1105
1106 cleanup_multiop_pause() {
1107         trap 0
1108         kill -USR1 $MULTIPID
1109 }
1110
1111 test_24q() {
1112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1113
1114         test_mkdir $DIR/R13a
1115         test_mkdir $DIR/R13b
1116         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1117         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1118         MULTIPID=$!
1119
1120         trap cleanup_multiop_pause EXIT
1121         mrename $DIR/R13a $DIR/R13b
1122         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1123         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1124         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1125         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1126         cleanup_multiop_pause
1127         wait $MULTIPID || error "multiop close failed"
1128 }
1129 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1130
1131 test_24r() { #bug 3789
1132         test_mkdir $DIR/R14a
1133         test_mkdir $DIR/R14a/b
1134         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1136         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1137 }
1138 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1139
1140 test_24s() {
1141         test_mkdir $DIR/R15a
1142         test_mkdir $DIR/R15a/b
1143         test_mkdir $DIR/R15a/b/c
1144         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1145         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1146         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1147 }
1148 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1149
1150 test_24t() {
1151         test_mkdir $DIR/R16a
1152         test_mkdir $DIR/R16a/b
1153         test_mkdir $DIR/R16a/b/c
1154         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1155         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1156         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1157 }
1158 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1159
1160 test_24u() { # bug12192
1161         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1162         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1163 }
1164 run_test 24u "create stripe file"
1165
1166 simple_cleanup_common() {
1167         local createmany=$1
1168         local rc=0
1169
1170         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1171
1172         local start=$SECONDS
1173
1174         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1175         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1176         rc=$?
1177         wait_delete_completed
1178         echo "cleanup time $((SECONDS - start))"
1179         return $rc
1180 }
1181
1182 max_pages_per_rpc() {
1183         local mdtname="$(printf "MDT%04x" ${1:-0})"
1184         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1185 }
1186
1187 test_24v() {
1188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1189
1190         local nrfiles=${COUNT:-100000}
1191         local fname="$DIR/$tdir/$tfile"
1192
1193         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1194         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1195
1196         test_mkdir "$(dirname $fname)"
1197         # assume MDT0000 has the fewest inodes
1198         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1199         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1200         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1201
1202         stack_trap "simple_cleanup_common $nrfiles"
1203
1204         createmany -m "$fname" $nrfiles
1205
1206         cancel_lru_locks mdc
1207         lctl set_param mdc.*.stats clear
1208
1209         # was previously test_24D: LU-6101
1210         # readdir() returns correct number of entries after cursor reload
1211         local num_ls=$(ls $DIR/$tdir | wc -l)
1212         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1213         local num_all=$(ls -a $DIR/$tdir | wc -l)
1214         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1215                 [ $num_all -ne $((nrfiles + 2)) ]; then
1216                         error "Expected $nrfiles files, got $num_ls " \
1217                                 "($num_uniq unique $num_all .&..)"
1218         fi
1219         # LU-5 large readdir
1220         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1221         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1222         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1223         # take into account of overhead in lu_dirpage header and end mark in
1224         # each page, plus one in rpc_num calculation.
1225         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1226         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1227         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1228         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1229         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1230         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1231         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1232         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1233                 error "large readdir doesn't take effect: " \
1234                       "$mds_readpage should be about $rpc_max"
1235 }
1236 run_test 24v "list large directory (test hash collision, b=17560)"
1237
1238 test_24w() { # bug21506
1239         SZ1=234852
1240         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1241         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1242         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1243         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1244         [[ "$SZ1" -eq "$SZ2" ]] ||
1245                 error "Error reading at the end of the file $tfile"
1246 }
1247 run_test 24w "Reading a file larger than 4Gb"
1248
1249 test_24x() {
1250         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1252         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1253                 skip "Need MDS version at least 2.7.56"
1254
1255         local MDTIDX=1
1256         local remote_dir=$DIR/$tdir/remote_dir
1257
1258         test_mkdir $DIR/$tdir
1259         $LFS mkdir -i $MDTIDX $remote_dir ||
1260                 error "create remote directory failed"
1261
1262         test_mkdir $DIR/$tdir/src_dir
1263         touch $DIR/$tdir/src_file
1264         test_mkdir $remote_dir/tgt_dir
1265         touch $remote_dir/tgt_file
1266
1267         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1268                 error "rename dir cross MDT failed!"
1269
1270         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1271                 error "rename file cross MDT failed!"
1272
1273         touch $DIR/$tdir/ln_file
1274         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1275                 error "ln file cross MDT failed"
1276
1277         rm -rf $DIR/$tdir || error "Can not delete directories"
1278 }
1279 run_test 24x "cross MDT rename/link"
1280
1281 test_24y() {
1282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1284
1285         local remote_dir=$DIR/$tdir/remote_dir
1286         local mdtidx=1
1287
1288         test_mkdir $DIR/$tdir
1289         $LFS mkdir -i $mdtidx $remote_dir ||
1290                 error "create remote directory failed"
1291
1292         test_mkdir $remote_dir/src_dir
1293         touch $remote_dir/src_file
1294         test_mkdir $remote_dir/tgt_dir
1295         touch $remote_dir/tgt_file
1296
1297         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1298                 error "rename subdir in the same remote dir failed!"
1299
1300         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1301                 error "rename files in the same remote dir failed!"
1302
1303         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1304                 error "link files in the same remote dir failed!"
1305
1306         rm -rf $DIR/$tdir || error "Can not delete directories"
1307 }
1308 run_test 24y "rename/link on the same dir should succeed"
1309
1310 test_24z() {
1311         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1312         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1313                 skip "Need MDS version at least 2.12.51"
1314
1315         local index
1316
1317         for index in 0 1; do
1318                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1319                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1320         done
1321
1322         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1323
1324         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1325         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1326
1327         local mdts=$(comma_list $(mdts_nodes))
1328
1329         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1330         stack_trap "do_nodes $mdts $LCTL \
1331                 set_param mdt.*.enable_remote_rename=1" EXIT
1332
1333         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1334
1335         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1336         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1337 }
1338 run_test 24z "cross-MDT rename is done as cp"
1339
1340 test_24A() { # LU-3182
1341         local NFILES=5000
1342
1343         test_mkdir $DIR/$tdir
1344         stack_trap "simple_cleanup_common $NFILES"
1345         createmany -m $DIR/$tdir/$tfile $NFILES
1346         local t=$(ls $DIR/$tdir | wc -l)
1347         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1348         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1349
1350         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1351                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1352 }
1353 run_test 24A "readdir() returns correct number of entries."
1354
1355 test_24B() { # LU-4805
1356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1357
1358         local count
1359
1360         test_mkdir $DIR/$tdir
1361         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1362                 error "create striped dir failed"
1363
1364         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1365         [ $count -eq 2 ] || error "Expected 2, got $count"
1366
1367         touch $DIR/$tdir/striped_dir/a
1368
1369         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1370         [ $count -eq 3 ] || error "Expected 3, got $count"
1371
1372         touch $DIR/$tdir/striped_dir/.f
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 4 ] || error "Expected 4, got $count"
1376
1377         rm -rf $DIR/$tdir || error "Can not delete directories"
1378 }
1379 run_test 24B "readdir for striped dir return correct number of entries"
1380
1381 test_24C() {
1382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1383
1384         mkdir $DIR/$tdir
1385         mkdir $DIR/$tdir/d0
1386         mkdir $DIR/$tdir/d1
1387
1388         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1389                 error "create striped dir failed"
1390
1391         cd $DIR/$tdir/d0/striped_dir
1392
1393         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1394         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1395         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d0_ino" = "$parent_ino" ] ||
1398                 error ".. wrong, expect $d0_ino, get $parent_ino"
1399
1400         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1401                 error "mv striped dir failed"
1402
1403         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1404
1405         [ "$d1_ino" = "$parent_ino" ] ||
1406                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1407 }
1408 run_test 24C "check .. in striped dir"
1409
1410 test_24E() {
1411         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1413
1414         mkdir -p $DIR/$tdir
1415         mkdir $DIR/$tdir/src_dir
1416         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1417                 error "create remote source failed"
1418
1419         touch $DIR/$tdir/src_dir/src_child/a
1420
1421         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1422                 error "create remote target dir failed"
1423
1424         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1425                 error "create remote target child failed"
1426
1427         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1428                 error "rename dir cross MDT failed!"
1429
1430         find $DIR/$tdir
1431
1432         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1433                 error "src_child still exists after rename"
1434
1435         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1436                 error "missing file(a) after rename"
1437
1438         rm -rf $DIR/$tdir || error "Can not delete directories"
1439 }
1440 run_test 24E "cross MDT rename/link"
1441
1442 test_24F () {
1443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1444
1445         local repeats=1000
1446         [ "$SLOW" = "no" ] && repeats=100
1447
1448         mkdir -p $DIR/$tdir
1449
1450         echo "$repeats repeats"
1451         for ((i = 0; i < repeats; i++)); do
1452                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1453                 touch $DIR/$tdir/test/a || error "touch fails"
1454                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1455                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1456         done
1457
1458         true
1459 }
1460 run_test 24F "hash order vs readdir (LU-11330)"
1461
1462 test_24G () {
1463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1464
1465         local ino1
1466         local ino2
1467
1468         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1469         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1470         touch $DIR/$tdir-0/f1 || error "touch f1"
1471         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1472         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1473         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1474         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1475         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1476 }
1477 run_test 24G "migrate symlink in rename"
1478
1479 test_24H() {
1480         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1481         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1482                 skip "MDT1 should be on another node"
1483
1484         test_mkdir -i 1 -c 1 $DIR/$tdir
1485 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1486         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1487         touch $DIR/$tdir/$tfile || error "touch failed"
1488 }
1489 run_test 24H "repeat FLD_QUERY rpc"
1490
1491 test_25a() {
1492         echo '== symlink sanity ============================================='
1493
1494         test_mkdir $DIR/d25
1495         ln -s d25 $DIR/s25
1496         touch $DIR/s25/foo ||
1497                 error "File creation in symlinked directory failed"
1498 }
1499 run_test 25a "create file in symlinked directory ==============="
1500
1501 test_25b() {
1502         [ ! -d $DIR/d25 ] && test_25a
1503         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1504 }
1505 run_test 25b "lookup file in symlinked directory ==============="
1506
1507 test_26a() {
1508         test_mkdir $DIR/d26
1509         test_mkdir $DIR/d26/d26-2
1510         ln -s d26/d26-2 $DIR/s26
1511         touch $DIR/s26/foo || error "File creation failed"
1512 }
1513 run_test 26a "multiple component symlink ======================="
1514
1515 test_26b() {
1516         test_mkdir -p $DIR/$tdir/d26-2
1517         ln -s $tdir/d26-2/foo $DIR/s26-2
1518         touch $DIR/s26-2 || error "File creation failed"
1519 }
1520 run_test 26b "multiple component symlink at end of lookup ======"
1521
1522 test_26c() {
1523         test_mkdir $DIR/d26.2
1524         touch $DIR/d26.2/foo
1525         ln -s d26.2 $DIR/s26.2-1
1526         ln -s s26.2-1 $DIR/s26.2-2
1527         ln -s s26.2-2 $DIR/s26.2-3
1528         chmod 0666 $DIR/s26.2-3/foo
1529 }
1530 run_test 26c "chain of symlinks"
1531
1532 # recursive symlinks (bug 439)
1533 test_26d() {
1534         ln -s d26-3/foo $DIR/d26-3
1535 }
1536 run_test 26d "create multiple component recursive symlink"
1537
1538 test_26e() {
1539         [ ! -h $DIR/d26-3 ] && test_26d
1540         rm $DIR/d26-3
1541 }
1542 run_test 26e "unlink multiple component recursive symlink"
1543
1544 # recursive symlinks (bug 7022)
1545 test_26f() {
1546         test_mkdir $DIR/$tdir
1547         test_mkdir $DIR/$tdir/$tfile
1548         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1549         test_mkdir -p lndir/bar1
1550         test_mkdir $DIR/$tdir/$tfile/$tfile
1551         cd $tfile                || error "cd $tfile failed"
1552         ln -s .. dotdot          || error "ln dotdot failed"
1553         ln -s dotdot/lndir lndir || error "ln lndir failed"
1554         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1555         output=`ls $tfile/$tfile/lndir/bar1`
1556         [ "$output" = bar1 ] && error "unexpected output"
1557         rm -r $tfile             || error "rm $tfile failed"
1558         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1559 }
1560 run_test 26f "rm -r of a directory which has recursive symlink"
1561
1562 test_27a() {
1563         test_mkdir $DIR/$tdir
1564         $LFS getstripe $DIR/$tdir
1565         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1566         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1567         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1568 }
1569 run_test 27a "one stripe file"
1570
1571 test_27b() {
1572         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1573
1574         test_mkdir $DIR/$tdir
1575         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1576         $LFS getstripe -c $DIR/$tdir/$tfile
1577         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1578                 error "two-stripe file doesn't have two stripes"
1579
1580         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1581 }
1582 run_test 27b "create and write to two stripe file"
1583
1584 # 27c family tests specific striping, setstripe -o
1585 test_27ca() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1587         test_mkdir -p $DIR/$tdir
1588         local osts="1"
1589
1590         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1591         $LFS getstripe -i $DIR/$tdir/$tfile
1592         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1593                 error "stripe not on specified OST"
1594
1595         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1596 }
1597 run_test 27ca "one stripe on specified OST"
1598
1599 test_27cb() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         test_mkdir -p $DIR/$tdir
1602         local osts="1,0"
1603         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1604         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1605         echo "$getstripe"
1606
1607         # Strip getstripe output to a space separated list of OSTs
1608         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1609                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1610         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1611                 error "stripes not on specified OSTs"
1612
1613         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1614 }
1615 run_test 27cb "two stripes on specified OSTs"
1616
1617 test_27cc() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1620                 skip "server does not support overstriping"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cc "two stripes on the same OST"
1637
1638 test_27cd() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642         test_mkdir -p $DIR/$tdir
1643         local osts="0,1,1,0"
1644         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1645         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1646         echo "$getstripe"
1647
1648         # Strip getstripe output to a space separated list of OSTs
1649         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1650                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1651         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1652                 error "stripes not on specified OSTs"
1653
1654         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1655 }
1656 run_test 27cd "four stripes on two OSTs"
1657
1658 test_27ce() {
1659         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1660                 skip_env "too many osts, skipping"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         # We do one more stripe than we have OSTs
1664         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1665                 skip_env "ea_inode feature disabled"
1666
1667         test_mkdir -p $DIR/$tdir
1668         local osts=""
1669         for i in $(seq 0 $OSTCOUNT);
1670         do
1671                 osts=$osts"0"
1672                 if [ $i -ne $OSTCOUNT ]; then
1673                         osts=$osts","
1674                 fi
1675         done
1676         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1677         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1678         echo "$getstripe"
1679
1680         # Strip getstripe output to a space separated list of OSTs
1681         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1682                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1683         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1684                 error "stripes not on specified OSTs"
1685
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1687 }
1688 run_test 27ce "more stripes than OSTs with -o"
1689
1690 test_27cf() {
1691         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1692         local pid=0
1693
1694         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1695         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1696         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1697         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1698                 error "failed to set $osp_proc=0"
1699
1700         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1701         pid=$!
1702         sleep 1
1703         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1704         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1705                 error "failed to set $osp_proc=1"
1706         wait $pid
1707         [[ $pid -ne 0 ]] ||
1708                 error "should return error due to $osp_proc=0"
1709 }
1710 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1711
1712 test_27d() {
1713         test_mkdir $DIR/$tdir
1714         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1715                 error "setstripe failed"
1716         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1718 }
1719 run_test 27d "create file with default settings"
1720
1721 test_27e() {
1722         # LU-5839 adds check for existed layout before setting it
1723         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1724                 skip "Need MDS version at least 2.7.56"
1725
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1729         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1730 }
1731 run_test 27e "setstripe existing file (should return error)"
1732
1733 test_27f() {
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1736                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1737         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1738                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1739         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1740         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1741 }
1742 run_test 27f "setstripe with bad stripe size (should return error)"
1743
1744 test_27g() {
1745         test_mkdir $DIR/$tdir
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1748                 error "$DIR/$tdir/$tfile has object"
1749 }
1750 run_test 27g "$LFS getstripe with no objects"
1751
1752 test_27ga() {
1753         test_mkdir $DIR/$tdir
1754         touch $DIR/$tdir/$tfile || error "touch failed"
1755         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1756         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1757         local rc=$?
1758         (( rc == 2 )) || error "getstripe did not return ENOENT"
1759 }
1760 run_test 27ga "$LFS getstripe with missing file (should return error)"
1761
1762 test_27i() {
1763         test_mkdir $DIR/$tdir
1764         touch $DIR/$tdir/$tfile || error "touch failed"
1765         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1766                 error "missing objects"
1767 }
1768 run_test 27i "$LFS getstripe with some objects"
1769
1770 test_27j() {
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1773                 error "setstripe failed" || true
1774 }
1775 run_test 27j "setstripe with bad stripe offset (should return error)"
1776
1777 test_27k() { # bug 2844
1778         test_mkdir $DIR/$tdir
1779         local file=$DIR/$tdir/$tfile
1780         local ll_max_blksize=$((4 * 1024 * 1024))
1781         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1782         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1783         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1784         dd if=/dev/zero of=$file bs=4k count=1
1785         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1786         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1787 }
1788 run_test 27k "limit i_blksize for broken user apps"
1789
1790 test_27l() {
1791         mcreate $DIR/$tfile || error "creating file"
1792         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1793                 error "setstripe should have failed" || true
1794 }
1795 run_test 27l "check setstripe permissions (should return error)"
1796
1797 test_27m() {
1798         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1799
1800         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1801                 skip_env "multiple clients -- skipping"
1802
1803         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1804                    head -n1)
1805         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1806                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1807         fi
1808         stack_trap simple_cleanup_common
1809         test_mkdir $DIR/$tdir
1810         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1811         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1812                 error "dd should fill OST0"
1813         i=2
1814         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1815                 i=$((i + 1))
1816                 [ $i -gt 256 ] && break
1817         done
1818         i=$((i + 1))
1819         touch $DIR/$tdir/$tfile.$i
1820         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1821             awk '{print $1}'| grep -w "0") ] &&
1822                 error "OST0 was full but new created file still use it"
1823         i=$((i + 1))
1824         touch $DIR/$tdir/$tfile.$i
1825         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1826             awk '{print $1}'| grep -w "0") ] &&
1827                 error "OST0 was full but new created file still use it" || true
1828 }
1829 run_test 27m "create file while OST0 was full"
1830
1831 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1832 # if the OST isn't full anymore.
1833 reset_enospc() {
1834         local ostidx=${1:-""}
1835         local delay
1836         local ready
1837         local get_prealloc
1838
1839         local list=$(comma_list $(osts_nodes))
1840         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1841
1842         do_nodes $list lctl set_param fail_loc=0
1843         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1844         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1845                 awk '{print $1 * 2;exit;}')
1846         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1847                         grep -v \"^0$\""
1848         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1849 }
1850
1851 test_27n() {
1852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1854         remote_mds_nodsh && skip "remote MDS with nodsh"
1855         remote_ost_nodsh && skip "remote OST with nodsh"
1856
1857         reset_enospc
1858         rm -f $DIR/$tdir/$tfile
1859         exhaust_precreations 0 0x80000215
1860         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1861         touch $DIR/$tdir/$tfile || error "touch failed"
1862         $LFS getstripe $DIR/$tdir/$tfile
1863         reset_enospc
1864 }
1865 run_test 27n "create file with some full OSTs"
1866
1867 test_27o() {
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_all_precreations 0x215
1876
1877         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1878
1879         reset_enospc
1880         rm -rf $DIR/$tdir/*
1881 }
1882 run_test 27o "create file with all full OSTs (should error)"
1883
1884 function create_and_checktime() {
1885         local fname=$1
1886         local loops=$2
1887         local i
1888
1889         for ((i=0; i < $loops; i++)); do
1890                 local start=$SECONDS
1891                 multiop $fname-$i Oc
1892                 ((SECONDS-start < TIMEOUT)) ||
1893                         error "creation took " $((SECONDS-$start)) && return 1
1894         done
1895 }
1896
1897 test_27oo() {
1898         local mdts=$(comma_list $(mdts_nodes))
1899
1900         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1901                 skip "Need MDS version at least 2.13.57"
1902
1903         local f0=$DIR/${tfile}-0
1904         local f1=$DIR/${tfile}-1
1905
1906         wait_delete_completed
1907
1908         # refill precreated objects
1909         $LFS setstripe -i0 -c1 $f0
1910
1911         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1912         # force QoS allocation policy
1913         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1914         stack_trap "do_nodes $mdts $LCTL set_param \
1915                 lov.*.qos_threshold_rr=$saved" EXIT
1916         sleep_maxage
1917
1918         # one OST is unavailable, but still have few objects preallocated
1919         stop ost1
1920         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1921                 rm -rf $f1 $DIR/$tdir*" EXIT
1922
1923         for ((i=0; i < 7; i++)); do
1924                 mkdir $DIR/$tdir$i || error "can't create dir"
1925                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1926                         error "can't set striping"
1927         done
1928         for ((i=0; i < 7; i++)); do
1929                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1930         done
1931         wait
1932 }
1933 run_test 27oo "don't let few threads to reserve too many objects"
1934
1935 test_27p() {
1936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1938         remote_mds_nodsh && skip "remote MDS with nodsh"
1939         remote_ost_nodsh && skip "remote OST with nodsh"
1940
1941         reset_enospc
1942         rm -f $DIR/$tdir/$tfile
1943         test_mkdir $DIR/$tdir
1944
1945         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1946         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_precreations 0 0x80000215
1950         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1951         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1952         $LFS getstripe $DIR/$tdir/$tfile
1953
1954         reset_enospc
1955 }
1956 run_test 27p "append to a truncated file with some full OSTs"
1957
1958 test_27q() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966
1967         mkdir_on_mdt0 $DIR/$tdir
1968         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1969         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1970                 error "truncate $DIR/$tdir/$tfile failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_all_precreations 0x215
1974
1975         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1976         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1977
1978         reset_enospc
1979 }
1980 run_test 27q "append to truncated file with all OSTs full (should error)"
1981
1982 test_27r() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990         exhaust_precreations 0 0x80000215
1991
1992         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1993
1994         reset_enospc
1995 }
1996 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1997
1998 test_27s() { # bug 10725
1999         test_mkdir $DIR/$tdir
2000         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2001         local stripe_count=0
2002         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2003         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2004                 error "stripe width >= 2^32 succeeded" || true
2005
2006 }
2007 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2008
2009 test_27t() { # bug 10864
2010         WDIR=$(pwd)
2011         WLFS=$(which lfs)
2012         cd $DIR
2013         touch $tfile
2014         $WLFS getstripe $tfile
2015         cd $WDIR
2016 }
2017 run_test 27t "check that utils parse path correctly"
2018
2019 test_27u() { # bug 4900
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         remote_mds_nodsh && skip "remote MDS with nodsh"
2022
2023         local index
2024         local list=$(comma_list $(mdts_nodes))
2025
2026 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2027         do_nodes $list $LCTL set_param fail_loc=0x139
2028         test_mkdir -p $DIR/$tdir
2029         stack_trap "simple_cleanup_common 1000"
2030         createmany -o $DIR/$tdir/$tfile 1000
2031         do_nodes $list $LCTL set_param fail_loc=0
2032
2033         TLOG=$TMP/$tfile.getstripe
2034         $LFS getstripe $DIR/$tdir > $TLOG
2035         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2036         [[ $OBJS -gt 0 ]] &&
2037                 error "$OBJS objects created on OST-0. See $TLOG" ||
2038                 rm -f $TLOG
2039 }
2040 run_test 27u "skip object creation on OSC w/o objects"
2041
2042 test_27v() { # bug 4900
2043         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046         remote_ost_nodsh && skip "remote OST with nodsh"
2047
2048         exhaust_all_precreations 0x215
2049         reset_enospc
2050
2051         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2052
2053         touch $DIR/$tdir/$tfile
2054         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2055         # all except ost1
2056         for (( i=1; i < OSTCOUNT; i++ )); do
2057                 do_facet ost$i lctl set_param fail_loc=0x705
2058         done
2059         local START=`date +%s`
2060         createmany -o $DIR/$tdir/$tfile 32
2061
2062         local FINISH=`date +%s`
2063         local TIMEOUT=`lctl get_param -n timeout`
2064         local PROCESS=$((FINISH - START))
2065         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2066                error "$FINISH - $START >= $TIMEOUT / 2"
2067         sleep $((TIMEOUT / 2 - PROCESS))
2068         reset_enospc
2069 }
2070 run_test 27v "skip object creation on slow OST"
2071
2072 test_27w() { # bug 10997
2073         test_mkdir $DIR/$tdir
2074         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2075         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2076                 error "stripe size $size != 65536" || true
2077         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2078                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2079 }
2080 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2081
2082 test_27wa() {
2083         [[ $OSTCOUNT -lt 2 ]] &&
2084                 skip_env "skipping multiple stripe count/offset test"
2085
2086         test_mkdir $DIR/$tdir
2087         for i in $(seq 1 $OSTCOUNT); do
2088                 offset=$((i - 1))
2089                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2090                         error "setstripe -c $i -i $offset failed"
2091                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2092                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2093                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2094                 [ $index -ne $offset ] &&
2095                         error "stripe offset $index != $offset" || true
2096         done
2097 }
2098 run_test 27wa "check $LFS setstripe -c -i options"
2099
2100 test_27x() {
2101         remote_ost_nodsh && skip "remote OST with nodsh"
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104
2105         OFFSET=$(($OSTCOUNT - 1))
2106         OSTIDX=0
2107         local OST=$(ostname_from_index $OSTIDX)
2108
2109         test_mkdir $DIR/$tdir
2110         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2111         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2112         sleep_maxage
2113         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2114         for i in $(seq 0 $OFFSET); do
2115                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2116                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2117                 error "OST0 was degraded but new created file still use it"
2118         done
2119         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2120 }
2121 run_test 27x "create files while OST0 is degraded"
2122
2123 test_27y() {
2124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2125         remote_mds_nodsh && skip "remote MDS with nodsh"
2126         remote_ost_nodsh && skip "remote OST with nodsh"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2130         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2131                 osp.$mdtosc.prealloc_last_id)
2132         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2133                 osp.$mdtosc.prealloc_next_id)
2134         local fcount=$((last_id - next_id))
2135         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2136         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2137
2138         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2139                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2140         local OST_DEACTIVE_IDX=-1
2141         local OSC
2142         local OSTIDX
2143         local OST
2144
2145         for OSC in $MDS_OSCS; do
2146                 OST=$(osc_to_ost $OSC)
2147                 OSTIDX=$(index_from_ostuuid $OST)
2148                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2149                         OST_DEACTIVE_IDX=$OSTIDX
2150                 fi
2151                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2152                         echo $OSC "is Deactivated:"
2153                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2154                 fi
2155         done
2156
2157         OSTIDX=$(index_from_ostuuid $OST)
2158         test_mkdir $DIR/$tdir
2159         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2160
2161         for OSC in $MDS_OSCS; do
2162                 OST=$(osc_to_ost $OSC)
2163                 OSTIDX=$(index_from_ostuuid $OST)
2164                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2165                         echo $OST "is degraded:"
2166                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2167                                                 obdfilter.$OST.degraded=1
2168                 fi
2169         done
2170
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $fcount
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2178                         echo $OST "is recovered from degraded:"
2179                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2180                                                 obdfilter.$OST.degraded=0
2181                 else
2182                         do_facet $SINGLEMDS lctl --device %$OSC activate
2183                 fi
2184         done
2185
2186         # all osp devices get activated, hence -1 stripe count restored
2187         local stripe_count=0
2188
2189         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2190         # devices get activated.
2191         sleep_maxage
2192         $LFS setstripe -c -1 $DIR/$tfile
2193         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2194         rm -f $DIR/$tfile
2195         [ $stripe_count -ne $OSTCOUNT ] &&
2196                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2197         return 0
2198 }
2199 run_test 27y "create files while OST0 is degraded and the rest inactive"
2200
2201 check_seq_oid()
2202 {
2203         log "check file $1"
2204
2205         lmm_count=$($LFS getstripe -c $1)
2206         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2207         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2208
2209         local old_ifs="$IFS"
2210         IFS=$'[:]'
2211         fid=($($LFS path2fid $1))
2212         IFS="$old_ifs"
2213
2214         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2215         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2216
2217         # compare lmm_seq and lu_fid->f_seq
2218         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2219         # compare lmm_object_id and lu_fid->oid
2220         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2221
2222         # check the trusted.fid attribute of the OST objects of the file
2223         local have_obdidx=false
2224         local stripe_nr=0
2225         $LFS getstripe $1 | while read obdidx oid hex seq; do
2226                 # skip lines up to and including "obdidx"
2227                 [ -z "$obdidx" ] && break
2228                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2229                 $have_obdidx || continue
2230
2231                 local ost=$((obdidx + 1))
2232                 local dev=$(ostdevname $ost)
2233                 local oid_hex
2234
2235                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2236
2237                 seq=$(echo $seq | sed -e "s/^0x//g")
2238                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2239                         oid_hex=$(echo $oid)
2240                 else
2241                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2242                 fi
2243                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2244
2245                 local ff=""
2246                 #
2247                 # Don't unmount/remount the OSTs if we don't need to do that.
2248                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2249                 # update too, until that use mount/ll_decode_filter_fid/mount.
2250                 # Re-enable when debugfs will understand new filter_fid.
2251                 #
2252                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2253                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2254                                 $dev 2>/dev/null" | grep "parent=")
2255                 fi
2256                 if [ -z "$ff" ]; then
2257                         stop ost$ost
2258                         mount_fstype ost$ost
2259                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2260                                 $(facet_mntpt ost$ost)/$obj_file)
2261                         unmount_fstype ost$ost
2262                         start ost$ost $dev $OST_MOUNT_OPTS
2263                         clients_up
2264                 fi
2265
2266                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2267
2268                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2269
2270                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2271                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2272                 #
2273                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2274                 #       stripe_size=1048576 component_id=1 component_start=0 \
2275                 #       component_end=33554432
2276                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2277                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2278                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2279                 local ff_pstripe
2280                 if grep -q 'stripe=' <<<$ff; then
2281                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2282                 else
2283                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2284                         # into f_ver in this case.  See comment on ff_parent.
2285                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2286                 fi
2287
2288                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2289                 [ $ff_pseq = $lmm_seq ] ||
2290                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2291                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2292                 [ $ff_poid = $lmm_oid ] ||
2293                         error "FF parent OID $ff_poid != $lmm_oid"
2294                 (($ff_pstripe == $stripe_nr)) ||
2295                         error "FF stripe $ff_pstripe != $stripe_nr"
2296
2297                 stripe_nr=$((stripe_nr + 1))
2298                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2299                         continue
2300                 if grep -q 'stripe_count=' <<<$ff; then
2301                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2302                                             -e 's/ .*//' <<<$ff)
2303                         [ $lmm_count = $ff_scnt ] ||
2304                                 error "FF stripe count $lmm_count != $ff_scnt"
2305                 fi
2306         done
2307 }
2308
2309 test_27z() {
2310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2311         remote_ost_nodsh && skip "remote OST with nodsh"
2312
2313         test_mkdir $DIR/$tdir
2314         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2315                 { error "setstripe -c -1 failed"; return 1; }
2316         # We need to send a write to every object to get parent FID info set.
2317         # This _should_ also work for setattr, but does not currently.
2318         # touch $DIR/$tdir/$tfile-1 ||
2319         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2320                 { error "dd $tfile-1 failed"; return 2; }
2321         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2322                 { error "setstripe -c -1 failed"; return 3; }
2323         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2324                 { error "dd $tfile-2 failed"; return 4; }
2325
2326         # make sure write RPCs have been sent to OSTs
2327         sync; sleep 5; sync
2328
2329         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2330         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2331 }
2332 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2333
2334 test_27A() { # b=19102
2335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2336
2337         save_layout_restore_at_exit $MOUNT
2338         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2339         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2340                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2341         local default_size=$($LFS getstripe -S $MOUNT)
2342         local default_offset=$($LFS getstripe -i $MOUNT)
2343         local dsize=$(do_facet $SINGLEMDS \
2344                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2345         [ $default_size -eq $dsize ] ||
2346                 error "stripe size $default_size != $dsize"
2347         [ $default_offset -eq -1 ] ||
2348                 error "stripe offset $default_offset != -1"
2349 }
2350 run_test 27A "check filesystem-wide default LOV EA values"
2351
2352 test_27B() { # LU-2523
2353         test_mkdir $DIR/$tdir
2354         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2355         touch $DIR/$tdir/f0
2356         # open f1 with O_LOV_DELAY_CREATE
2357         # rename f0 onto f1
2358         # call setstripe ioctl on open file descriptor for f1
2359         # close
2360         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2361                 $DIR/$tdir/f0
2362
2363         rm -f $DIR/$tdir/f1
2364         # open f1 with O_LOV_DELAY_CREATE
2365         # unlink f1
2366         # call setstripe ioctl on open file descriptor for f1
2367         # close
2368         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2369
2370         # Allow multiop to fail in imitation of NFS's busted semantics.
2371         true
2372 }
2373 run_test 27B "call setstripe on open unlinked file/rename victim"
2374
2375 # 27C family tests full striping and overstriping
2376 test_27Ca() { #LU-2871
2377         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2378
2379         declare -a ost_idx
2380         local index
2381         local found
2382         local i
2383         local j
2384
2385         test_mkdir $DIR/$tdir
2386         cd $DIR/$tdir
2387         for i in $(seq 0 $((OSTCOUNT - 1))); do
2388                 # set stripe across all OSTs starting from OST$i
2389                 $LFS setstripe -i $i -c -1 $tfile$i
2390                 # get striping information
2391                 ost_idx=($($LFS getstripe $tfile$i |
2392                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2393                 echo "OST Index: ${ost_idx[*]}"
2394
2395                 # check the layout
2396                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2397                         error "${#ost_idx[@]} != $OSTCOUNT"
2398
2399                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2400                         found=0
2401                         for j in "${ost_idx[@]}"; do
2402                                 if [ $index -eq $j ]; then
2403                                         found=1
2404                                         break
2405                                 fi
2406                         done
2407                         [ $found = 1 ] ||
2408                                 error "Can not find $index in ${ost_idx[*]}"
2409                 done
2410         done
2411 }
2412 run_test 27Ca "check full striping across all OSTs"
2413
2414 test_27Cb() {
2415         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2416                 skip "server does not support overstriping"
2417         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2418                 skip_env "too many osts, skipping"
2419
2420         test_mkdir -p $DIR/$tdir
2421         local setcount=$(($OSTCOUNT * 2))
2422         [ $setcount -lt 160 ] || large_xattr_enabled ||
2423                 skip_env "ea_inode feature disabled"
2424
2425         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2426                 error "setstripe failed"
2427
2428         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2429         [ $count -eq $setcount ] ||
2430                 error "stripe count $count, should be $setcount"
2431
2432         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2433                 error "overstriped should be set in pattern"
2434
2435         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2436                 error "dd failed"
2437 }
2438 run_test 27Cb "more stripes than OSTs with -C"
2439
2440 test_27Cc() {
2441         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2442                 skip "server does not support overstriping"
2443         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2444
2445         test_mkdir -p $DIR/$tdir
2446         local setcount=$(($OSTCOUNT - 1))
2447
2448         [ $setcount -lt 160 ] || large_xattr_enabled ||
2449                 skip_env "ea_inode feature disabled"
2450
2451         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2452                 error "setstripe failed"
2453
2454         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2455         [ $count -eq $setcount ] ||
2456                 error "stripe count $count, should be $setcount"
2457
2458         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2459                 error "overstriped should not be set in pattern"
2460
2461         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2462                 error "dd failed"
2463 }
2464 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2465
2466 test_27Cd() {
2467         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2468                 skip "server does not support overstriping"
2469         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2470         large_xattr_enabled || skip_env "ea_inode feature disabled"
2471
2472         test_mkdir -p $DIR/$tdir
2473         local setcount=$LOV_MAX_STRIPE_COUNT
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2483                 error "overstriped should be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487
2488         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2489 }
2490 run_test 27Cd "test maximum stripe count"
2491
2492 test_27Ce() {
2493         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2494                 skip "server does not support overstriping"
2495         test_mkdir -p $DIR/$tdir
2496
2497         pool_add $TESTNAME || error "Pool creation failed"
2498         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2499
2500         local setcount=8
2501
2502         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2503                 error "setstripe failed"
2504
2505         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2506         [ $count -eq $setcount ] ||
2507                 error "stripe count $count, should be $setcount"
2508
2509         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2510                 error "overstriped should be set in pattern"
2511
2512         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2513                 error "dd failed"
2514
2515         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2516 }
2517 run_test 27Ce "test pool with overstriping"
2518
2519 test_27Cf() {
2520         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2521                 skip "server does not support overstriping"
2522         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2523                 skip_env "too many osts, skipping"
2524
2525         test_mkdir -p $DIR/$tdir
2526
2527         local setcount=$(($OSTCOUNT * 2))
2528         [ $setcount -lt 160 ] || large_xattr_enabled ||
2529                 skip_env "ea_inode feature disabled"
2530
2531         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2532                 error "setstripe failed"
2533
2534         echo 1 > $DIR/$tdir/$tfile
2535
2536         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2537         [ $count -eq $setcount ] ||
2538                 error "stripe count $count, should be $setcount"
2539
2540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2541                 error "overstriped should be set in pattern"
2542
2543         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2544                 error "dd failed"
2545
2546         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2547 }
2548 run_test 27Cf "test default inheritance with overstriping"
2549
2550 test_27D() {
2551         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2552         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2553         remote_mds_nodsh && skip "remote MDS with nodsh"
2554
2555         local POOL=${POOL:-testpool}
2556         local first_ost=0
2557         local last_ost=$(($OSTCOUNT - 1))
2558         local ost_step=1
2559         local ost_list=$(seq $first_ost $ost_step $last_ost)
2560         local ost_range="$first_ost $last_ost $ost_step"
2561
2562         test_mkdir $DIR/$tdir
2563         pool_add $POOL || error "pool_add failed"
2564         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2565
2566         local skip27D
2567         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2568                 skip27D+="-s 29"
2569         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2570                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2571                         skip27D+=" -s 30,31"
2572         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2573           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2574                 skip27D+=" -s 32,33"
2575         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2576                 skip27D+=" -s 34"
2577         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2578                 error "llapi_layout_test failed"
2579
2580         destroy_test_pools || error "destroy test pools failed"
2581 }
2582 run_test 27D "validate llapi_layout API"
2583
2584 # Verify that default_easize is increased from its initial value after
2585 # accessing a widely striped file.
2586 test_27E() {
2587         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2588         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2589                 skip "client does not have LU-3338 fix"
2590
2591         # 72 bytes is the minimum space required to store striping
2592         # information for a file striped across one OST:
2593         # (sizeof(struct lov_user_md_v3) +
2594         #  sizeof(struct lov_user_ost_data_v1))
2595         local min_easize=72
2596         $LCTL set_param -n llite.*.default_easize $min_easize ||
2597                 error "lctl set_param failed"
2598         local easize=$($LCTL get_param -n llite.*.default_easize)
2599
2600         [ $easize -eq $min_easize ] ||
2601                 error "failed to set default_easize"
2602
2603         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2604                 error "setstripe failed"
2605         # In order to ensure stat() call actually talks to MDS we need to
2606         # do something drastic to this file to shake off all lock, e.g.
2607         # rename it (kills lookup lock forcing cache cleaning)
2608         mv $DIR/$tfile $DIR/${tfile}-1
2609         ls -l $DIR/${tfile}-1
2610         rm $DIR/${tfile}-1
2611
2612         easize=$($LCTL get_param -n llite.*.default_easize)
2613
2614         [ $easize -gt $min_easize ] ||
2615                 error "default_easize not updated"
2616 }
2617 run_test 27E "check that default extended attribute size properly increases"
2618
2619 test_27F() { # LU-5346/LU-7975
2620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2621         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2622         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2623                 skip "Need MDS version at least 2.8.51"
2624         remote_ost_nodsh && skip "remote OST with nodsh"
2625
2626         test_mkdir $DIR/$tdir
2627         rm -f $DIR/$tdir/f0
2628         $LFS setstripe -c 2 $DIR/$tdir
2629
2630         # stop all OSTs to reproduce situation for LU-7975 ticket
2631         for num in $(seq $OSTCOUNT); do
2632                 stop ost$num
2633         done
2634
2635         # open/create f0 with O_LOV_DELAY_CREATE
2636         # truncate f0 to a non-0 size
2637         # close
2638         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2639
2640         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2641         # open/write it again to force delayed layout creation
2642         cat /etc/hosts > $DIR/$tdir/f0 &
2643         catpid=$!
2644
2645         # restart OSTs
2646         for num in $(seq $OSTCOUNT); do
2647                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2648                         error "ost$num failed to start"
2649         done
2650
2651         wait $catpid || error "cat failed"
2652
2653         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2654         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2655                 error "wrong stripecount"
2656
2657 }
2658 run_test 27F "Client resend delayed layout creation with non-zero size"
2659
2660 test_27G() { #LU-10629
2661         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2662                 skip "Need MDS version at least 2.11.51"
2663         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2664         remote_mds_nodsh && skip "remote MDS with nodsh"
2665         local POOL=${POOL:-testpool}
2666         local ostrange="0 0 1"
2667
2668         test_mkdir $DIR/$tdir
2669         touch $DIR/$tdir/$tfile.nopool
2670         pool_add $POOL || error "pool_add failed"
2671         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2672         $LFS setstripe -p $POOL $DIR/$tdir
2673
2674         local pool=$($LFS getstripe -p $DIR/$tdir)
2675
2676         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2677         touch $DIR/$tdir/$tfile.default
2678         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2679         $LFS find $DIR/$tdir -type f --pool $POOL
2680         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2681         [[ "$found" == "2" ]] ||
2682                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2683
2684         $LFS setstripe -d $DIR/$tdir
2685
2686         pool=$($LFS getstripe -p -d $DIR/$tdir)
2687
2688         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2689 }
2690 run_test 27G "Clear OST pool from stripe"
2691
2692 test_27H() {
2693         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2694                 skip "Need MDS version newer than 2.11.54"
2695         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2696         test_mkdir $DIR/$tdir
2697         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2698         touch $DIR/$tdir/$tfile
2699         $LFS getstripe -c $DIR/$tdir/$tfile
2700         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2701                 error "two-stripe file doesn't have two stripes"
2702
2703         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2704         $LFS getstripe -y $DIR/$tdir/$tfile
2705         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2706              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2707                 error "expected l_ost_idx: [02]$ not matched"
2708
2709         # make sure ost list has been cleared
2710         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2711         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2712                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2713         touch $DIR/$tdir/f3
2714         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2715 }
2716 run_test 27H "Set specific OSTs stripe"
2717
2718 test_27I() {
2719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2721         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2722                 skip "Need MDS version newer than 2.12.52"
2723         local pool=$TESTNAME
2724         local ostrange="1 1 1"
2725
2726         save_layout_restore_at_exit $MOUNT
2727         $LFS setstripe -c 2 -i 0 $MOUNT
2728         pool_add $pool || error "pool_add failed"
2729         pool_add_targets $pool $ostrange ||
2730                 error "pool_add_targets failed"
2731         test_mkdir $DIR/$tdir
2732         $LFS setstripe -p $pool $DIR/$tdir
2733         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2734         $LFS getstripe $DIR/$tdir/$tfile
2735 }
2736 run_test 27I "check that root dir striping does not break parent dir one"
2737
2738 test_27J() {
2739         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2740                 skip "Need MDS version newer than 2.12.51"
2741
2742         test_mkdir $DIR/$tdir
2743         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2744         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2745
2746         # create foreign file (raw way)
2747         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2748                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2749
2750         ! $LFS setstripe --foreign --flags foo \
2751                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2752                         error "creating $tfile with '--flags foo' should fail"
2753
2754         ! $LFS setstripe --foreign --flags 0xffffffff \
2755                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2756                         error "creating $tfile w/ 0xffffffff flags should fail"
2757
2758         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2759                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2760
2761         # verify foreign file (raw way)
2762         parse_foreign_file -f $DIR/$tdir/$tfile |
2763                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2764                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2765         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2766                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2767         parse_foreign_file -f $DIR/$tdir/$tfile |
2768                 grep "lov_foreign_size: 73" ||
2769                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2770         parse_foreign_file -f $DIR/$tdir/$tfile |
2771                 grep "lov_foreign_type: 1" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_flags: 0x0000DA08" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2776         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_value: 0x" |
2778                 sed -e 's/lov_foreign_value: 0x//')
2779         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2780         [[ $lov = ${lov2// /} ]] ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2782
2783         # create foreign file (lfs + API)
2784         $LFS setstripe --foreign=none --flags 0xda08 \
2785                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2786                 error "$DIR/$tdir/${tfile}2: create failed"
2787
2788         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2789                 grep "lfm_magic:.*0x0BD70BD0" ||
2790                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2791         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2792         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2793                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2795                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2796         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2797                 grep "lfm_flags:.*0x0000DA08" ||
2798                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2799         $LFS getstripe $DIR/$tdir/${tfile}2 |
2800                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2802
2803         # modify striping should fail
2804         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2805                 error "$DIR/$tdir/$tfile: setstripe should fail"
2806         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2807                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2808
2809         # R/W should fail
2810         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2811         cat $DIR/$tdir/${tfile}2 &&
2812                 error "$DIR/$tdir/${tfile}2: read should fail"
2813         cat /etc/passwd > $DIR/$tdir/$tfile &&
2814                 error "$DIR/$tdir/$tfile: write should fail"
2815         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2816                 error "$DIR/$tdir/${tfile}2: write should fail"
2817
2818         # chmod should work
2819         chmod 222 $DIR/$tdir/$tfile ||
2820                 error "$DIR/$tdir/$tfile: chmod failed"
2821         chmod 222 $DIR/$tdir/${tfile}2 ||
2822                 error "$DIR/$tdir/${tfile}2: chmod failed"
2823
2824         # chown should work
2825         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chown failed"
2827         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chown failed"
2829
2830         # rename should work
2831         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2832                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2833         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2834                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2835
2836         #remove foreign file
2837         rm $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2839         rm $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2841 }
2842 run_test 27J "basic ops on file with foreign LOV"
2843
2844 test_27K() {
2845         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2846                 skip "Need MDS version newer than 2.12.49"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign dir (raw way)
2853         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2854                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setdirstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2858                         error "creating $tdir with '--flags foo' should fail"
2859
2860         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2862                         error "creating $tdir w/ 0xffffffff flags should fail"
2863
2864         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2865                 error "create_foreign_dir FAILED"
2866
2867         # verify foreign dir (raw way)
2868         parse_foreign_dir -d $DIR/$tdir/$tdir |
2869                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2871         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2872                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2873         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2874                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2875         parse_foreign_dir -d $DIR/$tdir/$tdir |
2876                 grep "lmv_foreign_flags: 55813$" ||
2877                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2878         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2879                 grep "lmv_foreign_value: 0x" |
2880                 sed 's/lmv_foreign_value: 0x//')
2881         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2882                 sed 's/ //g')
2883         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2884
2885         # create foreign dir (lfs + API)
2886         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2887                 $DIR/$tdir/${tdir}2 ||
2888                 error "$DIR/$tdir/${tdir}2: create failed"
2889
2890         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2891
2892         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2893                 grep "lfm_magic:.*0x0CD50CD0" ||
2894                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2895         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2896         # - sizeof(lfm_type) - sizeof(lfm_flags)
2897         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2898                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2899         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2901         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2902                 grep "lfm_flags:.*0x0000DA05" ||
2903                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2904         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2905                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2907
2908         # file create in dir should fail
2909         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2910         touch $DIR/$tdir/${tdir}2/$tfile &&
2911                 error "$DIR/${tdir}2: file create should fail"
2912
2913         # chmod should work
2914         chmod 777 $DIR/$tdir/$tdir ||
2915                 error "$DIR/$tdir: chmod failed"
2916         chmod 777 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/${tdir}2: chmod failed"
2918
2919         # chown should work
2920         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chown failed"
2922         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chown failed"
2924
2925         # rename should work
2926         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2927                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2928         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2929                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2930
2931         #remove foreign dir
2932         rmdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2934         rmdir $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2936 }
2937 run_test 27K "basic ops on dir with foreign LMV"
2938
2939 test_27L() {
2940         remote_mds_nodsh && skip "remote MDS with nodsh"
2941
2942         local POOL=${POOL:-$TESTNAME}
2943
2944         pool_add $POOL || error "pool_add failed"
2945
2946         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2947                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2948                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2949 }
2950 run_test 27L "lfs pool_list gives correct pool name"
2951
2952 test_27M() {
2953         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2954                 skip "Need MDS version >= than 2.12.57"
2955         remote_mds_nodsh && skip "remote MDS with nodsh"
2956         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2957
2958         # Set default striping on directory
2959         local setcount=4
2960         local stripe_opt
2961         local mdts=$(comma_list $(mdts_nodes))
2962
2963         # if we run against a 2.12 server which lacks overstring support
2964         # then the connect_flag will not report overstriping, even if client
2965         # is 2.14+
2966         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2967                 stripe_opt="-C $setcount"
2968         elif (( $OSTCOUNT >= $setcount )); then
2969                 stripe_opt="-c $setcount"
2970         else
2971                 skip "server does not support overstriping"
2972         fi
2973
2974         test_mkdir $DIR/$tdir
2975
2976         # Validate existing append_* params and ensure restore
2977         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2978         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2980
2981         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2982         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2983         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2984
2985         $LFS setstripe $stripe_opt $DIR/$tdir
2986
2987         echo 1 > $DIR/$tdir/${tfile}.1
2988         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2989         [ $count -eq $setcount ] ||
2990                 error "(1) stripe count $count, should be $setcount"
2991
2992         local appendcount=$orig_count
2993         echo 1 >> $DIR/$tdir/${tfile}.2_append
2994         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2995         [ $count -eq $appendcount ] ||
2996                 error "(2)stripe count $count, should be $appendcount for append"
2997
2998         # Disable O_APPEND striping, verify it works
2999         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3000
3001         # Should now get the default striping, which is 4
3002         setcount=4
3003         echo 1 >> $DIR/$tdir/${tfile}.3_append
3004         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3005         [ $count -eq $setcount ] ||
3006                 error "(3) stripe count $count, should be $setcount"
3007
3008         # Try changing the stripe count for append files
3009         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3010
3011         # Append striping is now 2 (directory default is still 4)
3012         appendcount=2
3013         echo 1 >> $DIR/$tdir/${tfile}.4_append
3014         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3015         [ $count -eq $appendcount ] ||
3016                 error "(4) stripe count $count, should be $appendcount for append"
3017
3018         # Test append stripe count of -1
3019         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3020         appendcount=$OSTCOUNT
3021         echo 1 >> $DIR/$tdir/${tfile}.5
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3023         [ $count -eq $appendcount ] ||
3024                 error "(5) stripe count $count, should be $appendcount for append"
3025
3026         # Set append striping back to default of 1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3028
3029         # Try a new default striping, PFL + DOM
3030         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3031
3032         # Create normal DOM file, DOM returns stripe count == 0
3033         setcount=0
3034         touch $DIR/$tdir/${tfile}.6
3035         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3036         [ $count -eq $setcount ] ||
3037                 error "(6) stripe count $count, should be $setcount"
3038
3039         # Show
3040         appendcount=1
3041         echo 1 >> $DIR/$tdir/${tfile}.7_append
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3043         [ $count -eq $appendcount ] ||
3044                 error "(7) stripe count $count, should be $appendcount for append"
3045
3046         # Clean up DOM layout
3047         $LFS setstripe -d $DIR/$tdir
3048
3049         save_layout_restore_at_exit $MOUNT
3050         # Now test that append striping works when layout is from root
3051         $LFS setstripe -c 2 $MOUNT
3052         # Make a special directory for this
3053         mkdir $DIR/${tdir}/${tdir}.2
3054
3055         # Verify for normal file
3056         setcount=2
3057         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3058         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3059         [ $count -eq $setcount ] ||
3060                 error "(8) stripe count $count, should be $setcount"
3061
3062         appendcount=1
3063         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3064         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(9) stripe count $count, should be $appendcount for append"
3067
3068         # Now test O_APPEND striping with pools
3069         pool_add $TESTNAME || error "pool creation failed"
3070         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3071         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3072
3073         echo 1 >> $DIR/$tdir/${tfile}.10_append
3074
3075         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3076         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3077
3078         # Check that count is still correct
3079         appendcount=1
3080         echo 1 >> $DIR/$tdir/${tfile}.11_append
3081         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3082         [ $count -eq $appendcount ] ||
3083                 error "(11) stripe count $count, should be $appendcount for append"
3084
3085         # Disable O_APPEND stripe count, verify pool works separately
3086         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3087
3088         echo 1 >> $DIR/$tdir/${tfile}.12_append
3089
3090         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3091         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3092
3093         # Remove pool setting, verify it's not applied
3094         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3095
3096         echo 1 >> $DIR/$tdir/${tfile}.13_append
3097
3098         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3099         [ "$pool" = "" ] || error "(13) pool found: $pool"
3100 }
3101 run_test 27M "test O_APPEND striping"
3102
3103 test_27N() {
3104         combined_mgs_mds && skip "needs separate MGS/MDT"
3105
3106         pool_add $TESTNAME || error "pool_add failed"
3107         do_facet mgs "$LCTL pool_list $FSNAME" |
3108                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3109                 error "lctl pool_list on MGS failed"
3110 }
3111 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3112
3113 clean_foreign_symlink() {
3114         trap 0
3115         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3116         for i in $DIR/$tdir/* ; do
3117                 $LFS unlink_foreign $i || true
3118         done
3119 }
3120
3121 test_27O() {
3122         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3123                 skip "Need MDS version newer than 2.12.51"
3124
3125         test_mkdir $DIR/$tdir
3126         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3127         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3128
3129         trap clean_foreign_symlink EXIT
3130
3131         # enable foreign_symlink behaviour
3132         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3133
3134         # foreign symlink LOV format is a partial path by default
3135
3136         # create foreign file (lfs + API)
3137         $LFS setstripe --foreign=symlink --flags 0xda05 \
3138                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3139                 error "$DIR/$tdir/${tfile}: create failed"
3140
3141         $LFS getstripe -v $DIR/$tdir/${tfile} |
3142                 grep "lfm_magic:.*0x0BD70BD0" ||
3143                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3144         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3145                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3146         $LFS getstripe -v $DIR/$tdir/${tfile} |
3147                 grep "lfm_flags:.*0x0000DA05" ||
3148                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3149         $LFS getstripe $DIR/$tdir/${tfile} |
3150                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3152
3153         # modify striping should fail
3154         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3155                 error "$DIR/$tdir/$tfile: setstripe should fail"
3156
3157         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3158         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3159         cat /etc/passwd > $DIR/$tdir/$tfile &&
3160                 error "$DIR/$tdir/$tfile: write should fail"
3161
3162         # rename should succeed
3163         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3164                 error "$DIR/$tdir/$tfile: rename has failed"
3165
3166         #remove foreign_symlink file should fail
3167         rm $DIR/$tdir/${tfile}.new &&
3168                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3169
3170         #test fake symlink
3171         mkdir /tmp/${uuid1} ||
3172                 error "/tmp/${uuid1}: mkdir has failed"
3173         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3174                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3175         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3176         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3177                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3178         #read should succeed now
3179         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3180                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3181         #write should succeed now
3182         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3184         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3185                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3186         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3187                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3188
3189         #check that getstripe still works
3190         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3192
3193         # chmod should still succeed
3194         chmod 644 $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3196
3197         # chown should still succeed
3198         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3199                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3200
3201         # rename should still succeed
3202         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3203                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3204
3205         #remove foreign_symlink file should still fail
3206         rm $DIR/$tdir/${tfile} &&
3207                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3208
3209         #use special ioctl() to unlink foreign_symlink file
3210         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3211                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3212
3213 }
3214 run_test 27O "basic ops on foreign file of symlink type"
3215
3216 test_27P() {
3217         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3218                 skip "Need MDS version newer than 2.12.49"
3219
3220         test_mkdir $DIR/$tdir
3221         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3222         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3223
3224         trap clean_foreign_symlink EXIT
3225
3226         # enable foreign_symlink behaviour
3227         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3228
3229         # foreign symlink LMV format is a partial path by default
3230
3231         # create foreign dir (lfs + API)
3232         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3233                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3234                 error "$DIR/$tdir/${tdir}: create failed"
3235
3236         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3237
3238         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3239                 grep "lfm_magic:.*0x0CD50CD0" ||
3240                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3241         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3242                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3243         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3244                 grep "lfm_flags:.*0x0000DA05" ||
3245                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3246         $LFS getdirstripe $DIR/$tdir/${tdir} |
3247                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3249
3250         # file create in dir should fail
3251         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3252         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3253
3254         # rename should succeed
3255         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3256                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3257
3258         #remove foreign_symlink dir should fail
3259         rmdir $DIR/$tdir/${tdir}.new &&
3260                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3261
3262         #test fake symlink
3263         mkdir -p /tmp/${uuid1}/${uuid2} ||
3264                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3265         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3266                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3267         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3268         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3269                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3270         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3271                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3272
3273         #check that getstripe fails now that foreign_symlink enabled
3274         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3276
3277         # file create in dir should work now
3278         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3279                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3280         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3281                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3282         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3283                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3284
3285         # chmod should still succeed
3286         chmod 755 $DIR/$tdir/${tdir}.new ||
3287                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3288
3289         # chown should still succeed
3290         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3291                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3292
3293         # rename should still succeed
3294         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3295                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3296
3297         #remove foreign_symlink dir should still fail
3298         rmdir $DIR/$tdir/${tdir} &&
3299                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3300
3301         #use special ioctl() to unlink foreign_symlink file
3302         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3303                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3304
3305         #created file should still exist
3306         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3307                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3308         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3309                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3310 }
3311 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3312
3313 test_27Q() {
3314         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3315         stack_trap "rm -f $TMP/$tfile*"
3316
3317         test_mkdir $DIR/$tdir-1
3318         test_mkdir $DIR/$tdir-2
3319
3320         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3321         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3322
3323         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3324         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3325
3326         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3327         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3328
3329         # Create some bad symlinks and ensure that we don't loop
3330         # forever or something. These should return ELOOP (40) and
3331         # ENOENT (2) but I don't want to test for that because there's
3332         # always some weirdo architecture that needs to ruin
3333         # everything by defining these error numbers differently.
3334
3335         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3336         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3337
3338         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3339         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3340
3341         return 0
3342 }
3343 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3344
3345 test_27R() {
3346         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3347                 skip "need MDS 2.14.55 or later"
3348         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3349
3350         local testdir="$DIR/$tdir"
3351         test_mkdir -p $testdir
3352         stack_trap "rm -rf $testdir"
3353         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3354
3355         local f1="$testdir/f1"
3356         touch $f1 || error "failed to touch $f1"
3357         local count=$($LFS getstripe -c $f1)
3358         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3359
3360         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3361         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3362
3363         local maxcount=$(($OSTCOUNT - 1))
3364         local mdts=$(comma_list $(mdts_nodes))
3365         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3366         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3367
3368         local f2="$testdir/f2"
3369         touch $f2 || error "failed to touch $f2"
3370         local count=$($LFS getstripe -c $f2)
3371         (( $count == $maxcount )) || error "wrong stripe count"
3372 }
3373 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3374
3375 test_27T() {
3376         [ $(facet_host client) == $(facet_host ost1) ] &&
3377                 skip "need ost1 and client on different nodes"
3378
3379 #define OBD_FAIL_OSC_NO_GRANT            0x411
3380         $LCTL set_param fail_loc=0x20000411 fail_val=1
3381 #define OBD_FAIL_OST_ENOSPC              0x215
3382         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3383         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3384         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3385                 error "multiop failed"
3386 }
3387 run_test 27T "no eio on close on partial write due to enosp"
3388
3389 test_27U() {
3390         local dir=$DIR/$tdir
3391         local file=$dir/$tfile
3392         local append_pool=${TESTNAME}-append
3393         local normal_pool=${TESTNAME}-normal
3394         local pool
3395         local stripe_count
3396         local stripe_count2
3397         local mdts=$(comma_list $(mdts_nodes))
3398
3399         # FIMXE
3400         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3401         #       skip "Need MDS version at least 2.15.42"
3402
3403         # Validate existing append_* params and ensure restore
3404         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3405         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3406         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3407
3408         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3409         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3410         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3411
3412         pool_add $append_pool || error "pool creation failed"
3413         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3414
3415         pool_add $normal_pool || error "pool creation failed"
3416         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3417
3418         test_mkdir $dir
3419         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3420
3421         echo XXX >> $file.1
3422         $LFS getstripe $file.1
3423
3424         pool=$($LFS getstripe -p $file.1)
3425         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3426
3427         stripe_count2=$($LFS getstripe -c $file.1)
3428         ((stripe_count2 == stripe_count)) ||
3429                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3430
3431         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3432
3433         echo XXX >> $file.2
3434         $LFS getstripe $file.2
3435
3436         pool=$($LFS getstripe -p $file.2)
3437         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3438
3439         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3440
3441         echo XXX >> $file.3
3442         $LFS getstripe $file.3
3443
3444         stripe_count2=$($LFS getstripe -c $file.3)
3445         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3446 }
3447 run_test 27U "append pool and stripe count work with composite default layout"
3448
3449 # createtest also checks that device nodes are created and
3450 # then visible correctly (#2091)
3451 test_28() { # bug 2091
3452         test_mkdir $DIR/d28
3453         $CREATETEST $DIR/d28/ct || error "createtest failed"
3454 }
3455 run_test 28 "create/mknod/mkdir with bad file types ============"
3456
3457 test_29() {
3458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3459
3460         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3461                 disable_opencache
3462                 stack_trap "restore_opencache"
3463         }
3464
3465         sync; sleep 1; sync # flush out any dirty pages from previous tests
3466         cancel_lru_locks
3467         test_mkdir $DIR/d29
3468         touch $DIR/d29/foo
3469         log 'first d29'
3470         ls -l $DIR/d29
3471
3472         declare -i LOCKCOUNTORIG=0
3473         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3474                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3475         done
3476         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3477
3478         declare -i LOCKUNUSEDCOUNTORIG=0
3479         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3480                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3481         done
3482
3483         log 'second d29'
3484         ls -l $DIR/d29
3485         log 'done'
3486
3487         declare -i LOCKCOUNTCURRENT=0
3488         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3489                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3490         done
3491
3492         declare -i LOCKUNUSEDCOUNTCURRENT=0
3493         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3494                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3495         done
3496
3497         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3498                 $LCTL set_param -n ldlm.dump_namespaces ""
3499                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3500                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3501                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3502                 return 2
3503         fi
3504         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3505                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 3
3509         fi
3510 }
3511 run_test 29 "IT_GETATTR regression  ============================"
3512
3513 test_30a() { # was test_30
3514         cp $(which ls) $DIR || cp /bin/ls $DIR
3515         $DIR/ls / || error "Can't execute binary from lustre"
3516         rm $DIR/ls
3517 }
3518 run_test 30a "execute binary from Lustre (execve) =============="
3519
3520 test_30b() {
3521         cp `which ls` $DIR || cp /bin/ls $DIR
3522         chmod go+rx $DIR/ls
3523         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3524         rm $DIR/ls
3525 }
3526 run_test 30b "execute binary from Lustre as non-root ==========="
3527
3528 test_30c() { # b=22376
3529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3530
3531         cp $(which ls) $DIR || cp /bin/ls $DIR
3532         chmod a-rw $DIR/ls
3533         cancel_lru_locks mdc
3534         cancel_lru_locks osc
3535         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3536         rm -f $DIR/ls
3537 }
3538 run_test 30c "execute binary from Lustre without read perms ===="
3539
3540 test_30d() {
3541         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3542
3543         for i in {1..10}; do
3544                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3545                 local PID=$!
3546                 sleep 1
3547                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3548                 wait $PID || error "executing dd from Lustre failed"
3549                 rm -f $DIR/$tfile
3550         done
3551
3552         rm -f $DIR/dd
3553 }
3554 run_test 30d "execute binary from Lustre while clear locks"
3555
3556 test_31a() {
3557         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3558         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3559 }
3560 run_test 31a "open-unlink file =================================="
3561
3562 test_31b() {
3563         touch $DIR/f31 || error "touch $DIR/f31 failed"
3564         ln $DIR/f31 $DIR/f31b || error "ln failed"
3565         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3566         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3567 }
3568 run_test 31b "unlink file with multiple links while open ======="
3569
3570 test_31c() {
3571         touch $DIR/f31 || error "touch $DIR/f31 failed"
3572         ln $DIR/f31 $DIR/f31c || error "ln failed"
3573         multiop_bg_pause $DIR/f31 O_uc ||
3574                 error "multiop_bg_pause for $DIR/f31 failed"
3575         MULTIPID=$!
3576         $MULTIOP $DIR/f31c Ouc
3577         kill -USR1 $MULTIPID
3578         wait $MULTIPID
3579 }
3580 run_test 31c "open-unlink file with multiple links ============="
3581
3582 test_31d() {
3583         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3584         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3585 }
3586 run_test 31d "remove of open directory ========================="
3587
3588 test_31e() { # bug 2904
3589         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3590 }
3591 run_test 31e "remove of open non-empty directory ==============="
3592
3593 test_31f() { # bug 4554
3594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3595
3596         set -vx
3597         test_mkdir $DIR/d31f
3598         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3599         cp /etc/hosts $DIR/d31f
3600         ls -l $DIR/d31f
3601         $LFS getstripe $DIR/d31f/hosts
3602         multiop_bg_pause $DIR/d31f D_c || return 1
3603         MULTIPID=$!
3604
3605         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3606         test_mkdir $DIR/d31f
3607         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3608         cp /etc/hosts $DIR/d31f
3609         ls -l $DIR/d31f
3610         $LFS getstripe $DIR/d31f/hosts
3611         multiop_bg_pause $DIR/d31f D_c || return 1
3612         MULTIPID2=$!
3613
3614         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3615         wait $MULTIPID || error "first opendir $MULTIPID failed"
3616
3617         sleep 6
3618
3619         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3620         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3621         set +vx
3622 }
3623 run_test 31f "remove of open directory with open-unlink file ==="
3624
3625 test_31g() {
3626         echo "-- cross directory link --"
3627         test_mkdir -c1 $DIR/${tdir}ga
3628         test_mkdir -c1 $DIR/${tdir}gb
3629         touch $DIR/${tdir}ga/f
3630         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3631         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3632         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3633         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3634         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3635 }
3636 run_test 31g "cross directory link==============="
3637
3638 test_31h() {
3639         echo "-- cross directory link --"
3640         test_mkdir -c1 $DIR/${tdir}
3641         test_mkdir -c1 $DIR/${tdir}/dir
3642         touch $DIR/${tdir}/f
3643         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3644         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3645         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3646         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3647         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3648 }
3649 run_test 31h "cross directory link under child==============="
3650
3651 test_31i() {
3652         echo "-- cross directory link --"
3653         test_mkdir -c1 $DIR/$tdir
3654         test_mkdir -c1 $DIR/$tdir/dir
3655         touch $DIR/$tdir/dir/f
3656         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3657         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3658         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3659         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3660         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3661 }
3662 run_test 31i "cross directory link under parent==============="
3663
3664 test_31j() {
3665         test_mkdir -c1 -p $DIR/$tdir
3666         test_mkdir -c1 -p $DIR/$tdir/dir1
3667         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3668         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3669         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3671         return 0
3672 }
3673 run_test 31j "link for directory==============="
3674
3675 test_31k() {
3676         test_mkdir -c1 -p $DIR/$tdir
3677         touch $DIR/$tdir/s
3678         touch $DIR/$tdir/exist
3679         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3680         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3681         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3682         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3683         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3684         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3686         return 0
3687 }
3688 run_test 31k "link to file: the same, non-existing, dir==============="
3689
3690 test_31m() {
3691         mkdir $DIR/d31m
3692         touch $DIR/d31m/s
3693         mkdir $DIR/d31m2
3694         touch $DIR/d31m2/exist
3695         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3696         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3697         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3698         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3699         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3701         return 0
3702 }
3703 run_test 31m "link to file: the same, non-existing, dir==============="
3704
3705 test_31n() {
3706         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3707         nlink=$(stat --format=%h $DIR/$tfile)
3708         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3709         local fd=$(free_fd)
3710         local cmd="exec $fd<$DIR/$tfile"
3711         eval $cmd
3712         cmd="exec $fd<&-"
3713         trap "eval $cmd" EXIT
3714         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3715         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3716         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3717         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3718         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3719         eval $cmd
3720 }
3721 run_test 31n "check link count of unlinked file"
3722
3723 link_one() {
3724         local tempfile=$(mktemp $1_XXXXXX)
3725         mlink $tempfile $1 2> /dev/null &&
3726                 echo "$BASHPID: link $tempfile to $1 succeeded"
3727         munlink $tempfile
3728 }
3729
3730 test_31o() { # LU-2901
3731         test_mkdir $DIR/$tdir
3732         for LOOP in $(seq 100); do
3733                 rm -f $DIR/$tdir/$tfile*
3734                 for THREAD in $(seq 8); do
3735                         link_one $DIR/$tdir/$tfile.$LOOP &
3736                 done
3737                 wait
3738                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3739                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3740                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3741                         break || true
3742         done
3743 }
3744 run_test 31o "duplicate hard links with same filename"
3745
3746 test_31p() {
3747         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3748
3749         test_mkdir $DIR/$tdir
3750         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3751         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3752
3753         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3754                 error "open unlink test1 failed"
3755         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3756                 error "open unlink test2 failed"
3757
3758         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3759                 error "test1 still exists"
3760         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3761                 error "test2 still exists"
3762 }
3763 run_test 31p "remove of open striped directory"
3764
3765 test_31q() {
3766         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3767
3768         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3769         index=$($LFS getdirstripe -i $DIR/$tdir)
3770         [ $index -eq 3 ] || error "first stripe index $index != 3"
3771         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3772         [ $index -eq 1 ] || error "second stripe index $index != 1"
3773
3774         # when "-c <stripe_count>" is set, the number of MDTs specified after
3775         # "-i" should equal to the stripe count
3776         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3777 }
3778 run_test 31q "create striped directory on specific MDTs"
3779
3780 #LU-14949
3781 test_31r() {
3782         touch $DIR/$tfile.target
3783         touch $DIR/$tfile.source
3784
3785         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3786         $LCTL set_param fail_loc=0x1419 fail_val=3
3787         cat $DIR/$tfile.target &
3788         CATPID=$!
3789
3790         # Guarantee open is waiting before we get here
3791         sleep 1
3792         mv $DIR/$tfile.source $DIR/$tfile.target
3793
3794         wait $CATPID
3795         RC=$?
3796         if [[ $RC -ne 0 ]]; then
3797                 error "open with cat failed, rc=$RC"
3798         fi
3799 }
3800 run_test 31r "open-rename(replace) race"
3801
3802 cleanup_test32_mount() {
3803         local rc=0
3804         trap 0
3805         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3806         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3807         losetup -d $loopdev || true
3808         rm -rf $DIR/$tdir
3809         return $rc
3810 }
3811
3812 test_32a() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         echo "== more mountpoints and symlinks ================="
3816         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3817         trap cleanup_test32_mount EXIT
3818         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3819         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3820                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3821         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3822                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3823         cleanup_test32_mount
3824 }
3825 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3826
3827 test_32b() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3836                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3837         cleanup_test32_mount
3838 }
3839 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3840
3841 test_32c() {
3842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3843
3844         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3845         trap cleanup_test32_mount EXIT
3846         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3847         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3848                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3849         test_mkdir -p $DIR/$tdir/d2/test_dir
3850         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3851                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3852         cleanup_test32_mount
3853 }
3854 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3855
3856 test_32d() {
3857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3858
3859         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3860         trap cleanup_test32_mount EXIT
3861         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3862         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3863                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3864         test_mkdir -p $DIR/$tdir/d2/test_dir
3865         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3866                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3867         cleanup_test32_mount
3868 }
3869 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3870
3871 test_32e() {
3872         rm -fr $DIR/$tdir
3873         test_mkdir -p $DIR/$tdir/tmp
3874         local tmp_dir=$DIR/$tdir/tmp
3875         ln -s $DIR/$tdir $tmp_dir/symlink11
3876         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3877         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3878         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3879 }
3880 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3881
3882 test_32f() {
3883         rm -fr $DIR/$tdir
3884         test_mkdir -p $DIR/$tdir/tmp
3885         local tmp_dir=$DIR/$tdir/tmp
3886         ln -s $DIR/$tdir $tmp_dir/symlink11
3887         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3888         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3889         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3890 }
3891 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3892
3893 test_32g() {
3894         local tmp_dir=$DIR/$tdir/tmp
3895         test_mkdir -p $tmp_dir
3896         test_mkdir $DIR/${tdir}2
3897         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3898         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3899         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3900         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3901         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3902         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3903 }
3904 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3905
3906 test_32h() {
3907         rm -fr $DIR/$tdir $DIR/${tdir}2
3908         tmp_dir=$DIR/$tdir/tmp
3909         test_mkdir -p $tmp_dir
3910         test_mkdir $DIR/${tdir}2
3911         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3912         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3913         ls $tmp_dir/symlink12 || error "listing symlink12"
3914         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3915 }
3916 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3917
3918 test_32i() {
3919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3920
3921         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3922         trap cleanup_test32_mount EXIT
3923         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3924         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3925                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3926         touch $DIR/$tdir/test_file
3927         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3928                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3929         cleanup_test32_mount
3930 }
3931 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3932
3933 test_32j() {
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3937         trap cleanup_test32_mount EXIT
3938         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3941         touch $DIR/$tdir/test_file
3942         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3943                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3944         cleanup_test32_mount
3945 }
3946 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3947
3948 test_32k() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         rm -fr $DIR/$tdir
3952         trap cleanup_test32_mount EXIT
3953         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3954         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3955                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3956         test_mkdir -p $DIR/$tdir/d2
3957         touch $DIR/$tdir/d2/test_file || error "touch failed"
3958         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3959                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3960         cleanup_test32_mount
3961 }
3962 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3963
3964 test_32l() {
3965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3966
3967         rm -fr $DIR/$tdir
3968         trap cleanup_test32_mount EXIT
3969         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3970         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3971                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3972         test_mkdir -p $DIR/$tdir/d2
3973         touch $DIR/$tdir/d2/test_file || error "touch failed"
3974         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3975                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3976         cleanup_test32_mount
3977 }
3978 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3979
3980 test_32m() {
3981         rm -fr $DIR/d32m
3982         test_mkdir -p $DIR/d32m/tmp
3983         TMP_DIR=$DIR/d32m/tmp
3984         ln -s $DIR $TMP_DIR/symlink11
3985         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3986         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3987                 error "symlink11 not a link"
3988         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3989                 error "symlink01 not a link"
3990 }
3991 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3992
3993 test_32n() {
3994         rm -fr $DIR/d32n
3995         test_mkdir -p $DIR/d32n/tmp
3996         TMP_DIR=$DIR/d32n/tmp
3997         ln -s $DIR $TMP_DIR/symlink11
3998         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3999         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4000         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4001 }
4002 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4003
4004 test_32o() {
4005         touch $DIR/$tfile
4006         test_mkdir -p $DIR/d32o/tmp
4007         TMP_DIR=$DIR/d32o/tmp
4008         ln -s $DIR/$tfile $TMP_DIR/symlink12
4009         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4010         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4011                 error "symlink12 not a link"
4012         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4013         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4014                 error "$DIR/d32o/tmp/symlink12 not file type"
4015         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4016                 error "$DIR/d32o/symlink02 not file type"
4017 }
4018 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4019
4020 test_32p() {
4021         log 32p_1
4022         rm -fr $DIR/d32p
4023         log 32p_2
4024         rm -f $DIR/$tfile
4025         log 32p_3
4026         touch $DIR/$tfile
4027         log 32p_4
4028         test_mkdir -p $DIR/d32p/tmp
4029         log 32p_5
4030         TMP_DIR=$DIR/d32p/tmp
4031         log 32p_6
4032         ln -s $DIR/$tfile $TMP_DIR/symlink12
4033         log 32p_7
4034         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4035         log 32p_8
4036         cat $DIR/d32p/tmp/symlink12 ||
4037                 error "Can't open $DIR/d32p/tmp/symlink12"
4038         log 32p_9
4039         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4040         log 32p_10
4041 }
4042 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4043
4044 test_32q() {
4045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4046
4047         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4048         trap cleanup_test32_mount EXIT
4049         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4050         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4051         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4052                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4053         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4054         cleanup_test32_mount
4055 }
4056 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4057
4058 test_32r() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4062         trap cleanup_test32_mount EXIT
4063         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4064         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4065         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4066                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4067         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4068         cleanup_test32_mount
4069 }
4070 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4071
4072 test_33aa() {
4073         rm -f $DIR/$tfile
4074         touch $DIR/$tfile
4075         chmod 444 $DIR/$tfile
4076         chown $RUNAS_ID $DIR/$tfile
4077         log 33_1
4078         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4079         log 33_2
4080 }
4081 run_test 33aa "write file with mode 444 (should return error)"
4082
4083 test_33a() {
4084         rm -fr $DIR/$tdir
4085         test_mkdir $DIR/$tdir
4086         chown $RUNAS_ID $DIR/$tdir
4087         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4088                 error "$RUNAS create $tdir/$tfile failed"
4089         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4090                 error "open RDWR" || true
4091 }
4092 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4093
4094 test_33b() {
4095         rm -fr $DIR/$tdir
4096         test_mkdir $DIR/$tdir
4097         chown $RUNAS_ID $DIR/$tdir
4098         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4099 }
4100 run_test 33b "test open file with malformed flags (No panic)"
4101
4102 test_33c() {
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104         remote_ost_nodsh && skip "remote OST with nodsh"
4105
4106         local ostnum
4107         local ostname
4108         local write_bytes
4109         local all_zeros
4110
4111         all_zeros=true
4112         test_mkdir $DIR/$tdir
4113         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4114
4115         sync
4116         for ostnum in $(seq $OSTCOUNT); do
4117                 # test-framework's OST numbering is one-based, while Lustre's
4118                 # is zero-based
4119                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4120                 # check if at least some write_bytes stats are counted
4121                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4122                               obdfilter.$ostname.stats |
4123                               awk '/^write_bytes/ {print $7}' )
4124                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4125                 if (( ${write_bytes:-0} > 0 )); then
4126                         all_zeros=false
4127                         break
4128                 fi
4129         done
4130
4131         $all_zeros || return 0
4132
4133         # Write four bytes
4134         echo foo > $DIR/$tdir/bar
4135         # Really write them
4136         sync
4137
4138         # Total up write_bytes after writing.  We'd better find non-zeros.
4139         for ostnum in $(seq $OSTCOUNT); do
4140                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4141                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4142                               obdfilter/$ostname/stats |
4143                               awk '/^write_bytes/ {print $7}' )
4144                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4145                 if (( ${write_bytes:-0} > 0 )); then
4146                         all_zeros=false
4147                         break
4148                 fi
4149         done
4150
4151         if $all_zeros; then
4152                 for ostnum in $(seq $OSTCOUNT); do
4153                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4154                         echo "Check write_bytes is in obdfilter.*.stats:"
4155                         do_facet ost$ostnum lctl get_param -n \
4156                                 obdfilter.$ostname.stats
4157                 done
4158                 error "OST not keeping write_bytes stats (b=22312)"
4159         fi
4160 }
4161 run_test 33c "test write_bytes stats"
4162
4163 test_33d() {
4164         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4166
4167         local MDTIDX=1
4168         local remote_dir=$DIR/$tdir/remote_dir
4169
4170         test_mkdir $DIR/$tdir
4171         $LFS mkdir -i $MDTIDX $remote_dir ||
4172                 error "create remote directory failed"
4173
4174         touch $remote_dir/$tfile
4175         chmod 444 $remote_dir/$tfile
4176         chown $RUNAS_ID $remote_dir/$tfile
4177
4178         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4179
4180         chown $RUNAS_ID $remote_dir
4181         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4182                                         error "create" || true
4183         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4184                                     error "open RDWR" || true
4185         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4186 }
4187 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4188
4189 test_33e() {
4190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4191
4192         mkdir $DIR/$tdir
4193
4194         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4195         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4196         mkdir $DIR/$tdir/local_dir
4197
4198         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4199         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4200         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4201
4202         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4203                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4204
4205         rmdir $DIR/$tdir/* || error "rmdir failed"
4206
4207         umask 777
4208         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4209         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4210         mkdir $DIR/$tdir/local_dir
4211
4212         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4213         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4214         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4215
4216         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4217                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4218
4219         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4220
4221         umask 000
4222         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4223         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4224         mkdir $DIR/$tdir/local_dir
4225
4226         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4227         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4228         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4229
4230         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4231                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4232 }
4233 run_test 33e "mkdir and striped directory should have same mode"
4234
4235 cleanup_33f() {
4236         trap 0
4237         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4238 }
4239
4240 test_33f() {
4241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4242         remote_mds_nodsh && skip "remote MDS with nodsh"
4243
4244         mkdir $DIR/$tdir
4245         chmod go+rwx $DIR/$tdir
4246         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4247         trap cleanup_33f EXIT
4248
4249         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4250                 error "cannot create striped directory"
4251
4252         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4253                 error "cannot create files in striped directory"
4254
4255         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4256                 error "cannot remove files in striped directory"
4257
4258         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4259                 error "cannot remove striped directory"
4260
4261         cleanup_33f
4262 }
4263 run_test 33f "nonroot user can create, access, and remove a striped directory"
4264
4265 test_33g() {
4266         mkdir -p $DIR/$tdir/dir2
4267
4268         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4269         echo $err
4270         [[ $err =~ "exists" ]] || error "Not exists error"
4271 }
4272 run_test 33g "nonroot user create already existing root created file"
4273
4274 sub_33h() {
4275         local hash_type=$1
4276         local count=250
4277
4278         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4279                 error "lfs mkdir -H $hash_type $tdir failed"
4280         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4281
4282         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4283         local index2
4284         local fname
4285
4286         for fname in $DIR/$tdir/$tfile.bak \
4287                      $DIR/$tdir/$tfile.SAV \
4288                      $DIR/$tdir/$tfile.orig \
4289                      $DIR/$tdir/$tfile~; do
4290                 touch $fname || error "touch $fname failed"
4291                 index2=$($LFS getstripe -m $fname)
4292                 (( $index == $index2 )) ||
4293                         error "$fname MDT index mismatch $index != $index2"
4294         done
4295
4296         local failed=0
4297         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4298         local pattern
4299
4300         for pattern in ${patterns[*]}; do
4301                 echo "pattern $pattern"
4302                 fname=$DIR/$tdir/$pattern
4303                 for (( i = 0; i < $count; i++ )); do
4304                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4305                                 error "mktemp $DIR/$tdir/$pattern failed"
4306                         index2=$($LFS getstripe -m $fname)
4307                         (( $index == $index2 )) && continue
4308
4309                         failed=$((failed + 1))
4310                         echo "$fname MDT index mismatch $index != $index2"
4311                 done
4312         done
4313
4314         echo "$failed/$count MDT index mismatches, expect ~2-4"
4315         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4316
4317         local same=0
4318         local expect
4319
4320         # verify that "crush" is still broken with all files on same MDT,
4321         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4322         [[ "$hash_type" == "crush" ]] && expect=$count ||
4323                 expect=$((count / MDSCOUNT))
4324
4325         # crush2 doesn't put all-numeric suffixes on the same MDT,
4326         # filename like $tfile.12345678 should *not* be considered temp
4327         for pattern in ${patterns[*]}; do
4328                 local base=${pattern%%X*}
4329                 local suff=${pattern#$base}
4330
4331                 echo "pattern $pattern"
4332                 for (( i = 0; i < $count; i++ )); do
4333                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4334                         touch $fname || error "touch $fname failed"
4335                         index2=$($LFS getstripe -m $fname)
4336                         (( $index != $index2 )) && continue
4337
4338                         same=$((same + 1))
4339                 done
4340         done
4341
4342         # the number of "bad" hashes is random, as it depends on the random
4343         # filenames generated by "mktemp".  Allow some margin in the results.
4344         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4345         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4346            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4347                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4348         same=0
4349
4350         # crush2 doesn't put suffixes with special characters on the same MDT
4351         # filename like $tfile.txt.1234 should *not* be considered temp
4352         for pattern in ${patterns[*]}; do
4353                 local base=${pattern%%X*}
4354                 local suff=${pattern#$base}
4355
4356                 pattern=$base...${suff/XXX}
4357                 echo "pattern=$pattern"
4358                 for (( i = 0; i < $count; i++ )); do
4359                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4360                                 error "touch $fname failed"
4361                         index2=$($LFS getstripe -m $fname)
4362                         (( $index != $index2 )) && continue
4363
4364                         same=$((same + 1))
4365                 done
4366         done
4367
4368         # the number of "bad" hashes is random, as it depends on the random
4369         # filenames generated by "mktemp".  Allow some margin in the results.
4370         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4371         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4372            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4373                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4374 }
4375
4376 test_33h() {
4377         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4378         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4379                 skip "Need MDS version at least 2.13.50"
4380
4381         sub_33h crush
4382 }
4383 run_test 33h "temp file is located on the same MDT as target (crush)"
4384
4385 test_33hh() {
4386         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4387         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4388         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4389                 skip "Need MDS version at least 2.15.0 for crush2"
4390
4391         sub_33h crush2
4392 }
4393 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4394
4395 test_33i()
4396 {
4397         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4398
4399         local FNAME=$(str_repeat 'f' 250)
4400
4401         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4402         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4403
4404         local count
4405         local total
4406
4407         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4408
4409         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4410
4411         lctl --device %$MDC deactivate
4412         stack_trap "lctl --device %$MDC activate"
4413         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4414         total=$(\ls -l $DIR/$tdir | wc -l)
4415         # "ls -l" will list total in the first line
4416         total=$((total - 1))
4417         (( total + count == 1000 )) ||
4418                 error "ls list $total files, $count files on MDT1"
4419 }
4420 run_test 33i "striped directory can be accessed when one MDT is down"
4421
4422 test_33j() {
4423         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4424
4425         mkdir -p $DIR/$tdir/
4426
4427         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4428                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4429
4430         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4431                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4432
4433         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4434                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4435
4436         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4437                 error "-D was not specified, but still failed"
4438 }
4439 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4440
4441 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4442 test_34a() {
4443         rm -f $DIR/f34
4444         $MCREATE $DIR/f34 || error "mcreate failed"
4445         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4446                 error "getstripe failed"
4447         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4448         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4449                 error "getstripe failed"
4450         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4451                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4452 }
4453 run_test 34a "truncate file that has not been opened ==========="
4454
4455 test_34b() {
4456         [ ! -f $DIR/f34 ] && test_34a
4457         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4458                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4459         $OPENFILE -f O_RDONLY $DIR/f34
4460         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4461                 error "getstripe failed"
4462         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4463                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4464 }
4465 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4466
4467 test_34c() {
4468         [ ! -f $DIR/f34 ] && test_34a
4469         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4470                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4471         $OPENFILE -f O_RDWR $DIR/f34
4472         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4473                 error "$LFS getstripe failed"
4474         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4475                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4476 }
4477 run_test 34c "O_RDWR opening file-with-size works =============="
4478
4479 test_34d() {
4480         [ ! -f $DIR/f34 ] && test_34a
4481         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4482                 error "dd failed"
4483         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4484                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4485         rm $DIR/f34
4486 }
4487 run_test 34d "write to sparse file ============================="
4488
4489 test_34e() {
4490         rm -f $DIR/f34e
4491         $MCREATE $DIR/f34e || error "mcreate failed"
4492         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4493         $CHECKSTAT -s 1000 $DIR/f34e ||
4494                 error "Size of $DIR/f34e not equal to 1000 bytes"
4495         $OPENFILE -f O_RDWR $DIR/f34e
4496         $CHECKSTAT -s 1000 $DIR/f34e ||
4497                 error "Size of $DIR/f34e not equal to 1000 bytes"
4498 }
4499 run_test 34e "create objects, some with size and some without =="
4500
4501 test_34f() { # bug 6242, 6243
4502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4503
4504         SIZE34F=48000
4505         rm -f $DIR/f34f
4506         $MCREATE $DIR/f34f || error "mcreate failed"
4507         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4508         dd if=$DIR/f34f of=$TMP/f34f
4509         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4510         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4511         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4512         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4513         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4514 }
4515 run_test 34f "read from a file with no objects until EOF ======="
4516
4517 test_34g() {
4518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4519
4520         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4521                 error "dd failed"
4522         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4523         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4524                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4525         cancel_lru_locks osc
4526         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4527                 error "wrong size after lock cancel"
4528
4529         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4530         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4531                 error "expanding truncate failed"
4532         cancel_lru_locks osc
4533         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4534                 error "wrong expanded size after lock cancel"
4535 }
4536 run_test 34g "truncate long file ==============================="
4537
4538 test_34h() {
4539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4540
4541         local gid=10
4542         local sz=1000
4543
4544         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4545         sync # Flush the cache so that multiop below does not block on cache
4546              # flush when getting the group lock
4547         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4548         MULTIPID=$!
4549
4550         # Since just timed wait is not good enough, let's do a sync write
4551         # that way we are sure enough time for a roundtrip + processing
4552         # passed + 2 seconds of extra margin.
4553         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4554         rm $DIR/${tfile}-1
4555         sleep 2
4556
4557         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4558                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4559                 kill -9 $MULTIPID
4560         fi
4561         wait $MULTIPID
4562         local nsz=`stat -c %s $DIR/$tfile`
4563         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4564 }
4565 run_test 34h "ftruncate file under grouplock should not block"
4566
4567 test_35a() {
4568         cp /bin/sh $DIR/f35a
4569         chmod 444 $DIR/f35a
4570         chown $RUNAS_ID $DIR/f35a
4571         $RUNAS $DIR/f35a && error || true
4572         rm $DIR/f35a
4573 }
4574 run_test 35a "exec file with mode 444 (should return and not leak)"
4575
4576 test_36a() {
4577         rm -f $DIR/f36
4578         utime $DIR/f36 || error "utime failed for MDS"
4579 }
4580 run_test 36a "MDS utime check (mknod, utime)"
4581
4582 test_36b() {
4583         echo "" > $DIR/f36
4584         utime $DIR/f36 || error "utime failed for OST"
4585 }
4586 run_test 36b "OST utime check (open, utime)"
4587
4588 test_36c() {
4589         rm -f $DIR/d36/f36
4590         test_mkdir $DIR/d36
4591         chown $RUNAS_ID $DIR/d36
4592         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4593 }
4594 run_test 36c "non-root MDS utime check (mknod, utime)"
4595
4596 test_36d() {
4597         [ ! -d $DIR/d36 ] && test_36c
4598         echo "" > $DIR/d36/f36
4599         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4600 }
4601 run_test 36d "non-root OST utime check (open, utime)"
4602
4603 test_36e() {
4604         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4605
4606         test_mkdir $DIR/$tdir
4607         touch $DIR/$tdir/$tfile
4608         $RUNAS utime $DIR/$tdir/$tfile &&
4609                 error "utime worked, expected failure" || true
4610 }
4611 run_test 36e "utime on non-owned file (should return error)"
4612
4613 subr_36fh() {
4614         local fl="$1"
4615         local LANG_SAVE=$LANG
4616         local LC_LANG_SAVE=$LC_LANG
4617         export LANG=C LC_LANG=C # for date language
4618
4619         DATESTR="Dec 20  2000"
4620         test_mkdir $DIR/$tdir
4621         lctl set_param fail_loc=$fl
4622         date; date +%s
4623         cp /etc/hosts $DIR/$tdir/$tfile
4624         sync & # write RPC generated with "current" inode timestamp, but delayed
4625         sleep 1
4626         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4627         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4628         cancel_lru_locks $OSC
4629         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4630         date; date +%s
4631         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4632                 echo "BEFORE: $LS_BEFORE" && \
4633                 echo "AFTER : $LS_AFTER" && \
4634                 echo "WANT  : $DATESTR" && \
4635                 error "$DIR/$tdir/$tfile timestamps changed" || true
4636
4637         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4638 }
4639
4640 test_36f() {
4641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4642
4643         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4644         subr_36fh "0x80000214"
4645 }
4646 run_test 36f "utime on file racing with OST BRW write =========="
4647
4648 test_36g() {
4649         remote_ost_nodsh && skip "remote OST with nodsh"
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4652                 skip "Need MDS version at least 2.12.51"
4653
4654         local fmd_max_age
4655         local fmd
4656         local facet="ost1"
4657         local tgt="obdfilter"
4658
4659         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4660
4661         test_mkdir $DIR/$tdir
4662         fmd_max_age=$(do_facet $facet \
4663                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4664                 head -n 1")
4665
4666         echo "FMD max age: ${fmd_max_age}s"
4667         touch $DIR/$tdir/$tfile
4668         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4669                 gawk '{cnt=cnt+$1}  END{print cnt}')
4670         echo "FMD before: $fmd"
4671         [[ $fmd == 0 ]] &&
4672                 error "FMD wasn't create by touch"
4673         sleep $((fmd_max_age + 12))
4674         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4675                 gawk '{cnt=cnt+$1}  END{print cnt}')
4676         echo "FMD after: $fmd"
4677         [[ $fmd == 0 ]] ||
4678                 error "FMD wasn't expired by ping"
4679 }
4680 run_test 36g "FMD cache expiry ====================="
4681
4682 test_36h() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4686         subr_36fh "0x80000227"
4687 }
4688 run_test 36h "utime on file racing with OST BRW write =========="
4689
4690 test_36i() {
4691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4692
4693         test_mkdir $DIR/$tdir
4694         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4695
4696         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4697         local new_mtime=$((mtime + 200))
4698
4699         #change Modify time of striped dir
4700         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4701                         error "change mtime failed"
4702
4703         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4704
4705         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4706 }
4707 run_test 36i "change mtime on striped directory"
4708
4709 # test_37 - duplicate with tests 32q 32r
4710
4711 test_38() {
4712         local file=$DIR/$tfile
4713         touch $file
4714         openfile -f O_DIRECTORY $file
4715         local RC=$?
4716         local ENOTDIR=20
4717         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4718         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4719 }
4720 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4721
4722 test_39a() { # was test_39
4723         touch $DIR/$tfile
4724         touch $DIR/${tfile}2
4725 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4726 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4727 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4728         sleep 2
4729         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4730         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4731                 echo "mtime"
4732                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4733                 echo "atime"
4734                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4735                 echo "ctime"
4736                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4737                 error "O_TRUNC didn't change timestamps"
4738         fi
4739 }
4740 run_test 39a "mtime changed on create"
4741
4742 test_39b() {
4743         test_mkdir -c1 $DIR/$tdir
4744         cp -p /etc/passwd $DIR/$tdir/fopen
4745         cp -p /etc/passwd $DIR/$tdir/flink
4746         cp -p /etc/passwd $DIR/$tdir/funlink
4747         cp -p /etc/passwd $DIR/$tdir/frename
4748         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4749
4750         sleep 1
4751         echo "aaaaaa" >> $DIR/$tdir/fopen
4752         echo "aaaaaa" >> $DIR/$tdir/flink
4753         echo "aaaaaa" >> $DIR/$tdir/funlink
4754         echo "aaaaaa" >> $DIR/$tdir/frename
4755
4756         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4757         local link_new=`stat -c %Y $DIR/$tdir/flink`
4758         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4759         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4760
4761         cat $DIR/$tdir/fopen > /dev/null
4762         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4763         rm -f $DIR/$tdir/funlink2
4764         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4765
4766         for (( i=0; i < 2; i++ )) ; do
4767                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4768                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4769                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4770                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4771
4772                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4773                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4774                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4775                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4776
4777                 cancel_lru_locks $OSC
4778                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4779         done
4780 }
4781 run_test 39b "mtime change on open, link, unlink, rename  ======"
4782
4783 # this should be set to past
4784 TEST_39_MTIME=`date -d "1 year ago" +%s`
4785
4786 # bug 11063
4787 test_39c() {
4788         touch $DIR1/$tfile
4789         sleep 2
4790         local mtime0=`stat -c %Y $DIR1/$tfile`
4791
4792         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4793         local mtime1=`stat -c %Y $DIR1/$tfile`
4794         [ "$mtime1" = $TEST_39_MTIME ] || \
4795                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4796
4797         local d1=`date +%s`
4798         echo hello >> $DIR1/$tfile
4799         local d2=`date +%s`
4800         local mtime2=`stat -c %Y $DIR1/$tfile`
4801         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4802                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4803
4804         mv $DIR1/$tfile $DIR1/$tfile-1
4805
4806         for (( i=0; i < 2; i++ )) ; do
4807                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4808                 [ "$mtime2" = "$mtime3" ] || \
4809                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4810
4811                 cancel_lru_locks $OSC
4812                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4813         done
4814 }
4815 run_test 39c "mtime change on rename ==========================="
4816
4817 # bug 21114
4818 test_39d() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         touch $DIR1/$tfile
4822         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local mtime=`stat -c %Y $DIR1/$tfile`
4826                 [ $mtime = $TEST_39_MTIME ] || \
4827                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4828
4829                 cancel_lru_locks $OSC
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832 }
4833 run_test 39d "create, utime, stat =============================="
4834
4835 # bug 21114
4836 test_39e() {
4837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4838
4839         touch $DIR1/$tfile
4840         local mtime1=`stat -c %Y $DIR1/$tfile`
4841
4842         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4843
4844         for (( i=0; i < 2; i++ )) ; do
4845                 local mtime2=`stat -c %Y $DIR1/$tfile`
4846                 [ $mtime2 = $TEST_39_MTIME ] || \
4847                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4848
4849                 cancel_lru_locks $OSC
4850                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4851         done
4852 }
4853 run_test 39e "create, stat, utime, stat ========================"
4854
4855 # bug 21114
4856 test_39f() {
4857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4858
4859         touch $DIR1/$tfile
4860         mtime1=`stat -c %Y $DIR1/$tfile`
4861
4862         sleep 2
4863         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4864
4865         for (( i=0; i < 2; i++ )) ; do
4866                 local mtime2=`stat -c %Y $DIR1/$tfile`
4867                 [ $mtime2 = $TEST_39_MTIME ] || \
4868                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4869
4870                 cancel_lru_locks $OSC
4871                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4872         done
4873 }
4874 run_test 39f "create, stat, sleep, utime, stat ================="
4875
4876 # bug 11063
4877 test_39g() {
4878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4879
4880         echo hello >> $DIR1/$tfile
4881         local mtime1=`stat -c %Y $DIR1/$tfile`
4882
4883         sleep 2
4884         chmod o+r $DIR1/$tfile
4885
4886         for (( i=0; i < 2; i++ )) ; do
4887                 local mtime2=`stat -c %Y $DIR1/$tfile`
4888                 [ "$mtime1" = "$mtime2" ] || \
4889                         error "lost mtime: $mtime2, should be $mtime1"
4890
4891                 cancel_lru_locks $OSC
4892                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4893         done
4894 }
4895 run_test 39g "write, chmod, stat ==============================="
4896
4897 # bug 11063
4898 test_39h() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         touch $DIR1/$tfile
4902         sleep 1
4903
4904         local d1=`date`
4905         echo hello >> $DIR1/$tfile
4906         local mtime1=`stat -c %Y $DIR1/$tfile`
4907
4908         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4909         local d2=`date`
4910         if [ "$d1" != "$d2" ]; then
4911                 echo "write and touch not within one second"
4912         else
4913                 for (( i=0; i < 2; i++ )) ; do
4914                         local mtime2=`stat -c %Y $DIR1/$tfile`
4915                         [ "$mtime2" = $TEST_39_MTIME ] || \
4916                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4917
4918                         cancel_lru_locks $OSC
4919                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4920                 done
4921         fi
4922 }
4923 run_test 39h "write, utime within one second, stat ============="
4924
4925 test_39i() {
4926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4927
4928         touch $DIR1/$tfile
4929         sleep 1
4930
4931         echo hello >> $DIR1/$tfile
4932         local mtime1=`stat -c %Y $DIR1/$tfile`
4933
4934         mv $DIR1/$tfile $DIR1/$tfile-1
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4938
4939                 [ "$mtime1" = "$mtime2" ] || \
4940                         error "lost mtime: $mtime2, should be $mtime1"
4941
4942                 cancel_lru_locks $OSC
4943                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4944         done
4945 }
4946 run_test 39i "write, rename, stat =============================="
4947
4948 test_39j() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         start_full_debug_logging
4952         touch $DIR1/$tfile
4953         sleep 1
4954
4955         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4956         lctl set_param fail_loc=0x80000412
4957         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4958                 error "multiop failed"
4959         local multipid=$!
4960         local mtime1=`stat -c %Y $DIR1/$tfile`
4961
4962         mv $DIR1/$tfile $DIR1/$tfile-1
4963
4964         kill -USR1 $multipid
4965         wait $multipid || error "multiop close failed"
4966
4967         for (( i=0; i < 2; i++ )) ; do
4968                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4969                 [ "$mtime1" = "$mtime2" ] ||
4970                         error "mtime is lost on close: $mtime2, " \
4971                               "should be $mtime1"
4972
4973                 cancel_lru_locks
4974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4975         done
4976         lctl set_param fail_loc=0
4977         stop_full_debug_logging
4978 }
4979 run_test 39j "write, rename, close, stat ======================="
4980
4981 test_39k() {
4982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4983
4984         touch $DIR1/$tfile
4985         sleep 1
4986
4987         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4988         local multipid=$!
4989         local mtime1=`stat -c %Y $DIR1/$tfile`
4990
4991         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4992
4993         kill -USR1 $multipid
4994         wait $multipid || error "multiop close failed"
4995
4996         for (( i=0; i < 2; i++ )) ; do
4997                 local mtime2=`stat -c %Y $DIR1/$tfile`
4998
4999                 [ "$mtime2" = $TEST_39_MTIME ] || \
5000                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5001
5002                 cancel_lru_locks
5003                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5004         done
5005 }
5006 run_test 39k "write, utime, close, stat ========================"
5007
5008 # this should be set to future
5009 TEST_39_ATIME=`date -d "1 year" +%s`
5010
5011 test_39l() {
5012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5013         remote_mds_nodsh && skip "remote MDS with nodsh"
5014
5015         local atime_diff=$(do_facet $SINGLEMDS \
5016                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5017         rm -rf $DIR/$tdir
5018         mkdir_on_mdt0 $DIR/$tdir
5019
5020         # test setting directory atime to future
5021         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5022         local atime=$(stat -c %X $DIR/$tdir)
5023         [ "$atime" = $TEST_39_ATIME ] ||
5024                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5025
5026         # test setting directory atime from future to now
5027         local now=$(date +%s)
5028         touch -a -d @$now $DIR/$tdir
5029
5030         atime=$(stat -c %X $DIR/$tdir)
5031         [ "$atime" -eq "$now"  ] ||
5032                 error "atime is not updated from future: $atime, $now"
5033
5034         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5035         sleep 3
5036
5037         # test setting directory atime when now > dir atime + atime_diff
5038         local d1=$(date +%s)
5039         ls $DIR/$tdir
5040         local d2=$(date +%s)
5041         cancel_lru_locks mdc
5042         atime=$(stat -c %X $DIR/$tdir)
5043         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5044                 error "atime is not updated  : $atime, should be $d2"
5045
5046         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5047         sleep 3
5048
5049         # test not setting directory atime when now < dir atime + atime_diff
5050         ls $DIR/$tdir
5051         cancel_lru_locks mdc
5052         atime=$(stat -c %X $DIR/$tdir)
5053         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5054                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5055
5056         do_facet $SINGLEMDS \
5057                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5058 }
5059 run_test 39l "directory atime update ==========================="
5060
5061 test_39m() {
5062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5063
5064         touch $DIR1/$tfile
5065         sleep 2
5066         local far_past_mtime=$(date -d "May 29 1953" +%s)
5067         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5068
5069         touch -m -d @$far_past_mtime $DIR1/$tfile
5070         touch -a -d @$far_past_atime $DIR1/$tfile
5071
5072         for (( i=0; i < 2; i++ )) ; do
5073                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5074                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5075                         error "atime or mtime set incorrectly"
5076
5077                 cancel_lru_locks $OSC
5078                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5079         done
5080 }
5081 run_test 39m "test atime and mtime before 1970"
5082
5083 test_39n() { # LU-3832
5084         remote_mds_nodsh && skip "remote MDS with nodsh"
5085
5086         local atime_diff=$(do_facet $SINGLEMDS \
5087                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5088         local atime0
5089         local atime1
5090         local atime2
5091
5092         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5093
5094         rm -rf $DIR/$tfile
5095         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5096         atime0=$(stat -c %X $DIR/$tfile)
5097
5098         sleep 5
5099         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5100         atime1=$(stat -c %X $DIR/$tfile)
5101
5102         sleep 5
5103         cancel_lru_locks mdc
5104         cancel_lru_locks osc
5105         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5106         atime2=$(stat -c %X $DIR/$tfile)
5107
5108         do_facet $SINGLEMDS \
5109                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5110
5111         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5112         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5113 }
5114 run_test 39n "check that O_NOATIME is honored"
5115
5116 test_39o() {
5117         TESTDIR=$DIR/$tdir/$tfile
5118         [ -e $TESTDIR ] && rm -rf $TESTDIR
5119         mkdir -p $TESTDIR
5120         cd $TESTDIR
5121         links1=2
5122         ls
5123         mkdir a b
5124         ls
5125         links2=$(stat -c %h .)
5126         [ $(($links1 + 2)) != $links2 ] &&
5127                 error "wrong links count $(($links1 + 2)) != $links2"
5128         rmdir b
5129         links3=$(stat -c %h .)
5130         [ $(($links1 + 1)) != $links3 ] &&
5131                 error "wrong links count $links1 != $links3"
5132         return 0
5133 }
5134 run_test 39o "directory cached attributes updated after create"
5135
5136 test_39p() {
5137         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5138
5139         local MDTIDX=1
5140         TESTDIR=$DIR/$tdir/$tdir
5141         [ -e $TESTDIR ] && rm -rf $TESTDIR
5142         test_mkdir -p $TESTDIR
5143         cd $TESTDIR
5144         links1=2
5145         ls
5146         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5147         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5148         ls
5149         links2=$(stat -c %h .)
5150         [ $(($links1 + 2)) != $links2 ] &&
5151                 error "wrong links count $(($links1 + 2)) != $links2"
5152         rmdir remote_dir2
5153         links3=$(stat -c %h .)
5154         [ $(($links1 + 1)) != $links3 ] &&
5155                 error "wrong links count $links1 != $links3"
5156         return 0
5157 }
5158 run_test 39p "remote directory cached attributes updated after create ========"
5159
5160 test_39r() {
5161         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5162                 skip "no atime update on old OST"
5163         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5164                 skip_env "ldiskfs only test"
5165         fi
5166
5167         local saved_adiff
5168         saved_adiff=$(do_facet ost1 \
5169                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5170         stack_trap "do_facet ost1 \
5171                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5172
5173         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5174
5175         $LFS setstripe -i 0 $DIR/$tfile
5176         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5177                 error "can't write initial file"
5178         cancel_lru_locks osc
5179
5180         # exceed atime_diff and access file
5181         sleep 10
5182         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5183                 error "can't udpate atime"
5184
5185         local atime_cli=$(stat -c %X $DIR/$tfile)
5186         echo "client atime: $atime_cli"
5187         # allow atime update to be written to device
5188         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5189         sleep 5
5190
5191         local ostdev=$(ostdevname 1)
5192         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5193         local seq=${fid[3]#0x}
5194         local oid=${fid[1]}
5195         local oid_hex
5196
5197         if [ $seq == 0 ]; then
5198                 oid_hex=${fid[1]}
5199         else
5200                 oid_hex=${fid[2]#0x}
5201         fi
5202         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5203         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5204
5205         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5206         local atime_ost=$(do_facet ost1 "$cmd" |&
5207                           awk -F'[: ]' '/atime:/ { print $4 }')
5208         (( atime_cli == atime_ost )) ||
5209                 error "atime on client $atime_cli != ost $atime_ost"
5210 }
5211 run_test 39r "lazy atime update on OST"
5212
5213 test_39q() { # LU-8041
5214         local testdir=$DIR/$tdir
5215         mkdir -p $testdir
5216         multiop_bg_pause $testdir D_c || error "multiop failed"
5217         local multipid=$!
5218         cancel_lru_locks mdc
5219         kill -USR1 $multipid
5220         local atime=$(stat -c %X $testdir)
5221         [ "$atime" -ne 0 ] || error "atime is zero"
5222 }
5223 run_test 39q "close won't zero out atime"
5224
5225 test_40() {
5226         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5227         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5228                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5229         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5230                 error "$tfile is not 4096 bytes in size"
5231 }
5232 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5233
5234 test_41() {
5235         # bug 1553
5236         small_write $DIR/f41 18
5237 }
5238 run_test 41 "test small file write + fstat ====================="
5239
5240 count_ost_writes() {
5241         lctl get_param -n ${OSC}.*.stats |
5242                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5243                         END { printf("%0.0f", writes) }'
5244 }
5245
5246 # decent default
5247 WRITEBACK_SAVE=500
5248 DIRTY_RATIO_SAVE=40
5249 MAX_DIRTY_RATIO=50
5250 BG_DIRTY_RATIO_SAVE=10
5251 MAX_BG_DIRTY_RATIO=25
5252
5253 start_writeback() {
5254         trap 0
5255         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5256         # dirty_ratio, dirty_background_ratio
5257         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5258                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5259                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5260                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5261         else
5262                 # if file not here, we are a 2.4 kernel
5263                 kill -CONT `pidof kupdated`
5264         fi
5265 }
5266
5267 stop_writeback() {
5268         # setup the trap first, so someone cannot exit the test at the
5269         # exact wrong time and mess up a machine
5270         trap start_writeback EXIT
5271         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5272         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5273                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5274                 sysctl -w vm.dirty_writeback_centisecs=0
5275                 sysctl -w vm.dirty_writeback_centisecs=0
5276                 # save and increase /proc/sys/vm/dirty_ratio
5277                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5278                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5279                 # save and increase /proc/sys/vm/dirty_background_ratio
5280                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5281                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5282         else
5283                 # if file not here, we are a 2.4 kernel
5284                 kill -STOP `pidof kupdated`
5285         fi
5286 }
5287
5288 # ensure that all stripes have some grant before we test client-side cache
5289 setup_test42() {
5290         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5291                 dd if=/dev/zero of=$i bs=4k count=1
5292                 rm $i
5293         done
5294 }
5295
5296 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5297 # file truncation, and file removal.
5298 test_42a() {
5299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5300
5301         setup_test42
5302         cancel_lru_locks $OSC
5303         stop_writeback
5304         sync; sleep 1; sync # just to be safe
5305         BEFOREWRITES=`count_ost_writes`
5306         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5307         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5308         AFTERWRITES=`count_ost_writes`
5309         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5310                 error "$BEFOREWRITES < $AFTERWRITES"
5311         start_writeback
5312 }
5313 run_test 42a "ensure that we don't flush on close"
5314
5315 test_42b() {
5316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5317
5318         setup_test42
5319         cancel_lru_locks $OSC
5320         stop_writeback
5321         sync
5322         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5323         BEFOREWRITES=$(count_ost_writes)
5324         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5325         AFTERWRITES=$(count_ost_writes)
5326         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5327                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5328         fi
5329         BEFOREWRITES=$(count_ost_writes)
5330         sync || error "sync: $?"
5331         AFTERWRITES=$(count_ost_writes)
5332         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5333                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5334         fi
5335         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5336         start_writeback
5337         return 0
5338 }
5339 run_test 42b "test destroy of file with cached dirty data ======"
5340
5341 # if these tests just want to test the effect of truncation,
5342 # they have to be very careful.  consider:
5343 # - the first open gets a {0,EOF}PR lock
5344 # - the first write conflicts and gets a {0, count-1}PW
5345 # - the rest of the writes are under {count,EOF}PW
5346 # - the open for truncate tries to match a {0,EOF}PR
5347 #   for the filesize and cancels the PWs.
5348 # any number of fixes (don't get {0,EOF} on open, match
5349 # composite locks, do smarter file size management) fix
5350 # this, but for now we want these tests to verify that
5351 # the cancellation with truncate intent works, so we
5352 # start the file with a full-file pw lock to match against
5353 # until the truncate.
5354 trunc_test() {
5355         test=$1
5356         file=$DIR/$test
5357         offset=$2
5358         cancel_lru_locks $OSC
5359         stop_writeback
5360         # prime the file with 0,EOF PW to match
5361         touch $file
5362         $TRUNCATE $file 0
5363         sync; sync
5364         # now the real test..
5365         dd if=/dev/zero of=$file bs=1024 count=100
5366         BEFOREWRITES=`count_ost_writes`
5367         $TRUNCATE $file $offset
5368         cancel_lru_locks $OSC
5369         AFTERWRITES=`count_ost_writes`
5370         start_writeback
5371 }
5372
5373 test_42c() {
5374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5375
5376         trunc_test 42c 1024
5377         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5378                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5379         rm $file
5380 }
5381 run_test 42c "test partial truncate of file with cached dirty data"
5382
5383 test_42d() {
5384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5385
5386         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5387         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5388         $LCTL set_param debug=+cache
5389
5390         trunc_test 42d 0
5391         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5392                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5393         rm $file
5394 }
5395 run_test 42d "test complete truncate of file with cached dirty data"
5396
5397 test_42e() { # bug22074
5398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5399
5400         local TDIR=$DIR/${tdir}e
5401         local pages=16 # hardcoded 16 pages, don't change it.
5402         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5403         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5404         local max_dirty_mb
5405         local warmup_files
5406
5407         test_mkdir $DIR/${tdir}e
5408         $LFS setstripe -c 1 $TDIR
5409         createmany -o $TDIR/f $files
5410
5411         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5412
5413         # we assume that with $OSTCOUNT files, at least one of them will
5414         # be allocated on OST0.
5415         warmup_files=$((OSTCOUNT * max_dirty_mb))
5416         createmany -o $TDIR/w $warmup_files
5417
5418         # write a large amount of data into one file and sync, to get good
5419         # avail_grant number from OST.
5420         for ((i=0; i<$warmup_files; i++)); do
5421                 idx=$($LFS getstripe -i $TDIR/w$i)
5422                 [ $idx -ne 0 ] && continue
5423                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5424                 break
5425         done
5426         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5427         sync
5428         $LCTL get_param $proc_osc0/cur_dirty_bytes
5429         $LCTL get_param $proc_osc0/cur_grant_bytes
5430
5431         # create as much dirty pages as we can while not to trigger the actual
5432         # RPCs directly. but depends on the env, VFS may trigger flush during this
5433         # period, hopefully we are good.
5434         for ((i=0; i<$warmup_files; i++)); do
5435                 idx=$($LFS getstripe -i $TDIR/w$i)
5436                 [ $idx -ne 0 ] && continue
5437                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5438         done
5439         $LCTL get_param $proc_osc0/cur_dirty_bytes
5440         $LCTL get_param $proc_osc0/cur_grant_bytes
5441
5442         # perform the real test
5443         $LCTL set_param $proc_osc0/rpc_stats 0
5444         for ((;i<$files; i++)); do
5445                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5446                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5447         done
5448         sync
5449         $LCTL get_param $proc_osc0/rpc_stats
5450
5451         local percent=0
5452         local have_ppr=false
5453         $LCTL get_param $proc_osc0/rpc_stats |
5454                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5455                         # skip lines until we are at the RPC histogram data
5456                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5457                         $have_ppr || continue
5458
5459                         # we only want the percent stat for < 16 pages
5460                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5461
5462                         percent=$((percent + WPCT))
5463                         if [[ $percent -gt 15 ]]; then
5464                                 error "less than 16-pages write RPCs" \
5465                                       "$percent% > 15%"
5466                                 break
5467                         fi
5468                 done
5469         rm -rf $TDIR
5470 }
5471 run_test 42e "verify sub-RPC writes are not done synchronously"
5472
5473 test_43A() { # was test_43
5474         test_mkdir $DIR/$tdir
5475         cp -p /bin/ls $DIR/$tdir/$tfile
5476         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5477         pid=$!
5478         # give multiop a chance to open
5479         sleep 1
5480
5481         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5482         kill -USR1 $pid
5483         # Wait for multiop to exit
5484         wait $pid
5485 }
5486 run_test 43A "execution of file opened for write should return -ETXTBSY"
5487
5488 test_43a() {
5489         test_mkdir $DIR/$tdir
5490         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5491         $DIR/$tdir/sleep 60 &
5492         SLEEP_PID=$!
5493         # Make sure exec of $tdir/sleep wins race with truncate
5494         sleep 1
5495         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5496         kill $SLEEP_PID
5497 }
5498 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5499
5500 test_43b() {
5501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5502
5503         test_mkdir $DIR/$tdir
5504         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5505         $DIR/$tdir/sleep 60 &
5506         SLEEP_PID=$!
5507         # Make sure exec of $tdir/sleep wins race with truncate
5508         sleep 1
5509         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5510         kill $SLEEP_PID
5511 }
5512 run_test 43b "truncate of file being executed should return -ETXTBSY"
5513
5514 test_43c() {
5515         local testdir="$DIR/$tdir"
5516         test_mkdir $testdir
5517         cp $SHELL $testdir/
5518         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5519                 ( cd $testdir && md5sum -c )
5520 }
5521 run_test 43c "md5sum of copy into lustre"
5522
5523 test_44A() { # was test_44
5524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5525
5526         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5527         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5528 }
5529 run_test 44A "zero length read from a sparse stripe"
5530
5531 test_44a() {
5532         local nstripe=$($LFS getstripe -c -d $DIR)
5533         [ -z "$nstripe" ] && skip "can't get stripe info"
5534         [[ $nstripe -gt $OSTCOUNT ]] &&
5535                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5536
5537         local stride=$($LFS getstripe -S -d $DIR)
5538         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5539                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5540         fi
5541
5542         OFFSETS="0 $((stride/2)) $((stride-1))"
5543         for offset in $OFFSETS; do
5544                 for i in $(seq 0 $((nstripe-1))); do
5545                         local GLOBALOFFSETS=""
5546                         # size in Bytes
5547                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5548                         local myfn=$DIR/d44a-$size
5549                         echo "--------writing $myfn at $size"
5550                         ll_sparseness_write $myfn $size ||
5551                                 error "ll_sparseness_write"
5552                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5553                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5554                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5555
5556                         for j in $(seq 0 $((nstripe-1))); do
5557                                 # size in Bytes
5558                                 size=$((((j + $nstripe )*$stride + $offset)))
5559                                 ll_sparseness_write $myfn $size ||
5560                                         error "ll_sparseness_write"
5561                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5562                         done
5563                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5564                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5565                         rm -f $myfn
5566                 done
5567         done
5568 }
5569 run_test 44a "test sparse pwrite ==============================="
5570
5571 dirty_osc_total() {
5572         tot=0
5573         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5574                 tot=$(($tot + $d))
5575         done
5576         echo $tot
5577 }
5578 do_dirty_record() {
5579         before=`dirty_osc_total`
5580         echo executing "\"$*\""
5581         eval $*
5582         after=`dirty_osc_total`
5583         echo before $before, after $after
5584 }
5585 test_45() {
5586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5587
5588         f="$DIR/f45"
5589         # Obtain grants from OST if it supports it
5590         echo blah > ${f}_grant
5591         stop_writeback
5592         sync
5593         do_dirty_record "echo blah > $f"
5594         [[ $before -eq $after ]] && error "write wasn't cached"
5595         do_dirty_record "> $f"
5596         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5597         do_dirty_record "echo blah > $f"
5598         [[ $before -eq $after ]] && error "write wasn't cached"
5599         do_dirty_record "sync"
5600         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5601         do_dirty_record "echo blah > $f"
5602         [[ $before -eq $after ]] && error "write wasn't cached"
5603         do_dirty_record "cancel_lru_locks osc"
5604         [[ $before -gt $after ]] ||
5605                 error "lock cancellation didn't lower dirty count"
5606         start_writeback
5607 }
5608 run_test 45 "osc io page accounting ============================"
5609
5610 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5611 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5612 # objects offset and an assert hit when an rpc was built with 1023's mapped
5613 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5614 test_46() {
5615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5616
5617         f="$DIR/f46"
5618         stop_writeback
5619         sync
5620         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5621         sync
5622         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5623         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5624         sync
5625         start_writeback
5626 }
5627 run_test 46 "dirtying a previously written page ================"
5628
5629 # test_47 is removed "Device nodes check" is moved to test_28
5630
5631 test_48a() { # bug 2399
5632         [ "$mds1_FSTYPE" = "zfs" ] &&
5633         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5634                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5635
5636         test_mkdir $DIR/$tdir
5637         cd $DIR/$tdir
5638         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5639         test_mkdir $DIR/$tdir
5640         touch foo || error "'touch foo' failed after recreating cwd"
5641         test_mkdir bar
5642         touch .foo || error "'touch .foo' failed after recreating cwd"
5643         test_mkdir .bar
5644         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5645         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5646         cd . || error "'cd .' failed after recreating cwd"
5647         mkdir . && error "'mkdir .' worked after recreating cwd"
5648         rmdir . && error "'rmdir .' worked after recreating cwd"
5649         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5650         cd .. || error "'cd ..' failed after recreating cwd"
5651 }
5652 run_test 48a "Access renamed working dir (should return errors)="
5653
5654 test_48b() { # bug 2399
5655         rm -rf $DIR/$tdir
5656         test_mkdir $DIR/$tdir
5657         cd $DIR/$tdir
5658         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5659         touch foo && error "'touch foo' worked after removing cwd"
5660         mkdir foo && error "'mkdir foo' worked after removing cwd"
5661         touch .foo && error "'touch .foo' worked after removing cwd"
5662         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5663         ls . > /dev/null && error "'ls .' worked after removing cwd"
5664         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5665         mkdir . && error "'mkdir .' worked after removing cwd"
5666         rmdir . && error "'rmdir .' worked after removing cwd"
5667         ln -s . foo && error "'ln -s .' worked after removing cwd"
5668         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5669 }
5670 run_test 48b "Access removed working dir (should return errors)="
5671
5672 test_48c() { # bug 2350
5673         #lctl set_param debug=-1
5674         #set -vx
5675         rm -rf $DIR/$tdir
5676         test_mkdir -p $DIR/$tdir/dir
5677         cd $DIR/$tdir/dir
5678         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5679         $TRACE touch foo && error "touch foo worked after removing cwd"
5680         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5681         touch .foo && error "touch .foo worked after removing cwd"
5682         mkdir .foo && error "mkdir .foo worked after removing cwd"
5683         $TRACE ls . && error "'ls .' worked after removing cwd"
5684         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5685         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5686         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5687         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5688         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5689 }
5690 run_test 48c "Access removed working subdir (should return errors)"
5691
5692 test_48d() { # bug 2350
5693         #lctl set_param debug=-1
5694         #set -vx
5695         rm -rf $DIR/$tdir
5696         test_mkdir -p $DIR/$tdir/dir
5697         cd $DIR/$tdir/dir
5698         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5699         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5700         $TRACE touch foo && error "'touch foo' worked after removing parent"
5701         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5702         touch .foo && error "'touch .foo' worked after removing parent"
5703         mkdir .foo && error "mkdir .foo worked after removing parent"
5704         $TRACE ls . && error "'ls .' worked after removing parent"
5705         $TRACE ls .. && error "'ls ..' worked after removing parent"
5706         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5707         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5708         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5709         true
5710 }
5711 run_test 48d "Access removed parent subdir (should return errors)"
5712
5713 test_48e() { # bug 4134
5714         #lctl set_param debug=-1
5715         #set -vx
5716         rm -rf $DIR/$tdir
5717         test_mkdir -p $DIR/$tdir/dir
5718         cd $DIR/$tdir/dir
5719         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5720         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5721         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5722         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5723         # On a buggy kernel addition of "touch foo" after cd .. will
5724         # produce kernel oops in lookup_hash_it
5725         touch ../foo && error "'cd ..' worked after recreate parent"
5726         cd $DIR
5727         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5728 }
5729 run_test 48e "Access to recreated parent subdir (should return errors)"
5730
5731 test_48f() {
5732         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5733                 skip "need MDS >= 2.13.55"
5734         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5735         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5736                 skip "needs different host for mdt1 mdt2"
5737         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5738
5739         $LFS mkdir -i0 $DIR/$tdir
5740         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5741
5742         for d in sub1 sub2 sub3; do
5743                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5744                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5745                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5746         done
5747
5748         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5749 }
5750 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5751
5752 test_49() { # LU-1030
5753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5754         remote_ost_nodsh && skip "remote OST with nodsh"
5755
5756         # get ost1 size - $FSNAME-OST0000
5757         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5758                 awk '{ print $4 }')
5759         # write 800M at maximum
5760         [[ $ost1_size -lt 2 ]] && ost1_size=2
5761         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5762
5763         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5764         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5765         local dd_pid=$!
5766
5767         # change max_pages_per_rpc while writing the file
5768         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5769         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5770         # loop until dd process exits
5771         while ps ax -opid | grep -wq $dd_pid; do
5772                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5773                 sleep $((RANDOM % 5 + 1))
5774         done
5775         # restore original max_pages_per_rpc
5776         $LCTL set_param $osc1_mppc=$orig_mppc
5777         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5778 }
5779 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5780
5781 test_50() {
5782         # bug 1485
5783         test_mkdir $DIR/$tdir
5784         cd $DIR/$tdir
5785         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5786 }
5787 run_test 50 "special situations: /proc symlinks  ==============="
5788
5789 test_51a() {    # was test_51
5790         # bug 1516 - create an empty entry right after ".." then split dir
5791         test_mkdir -c1 $DIR/$tdir
5792         touch $DIR/$tdir/foo
5793         $MCREATE $DIR/$tdir/bar
5794         rm $DIR/$tdir/foo
5795         createmany -m $DIR/$tdir/longfile 201
5796         FNUM=202
5797         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5798                 $MCREATE $DIR/$tdir/longfile$FNUM
5799                 FNUM=$(($FNUM + 1))
5800                 echo -n "+"
5801         done
5802         echo
5803         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5804 }
5805 run_test 51a "special situations: split htree with empty entry =="
5806
5807 cleanup_print_lfs_df () {
5808         trap 0
5809         $LFS df
5810         $LFS df -i
5811 }
5812
5813 test_51b() {
5814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5815
5816         local dir=$DIR/$tdir
5817         local nrdirs=$((65536 + 100))
5818
5819         # cleanup the directory
5820         rm -fr $dir
5821
5822         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5823
5824         $LFS df
5825         $LFS df -i
5826         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5827         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5828         [[ $numfree -lt $nrdirs ]] &&
5829                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5830
5831         # need to check free space for the directories as well
5832         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5833         numfree=$(( blkfree / $(fs_inode_ksize) ))
5834         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5835
5836         trap cleanup_print_lfs_df EXIT
5837
5838         # create files
5839         createmany -d $dir/d $nrdirs || {
5840                 unlinkmany $dir/d $nrdirs
5841                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5842         }
5843
5844         # really created :
5845         nrdirs=$(ls -U $dir | wc -l)
5846
5847         # unlink all but 100 subdirectories, then check it still works
5848         local left=100
5849         local delete=$((nrdirs - left))
5850
5851         $LFS df
5852         $LFS df -i
5853
5854         # for ldiskfs the nlink count should be 1, but this is OSD specific
5855         # and so this is listed for informational purposes only
5856         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5857         unlinkmany -d $dir/d $delete ||
5858                 error "unlink of first $delete subdirs failed"
5859
5860         echo "nlink between: $(stat -c %h $dir)"
5861         local found=$(ls -U $dir | wc -l)
5862         [ $found -ne $left ] &&
5863                 error "can't find subdirs: found only $found, expected $left"
5864
5865         unlinkmany -d $dir/d $delete $left ||
5866                 error "unlink of second $left subdirs failed"
5867         # regardless of whether the backing filesystem tracks nlink accurately
5868         # or not, the nlink count shouldn't be more than "." and ".." here
5869         local after=$(stat -c %h $dir)
5870         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5871                 echo "nlink after: $after"
5872
5873         cleanup_print_lfs_df
5874 }
5875 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5876
5877 test_51d_sub() {
5878         local stripecount=$1
5879         local nfiles=$2
5880
5881         log "create files with stripecount=$stripecount"
5882         $LFS setstripe -C $stripecount $DIR/$tdir
5883         createmany -o $DIR/$tdir/t- $nfiles
5884         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5885         for ((n = 0; n < $OSTCOUNT; n++)); do
5886                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5887                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5888                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5889                             '($1 == '$n') { objs += 1 } \
5890                             END { printf("%0.0f", objs) }')
5891                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5892         done
5893         unlinkmany $DIR/$tdir/t- $nfiles
5894         rm  -f $TMP/$tfile
5895
5896         local nlast
5897         local min=4
5898         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5899
5900         # For some combinations of stripecount and OSTCOUNT current code
5901         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5902         # than others. Rather than skipping this test entirely, check that
5903         # and keep testing to ensure imbalance does not get worse. LU-15282
5904         (( (OSTCOUNT == 6 && stripecount == 4) ||
5905            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5906            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5907         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5908                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5909                         { $LFS df && $LFS df -i &&
5910                         error "stripecount=$stripecount: " \
5911                               "OST $n has fewer objects vs. OST $nlast " \
5912                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5913                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5914                         { $LFS df && $LFS df -i &&
5915                         error "stripecount=$stripecount: " \
5916                               "OST $n has more objects vs. OST $nlast " \
5917                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5918
5919                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5920                         { $LFS df && $LFS df -i &&
5921                         error "stripecount=$stripecount: " \
5922                               "OST $n has fewer #0 objects vs. OST $nlast " \
5923                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5924                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5925                         { $LFS df && $LFS df -i &&
5926                         error "stripecount=$stripecount: " \
5927                               "OST $n has more #0 objects vs. OST $nlast " \
5928                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5929         done
5930 }
5931
5932 test_51d() {
5933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5934         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5935
5936         local stripecount
5937         local per_ost=100
5938         local nfiles=$((per_ost * OSTCOUNT))
5939         local mdts=$(comma_list $(mdts_nodes))
5940         local param="osp.*.create_count"
5941         local qos_old=$(do_facet mds1 \
5942                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5943
5944         do_nodes $mdts \
5945                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5946         stack_trap "do_nodes $mdts \
5947                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5948
5949         test_mkdir $DIR/$tdir
5950         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5951         (( dirstripes > 0 )) || dirstripes=1
5952
5953         # Ensure enough OST objects precreated for tests to pass without
5954         # running out of objects.  This is an LOV r-r OST algorithm test,
5955         # not an OST object precreation test.
5956         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5957         (( old >= nfiles )) ||
5958         {
5959                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5960
5961                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5962                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5963
5964                 # trigger precreation from all MDTs for all OSTs
5965                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5966                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5967                 done
5968         }
5969
5970         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5971                 sleep 8  # allow object precreation to catch up
5972                 test_51d_sub $stripecount $nfiles
5973         done
5974 }
5975 run_test 51d "check LOV round-robin OST object distribution"
5976
5977 test_51e() {
5978         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5979                 skip_env "ldiskfs only test"
5980         fi
5981
5982         test_mkdir -c1 $DIR/$tdir
5983         test_mkdir -c1 $DIR/$tdir/d0
5984
5985         touch $DIR/$tdir/d0/foo
5986         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5987                 error "file exceed 65000 nlink limit!"
5988         unlinkmany $DIR/$tdir/d0/f- 65001
5989         return 0
5990 }
5991 run_test 51e "check file nlink limit"
5992
5993 test_51f() {
5994         test_mkdir $DIR/$tdir
5995
5996         local max=100000
5997         local ulimit_old=$(ulimit -n)
5998         local spare=20 # number of spare fd's for scripts/libraries, etc.
5999         local mdt=$($LFS getstripe -m $DIR/$tdir)
6000         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6001
6002         echo "MDT$mdt numfree=$numfree, max=$max"
6003         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6004         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6005                 while ! ulimit -n $((numfree + spare)); do
6006                         numfree=$((numfree * 3 / 4))
6007                 done
6008                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6009         else
6010                 echo "left ulimit at $ulimit_old"
6011         fi
6012
6013         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6014                 unlinkmany $DIR/$tdir/f $numfree
6015                 error "create+open $numfree files in $DIR/$tdir failed"
6016         }
6017         ulimit -n $ulimit_old
6018
6019         # if createmany exits at 120s there will be fewer than $numfree files
6020         unlinkmany $DIR/$tdir/f $numfree || true
6021 }
6022 run_test 51f "check many open files limit"
6023
6024 test_52a() {
6025         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6026         test_mkdir $DIR/$tdir
6027         touch $DIR/$tdir/foo
6028         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6029         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6030         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6031         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6032         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6033                                         error "link worked"
6034         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6035         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6036         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6037                                                      error "lsattr"
6038         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6039         cp -r $DIR/$tdir $TMP/
6040         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6041 }
6042 run_test 52a "append-only flag test (should return errors)"
6043
6044 test_52b() {
6045         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6046         test_mkdir $DIR/$tdir
6047         touch $DIR/$tdir/foo
6048         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6049         cat test > $DIR/$tdir/foo && error "cat test worked"
6050         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6051         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6052         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6053                                         error "link worked"
6054         echo foo >> $DIR/$tdir/foo && error "echo worked"
6055         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6056         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6057         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6058         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6059                                                         error "lsattr"
6060         chattr -i $DIR/$tdir/foo || error "chattr failed"
6061
6062         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6063 }
6064 run_test 52b "immutable flag test (should return errors) ======="
6065
6066 test_53() {
6067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6068         remote_mds_nodsh && skip "remote MDS with nodsh"
6069         remote_ost_nodsh && skip "remote OST with nodsh"
6070
6071         local param
6072         local param_seq
6073         local ostname
6074         local mds_last
6075         local mds_last_seq
6076         local ost_last
6077         local ost_last_seq
6078         local ost_last_id
6079         local ostnum
6080         local node
6081         local found=false
6082         local support_last_seq=true
6083
6084         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6085                 support_last_seq=false
6086
6087         # only test MDT0000
6088         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6089         local value
6090         for value in $(do_facet $SINGLEMDS \
6091                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6092                 param=$(echo ${value[0]} | cut -d "=" -f1)
6093                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6094
6095                 if $support_last_seq; then
6096                         param_seq=$(echo $param |
6097                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6098                         mds_last_seq=$(do_facet $SINGLEMDS \
6099                                        $LCTL get_param -n $param_seq)
6100                 fi
6101                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6102
6103                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6104                 node=$(facet_active_host ost$((ostnum+1)))
6105                 param="obdfilter.$ostname.last_id"
6106                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6107                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6108                         ost_last_id=$ost_last
6109
6110                         if $support_last_seq; then
6111                                 ost_last_id=$(echo $ost_last |
6112                                               awk -F':' '{print $2}' |
6113                                               sed -e "s/^0x//g")
6114                                 ost_last_seq=$(echo $ost_last |
6115                                                awk -F':' '{print $1}')
6116                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6117                         fi
6118
6119                         if [[ $ost_last_id != $mds_last ]]; then
6120                                 error "$ost_last_id != $mds_last"
6121                         else
6122                                 found=true
6123                                 break
6124                         fi
6125                 done
6126         done
6127         $found || error "can not match last_seq/last_id for $mdtosc"
6128         return 0
6129 }
6130 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6131
6132 test_54a() {
6133         perl -MSocket -e ';' || skip "no Socket perl module installed"
6134
6135         $SOCKETSERVER $DIR/socket ||
6136                 error "$SOCKETSERVER $DIR/socket failed: $?"
6137         $SOCKETCLIENT $DIR/socket ||
6138                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6139         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6140 }
6141 run_test 54a "unix domain socket test =========================="
6142
6143 test_54b() {
6144         f="$DIR/f54b"
6145         mknod $f c 1 3
6146         chmod 0666 $f
6147         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6148 }
6149 run_test 54b "char device works in lustre ======================"
6150
6151 find_loop_dev() {
6152         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6153         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6154         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6155
6156         for i in $(seq 3 7); do
6157                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6158                 LOOPDEV=$LOOPBASE$i
6159                 LOOPNUM=$i
6160                 break
6161         done
6162 }
6163
6164 cleanup_54c() {
6165         local rc=0
6166         loopdev="$DIR/loop54c"
6167
6168         trap 0
6169         $UMOUNT $DIR/$tdir || rc=$?
6170         losetup -d $loopdev || true
6171         losetup -d $LOOPDEV || true
6172         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6173         return $rc
6174 }
6175
6176 test_54c() {
6177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6178
6179         loopdev="$DIR/loop54c"
6180
6181         find_loop_dev
6182         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6183         trap cleanup_54c EXIT
6184         mknod $loopdev b 7 $LOOPNUM
6185         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6186         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6187         losetup $loopdev $DIR/$tfile ||
6188                 error "can't set up $loopdev for $DIR/$tfile"
6189         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6190         test_mkdir $DIR/$tdir
6191         mount -t ext2 $loopdev $DIR/$tdir ||
6192                 error "error mounting $loopdev on $DIR/$tdir"
6193         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6194                 error "dd write"
6195         df $DIR/$tdir
6196         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6197                 error "dd read"
6198         cleanup_54c
6199 }
6200 run_test 54c "block device works in lustre ====================="
6201
6202 test_54d() {
6203         local pipe="$DIR/$tfile.pipe"
6204         local string="aaaaaa"
6205
6206         mknod $pipe p
6207         echo -n "$string" > $pipe &
6208         local result=$(cat $pipe)
6209         [[ "$result" == "$string" ]] || error "$result != $string"
6210 }
6211 run_test 54d "fifo device works in lustre ======================"
6212
6213 test_54e() {
6214         f="$DIR/f54e"
6215         string="aaaaaa"
6216         cp -aL /dev/console $f
6217         echo $string > $f || error "echo $string to $f failed"
6218 }
6219 run_test 54e "console/tty device works in lustre ======================"
6220
6221 test_56a() {
6222         local numfiles=3
6223         local numdirs=2
6224         local dir=$DIR/$tdir
6225
6226         rm -rf $dir
6227         test_mkdir -p $dir/dir
6228         for i in $(seq $numfiles); do
6229                 touch $dir/file$i
6230                 touch $dir/dir/file$i
6231         done
6232
6233         local numcomp=$($LFS getstripe --component-count $dir)
6234
6235         [[ $numcomp == 0 ]] && numcomp=1
6236
6237         # test lfs getstripe with --recursive
6238         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6239
6240         [[ $filenum -eq $((numfiles * 2)) ]] ||
6241                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6242         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6243         [[ $filenum -eq $numfiles ]] ||
6244                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6245         echo "$LFS getstripe showed obdidx or l_ost_idx"
6246
6247         # test lfs getstripe with file instead of dir
6248         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6249         [[ $filenum -eq 1 ]] ||
6250                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6251         echo "$LFS getstripe file1 passed"
6252
6253         #test lfs getstripe with --verbose
6254         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6255         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6256                 error "$LFS getstripe --verbose $dir: "\
6257                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6258         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6259                 error "$LFS getstripe $dir: showed lmm_magic"
6260
6261         #test lfs getstripe with -v prints lmm_fid
6262         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6263         local countfids=$((numdirs + numfiles * numcomp))
6264         [[ $filenum -eq $countfids ]] ||
6265                 error "$LFS getstripe -v $dir: "\
6266                       "got $filenum want $countfids lmm_fid"
6267         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6268                 error "$LFS getstripe $dir: showed lmm_fid by default"
6269         echo "$LFS getstripe --verbose passed"
6270
6271         #check for FID information
6272         local fid1=$($LFS getstripe --fid $dir/file1)
6273         local fid2=$($LFS getstripe --verbose $dir/file1 |
6274                      awk '/lmm_fid: / { print $2; exit; }')
6275         local fid3=$($LFS path2fid $dir/file1)
6276
6277         [ "$fid1" != "$fid2" ] &&
6278                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6279         [ "$fid1" != "$fid3" ] &&
6280                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6281         echo "$LFS getstripe --fid passed"
6282
6283         #test lfs getstripe with --obd
6284         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6285                 error "$LFS getstripe --obd wrong_uuid: should return error"
6286
6287         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6288
6289         local ostidx=1
6290         local obduuid=$(ostuuid_from_index $ostidx)
6291         local found=$($LFS getstripe -r --obd $obduuid $dir |
6292                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6293
6294         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6295         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6296                 ((filenum--))
6297         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6298                 ((filenum--))
6299
6300         [[ $found -eq $filenum ]] ||
6301                 error "$LFS getstripe --obd: found $found expect $filenum"
6302         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6303                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6304                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6305                 error "$LFS getstripe --obd: should not show file on other obd"
6306         echo "$LFS getstripe --obd passed"
6307 }
6308 run_test 56a "check $LFS getstripe"
6309
6310 test_56b() {
6311         local dir=$DIR/$tdir
6312         local numdirs=3
6313
6314         test_mkdir $dir
6315         for i in $(seq $numdirs); do
6316                 test_mkdir $dir/dir$i
6317         done
6318
6319         # test lfs getdirstripe default mode is non-recursion, which is
6320         # different from lfs getstripe
6321         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6322
6323         [[ $dircnt -eq 1 ]] ||
6324                 error "$LFS getdirstripe: found $dircnt, not 1"
6325         dircnt=$($LFS getdirstripe --recursive $dir |
6326                 grep -c lmv_stripe_count)
6327         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6328                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6329 }
6330 run_test 56b "check $LFS getdirstripe"
6331
6332 test_56c() {
6333         remote_ost_nodsh && skip "remote OST with nodsh"
6334
6335         local ost_idx=0
6336         local ost_name=$(ostname_from_index $ost_idx)
6337         local old_status=$(ost_dev_status $ost_idx)
6338         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6339
6340         [[ -z "$old_status" ]] ||
6341                 skip_env "OST $ost_name is in $old_status status"
6342
6343         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6344         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6345                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6346         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6347                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6348                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6349         fi
6350
6351         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6352                 error "$LFS df -v showing inactive devices"
6353         sleep_maxage
6354
6355         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6356
6357         [[ "$new_status" =~ "D" ]] ||
6358                 error "$ost_name status is '$new_status', missing 'D'"
6359         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6360                 [[ "$new_status" =~ "N" ]] ||
6361                         error "$ost_name status is '$new_status', missing 'N'"
6362         fi
6363         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6364                 [[ "$new_status" =~ "f" ]] ||
6365                         error "$ost_name status is '$new_status', missing 'f'"
6366         fi
6367
6368         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6369         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6370                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6371         [[ -z "$p" ]] && restore_lustre_params < $p || true
6372         sleep_maxage
6373
6374         new_status=$(ost_dev_status $ost_idx)
6375         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6376                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6377         # can't check 'f' as devices may actually be on flash
6378 }
6379 run_test 56c "check 'lfs df' showing device status"
6380
6381 test_56d() {
6382         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6383         local osts=$($LFS df -v $MOUNT | grep -c OST)
6384
6385         $LFS df $MOUNT
6386
6387         (( mdts == MDSCOUNT )) ||
6388                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6389         (( osts == OSTCOUNT )) ||
6390                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6391 }
6392 run_test 56d "'lfs df -v' prints only configured devices"
6393
6394 test_56e() {
6395         err_enoent=2 # No such file or directory
6396         err_eopnotsupp=95 # Operation not supported
6397
6398         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6399         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6400
6401         # Check for handling of path not exists
6402         output=$($LFS df $enoent_mnt 2>&1)
6403         ret=$?
6404
6405         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6406         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6407                 error "expect failure $err_enoent, not $ret"
6408
6409         # Check for handling of non-Lustre FS
6410         output=$($LFS df $notsup_mnt)
6411         ret=$?
6412
6413         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6414         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6415                 error "expect success $err_eopnotsupp, not $ret"
6416
6417         # Check for multiple LustreFS argument
6418         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6419         ret=$?
6420
6421         [[ $output -eq 3 && $ret -eq 0 ]] ||
6422                 error "expect success 3, not $output, rc = $ret"
6423
6424         # Check for correct non-Lustre FS handling among multiple
6425         # LustreFS argument
6426         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6427                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6428         ret=$?
6429
6430         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6431                 error "expect success 2, not $output, rc = $ret"
6432 }
6433 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6434
6435 NUMFILES=3
6436 NUMDIRS=3
6437 setup_56() {
6438         local local_tdir="$1"
6439         local local_numfiles="$2"
6440         local local_numdirs="$3"
6441         local dir_params="$4"
6442         local dir_stripe_params="$5"
6443
6444         if [ ! -d "$local_tdir" ] ; then
6445                 test_mkdir -p $dir_stripe_params $local_tdir
6446                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6447                 for i in $(seq $local_numfiles) ; do
6448                         touch $local_tdir/file$i
6449                 done
6450                 for i in $(seq $local_numdirs) ; do
6451                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6452                         for j in $(seq $local_numfiles) ; do
6453                                 touch $local_tdir/dir$i/file$j
6454                         done
6455                 done
6456         fi
6457 }
6458
6459 setup_56_special() {
6460         local local_tdir=$1
6461         local local_numfiles=$2
6462         local local_numdirs=$3
6463
6464         setup_56 $local_tdir $local_numfiles $local_numdirs
6465
6466         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6467                 for i in $(seq $local_numfiles) ; do
6468                         mknod $local_tdir/loop${i}b b 7 $i
6469                         mknod $local_tdir/null${i}c c 1 3
6470                         ln -s $local_tdir/file1 $local_tdir/link${i}
6471                 done
6472                 for i in $(seq $local_numdirs) ; do
6473                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6474                         mknod $local_tdir/dir$i/null${i}c c 1 3
6475                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6476                 done
6477         fi
6478 }
6479
6480 test_56g() {
6481         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6482         local expected=$(($NUMDIRS + 2))
6483
6484         setup_56 $dir $NUMFILES $NUMDIRS
6485
6486         # test lfs find with -name
6487         for i in $(seq $NUMFILES) ; do
6488                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6489
6490                 [ $nums -eq $expected ] ||
6491                         error "lfs find -name '*$i' $dir wrong: "\
6492                               "found $nums, expected $expected"
6493         done
6494 }
6495 run_test 56g "check lfs find -name"
6496
6497 test_56h() {
6498         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6499         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6500
6501         setup_56 $dir $NUMFILES $NUMDIRS
6502
6503         # test lfs find with ! -name
6504         for i in $(seq $NUMFILES) ; do
6505                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6506
6507                 [ $nums -eq $expected ] ||
6508                         error "lfs find ! -name '*$i' $dir wrong: "\
6509                               "found $nums, expected $expected"
6510         done
6511 }
6512 run_test 56h "check lfs find ! -name"
6513
6514 test_56i() {
6515         local dir=$DIR/$tdir
6516
6517         test_mkdir $dir
6518
6519         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6520         local out=$($cmd)
6521
6522         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6523 }
6524 run_test 56i "check 'lfs find -ost UUID' skips directories"
6525
6526 test_56j() {
6527         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6528
6529         setup_56_special $dir $NUMFILES $NUMDIRS
6530
6531         local expected=$((NUMDIRS + 1))
6532         local cmd="$LFS find -type d $dir"
6533         local nums=$($cmd | wc -l)
6534
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537 }
6538 run_test 56j "check lfs find -type d"
6539
6540 test_56k() {
6541         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6542
6543         setup_56_special $dir $NUMFILES $NUMDIRS
6544
6545         local expected=$(((NUMDIRS + 1) * NUMFILES))
6546         local cmd="$LFS find -type f $dir"
6547         local nums=$($cmd | wc -l)
6548
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551 }
6552 run_test 56k "check lfs find -type f"
6553
6554 test_56l() {
6555         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6556
6557         setup_56_special $dir $NUMFILES $NUMDIRS
6558
6559         local expected=$((NUMDIRS + NUMFILES))
6560         local cmd="$LFS find -type b $dir"
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565 }
6566 run_test 56l "check lfs find -type b"
6567
6568 test_56m() {
6569         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6570
6571         setup_56_special $dir $NUMFILES $NUMDIRS
6572
6573         local expected=$((NUMDIRS + NUMFILES))
6574         local cmd="$LFS find -type c $dir"
6575         local nums=$($cmd | wc -l)
6576         [ $nums -eq $expected ] ||
6577                 error "'$cmd' wrong: found $nums, expected $expected"
6578 }
6579 run_test 56m "check lfs find -type c"
6580
6581 test_56n() {
6582         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6583         setup_56_special $dir $NUMFILES $NUMDIRS
6584
6585         local expected=$((NUMDIRS + NUMFILES))
6586         local cmd="$LFS find -type l $dir"
6587         local nums=$($cmd | wc -l)
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591 }
6592 run_test 56n "check lfs find -type l"
6593
6594 test_56o() {
6595         local dir=$DIR/$tdir
6596
6597         setup_56 $dir $NUMFILES $NUMDIRS
6598         utime $dir/file1 > /dev/null || error "utime (1)"
6599         utime $dir/file2 > /dev/null || error "utime (2)"
6600         utime $dir/dir1 > /dev/null || error "utime (3)"
6601         utime $dir/dir2 > /dev/null || error "utime (4)"
6602         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6603         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6604
6605         local expected=4
6606         local nums=$($LFS find -mtime +0 $dir | wc -l)
6607
6608         [ $nums -eq $expected ] ||
6609                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6610
6611         expected=12
6612         cmd="$LFS find -mtime 0 $dir"
6613         nums=$($cmd | wc -l)
6614         [ $nums -eq $expected ] ||
6615                 error "'$cmd' wrong: found $nums, expected $expected"
6616 }
6617 run_test 56o "check lfs find -mtime for old files"
6618
6619 test_56ob() {
6620         local dir=$DIR/$tdir
6621         local expected=1
6622         local count=0
6623
6624         # just to make sure there is something that won't be found
6625         test_mkdir $dir
6626         touch $dir/$tfile.now
6627
6628         for age in year week day hour min; do
6629                 count=$((count + 1))
6630
6631                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6632                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6633                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6634
6635                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6636                 local nums=$($cmd | wc -l)
6637                 [ $nums -eq $expected ] ||
6638                         error "'$cmd' wrong: found $nums, expected $expected"
6639
6640                 cmd="$LFS find $dir -atime $count${age:0:1}"
6641                 nums=$($cmd | wc -l)
6642                 [ $nums -eq $expected ] ||
6643                         error "'$cmd' wrong: found $nums, expected $expected"
6644         done
6645
6646         sleep 2
6647         cmd="$LFS find $dir -ctime +1s -type f"
6648         nums=$($cmd | wc -l)
6649         (( $nums == $count * 2 + 1)) ||
6650                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6651 }
6652 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6653
6654 test_newerXY_base() {
6655         local x=$1
6656         local y=$2
6657         local dir=$DIR/$tdir
6658         local ref
6659         local negref
6660
6661         if [ $y == "t" ]; then
6662                 if [ $x == "b" ]; then
6663                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6664                 else
6665                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6666                 fi
6667         else
6668                 ref=$DIR/$tfile.newer.$x$y
6669                 touch $ref || error "touch $ref failed"
6670         fi
6671
6672         echo "before = $ref"
6673         sleep 2
6674         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6675         sleep 2
6676         if [ $y == "t" ]; then
6677                 if [ $x == "b" ]; then
6678                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6679                 else
6680                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6681                 fi
6682         else
6683                 negref=$DIR/$tfile.negnewer.$x$y
6684                 touch $negref || error "touch $negref failed"
6685         fi
6686
6687         echo "after = $negref"
6688         local cmd="$LFS find $dir -newer$x$y $ref"
6689         local nums=$(eval $cmd | wc -l)
6690         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6691
6692         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6693                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6694
6695         cmd="$LFS find $dir ! -newer$x$y $negref"
6696         nums=$(eval $cmd | wc -l)
6697         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6698                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6699
6700         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6701         nums=$(eval $cmd | wc -l)
6702         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6703                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6704
6705         rm -rf $DIR/*
6706 }
6707
6708 test_56oc() {
6709         test_newerXY_base "a" "a"
6710         test_newerXY_base "a" "m"
6711         test_newerXY_base "a" "c"
6712         test_newerXY_base "m" "a"
6713         test_newerXY_base "m" "m"
6714         test_newerXY_base "m" "c"
6715         test_newerXY_base "c" "a"
6716         test_newerXY_base "c" "m"
6717         test_newerXY_base "c" "c"
6718
6719         test_newerXY_base "a" "t"
6720         test_newerXY_base "m" "t"
6721         test_newerXY_base "c" "t"
6722
6723         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6724            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6725                 ! btime_supported && echo "btime unsupported" && return 0
6726
6727         test_newerXY_base "b" "b"
6728         test_newerXY_base "b" "t"
6729 }
6730 run_test 56oc "check lfs find -newerXY work"
6731
6732 btime_supported() {
6733         local dir=$DIR/$tdir
6734         local rc
6735
6736         mkdir -p $dir
6737         touch $dir/$tfile
6738         $LFS find $dir -btime -1d -type f
6739         rc=$?
6740         rm -rf $dir
6741         return $rc
6742 }
6743
6744 test_56od() {
6745         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6746                 ! btime_supported && skip "btime unsupported on MDS"
6747
6748         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6749                 ! btime_supported && skip "btime unsupported on clients"
6750
6751         local dir=$DIR/$tdir
6752         local ref=$DIR/$tfile.ref
6753         local negref=$DIR/$tfile.negref
6754
6755         mkdir $dir || error "mkdir $dir failed"
6756         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6757         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6758         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6759         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6760         touch $ref || error "touch $ref failed"
6761         # sleep 3 seconds at least
6762         sleep 3
6763
6764         local before=$(do_facet mds1 date +%s)
6765         local skew=$(($(date +%s) - before + 1))
6766
6767         if (( skew < 0 && skew > -5 )); then
6768                 sleep $((0 - skew + 1))
6769                 skew=0
6770         fi
6771
6772         # Set the dir stripe params to limit files all on MDT0,
6773         # otherwise we need to calc the max clock skew between
6774         # the client and MDTs.
6775         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6776         sleep 2
6777         touch $negref || error "touch $negref failed"
6778
6779         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6780         local nums=$($cmd | wc -l)
6781         local expected=$(((NUMFILES + 1) * NUMDIRS))
6782
6783         [ $nums -eq $expected ] ||
6784                 error "'$cmd' wrong: found $nums, expected $expected"
6785
6786         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6787         nums=$($cmd | wc -l)
6788         expected=$((NUMFILES + 1))
6789         [ $nums -eq $expected ] ||
6790                 error "'$cmd' wrong: found $nums, expected $expected"
6791
6792         [ $skew -lt 0 ] && return
6793
6794         local after=$(do_facet mds1 date +%s)
6795         local age=$((after - before + 1 + skew))
6796
6797         cmd="$LFS find $dir -btime -${age}s -type f"
6798         nums=$($cmd | wc -l)
6799         expected=$(((NUMFILES + 1) * NUMDIRS))
6800
6801         echo "Clock skew between client and server: $skew, age:$age"
6802         [ $nums -eq $expected ] ||
6803                 error "'$cmd' wrong: found $nums, expected $expected"
6804
6805         expected=$(($NUMDIRS + 1))
6806         cmd="$LFS find $dir -btime -${age}s -type d"
6807         nums=$($cmd | wc -l)
6808         [ $nums -eq $expected ] ||
6809                 error "'$cmd' wrong: found $nums, expected $expected"
6810         rm -f $ref $negref || error "Failed to remove $ref $negref"
6811 }
6812 run_test 56od "check lfs find -btime with units"
6813
6814 test_56p() {
6815         [ $RUNAS_ID -eq $UID ] &&
6816                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6817
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS
6821         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6822
6823         local expected=$NUMFILES
6824         local cmd="$LFS find -uid $RUNAS_ID $dir"
6825         local nums=$($cmd | wc -l)
6826
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829
6830         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6831         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6832         nums=$($cmd | wc -l)
6833         [ $nums -eq $expected ] ||
6834                 error "'$cmd' wrong: found $nums, expected $expected"
6835 }
6836 run_test 56p "check lfs find -uid and ! -uid"
6837
6838 test_56q() {
6839         [ $RUNAS_ID -eq $UID ] &&
6840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6841
6842         local dir=$DIR/$tdir
6843
6844         setup_56 $dir $NUMFILES $NUMDIRS
6845         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6846
6847         local expected=$NUMFILES
6848         local cmd="$LFS find -gid $RUNAS_GID $dir"
6849         local nums=$($cmd | wc -l)
6850
6851         [ $nums -eq $expected ] ||
6852                 error "'$cmd' wrong: found $nums, expected $expected"
6853
6854         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6855         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6856         nums=$($cmd | wc -l)
6857         [ $nums -eq $expected ] ||
6858                 error "'$cmd' wrong: found $nums, expected $expected"
6859 }
6860 run_test 56q "check lfs find -gid and ! -gid"
6861
6862 test_56r() {
6863         local dir=$DIR/$tdir
6864
6865         setup_56 $dir $NUMFILES $NUMDIRS
6866
6867         local expected=12
6868         local cmd="$LFS find -size 0 -type f -lazy $dir"
6869         local nums=$($cmd | wc -l)
6870
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873         cmd="$LFS find -size 0 -type f $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877
6878         expected=0
6879         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6880         nums=$($cmd | wc -l)
6881         [ $nums -eq $expected ] ||
6882                 error "'$cmd' wrong: found $nums, expected $expected"
6883         cmd="$LFS find ! -size 0 -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         echo "test" > $dir/$tfile
6889         echo "test2" > $dir/$tfile.2 && sync
6890         expected=1
6891         cmd="$LFS find -size 5 -type f -lazy $dir"
6892         nums=$($cmd | wc -l)
6893         [ $nums -eq $expected ] ||
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895         cmd="$LFS find -size 5 -type f $dir"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] ||
6898                 error "'$cmd' wrong: found $nums, expected $expected"
6899
6900         expected=1
6901         cmd="$LFS find -size +5 -type f -lazy $dir"
6902         nums=$($cmd | wc -l)
6903         [ $nums -eq $expected ] ||
6904                 error "'$cmd' wrong: found $nums, expected $expected"
6905         cmd="$LFS find -size +5 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         expected=2
6911         cmd="$LFS find -size +0 -type f -lazy $dir"
6912         nums=$($cmd | wc -l)
6913         [ $nums -eq $expected ] ||
6914                 error "'$cmd' wrong: found $nums, expected $expected"
6915         cmd="$LFS find -size +0 -type f $dir"
6916         nums=$($cmd | wc -l)
6917         [ $nums -eq $expected ] ||
6918                 error "'$cmd' wrong: found $nums, expected $expected"
6919
6920         expected=2
6921         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6922         nums=$($cmd | wc -l)
6923         [ $nums -eq $expected ] ||
6924                 error "'$cmd' wrong: found $nums, expected $expected"
6925         cmd="$LFS find ! -size -5 -type f $dir"
6926         nums=$($cmd | wc -l)
6927         [ $nums -eq $expected ] ||
6928                 error "'$cmd' wrong: found $nums, expected $expected"
6929
6930         expected=12
6931         cmd="$LFS find -size -5 -type f -lazy $dir"
6932         nums=$($cmd | wc -l)
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935         cmd="$LFS find -size -5 -type f $dir"
6936         nums=$($cmd | wc -l)
6937         [ $nums -eq $expected ] ||
6938                 error "'$cmd' wrong: found $nums, expected $expected"
6939 }
6940 run_test 56r "check lfs find -size works"
6941
6942 test_56ra_sub() {
6943         local expected=$1
6944         local glimpses=$2
6945         local cmd="$3"
6946
6947         cancel_lru_locks $OSC
6948
6949         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6950         local nums=$($cmd | wc -l)
6951
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6956
6957         if (( rpcs_before + glimpses != rpcs_after )); then
6958                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6959                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6960
6961                 if [[ $glimpses == 0 ]]; then
6962                         error "'$cmd' should not send glimpse RPCs to OST"
6963                 else
6964                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6965                 fi
6966         fi
6967 }
6968
6969 test_56ra() {
6970         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6971                 skip "MDS < 2.12.58 doesn't return LSOM data"
6972         local dir=$DIR/$tdir
6973         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6974
6975         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6976
6977         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6978         $LCTL set_param -n llite.*.statahead_agl=0
6979         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6980
6981         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6982         # open and close all files to ensure LSOM is updated
6983         cancel_lru_locks $OSC
6984         find $dir -type f | xargs cat > /dev/null
6985
6986         #   expect_found  glimpse_rpcs  command_to_run
6987         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6988         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6989         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6990         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6991
6992         echo "test" > $dir/$tfile
6993         echo "test2" > $dir/$tfile.2 && sync
6994         cancel_lru_locks $OSC
6995         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6996
6997         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6998         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6999         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7000         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7001
7002         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7003         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7004         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7005         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7006         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7007         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7008 }
7009 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7010
7011 test_56rb() {
7012         local dir=$DIR/$tdir
7013         local tmp=$TMP/$tfile.log
7014         local mdt_idx;
7015
7016         test_mkdir -p $dir || error "failed to mkdir $dir"
7017         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7018                 error "failed to setstripe $dir/$tfile"
7019         mdt_idx=$($LFS getdirstripe -i $dir)
7020         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7021
7022         stack_trap "rm -f $tmp" EXIT
7023         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7024         ! grep -q obd_uuid $tmp ||
7025                 error "failed to find --size +100K --ost 0 $dir"
7026         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7027         ! grep -q obd_uuid $tmp ||
7028                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7029 }
7030 run_test 56rb "check lfs find --size --ost/--mdt works"
7031
7032 test_56rc() {
7033         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7034         local dir=$DIR/$tdir
7035         local found
7036
7037         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7038         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7039         (( $MDSCOUNT > 2 )) &&
7040                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7041         mkdir $dir/$tdir-{1..10}
7042         touch $dir/$tfile-{1..10}
7043
7044         found=$($LFS find $dir --mdt-count 2 | wc -l)
7045         expect=11
7046         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7047
7048         found=$($LFS find $dir -T +1 | wc -l)
7049         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7050         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7051
7052         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7053         expect=11
7054         (( $found == $expect )) || error "found $found all_char, expect $expect"
7055
7056         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7057         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7058         (( $found == $expect )) || error "found $found all_char, expect $expect"
7059 }
7060 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7061
7062 test_56s() { # LU-611 #LU-9369
7063         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7064
7065         local dir=$DIR/$tdir
7066         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7067
7068         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7069         for i in $(seq $NUMDIRS); do
7070                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7071         done
7072
7073         local expected=$NUMDIRS
7074         local cmd="$LFS find -c $OSTCOUNT $dir"
7075         local nums=$($cmd | wc -l)
7076
7077         [ $nums -eq $expected ] || {
7078                 $LFS getstripe -R $dir
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         }
7081
7082         expected=$((NUMDIRS + onestripe))
7083         cmd="$LFS find -stripe-count +0 -type f $dir"
7084         nums=$($cmd | wc -l)
7085         [ $nums -eq $expected ] || {
7086                 $LFS getstripe -R $dir
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088         }
7089
7090         expected=$onestripe
7091         cmd="$LFS find -stripe-count 1 -type f $dir"
7092         nums=$($cmd | wc -l)
7093         [ $nums -eq $expected ] || {
7094                 $LFS getstripe -R $dir
7095                 error "'$cmd' wrong: found $nums, expected $expected"
7096         }
7097
7098         cmd="$LFS find -stripe-count -2 -type f $dir"
7099         nums=$($cmd | wc -l)
7100         [ $nums -eq $expected ] || {
7101                 $LFS getstripe -R $dir
7102                 error "'$cmd' wrong: found $nums, expected $expected"
7103         }
7104
7105         expected=0
7106         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] || {
7109                 $LFS getstripe -R $dir
7110                 error "'$cmd' wrong: found $nums, expected $expected"
7111         }
7112 }
7113 run_test 56s "check lfs find -stripe-count works"
7114
7115 test_56t() { # LU-611 #LU-9369
7116         local dir=$DIR/$tdir
7117
7118         setup_56 $dir 0 $NUMDIRS
7119         for i in $(seq $NUMDIRS); do
7120                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7121         done
7122
7123         local expected=$NUMDIRS
7124         local cmd="$LFS find -S 8M $dir"
7125         local nums=$($cmd | wc -l)
7126
7127         [ $nums -eq $expected ] || {
7128                 $LFS getstripe -R $dir
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130         }
7131         rm -rf $dir
7132
7133         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7134
7135         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7136
7137         expected=$(((NUMDIRS + 1) * NUMFILES))
7138         cmd="$LFS find -stripe-size 512k -type f $dir"
7139         nums=$($cmd | wc -l)
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142
7143         cmd="$LFS find -stripe-size +320k -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147
7148         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7149         cmd="$LFS find -stripe-size +200k -type f $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153
7154         cmd="$LFS find -stripe-size -640k -type f $dir"
7155         nums=$($cmd | wc -l)
7156         [ $nums -eq $expected ] ||
7157                 error "'$cmd' wrong: found $nums, expected $expected"
7158
7159         expected=4
7160         cmd="$LFS find -stripe-size 256k -type f $dir"
7161         nums=$($cmd | wc -l)
7162         [ $nums -eq $expected ] ||
7163                 error "'$cmd' wrong: found $nums, expected $expected"
7164
7165         cmd="$LFS find -stripe-size -320k -type f $dir"
7166         nums=$($cmd | wc -l)
7167         [ $nums -eq $expected ] ||
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169
7170         expected=0
7171         cmd="$LFS find -stripe-size 1024k -type f $dir"
7172         nums=$($cmd | wc -l)
7173         [ $nums -eq $expected ] ||
7174                 error "'$cmd' wrong: found $nums, expected $expected"
7175 }
7176 run_test 56t "check lfs find -stripe-size works"
7177
7178 test_56u() { # LU-611
7179         local dir=$DIR/$tdir
7180
7181         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7182
7183         if [[ $OSTCOUNT -gt 1 ]]; then
7184                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7185                 onestripe=4
7186         else
7187                 onestripe=0
7188         fi
7189
7190         local expected=$(((NUMDIRS + 1) * NUMFILES))
7191         local cmd="$LFS find -stripe-index 0 -type f $dir"
7192         local nums=$($cmd | wc -l)
7193
7194         [ $nums -eq $expected ] ||
7195                 error "'$cmd' wrong: found $nums, expected $expected"
7196
7197         expected=$onestripe
7198         cmd="$LFS find -stripe-index 1 -type f $dir"
7199         nums=$($cmd | wc -l)
7200         [ $nums -eq $expected ] ||
7201                 error "'$cmd' wrong: found $nums, expected $expected"
7202
7203         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7204         nums=$($cmd | wc -l)
7205         [ $nums -eq $expected ] ||
7206                 error "'$cmd' wrong: found $nums, expected $expected"
7207
7208         expected=0
7209         # This should produce an error and not return any files
7210         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7211         nums=$($cmd 2>/dev/null | wc -l)
7212         [ $nums -eq $expected ] ||
7213                 error "'$cmd' wrong: found $nums, expected $expected"
7214
7215         if [[ $OSTCOUNT -gt 1 ]]; then
7216                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7217                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7218                 nums=$($cmd | wc -l)
7219                 [ $nums -eq $expected ] ||
7220                         error "'$cmd' wrong: found $nums, expected $expected"
7221         fi
7222 }
7223 run_test 56u "check lfs find -stripe-index works"
7224
7225 test_56v() {
7226         local mdt_idx=0
7227         local dir=$DIR/$tdir
7228
7229         setup_56 $dir $NUMFILES $NUMDIRS
7230
7231         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7232         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7233
7234         for file in $($LFS find -m $UUID $dir); do
7235                 file_midx=$($LFS getstripe -m $file)
7236                 [ $file_midx -eq $mdt_idx ] ||
7237                         error "lfs find -m $UUID != getstripe -m $file_midx"
7238         done
7239 }
7240 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7241
7242 test_56w() {
7243         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7245
7246         local dir=$DIR/$tdir
7247
7248         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7249
7250         local stripe_size=$($LFS getstripe -S -d $dir) ||
7251                 error "$LFS getstripe -S -d $dir failed"
7252         stripe_size=${stripe_size%% *}
7253
7254         local file_size=$((stripe_size * OSTCOUNT))
7255         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7256         local required_space=$((file_num * file_size))
7257         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7258                            head -n1)
7259         [[ $free_space -le $((required_space / 1024)) ]] &&
7260                 skip_env "need $required_space, have $free_space kbytes"
7261
7262         local dd_bs=65536
7263         local dd_count=$((file_size / dd_bs))
7264
7265         # write data into the files
7266         local i
7267         local j
7268         local file
7269
7270         for i in $(seq $NUMFILES); do
7271                 file=$dir/file$i
7272                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7273                         error "write data into $file failed"
7274         done
7275         for i in $(seq $NUMDIRS); do
7276                 for j in $(seq $NUMFILES); do
7277                         file=$dir/dir$i/file$j
7278                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7279                                 error "write data into $file failed"
7280                 done
7281         done
7282
7283         # $LFS_MIGRATE will fail if hard link migration is unsupported
7284         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7285                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7286                         error "creating links to $dir/dir1/file1 failed"
7287         fi
7288
7289         local expected=-1
7290
7291         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7292
7293         # lfs_migrate file
7294         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7295
7296         echo "$cmd"
7297         eval $cmd || error "$cmd failed"
7298
7299         check_stripe_count $dir/file1 $expected
7300
7301         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7302         then
7303                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7304                 # OST 1 if it is on OST 0. This file is small enough to
7305                 # be on only one stripe.
7306                 file=$dir/migr_1_ost
7307                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7308                         error "write data into $file failed"
7309                 local obdidx=$($LFS getstripe -i $file)
7310                 local oldmd5=$(md5sum $file)
7311                 local newobdidx=0
7312
7313                 [[ $obdidx -eq 0 ]] && newobdidx=1
7314                 cmd="$LFS migrate -i $newobdidx $file"
7315                 echo $cmd
7316                 eval $cmd || error "$cmd failed"
7317
7318                 local realobdix=$($LFS getstripe -i $file)
7319                 local newmd5=$(md5sum $file)
7320
7321                 [[ $newobdidx -ne $realobdix ]] &&
7322                         error "new OST is different (was=$obdidx, "\
7323                               "wanted=$newobdidx, got=$realobdix)"
7324                 [[ "$oldmd5" != "$newmd5" ]] &&
7325                         error "md5sum differ: $oldmd5, $newmd5"
7326         fi
7327
7328         # lfs_migrate dir
7329         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7330         echo "$cmd"
7331         eval $cmd || error "$cmd failed"
7332
7333         for j in $(seq $NUMFILES); do
7334                 check_stripe_count $dir/dir1/file$j $expected
7335         done
7336
7337         # lfs_migrate works with lfs find
7338         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7339              $LFS_MIGRATE -y -c $expected"
7340         echo "$cmd"
7341         eval $cmd || error "$cmd failed"
7342
7343         for i in $(seq 2 $NUMFILES); do
7344                 check_stripe_count $dir/file$i $expected
7345         done
7346         for i in $(seq 2 $NUMDIRS); do
7347                 for j in $(seq $NUMFILES); do
7348                 check_stripe_count $dir/dir$i/file$j $expected
7349                 done
7350         done
7351 }
7352 run_test 56w "check lfs_migrate -c stripe_count works"
7353
7354 test_56wb() {
7355         local file1=$DIR/$tdir/file1
7356         local create_pool=false
7357         local initial_pool=$($LFS getstripe -p $DIR)
7358         local pool_list=()
7359         local pool=""
7360
7361         echo -n "Creating test dir..."
7362         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7363         echo "done."
7364
7365         echo -n "Creating test file..."
7366         touch $file1 || error "cannot create file"
7367         echo "done."
7368
7369         echo -n "Detecting existing pools..."
7370         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7371
7372         if [ ${#pool_list[@]} -gt 0 ]; then
7373                 echo "${pool_list[@]}"
7374                 for thispool in "${pool_list[@]}"; do
7375                         if [[ -z "$initial_pool" ||
7376                               "$initial_pool" != "$thispool" ]]; then
7377                                 pool="$thispool"
7378                                 echo "Using existing pool '$pool'"
7379                                 break
7380                         fi
7381                 done
7382         else
7383                 echo "none detected."
7384         fi
7385         if [ -z "$pool" ]; then
7386                 pool=${POOL:-testpool}
7387                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7388                 echo -n "Creating pool '$pool'..."
7389                 create_pool=true
7390                 pool_add $pool &> /dev/null ||
7391                         error "pool_add failed"
7392                 echo "done."
7393
7394                 echo -n "Adding target to pool..."
7395                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7396                         error "pool_add_targets failed"
7397                 echo "done."
7398         fi
7399
7400         echo -n "Setting pool using -p option..."
7401         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7402                 error "migrate failed rc = $?"
7403         echo "done."
7404
7405         echo -n "Verifying test file is in pool after migrating..."
7406         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7407                 error "file was not migrated to pool $pool"
7408         echo "done."
7409
7410         echo -n "Removing test file from pool '$pool'..."
7411         # "lfs migrate $file" won't remove the file from the pool
7412         # until some striping information is changed.
7413         $LFS migrate -c 1 $file1 &> /dev/null ||
7414                 error "cannot remove from pool"
7415         [ "$($LFS getstripe -p $file1)" ] &&
7416                 error "pool still set"
7417         echo "done."
7418
7419         echo -n "Setting pool using --pool option..."
7420         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7421                 error "migrate failed rc = $?"
7422         echo "done."
7423
7424         # Clean up
7425         rm -f $file1
7426         if $create_pool; then
7427                 destroy_test_pools 2> /dev/null ||
7428                         error "destroy test pools failed"
7429         fi
7430 }
7431 run_test 56wb "check lfs_migrate pool support"
7432
7433 test_56wc() {
7434         local file1="$DIR/$tdir/file1"
7435         local parent_ssize
7436         local parent_scount
7437         local cur_ssize
7438         local cur_scount
7439         local orig_ssize
7440
7441         echo -n "Creating test dir..."
7442         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7443         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7444                 error "cannot set stripe by '-S 1M -c 1'"
7445         echo "done"
7446
7447         echo -n "Setting initial stripe for test file..."
7448         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7449                 error "cannot set stripe"
7450         cur_ssize=$($LFS getstripe -S "$file1")
7451         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7452         echo "done."
7453
7454         # File currently set to -S 512K -c 1
7455
7456         # Ensure -c and -S options are rejected when -R is set
7457         echo -n "Verifying incompatible options are detected..."
7458         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7459                 error "incompatible -c and -R options not detected"
7460         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7461                 error "incompatible -S and -R options not detected"
7462         echo "done."
7463
7464         # Ensure unrecognized options are passed through to 'lfs migrate'
7465         echo -n "Verifying -S option is passed through to lfs migrate..."
7466         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7467                 error "migration failed"
7468         cur_ssize=$($LFS getstripe -S "$file1")
7469         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7470         echo "done."
7471
7472         # File currently set to -S 1M -c 1
7473
7474         # Ensure long options are supported
7475         echo -n "Verifying long options supported..."
7476         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7477                 error "long option without argument not supported"
7478         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7479                 error "long option with argument not supported"
7480         cur_ssize=$($LFS getstripe -S "$file1")
7481         [ $cur_ssize -eq 524288 ] ||
7482                 error "migrate --stripe-size $cur_ssize != 524288"
7483         echo "done."
7484
7485         # File currently set to -S 512K -c 1
7486
7487         if [ "$OSTCOUNT" -gt 1 ]; then
7488                 echo -n "Verifying explicit stripe count can be set..."
7489                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7490                         error "migrate failed"
7491                 cur_scount=$($LFS getstripe -c "$file1")
7492                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7493                 echo "done."
7494         fi
7495
7496         # File currently set to -S 512K -c 1 or -S 512K -c 2
7497
7498         # Ensure parent striping is used if -R is set, and no stripe
7499         # count or size is specified
7500         echo -n "Setting stripe for parent directory..."
7501         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7502                 error "cannot set stripe '-S 2M -c 1'"
7503         echo "done."
7504
7505         echo -n "Verifying restripe option uses parent stripe settings..."
7506         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7507         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7508         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7509                 error "migrate failed"
7510         cur_ssize=$($LFS getstripe -S "$file1")
7511         [ $cur_ssize -eq $parent_ssize ] ||
7512                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7513         cur_scount=$($LFS getstripe -c "$file1")
7514         [ $cur_scount -eq $parent_scount ] ||
7515                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7516         echo "done."
7517
7518         # File currently set to -S 1M -c 1
7519
7520         # Ensure striping is preserved if -R is not set, and no stripe
7521         # count or size is specified
7522         echo -n "Verifying striping size preserved when not specified..."
7523         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7524         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7525                 error "cannot set stripe on parent directory"
7526         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7527                 error "migrate failed"
7528         cur_ssize=$($LFS getstripe -S "$file1")
7529         [ $cur_ssize -eq $orig_ssize ] ||
7530                 error "migrate by default $cur_ssize != $orig_ssize"
7531         echo "done."
7532
7533         # Ensure file name properly detected when final option has no argument
7534         echo -n "Verifying file name properly detected..."
7535         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7536                 error "file name interpreted as option argument"
7537         echo "done."
7538
7539         # Clean up
7540         rm -f "$file1"
7541 }
7542 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7543
7544 test_56wd() {
7545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7546
7547         local file1=$DIR/$tdir/file1
7548
7549         echo -n "Creating test dir..."
7550         test_mkdir $DIR/$tdir || error "cannot create dir"
7551         echo "done."
7552
7553         echo -n "Creating test file..."
7554         touch $file1
7555         echo "done."
7556
7557         # Ensure 'lfs migrate' will fail by using a non-existent option,
7558         # and make sure rsync is not called to recover
7559         echo -n "Make sure --no-rsync option works..."
7560         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7561                 grep -q 'refusing to fall back to rsync' ||
7562                 error "rsync was called with --no-rsync set"
7563         echo "done."
7564
7565         # Ensure rsync is called without trying 'lfs migrate' first
7566         echo -n "Make sure --rsync option works..."
7567         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7568                 grep -q 'falling back to rsync' &&
7569                 error "lfs migrate was called with --rsync set"
7570         echo "done."
7571
7572         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7573         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7574                 grep -q 'at the same time' ||
7575                 error "--rsync and --no-rsync accepted concurrently"
7576         echo "done."
7577
7578         # Clean up
7579         rm -f $file1
7580 }
7581 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7582
7583 test_56we() {
7584         local td=$DIR/$tdir
7585         local tf=$td/$tfile
7586
7587         test_mkdir $td || error "cannot create $td"
7588         touch $tf || error "cannot touch $tf"
7589
7590         echo -n "Make sure --non-direct|-D works..."
7591         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7592                 grep -q "lfs migrate --non-direct" ||
7593                 error "--non-direct option cannot work correctly"
7594         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7595                 grep -q "lfs migrate -D" ||
7596                 error "-D option cannot work correctly"
7597         echo "done."
7598 }
7599 run_test 56we "check lfs_migrate --non-direct|-D support"
7600
7601 test_56x() {
7602         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7603         check_swap_layouts_support
7604
7605         local dir=$DIR/$tdir
7606         local ref1=/etc/passwd
7607         local file1=$dir/file1
7608
7609         test_mkdir $dir || error "creating dir $dir"
7610         $LFS setstripe -c 2 $file1
7611         cp $ref1 $file1
7612         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7613         stripe=$($LFS getstripe -c $file1)
7614         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7615         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7616
7617         # clean up
7618         rm -f $file1
7619 }
7620 run_test 56x "lfs migration support"
7621
7622 test_56xa() {
7623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7624         check_swap_layouts_support
7625
7626         local dir=$DIR/$tdir/$testnum
7627
7628         test_mkdir -p $dir
7629
7630         local ref1=/etc/passwd
7631         local file1=$dir/file1
7632
7633         $LFS setstripe -c 2 $file1
7634         cp $ref1 $file1
7635         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7636
7637         local stripe=$($LFS getstripe -c $file1)
7638
7639         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7640         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7641
7642         # clean up
7643         rm -f $file1
7644 }
7645 run_test 56xa "lfs migration --block support"
7646
7647 check_migrate_links() {
7648         local dir="$1"
7649         local file1="$dir/file1"
7650         local begin="$2"
7651         local count="$3"
7652         local runas="$4"
7653         local total_count=$(($begin + $count - 1))
7654         local symlink_count=10
7655         local uniq_count=10
7656
7657         if [ ! -f "$file1" ]; then
7658                 echo -n "creating initial file..."
7659                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7660                         error "cannot setstripe initial file"
7661                 echo "done"
7662
7663                 echo -n "creating symlinks..."
7664                 for s in $(seq 1 $symlink_count); do
7665                         ln -s "$file1" "$dir/slink$s" ||
7666                                 error "cannot create symlinks"
7667                 done
7668                 echo "done"
7669
7670                 echo -n "creating nonlinked files..."
7671                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7672                         error "cannot create nonlinked files"
7673                 echo "done"
7674         fi
7675
7676         # create hard links
7677         if [ ! -f "$dir/file$total_count" ]; then
7678                 echo -n "creating hard links $begin:$total_count..."
7679                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7680                         /dev/null || error "cannot create hard links"
7681                 echo "done"
7682         fi
7683
7684         echo -n "checking number of hard links listed in xattrs..."
7685         local fid=$($LFS getstripe -F "$file1")
7686         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7687
7688         echo "${#paths[*]}"
7689         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7690                         skip "hard link list has unexpected size, skipping test"
7691         fi
7692         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7693                         error "link names should exceed xattrs size"
7694         fi
7695
7696         echo -n "migrating files..."
7697         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7698         local rc=$?
7699         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7700         echo "done"
7701
7702         # make sure all links have been properly migrated
7703         echo -n "verifying files..."
7704         fid=$($LFS getstripe -F "$file1") ||
7705                 error "cannot get fid for file $file1"
7706         for i in $(seq 2 $total_count); do
7707                 local fid2=$($LFS getstripe -F $dir/file$i)
7708
7709                 [ "$fid2" == "$fid" ] ||
7710                         error "migrated hard link has mismatched FID"
7711         done
7712
7713         # make sure hard links were properly detected, and migration was
7714         # performed only once for the entire link set; nonlinked files should
7715         # also be migrated
7716         local actual=$(grep -c 'done' <<< "$migrate_out")
7717         local expected=$(($uniq_count + 1))
7718
7719         [ "$actual" -eq  "$expected" ] ||
7720                 error "hard links individually migrated ($actual != $expected)"
7721
7722         # make sure the correct number of hard links are present
7723         local hardlinks=$(stat -c '%h' "$file1")
7724
7725         [ $hardlinks -eq $total_count ] ||
7726                 error "num hard links $hardlinks != $total_count"
7727         echo "done"
7728
7729         return 0
7730 }
7731
7732 test_56xb() {
7733         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7734                 skip "Need MDS version at least 2.10.55"
7735
7736         local dir="$DIR/$tdir"
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739
7740         echo "testing lfs migrate mode when all links fit within xattrs"
7741         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7742
7743         echo "testing rsync mode when all links fit within xattrs"
7744         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7745
7746         echo "testing lfs migrate mode when all links do not fit within xattrs"
7747         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7748
7749         echo "testing rsync mode when all links do not fit within xattrs"
7750         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7751
7752         chown -R $RUNAS_ID $dir
7753         echo "testing non-root lfs migrate mode when not all links are in xattr"
7754         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7755
7756         # clean up
7757         rm -rf $dir
7758 }
7759 run_test 56xb "lfs migration hard link support"
7760
7761 test_56xc() {
7762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7763
7764         local dir="$DIR/$tdir"
7765
7766         test_mkdir "$dir" || error "cannot create dir $dir"
7767
7768         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7769         echo -n "Setting initial stripe for 20MB test file..."
7770         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7771                 error "cannot setstripe 20MB file"
7772         echo "done"
7773         echo -n "Sizing 20MB test file..."
7774         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7775         echo "done"
7776         echo -n "Verifying small file autostripe count is 1..."
7777         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7778                 error "cannot migrate 20MB file"
7779         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7780                 error "cannot get stripe for $dir/20mb"
7781         [ $stripe_count -eq 1 ] ||
7782                 error "unexpected stripe count $stripe_count for 20MB file"
7783         rm -f "$dir/20mb"
7784         echo "done"
7785
7786         # Test 2: File is small enough to fit within the available space on
7787         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7788         # have at least an additional 1KB for each desired stripe for test 3
7789         echo -n "Setting stripe for 1GB test file..."
7790         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7791         echo "done"
7792         echo -n "Sizing 1GB test file..."
7793         # File size is 1GB + 3KB
7794         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7795         echo "done"
7796
7797         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7798         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7799         if (( avail > 524288 * OSTCOUNT )); then
7800                 echo -n "Migrating 1GB file..."
7801                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7802                         error "cannot migrate 1GB file"
7803                 echo "done"
7804                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7805                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7806                         error "cannot getstripe for 1GB file"
7807                 [ $stripe_count -eq 2 ] ||
7808                         error "unexpected stripe count $stripe_count != 2"
7809                 echo "done"
7810         fi
7811
7812         # Test 3: File is too large to fit within the available space on
7813         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7814         if [ $OSTCOUNT -ge 3 ]; then
7815                 # The required available space is calculated as
7816                 # file size (1GB + 3KB) / OST count (3).
7817                 local kb_per_ost=349526
7818
7819                 echo -n "Migrating 1GB file with limit..."
7820                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7821                         error "cannot migrate 1GB file with limit"
7822                 echo "done"
7823
7824                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7825                 echo -n "Verifying 1GB autostripe count with limited space..."
7826                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7827                         error "unexpected stripe count $stripe_count (min 3)"
7828                 echo "done"
7829         fi
7830
7831         # clean up
7832         rm -rf $dir
7833 }
7834 run_test 56xc "lfs migration autostripe"
7835
7836 test_56xd() {
7837         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7838
7839         local dir=$DIR/$tdir
7840         local f_mgrt=$dir/$tfile.mgrt
7841         local f_yaml=$dir/$tfile.yaml
7842         local f_copy=$dir/$tfile.copy
7843         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7844         local layout_copy="-c 2 -S 2M -i 1"
7845         local yamlfile=$dir/yamlfile
7846         local layout_before;
7847         local layout_after;
7848
7849         test_mkdir "$dir" || error "cannot create dir $dir"
7850         $LFS setstripe $layout_yaml $f_yaml ||
7851                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7852         $LFS getstripe --yaml $f_yaml > $yamlfile
7853         $LFS setstripe $layout_copy $f_copy ||
7854                 error "cannot setstripe $f_copy with layout $layout_copy"
7855         touch $f_mgrt
7856         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7857
7858         # 1. test option --yaml
7859         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7860                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7861         layout_before=$(get_layout_param $f_yaml)
7862         layout_after=$(get_layout_param $f_mgrt)
7863         [ "$layout_after" == "$layout_before" ] ||
7864                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7865
7866         # 2. test option --copy
7867         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7868                 error "cannot migrate $f_mgrt with --copy $f_copy"
7869         layout_before=$(get_layout_param $f_copy)
7870         layout_after=$(get_layout_param $f_mgrt)
7871         [ "$layout_after" == "$layout_before" ] ||
7872                 error "lfs_migrate --copy: $layout_after != $layout_before"
7873 }
7874 run_test 56xd "check lfs_migrate --yaml and --copy support"
7875
7876 test_56xe() {
7877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7878
7879         local dir=$DIR/$tdir
7880         local f_comp=$dir/$tfile
7881         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7882         local layout_before=""
7883         local layout_after=""
7884
7885         test_mkdir "$dir" || error "cannot create dir $dir"
7886         $LFS setstripe $layout $f_comp ||
7887                 error "cannot setstripe $f_comp with layout $layout"
7888         layout_before=$(get_layout_param $f_comp)
7889         dd if=/dev/zero of=$f_comp bs=1M count=4
7890
7891         # 1. migrate a comp layout file by lfs_migrate
7892         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7893         layout_after=$(get_layout_param $f_comp)
7894         [ "$layout_before" == "$layout_after" ] ||
7895                 error "lfs_migrate: $layout_before != $layout_after"
7896
7897         # 2. migrate a comp layout file by lfs migrate
7898         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7899         layout_after=$(get_layout_param $f_comp)
7900         [ "$layout_before" == "$layout_after" ] ||
7901                 error "lfs migrate: $layout_before != $layout_after"
7902 }
7903 run_test 56xe "migrate a composite layout file"
7904
7905 test_56xf() {
7906         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7907
7908         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7909                 skip "Need server version at least 2.13.53"
7910
7911         local dir=$DIR/$tdir
7912         local f_comp=$dir/$tfile
7913         local layout="-E 1M -c1 -E -1 -c2"
7914         local fid_before=""
7915         local fid_after=""
7916
7917         test_mkdir "$dir" || error "cannot create dir $dir"
7918         $LFS setstripe $layout $f_comp ||
7919                 error "cannot setstripe $f_comp with layout $layout"
7920         fid_before=$($LFS getstripe --fid $f_comp)
7921         dd if=/dev/zero of=$f_comp bs=1M count=4
7922
7923         # 1. migrate a comp layout file to a comp layout
7924         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7925         fid_after=$($LFS getstripe --fid $f_comp)
7926         [ "$fid_before" == "$fid_after" ] ||
7927                 error "comp-to-comp migrate: $fid_before != $fid_after"
7928
7929         # 2. migrate a comp layout file to a plain layout
7930         $LFS migrate -c2 $f_comp ||
7931                 error "cannot migrate $f_comp by lfs migrate"
7932         fid_after=$($LFS getstripe --fid $f_comp)
7933         [ "$fid_before" == "$fid_after" ] ||
7934                 error "comp-to-plain migrate: $fid_before != $fid_after"
7935
7936         # 3. migrate a plain layout file to a comp layout
7937         $LFS migrate $layout $f_comp ||
7938                 error "cannot migrate $f_comp by lfs migrate"
7939         fid_after=$($LFS getstripe --fid $f_comp)
7940         [ "$fid_before" == "$fid_after" ] ||
7941                 error "plain-to-comp migrate: $fid_before != $fid_after"
7942 }
7943 run_test 56xf "FID is not lost during migration of a composite layout file"
7944
7945 check_file_ost_range() {
7946         local file="$1"
7947         shift
7948         local range="$*"
7949         local -a file_range
7950         local idx
7951
7952         file_range=($($LFS getstripe -y "$file" |
7953                 awk '/l_ost_idx:/ { print $NF }'))
7954
7955         if [[ "${#file_range[@]}" = 0 ]]; then
7956                 echo "No osts found for $file"
7957                 return 1
7958         fi
7959
7960         for idx in "${file_range[@]}"; do
7961                 [[ " $range " =~ " $idx " ]] ||
7962                         return 1
7963         done
7964
7965         return 0
7966 }
7967
7968 sub_test_56xg() {
7969         local stripe_opt="$1"
7970         local pool="$2"
7971         shift 2
7972         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7973
7974         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7975                 error "Fail to migrate $tfile on $pool"
7976         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7977                 error "$tfile is not in pool $pool"
7978         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7979                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7980 }
7981
7982 test_56xg() {
7983         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7984         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7985         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7986                 skip "Need MDS version newer than 2.14.52"
7987
7988         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7989         local -a pool_ranges=("0 0" "1 1" "0 1")
7990
7991         # init pools
7992         for i in "${!pool_names[@]}"; do
7993                 pool_add ${pool_names[$i]} ||
7994                         error "pool_add failed (pool: ${pool_names[$i]})"
7995                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7996                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7997         done
7998
7999         # init the file to migrate
8000         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8001                 error "Unable to create $tfile on OST1"
8002         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8003                 error "Unable to write on $tfile"
8004
8005         echo "1. migrate $tfile on pool ${pool_names[0]}"
8006         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8007
8008         echo "2. migrate $tfile on pool ${pool_names[2]}"
8009         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8010
8011         echo "3. migrate $tfile on pool ${pool_names[1]}"
8012         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8013
8014         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8015         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8016         echo
8017
8018         # Clean pools
8019         destroy_test_pools ||
8020                 error "pool_destroy failed"
8021 }
8022 run_test 56xg "lfs migrate pool support"
8023
8024 test_56y() {
8025         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8026                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8027
8028         local res=""
8029         local dir=$DIR/$tdir
8030         local f1=$dir/file1
8031         local f2=$dir/file2
8032
8033         test_mkdir -p $dir || error "creating dir $dir"
8034         touch $f1 || error "creating std file $f1"
8035         $MULTIOP $f2 H2c || error "creating released file $f2"
8036
8037         # a directory can be raid0, so ask only for files
8038         res=$($LFS find $dir -L raid0 -type f | wc -l)
8039         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8040
8041         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8042         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8043
8044         # only files can be released, so no need to force file search
8045         res=$($LFS find $dir -L released)
8046         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8047
8048         res=$($LFS find $dir -type f \! -L released)
8049         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8050 }
8051 run_test 56y "lfs find -L raid0|released"
8052
8053 test_56z() { # LU-4824
8054         # This checks to make sure 'lfs find' continues after errors
8055         # There are two classes of errors that should be caught:
8056         # - If multiple paths are provided, all should be searched even if one
8057         #   errors out
8058         # - If errors are encountered during the search, it should not terminate
8059         #   early
8060         local dir=$DIR/$tdir
8061         local i
8062
8063         test_mkdir $dir
8064         for i in d{0..9}; do
8065                 test_mkdir $dir/$i
8066                 touch $dir/$i/$tfile
8067         done
8068         $LFS find $DIR/non_existent_dir $dir &&
8069                 error "$LFS find did not return an error"
8070         # Make a directory unsearchable. This should NOT be the last entry in
8071         # directory order.  Arbitrarily pick the 6th entry
8072         chmod 700 $($LFS find $dir -type d | sed '6!d')
8073
8074         $RUNAS $LFS find $DIR/non_existent $dir
8075         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8076
8077         # The user should be able to see 10 directories and 9 files
8078         (( count == 19 )) ||
8079                 error "$LFS find found $count != 19 entries after error"
8080 }
8081 run_test 56z "lfs find should continue after an error"
8082
8083 test_56aa() { # LU-5937
8084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8085
8086         local dir=$DIR/$tdir
8087
8088         mkdir $dir
8089         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8090
8091         createmany -o $dir/striped_dir/${tfile}- 1024
8092         local dirs=$($LFS find --size +8k $dir/)
8093
8094         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8095 }
8096 run_test 56aa "lfs find --size under striped dir"
8097
8098 test_56ab() { # LU-10705
8099         test_mkdir $DIR/$tdir
8100         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8101         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8102         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8103         # Flush writes to ensure valid blocks.  Need to be more thorough for
8104         # ZFS, since blocks are not allocated/returned to client immediately.
8105         sync_all_data
8106         wait_zfs_commit ost1 2
8107         cancel_lru_locks osc
8108         ls -ls $DIR/$tdir
8109
8110         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8111
8112         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8113
8114         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8115         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8116
8117         rm -f $DIR/$tdir/$tfile.[123]
8118 }
8119 run_test 56ab "lfs find --blocks"
8120
8121 # LU-11188
8122 test_56aca() {
8123         local dir="$DIR/$tdir"
8124         local perms=(001 002 003 004 005 006 007
8125                      010 020 030 040 050 060 070
8126                      100 200 300 400 500 600 700
8127                      111 222 333 444 555 666 777)
8128         local perm_minus=(8 8 4 8 4 4 2
8129                           8 8 4 8 4 4 2
8130                           8 8 4 8 4 4 2
8131                           4 4 2 4 2 2 1)
8132         local perm_slash=(8  8 12  8 12 12 14
8133                           8  8 12  8 12 12 14
8134                           8  8 12  8 12 12 14
8135                          16 16 24 16 24 24 28)
8136
8137         test_mkdir "$dir"
8138         for perm in ${perms[*]}; do
8139                 touch "$dir/$tfile.$perm"
8140                 chmod $perm "$dir/$tfile.$perm"
8141         done
8142
8143         for ((i = 0; i < ${#perms[*]}; i++)); do
8144                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8145                 (( $num == 1 )) ||
8146                         error "lfs find -perm ${perms[i]}:"\
8147                               "$num != 1"
8148
8149                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8150                 (( $num == ${perm_minus[i]} )) ||
8151                         error "lfs find -perm -${perms[i]}:"\
8152                               "$num != ${perm_minus[i]}"
8153
8154                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8155                 (( $num == ${perm_slash[i]} )) ||
8156                         error "lfs find -perm /${perms[i]}:"\
8157                               "$num != ${perm_slash[i]}"
8158         done
8159 }
8160 run_test 56aca "check lfs find -perm with octal representation"
8161
8162 test_56acb() {
8163         local dir=$DIR/$tdir
8164         # p is the permission of write and execute for user, group and other
8165         # without the umask. It is used to test +wx.
8166         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8167         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8168         local symbolic=(+t  a+t u+t g+t o+t
8169                         g+s u+s o+s +s o+sr
8170                         o=r,ug+o,u+w
8171                         u+ g+ o+ a+ ugo+
8172                         u- g- o- a- ugo-
8173                         u= g= o= a= ugo=
8174                         o=r,ug+o,u+w u=r,a+u,u+w
8175                         g=r,ugo=g,u+w u+x,+X +X
8176                         u+x,u+X u+X u+x,g+X o+r,+X
8177                         u+x,go+X +wx +rwx)
8178
8179         test_mkdir $dir
8180         for perm in ${perms[*]}; do
8181                 touch "$dir/$tfile.$perm"
8182                 chmod $perm "$dir/$tfile.$perm"
8183         done
8184
8185         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8186                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8187
8188                 (( $num == 1 )) ||
8189                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8190         done
8191 }
8192 run_test 56acb "check lfs find -perm with symbolic representation"
8193
8194 test_56acc() {
8195         local dir=$DIR/$tdir
8196         local tests="17777 787 789 abcd
8197                 ug=uu ug=a ug=gu uo=ou urw
8198                 u+xg+x a=r,u+x,"
8199
8200         test_mkdir $dir
8201         for err in $tests; do
8202                 if $LFS find $dir -perm $err 2>/dev/null; then
8203                         error "lfs find -perm $err: parsing should have failed"
8204                 fi
8205         done
8206 }
8207 run_test 56acc "check parsing error for lfs find -perm"
8208
8209 test_56ba() {
8210         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8211                 skip "Need MDS version at least 2.10.50"
8212
8213         # Create composite files with one component
8214         local dir=$DIR/$tdir
8215
8216         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8217         # Create composite files with three components
8218         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8219         # Create non-composite files
8220         createmany -o $dir/${tfile}- 10
8221
8222         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8223
8224         [[ $nfiles == 10 ]] ||
8225                 error "lfs find -E 1M found $nfiles != 10 files"
8226
8227         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8228         [[ $nfiles == 25 ]] ||
8229                 error "lfs find ! -E 1M found $nfiles != 25 files"
8230
8231         # All files have a component that starts at 0
8232         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8233         [[ $nfiles == 35 ]] ||
8234                 error "lfs find --component-start 0 - $nfiles != 35 files"
8235
8236         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8237         [[ $nfiles == 15 ]] ||
8238                 error "lfs find --component-start 2M - $nfiles != 15 files"
8239
8240         # All files created here have a componenet that does not starts at 2M
8241         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8242         [[ $nfiles == 35 ]] ||
8243                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8244
8245         # Find files with a specified number of components
8246         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8247         [[ $nfiles == 15 ]] ||
8248                 error "lfs find --component-count 3 - $nfiles != 15 files"
8249
8250         # Remember non-composite files have a component count of zero
8251         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8252         [[ $nfiles == 10 ]] ||
8253                 error "lfs find --component-count 0 - $nfiles != 10 files"
8254
8255         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8256         [[ $nfiles == 20 ]] ||
8257                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8258
8259         # All files have a flag called "init"
8260         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8261         [[ $nfiles == 35 ]] ||
8262                 error "lfs find --component-flags init - $nfiles != 35 files"
8263
8264         # Multi-component files will have a component not initialized
8265         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8266         [[ $nfiles == 15 ]] ||
8267                 error "lfs find !--component-flags init - $nfiles != 15 files"
8268
8269         rm -rf $dir
8270
8271 }
8272 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8273
8274 test_56ca() {
8275         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8276                 skip "Need MDS version at least 2.10.57"
8277
8278         local td=$DIR/$tdir
8279         local tf=$td/$tfile
8280         local dir
8281         local nfiles
8282         local cmd
8283         local i
8284         local j
8285
8286         # create mirrored directories and mirrored files
8287         mkdir $td || error "mkdir $td failed"
8288         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8289         createmany -o $tf- 10 || error "create $tf- failed"
8290
8291         for i in $(seq 2); do
8292                 dir=$td/dir$i
8293                 mkdir $dir || error "mkdir $dir failed"
8294                 $LFS mirror create -N$((3 + i)) $dir ||
8295                         error "create mirrored dir $dir failed"
8296                 createmany -o $dir/$tfile- 10 ||
8297                         error "create $dir/$tfile- failed"
8298         done
8299
8300         # change the states of some mirrored files
8301         echo foo > $tf-6
8302         for i in $(seq 2); do
8303                 dir=$td/dir$i
8304                 for j in $(seq 4 9); do
8305                         echo foo > $dir/$tfile-$j
8306                 done
8307         done
8308
8309         # find mirrored files with specific mirror count
8310         cmd="$LFS find --mirror-count 3 --type f $td"
8311         nfiles=$($cmd | wc -l)
8312         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8313
8314         cmd="$LFS find ! --mirror-count 3 --type f $td"
8315         nfiles=$($cmd | wc -l)
8316         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8317
8318         cmd="$LFS find --mirror-count +2 --type f $td"
8319         nfiles=$($cmd | wc -l)
8320         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8321
8322         cmd="$LFS find --mirror-count -6 --type f $td"
8323         nfiles=$($cmd | wc -l)
8324         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8325
8326         # find mirrored files with specific file state
8327         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8328         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8329
8330         cmd="$LFS find --mirror-state=ro --type f $td"
8331         nfiles=$($cmd | wc -l)
8332         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8333
8334         cmd="$LFS find ! --mirror-state=ro --type f $td"
8335         nfiles=$($cmd | wc -l)
8336         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8337
8338         cmd="$LFS find --mirror-state=wp --type f $td"
8339         nfiles=$($cmd | wc -l)
8340         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8341
8342         cmd="$LFS find ! --mirror-state=sp --type f $td"
8343         nfiles=$($cmd | wc -l)
8344         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8345 }
8346 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8347
8348 test_56da() { # LU-14179
8349         local path=$DIR/$tdir
8350
8351         test_mkdir $path
8352         cd $path
8353
8354         local longdir=$(str_repeat 'a' 255)
8355
8356         for i in {1..15}; do
8357                 path=$path/$longdir
8358                 test_mkdir $longdir
8359                 cd $longdir
8360         done
8361
8362         local len=${#path}
8363         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8364
8365         test_mkdir $lastdir
8366         cd $lastdir
8367         # PATH_MAX-1
8368         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8369
8370         # NAME_MAX
8371         touch $(str_repeat 'f' 255)
8372
8373         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8374                 error "lfs find reported an error"
8375
8376         rm -rf $DIR/$tdir
8377 }
8378 run_test 56da "test lfs find with long paths"
8379
8380 test_56ea() { #LU-10378
8381         local path=$DIR/$tdir
8382         local pool=$TESTNAME
8383
8384         # Create ost pool
8385         pool_add $pool || error "pool_add $pool failed"
8386         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8387                 error "adding targets to $pool failed"
8388
8389         # Set default pool on directory before creating file
8390         mkdir $path || error "mkdir $path failed"
8391         $LFS setstripe -p $pool $path ||
8392                 error "set OST pool on $pool failed"
8393         touch $path/$tfile || error "touch $path/$tfile failed"
8394
8395         # Compare basic file attributes from -printf and stat
8396         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8397         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8398
8399         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8400                 error "Attrs from lfs find and stat don't match"
8401
8402         # Compare Lustre attributes from lfs find and lfs getstripe
8403         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8404         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8405         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8406         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8407         local fpool=$($LFS getstripe --pool $path/$tfile)
8408         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8409
8410         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8411                 error "Attrs from lfs find and lfs getstripe don't match"
8412
8413         # Verify behavior for unknown escape/format sequences
8414         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8415
8416         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8417                 error "Escape/format codes don't match"
8418 }
8419 run_test 56ea "test lfs find -printf option"
8420
8421 test_56eb() {
8422         local dir=$DIR/$tdir
8423         local subdir_1=$dir/subdir_1
8424
8425         test_mkdir -p $subdir_1
8426         ln -s subdir_1 $dir/link_1
8427
8428         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8429                 error "symlink is not followed"
8430
8431         $LFS getstripe --no-follow $dir |
8432                 grep "^$dir/link_1 has no stripe info$" ||
8433                 error "symlink should not have stripe info"
8434
8435         touch $dir/testfile
8436         ln -s testfile $dir/file_link_2
8437
8438         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8439                 error "symlink is not followed"
8440
8441         $LFS getstripe --no-follow $dir |
8442                 grep "^$dir/file_link_2 has no stripe info$" ||
8443                 error "symlink should not have stripe info"
8444 }
8445 run_test 56eb "check lfs getstripe on symlink"
8446
8447 test_57a() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449         # note test will not do anything if MDS is not local
8450         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8451                 skip_env "ldiskfs only test"
8452         fi
8453         remote_mds_nodsh && skip "remote MDS with nodsh"
8454
8455         local MNTDEV="osd*.*MDT*.mntdev"
8456         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8457         [ -z "$DEV" ] && error "can't access $MNTDEV"
8458         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8459                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8460                         error "can't access $DEV"
8461                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8462                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8463                 rm $TMP/t57a.dump
8464         done
8465 }
8466 run_test 57a "verify MDS filesystem created with large inodes =="
8467
8468 test_57b() {
8469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8470         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8471                 skip_env "ldiskfs only test"
8472         fi
8473         remote_mds_nodsh && skip "remote MDS with nodsh"
8474
8475         local dir=$DIR/$tdir
8476         local filecount=100
8477         local file1=$dir/f1
8478         local fileN=$dir/f$filecount
8479
8480         rm -rf $dir || error "removing $dir"
8481         test_mkdir -c1 $dir
8482         local mdtidx=$($LFS getstripe -m $dir)
8483         local mdtname=MDT$(printf %04x $mdtidx)
8484         local facet=mds$((mdtidx + 1))
8485
8486         echo "mcreating $filecount files"
8487         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8488
8489         # verify that files do not have EAs yet
8490         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8491                 error "$file1 has an EA"
8492         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8493                 error "$fileN has an EA"
8494
8495         sync
8496         sleep 1
8497         df $dir  #make sure we get new statfs data
8498         local mdsfree=$(do_facet $facet \
8499                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8500         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8501         local file
8502
8503         echo "opening files to create objects/EAs"
8504         for file in $(seq -f $dir/f%g 1 $filecount); do
8505                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8506                         error "opening $file"
8507         done
8508
8509         # verify that files have EAs now
8510         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8511         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8512
8513         sleep 1  #make sure we get new statfs data
8514         df $dir
8515         local mdsfree2=$(do_facet $facet \
8516                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8517         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8518
8519         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8520                 if [ "$mdsfree" != "$mdsfree2" ]; then
8521                         error "MDC before $mdcfree != after $mdcfree2"
8522                 else
8523                         echo "MDC before $mdcfree != after $mdcfree2"
8524                         echo "unable to confirm if MDS has large inodes"
8525                 fi
8526         fi
8527         rm -rf $dir
8528 }
8529 run_test 57b "default LOV EAs are stored inside large inodes ==="
8530
8531 test_58() {
8532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8533         [ -z "$(which wiretest 2>/dev/null)" ] &&
8534                         skip_env "could not find wiretest"
8535
8536         wiretest
8537 }
8538 run_test 58 "verify cross-platform wire constants =============="
8539
8540 test_59() {
8541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8542
8543         echo "touch 130 files"
8544         createmany -o $DIR/f59- 130
8545         echo "rm 130 files"
8546         unlinkmany $DIR/f59- 130
8547         sync
8548         # wait for commitment of removal
8549         wait_delete_completed
8550 }
8551 run_test 59 "verify cancellation of llog records async ========="
8552
8553 TEST60_HEAD="test_60 run $RANDOM"
8554 test_60a() {
8555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8556         remote_mgs_nodsh && skip "remote MGS with nodsh"
8557         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8558                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8559                         skip_env "missing subtest run-llog.sh"
8560
8561         log "$TEST60_HEAD - from kernel mode"
8562         do_facet mgs "$LCTL dk > /dev/null"
8563         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8564         do_facet mgs $LCTL dk > $TMP/$tfile
8565
8566         # LU-6388: test llog_reader
8567         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8568         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8569         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8570                         skip_env "missing llog_reader"
8571         local fstype=$(facet_fstype mgs)
8572         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8573                 skip_env "Only for ldiskfs or zfs type mgs"
8574
8575         local mntpt=$(facet_mntpt mgs)
8576         local mgsdev=$(mgsdevname 1)
8577         local fid_list
8578         local fid
8579         local rec_list
8580         local rec
8581         local rec_type
8582         local obj_file
8583         local path
8584         local seq
8585         local oid
8586         local pass=true
8587
8588         #get fid and record list
8589         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8590                 tail -n 4))
8591         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8592                 tail -n 4))
8593         #remount mgs as ldiskfs or zfs type
8594         stop mgs || error "stop mgs failed"
8595         mount_fstype mgs || error "remount mgs failed"
8596         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8597                 fid=${fid_list[i]}
8598                 rec=${rec_list[i]}
8599                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8600                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8601                 oid=$((16#$oid))
8602
8603                 case $fstype in
8604                         ldiskfs )
8605                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8606                         zfs )
8607                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8608                 esac
8609                 echo "obj_file is $obj_file"
8610                 do_facet mgs $llog_reader $obj_file
8611
8612                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8613                         awk '{ print $3 }' | sed -e "s/^type=//g")
8614                 if [ $rec_type != $rec ]; then
8615                         echo "FAILED test_60a wrong record type $rec_type," \
8616                               "should be $rec"
8617                         pass=false
8618                         break
8619                 fi
8620
8621                 #check obj path if record type is LLOG_LOGID_MAGIC
8622                 if [ "$rec" == "1064553b" ]; then
8623                         path=$(do_facet mgs $llog_reader $obj_file |
8624                                 grep "path=" | awk '{ print $NF }' |
8625                                 sed -e "s/^path=//g")
8626                         if [ $obj_file != $mntpt/$path ]; then
8627                                 echo "FAILED test_60a wrong obj path" \
8628                                       "$montpt/$path, should be $obj_file"
8629                                 pass=false
8630                                 break
8631                         fi
8632                 fi
8633         done
8634         rm -f $TMP/$tfile
8635         #restart mgs before "error", otherwise it will block the next test
8636         stop mgs || error "stop mgs failed"
8637         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8638         $pass || error "test failed, see FAILED test_60a messages for specifics"
8639 }
8640 run_test 60a "llog_test run from kernel module and test llog_reader"
8641
8642 test_60b() { # bug 6411
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644
8645         dmesg > $DIR/$tfile
8646         LLOG_COUNT=$(do_facet mgs dmesg |
8647                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8648                           /llog_[a-z]*.c:[0-9]/ {
8649                                 if (marker)
8650                                         from_marker++
8651                                 from_begin++
8652                           }
8653                           END {
8654                                 if (marker)
8655                                         print from_marker
8656                                 else
8657                                         print from_begin
8658                           }")
8659
8660         [[ $LLOG_COUNT -gt 120 ]] &&
8661                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8662 }
8663 run_test 60b "limit repeated messages from CERROR/CWARN"
8664
8665 test_60c() {
8666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8667
8668         echo "create 5000 files"
8669         createmany -o $DIR/f60c- 5000
8670 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8671         lctl set_param fail_loc=0x80000137
8672         unlinkmany $DIR/f60c- 5000
8673         lctl set_param fail_loc=0
8674 }
8675 run_test 60c "unlink file when mds full"
8676
8677 test_60d() {
8678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8679
8680         SAVEPRINTK=$(lctl get_param -n printk)
8681         # verify "lctl mark" is even working"
8682         MESSAGE="test message ID $RANDOM $$"
8683         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8684         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8685
8686         lctl set_param printk=0 || error "set lnet.printk failed"
8687         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8688         MESSAGE="new test message ID $RANDOM $$"
8689         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8690         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8691         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8692
8693         lctl set_param -n printk="$SAVEPRINTK"
8694 }
8695 run_test 60d "test printk console message masking"
8696
8697 test_60e() {
8698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8699         remote_mds_nodsh && skip "remote MDS with nodsh"
8700
8701         touch $DIR/$tfile
8702 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8703         do_facet mds1 lctl set_param fail_loc=0x15b
8704         rm $DIR/$tfile
8705 }
8706 run_test 60e "no space while new llog is being created"
8707
8708 test_60f() {
8709         local old_path=$($LCTL get_param -n debug_path)
8710
8711         stack_trap "$LCTL set_param debug_path=$old_path"
8712         stack_trap "rm -f $TMP/$tfile*"
8713         rm -f $TMP/$tfile* 2> /dev/null
8714         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8715         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8716         test_mkdir $DIR/$tdir
8717         # retry in case the open is cached and not released
8718         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8719                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8720                 sleep 0.1
8721         done
8722         ls $TMP/$tfile*
8723         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8724 }
8725 run_test 60f "change debug_path works"
8726
8727 test_60g() {
8728         local pid
8729         local i
8730
8731         test_mkdir -c $MDSCOUNT $DIR/$tdir
8732
8733         (
8734                 local index=0
8735                 while true; do
8736                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8737                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8738                                 2>/dev/null
8739                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8740                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8741                         index=$((index + 1))
8742                 done
8743         ) &
8744
8745         pid=$!
8746
8747         for i in {0..100}; do
8748                 # define OBD_FAIL_OSD_TXN_START    0x19a
8749                 local index=$((i % MDSCOUNT + 1))
8750
8751                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8752                         > /dev/null
8753                 sleep 0.01
8754         done
8755
8756         kill -9 $pid
8757
8758         for i in $(seq $MDSCOUNT); do
8759                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8760         done
8761
8762         mkdir $DIR/$tdir/new || error "mkdir failed"
8763         rmdir $DIR/$tdir/new || error "rmdir failed"
8764
8765         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8766                 -t namespace
8767         for i in $(seq $MDSCOUNT); do
8768                 wait_update_facet mds$i "$LCTL get_param -n \
8769                         mdd.$(facet_svc mds$i).lfsck_namespace |
8770                         awk '/^status/ { print \\\$2 }'" "completed"
8771         done
8772
8773         ls -R $DIR/$tdir
8774         rm -rf $DIR/$tdir || error "rmdir failed"
8775 }
8776 run_test 60g "transaction abort won't cause MDT hung"
8777
8778 test_60h() {
8779         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8780                 skip "Need MDS version at least 2.12.52"
8781         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8782
8783         local f
8784
8785         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8786         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8787         for fail_loc in 0x80000188 0x80000189; do
8788                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8789                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8790                         error "mkdir $dir-$fail_loc failed"
8791                 for i in {0..10}; do
8792                         # create may fail on missing stripe
8793                         echo $i > $DIR/$tdir-$fail_loc/$i
8794                 done
8795                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8796                         error "getdirstripe $tdir-$fail_loc failed"
8797                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8798                         error "migrate $tdir-$fail_loc failed"
8799                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8800                         error "getdirstripe $tdir-$fail_loc failed"
8801                 pushd $DIR/$tdir-$fail_loc
8802                 for f in *; do
8803                         echo $f | cmp $f - || error "$f data mismatch"
8804                 done
8805                 popd
8806                 rm -rf $DIR/$tdir-$fail_loc
8807         done
8808 }
8809 run_test 60h "striped directory with missing stripes can be accessed"
8810
8811 function t60i_load() {
8812         mkdir $DIR/$tdir
8813         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8814         $LCTL set_param fail_loc=0x131c fail_val=1
8815         for ((i=0; i<5000; i++)); do
8816                 touch $DIR/$tdir/f$i
8817         done
8818 }
8819
8820 test_60i() {
8821         changelog_register || error "changelog_register failed"
8822         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8823         changelog_users $SINGLEMDS | grep -q $cl_user ||
8824                 error "User $cl_user not found in changelog_users"
8825         changelog_chmask "ALL"
8826         t60i_load &
8827         local PID=$!
8828         for((i=0; i<100; i++)); do
8829                 changelog_dump >/dev/null ||
8830                         error "can't read changelog"
8831         done
8832         kill $PID
8833         wait $PID
8834         changelog_deregister || error "changelog_deregister failed"
8835         $LCTL set_param fail_loc=0
8836 }
8837 run_test 60i "llog: new record vs reader race"
8838
8839 test_60j() {
8840         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8841                 skip "need MDS version at least 2.15.50"
8842         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8843         remote_mds_nodsh && skip "remote MDS with nodsh"
8844         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8845
8846         changelog_users $SINGLEMDS | grep "^cl" &&
8847                 skip "active changelog user"
8848
8849         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8850
8851         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8852                 skip_env "missing llog_reader"
8853
8854         mkdir_on_mdt0 $DIR/$tdir
8855
8856         local f=$DIR/$tdir/$tfile
8857         local mdt_dev
8858         local tmpfile
8859         local plain
8860
8861         changelog_register || error "cannot register changelog user"
8862
8863         # set changelog_mask to ALL
8864         changelog_chmask "ALL"
8865         changelog_clear
8866
8867         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8868         unlinkmany ${f}- 100 || error "unlinkmany failed"
8869
8870         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8871         mdt_dev=$(facet_device $SINGLEMDS)
8872
8873         do_facet $SINGLEMDS sync
8874         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8875                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8876                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8877
8878         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8879
8880         # if $tmpfile is not on EXT3 filesystem for some reason
8881         [[ ${plain:0:1} == 'O' ]] ||
8882                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8883
8884         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8885                 $mdt_dev; stat -c %s $tmpfile")
8886         echo "Truncate llog from $size to $((size - size % 8192))"
8887         size=$((size - size % 8192))
8888         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8889         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8890                 grep -c 'in bitmap only')
8891         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8892
8893         size=$((size - 9000))
8894         echo "Corrupt llog in the middle at $size"
8895         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8896                 count=333 conv=notrunc
8897         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8898                 grep -c 'next chunk')
8899         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
8900 }
8901 run_test 60j "llog_reader reports corruptions"
8902
8903 test_61a() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905
8906         f="$DIR/f61"
8907         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8908         cancel_lru_locks osc
8909         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8910         sync
8911 }
8912 run_test 61a "mmap() writes don't make sync hang ================"
8913
8914 test_61b() {
8915         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8916 }
8917 run_test 61b "mmap() of unstriped file is successful"
8918
8919 # bug 2330 - insufficient obd_match error checking causes LBUG
8920 test_62() {
8921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8922
8923         f="$DIR/f62"
8924         echo foo > $f
8925         cancel_lru_locks osc
8926         lctl set_param fail_loc=0x405
8927         cat $f && error "cat succeeded, expect -EIO"
8928         lctl set_param fail_loc=0
8929 }
8930 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8931 # match every page all of the time.
8932 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8933
8934 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8935 # Though this test is irrelevant anymore, it helped to reveal some
8936 # other grant bugs (LU-4482), let's keep it.
8937 test_63a() {   # was test_63
8938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8939
8940         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8941
8942         for i in `seq 10` ; do
8943                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8944                 sleep 5
8945                 kill $!
8946                 sleep 1
8947         done
8948
8949         rm -f $DIR/f63 || true
8950 }
8951 run_test 63a "Verify oig_wait interruption does not crash ======="
8952
8953 # bug 2248 - async write errors didn't return to application on sync
8954 # bug 3677 - async write errors left page locked
8955 test_63b() {
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957
8958         debugsave
8959         lctl set_param debug=-1
8960
8961         # ensure we have a grant to do async writes
8962         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8963         rm $DIR/$tfile
8964
8965         sync    # sync lest earlier test intercept the fail_loc
8966
8967         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8968         lctl set_param fail_loc=0x80000406
8969         $MULTIOP $DIR/$tfile Owy && \
8970                 error "sync didn't return ENOMEM"
8971         sync; sleep 2; sync     # do a real sync this time to flush page
8972         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8973                 error "locked page left in cache after async error" || true
8974         debugrestore
8975 }
8976 run_test 63b "async write errors should be returned to fsync ==="
8977
8978 test_64a () {
8979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8980
8981         lfs df $DIR
8982         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8983 }
8984 run_test 64a "verify filter grant calculations (in kernel) ====="
8985
8986 test_64b () {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988
8989         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8990 }
8991 run_test 64b "check out-of-space detection on client"
8992
8993 test_64c() {
8994         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8995 }
8996 run_test 64c "verify grant shrink"
8997
8998 import_param() {
8999         local tgt=$1
9000         local param=$2
9001
9002         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9003 }
9004
9005 # this does exactly what osc_request.c:osc_announce_cached() does in
9006 # order to calculate max amount of grants to ask from server
9007 want_grant() {
9008         local tgt=$1
9009
9010         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9011         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9012
9013         ((rpc_in_flight++));
9014         nrpages=$((nrpages * rpc_in_flight))
9015
9016         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9017
9018         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9019
9020         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9021         local undirty=$((nrpages * PAGE_SIZE))
9022
9023         local max_extent_pages
9024         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9025         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9026         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9027         local grant_extent_tax
9028         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9029
9030         undirty=$((undirty + nrextents * grant_extent_tax))
9031
9032         echo $undirty
9033 }
9034
9035 # this is size of unit for grant allocation. It should be equal to
9036 # what tgt_grant.c:tgt_grant_chunk() calculates
9037 grant_chunk() {
9038         local tgt=$1
9039         local max_brw_size
9040         local grant_extent_tax
9041
9042         max_brw_size=$(import_param $tgt max_brw_size)
9043
9044         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9045
9046         echo $(((max_brw_size + grant_extent_tax) * 2))
9047 }
9048
9049 test_64d() {
9050         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9051                 skip "OST < 2.10.55 doesn't limit grants enough"
9052
9053         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9054
9055         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9056                 skip "no grant_param connect flag"
9057
9058         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9059
9060         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9061         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9062
9063
9064         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9065         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9066
9067         $LFS setstripe $DIR/$tfile -i 0 -c 1
9068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9069         ddpid=$!
9070
9071         while kill -0 $ddpid; do
9072                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9073
9074                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9075                         kill $ddpid
9076                         error "cur_grant $cur_grant > $max_cur_granted"
9077                 fi
9078
9079                 sleep 1
9080         done
9081 }
9082 run_test 64d "check grant limit exceed"
9083
9084 check_grants() {
9085         local tgt=$1
9086         local expected=$2
9087         local msg=$3
9088         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9089
9090         ((cur_grants == expected)) ||
9091                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9092 }
9093
9094 round_up_p2() {
9095         echo $((($1 + $2 - 1) & ~($2 - 1)))
9096 }
9097
9098 test_64e() {
9099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9100         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9101                 skip "Need OSS version at least 2.11.56"
9102
9103         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9104         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9105         $LCTL set_param debug=+cache
9106
9107         # Remount client to reset grant
9108         remount_client $MOUNT || error "failed to remount client"
9109         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9110
9111         local init_grants=$(import_param $osc_tgt initial_grant)
9112
9113         check_grants $osc_tgt $init_grants "init grants"
9114
9115         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9116         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9117         local gbs=$(import_param $osc_tgt grant_block_size)
9118
9119         # write random number of bytes from max_brw_size / 4 to max_brw_size
9120         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9121         # align for direct io
9122         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9123         # round to grant consumption unit
9124         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9125
9126         local grants=$((wb_round_up + extent_tax))
9127
9128         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9129
9130         # define OBD_FAIL_TGT_NO_GRANT 0x725
9131         # make the server not grant more back
9132         do_facet ost1 $LCTL set_param fail_loc=0x725
9133         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9134
9135         do_facet ost1 $LCTL set_param fail_loc=0
9136
9137         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9138
9139         rm -f $DIR/$tfile || error "rm failed"
9140
9141         # Remount client to reset grant
9142         remount_client $MOUNT || error "failed to remount client"
9143         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9144
9145         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9146
9147         # define OBD_FAIL_TGT_NO_GRANT 0x725
9148         # make the server not grant more back
9149         do_facet ost1 $LCTL set_param fail_loc=0x725
9150         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9151         do_facet ost1 $LCTL set_param fail_loc=0
9152
9153         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9154 }
9155 run_test 64e "check grant consumption (no grant allocation)"
9156
9157 test_64f() {
9158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9159
9160         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9161         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9162         $LCTL set_param debug=+cache
9163
9164         # Remount client to reset grant
9165         remount_client $MOUNT || error "failed to remount client"
9166         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9167
9168         local init_grants=$(import_param $osc_tgt initial_grant)
9169         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9170         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9171         local gbs=$(import_param $osc_tgt grant_block_size)
9172         local chunk=$(grant_chunk $osc_tgt)
9173
9174         # write random number of bytes from max_brw_size / 4 to max_brw_size
9175         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9176         # align for direct io
9177         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9178         # round to grant consumption unit
9179         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9180
9181         local grants=$((wb_round_up + extent_tax))
9182
9183         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9184         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9185                 error "error writing to $DIR/$tfile"
9186
9187         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9188                 "direct io with grant allocation"
9189
9190         rm -f $DIR/$tfile || error "rm failed"
9191
9192         # Remount client to reset grant
9193         remount_client $MOUNT || error "failed to remount client"
9194         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9195
9196         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9197
9198         local cmd="oO_WRONLY:w${write_bytes}_yc"
9199
9200         $MULTIOP $DIR/$tfile $cmd &
9201         MULTIPID=$!
9202         sleep 1
9203
9204         check_grants $osc_tgt $((init_grants - grants)) \
9205                 "buffered io, not write rpc"
9206
9207         kill -USR1 $MULTIPID
9208         wait
9209
9210         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9211                 "buffered io, one RPC"
9212 }
9213 run_test 64f "check grant consumption (with grant allocation)"
9214
9215 test_64g() {
9216         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9217                 skip "Need MDS version at least 2.14.56"
9218
9219         local mdts=$(comma_list $(mdts_nodes))
9220
9221         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9222                         tr '\n' ' ')
9223         stack_trap "$LCTL set_param $old"
9224
9225         # generate dirty pages and increase dirty granted on MDT
9226         stack_trap "rm -f $DIR/$tfile-*"
9227         for (( i = 0; i < 10; i++)); do
9228                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9229                         error "can't set stripe"
9230                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9231                         error "can't dd"
9232                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9233                         $LFS getstripe $DIR/$tfile-$i
9234                         error "not DoM file"
9235                 }
9236         done
9237
9238         # flush dirty pages
9239         sync
9240
9241         # wait until grant shrink reset grant dirty on MDTs
9242         for ((i = 0; i < 120; i++)); do
9243                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9244                         awk '{sum=sum+$1} END {print sum}')
9245                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9246                 echo "$grant_dirty grants, $vm_dirty pages"
9247                 (( grant_dirty + vm_dirty == 0 )) && break
9248                 (( i == 3 )) && sync &&
9249                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9250                 sleep 1
9251         done
9252
9253         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9254                 awk '{sum=sum+$1} END {print sum}')
9255         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9256 }
9257 run_test 64g "grant shrink on MDT"
9258
9259 test_64h() {
9260         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9261                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9262
9263         local instance=$($LFS getname -i $DIR)
9264         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9265         local num_exps=$(do_facet ost1 \
9266             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9267         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9268         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9269         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9270
9271         # 10MiB is for file to be written, max_brw_size * 16 *
9272         # num_exps is space reserve so that tgt_grant_shrink() decided
9273         # to not shrink
9274         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9275         (( avail * 1024 < expect )) &&
9276                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9277
9278         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9279         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9280         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9281         $LCTL set_param osc.*OST0000*.grant_shrink=1
9282         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9283
9284         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9285         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9286
9287         # drop cache so that coming read would do rpc
9288         cancel_lru_locks osc
9289
9290         # shrink interval is set to 10, pause for 7 seconds so that
9291         # grant thread did not wake up yet but coming read entered
9292         # shrink mode for rpc (osc_should_shrink_grant())
9293         sleep 7
9294
9295         declare -a cur_grant_bytes
9296         declare -a tot_granted
9297         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9298         tot_granted[0]=$(do_facet ost1 \
9299             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9300
9301         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9302
9303         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9304         tot_granted[1]=$(do_facet ost1 \
9305             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9306
9307         # grant change should be equal on both sides
9308         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9309                 tot_granted[0] - tot_granted[1])) ||
9310                 error "grant change mismatch, "                                \
9311                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9312                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9313 }
9314 run_test 64h "grant shrink on read"
9315
9316 test_64i() {
9317         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9318                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9319
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321         remote_ost_nodsh && skip "remote OSTs with nodsh"
9322
9323         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9324
9325         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9326
9327         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9328         local instance=$($LFS getname -i $DIR)
9329
9330         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9331         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9332
9333         # shrink grants and simulate rpc loss
9334         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9335         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9336         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9337
9338         fail ost1
9339
9340         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9341
9342         local testid=$(echo $TESTNAME | tr '_' ' ')
9343
9344         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9345                 grep "GRANT, real grant" &&
9346                 error "client has more grants then it owns" || true
9347 }
9348 run_test 64i "shrink on reconnect"
9349
9350 # bug 1414 - set/get directories' stripe info
9351 test_65a() {
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         test_mkdir $DIR/$tdir
9355         touch $DIR/$tdir/f1
9356         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9357 }
9358 run_test 65a "directory with no stripe info"
9359
9360 test_65b() {
9361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9362
9363         test_mkdir $DIR/$tdir
9364         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9365
9366         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9367                                                 error "setstripe"
9368         touch $DIR/$tdir/f2
9369         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9370 }
9371 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9372
9373 test_65c() {
9374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9375         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9376
9377         test_mkdir $DIR/$tdir
9378         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9379
9380         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9381                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9382         touch $DIR/$tdir/f3
9383         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9384 }
9385 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9386
9387 test_65d() {
9388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9389
9390         test_mkdir $DIR/$tdir
9391         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9392         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9393
9394         if [[ $STRIPECOUNT -le 0 ]]; then
9395                 sc=1
9396         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9397                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9398                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9399         else
9400                 sc=$(($STRIPECOUNT - 1))
9401         fi
9402         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9403         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9404         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9405                 error "lverify failed"
9406 }
9407 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9408
9409 test_65e() {
9410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9411
9412         test_mkdir $DIR/$tdir
9413
9414         $LFS setstripe $DIR/$tdir || error "setstripe"
9415         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9416                                         error "no stripe info failed"
9417         touch $DIR/$tdir/f6
9418         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9419 }
9420 run_test 65e "directory setstripe defaults"
9421
9422 test_65f() {
9423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9424
9425         test_mkdir $DIR/${tdir}f
9426         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9427                 error "setstripe succeeded" || true
9428 }
9429 run_test 65f "dir setstripe permission (should return error) ==="
9430
9431 test_65g() {
9432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9433
9434         test_mkdir $DIR/$tdir
9435         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9436
9437         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9438                 error "setstripe -S failed"
9439         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9440         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9441                 error "delete default stripe failed"
9442 }
9443 run_test 65g "directory setstripe -d"
9444
9445 test_65h() {
9446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9447
9448         test_mkdir $DIR/$tdir
9449         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9450
9451         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9452                 error "setstripe -S failed"
9453         test_mkdir $DIR/$tdir/dd1
9454         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9455                 error "stripe info inherit failed"
9456 }
9457 run_test 65h "directory stripe info inherit ===================="
9458
9459 test_65i() {
9460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9461
9462         save_layout_restore_at_exit $MOUNT
9463
9464         # bug6367: set non-default striping on root directory
9465         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9466
9467         # bug12836: getstripe on -1 default directory striping
9468         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9469
9470         # bug12836: getstripe -v on -1 default directory striping
9471         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9472
9473         # bug12836: new find on -1 default directory striping
9474         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9475 }
9476 run_test 65i "various tests to set root directory striping"
9477
9478 test_65j() { # bug6367
9479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9480
9481         sync; sleep 1
9482
9483         # if we aren't already remounting for each test, do so for this test
9484         if [ "$I_MOUNTED" = "yes" ]; then
9485                 cleanup || error "failed to unmount"
9486                 setup
9487         fi
9488
9489         save_layout_restore_at_exit $MOUNT
9490
9491         $LFS setstripe -d $MOUNT || error "setstripe failed"
9492 }
9493 run_test 65j "set default striping on root directory (bug 6367)="
9494
9495 cleanup_65k() {
9496         rm -rf $DIR/$tdir
9497         wait_delete_completed
9498         do_facet $SINGLEMDS "lctl set_param -n \
9499                 osp.$ost*MDT0000.max_create_count=$max_count"
9500         do_facet $SINGLEMDS "lctl set_param -n \
9501                 osp.$ost*MDT0000.create_count=$count"
9502         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9503         echo $INACTIVE_OSC "is Activate"
9504
9505         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9506 }
9507
9508 test_65k() { # bug11679
9509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9510         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9511         remote_mds_nodsh && skip "remote MDS with nodsh"
9512
9513         local disable_precreate=true
9514         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9515                 disable_precreate=false
9516
9517         echo "Check OST status: "
9518         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9519                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9520
9521         for OSC in $MDS_OSCS; do
9522                 echo $OSC "is active"
9523                 do_facet $SINGLEMDS lctl --device %$OSC activate
9524         done
9525
9526         for INACTIVE_OSC in $MDS_OSCS; do
9527                 local ost=$(osc_to_ost $INACTIVE_OSC)
9528                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9529                                lov.*md*.target_obd |
9530                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9531
9532                 mkdir -p $DIR/$tdir
9533                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9534                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9535
9536                 echo "Deactivate: " $INACTIVE_OSC
9537                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9538
9539                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9540                               osp.$ost*MDT0000.create_count")
9541                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9542                                   osp.$ost*MDT0000.max_create_count")
9543                 $disable_precreate &&
9544                         do_facet $SINGLEMDS "lctl set_param -n \
9545                                 osp.$ost*MDT0000.max_create_count=0"
9546
9547                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9548                         [ -f $DIR/$tdir/$idx ] && continue
9549                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9550                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9551                                 { cleanup_65k;
9552                                   error "setstripe $idx should succeed"; }
9553                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9554                 done
9555                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9556                 rmdir $DIR/$tdir
9557
9558                 do_facet $SINGLEMDS "lctl set_param -n \
9559                         osp.$ost*MDT0000.max_create_count=$max_count"
9560                 do_facet $SINGLEMDS "lctl set_param -n \
9561                         osp.$ost*MDT0000.create_count=$count"
9562                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9563                 echo $INACTIVE_OSC "is Activate"
9564
9565                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9566         done
9567 }
9568 run_test 65k "validate manual striping works properly with deactivated OSCs"
9569
9570 test_65l() { # bug 12836
9571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9572
9573         test_mkdir -p $DIR/$tdir/test_dir
9574         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9575         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9576 }
9577 run_test 65l "lfs find on -1 stripe dir ========================"
9578
9579 test_65m() {
9580         local layout=$(save_layout $MOUNT)
9581         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9582                 restore_layout $MOUNT $layout
9583                 error "setstripe should fail by non-root users"
9584         }
9585         true
9586 }
9587 run_test 65m "normal user can't set filesystem default stripe"
9588
9589 test_65n() {
9590         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9591         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9592                 skip "Need MDS version at least 2.12.50"
9593         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9594
9595         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9596         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9597         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9598
9599         save_layout_restore_at_exit $MOUNT
9600
9601         # new subdirectory under root directory should not inherit
9602         # the default layout from root
9603         local dir1=$MOUNT/$tdir-1
9604         mkdir $dir1 || error "mkdir $dir1 failed"
9605         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9606                 error "$dir1 shouldn't have LOV EA"
9607
9608         # delete the default layout on root directory
9609         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9610
9611         local dir2=$MOUNT/$tdir-2
9612         mkdir $dir2 || error "mkdir $dir2 failed"
9613         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9614                 error "$dir2 shouldn't have LOV EA"
9615
9616         # set a new striping pattern on root directory
9617         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9618         local new_def_stripe_size=$((def_stripe_size * 2))
9619         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9620                 error "set stripe size on $MOUNT failed"
9621
9622         # new file created in $dir2 should inherit the new stripe size from
9623         # the filesystem default
9624         local file2=$dir2/$tfile-2
9625         touch $file2 || error "touch $file2 failed"
9626
9627         local file2_stripe_size=$($LFS getstripe -S $file2)
9628         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9629         {
9630                 echo "file2_stripe_size: '$file2_stripe_size'"
9631                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9632                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9633         }
9634
9635         local dir3=$MOUNT/$tdir-3
9636         mkdir $dir3 || error "mkdir $dir3 failed"
9637         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9638         # the root layout, which is the actual default layout that will be used
9639         # when new files are created in $dir3.
9640         local dir3_layout=$(get_layout_param $dir3)
9641         local root_dir_layout=$(get_layout_param $MOUNT)
9642         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9643         {
9644                 echo "dir3_layout: '$dir3_layout'"
9645                 echo "root_dir_layout: '$root_dir_layout'"
9646                 error "$dir3 should show the default layout from $MOUNT"
9647         }
9648
9649         # set OST pool on root directory
9650         local pool=$TESTNAME
9651         pool_add $pool || error "add $pool failed"
9652         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9653                 error "add targets to $pool failed"
9654
9655         $LFS setstripe -p $pool $MOUNT ||
9656                 error "set OST pool on $MOUNT failed"
9657
9658         # new file created in $dir3 should inherit the pool from
9659         # the filesystem default
9660         local file3=$dir3/$tfile-3
9661         touch $file3 || error "touch $file3 failed"
9662
9663         local file3_pool=$($LFS getstripe -p $file3)
9664         [[ "$file3_pool" = "$pool" ]] ||
9665                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9666
9667         local dir4=$MOUNT/$tdir-4
9668         mkdir $dir4 || error "mkdir $dir4 failed"
9669         local dir4_layout=$(get_layout_param $dir4)
9670         root_dir_layout=$(get_layout_param $MOUNT)
9671         echo "$LFS getstripe -d $dir4"
9672         $LFS getstripe -d $dir4
9673         echo "$LFS getstripe -d $MOUNT"
9674         $LFS getstripe -d $MOUNT
9675         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9676         {
9677                 echo "dir4_layout: '$dir4_layout'"
9678                 echo "root_dir_layout: '$root_dir_layout'"
9679                 error "$dir4 should show the default layout from $MOUNT"
9680         }
9681
9682         # new file created in $dir4 should inherit the pool from
9683         # the filesystem default
9684         local file4=$dir4/$tfile-4
9685         touch $file4 || error "touch $file4 failed"
9686
9687         local file4_pool=$($LFS getstripe -p $file4)
9688         [[ "$file4_pool" = "$pool" ]] ||
9689                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9690
9691         # new subdirectory under non-root directory should inherit
9692         # the default layout from its parent directory
9693         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9694                 error "set directory layout on $dir4 failed"
9695
9696         local dir5=$dir4/$tdir-5
9697         mkdir $dir5 || error "mkdir $dir5 failed"
9698
9699         dir4_layout=$(get_layout_param $dir4)
9700         local dir5_layout=$(get_layout_param $dir5)
9701         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9702         {
9703                 echo "dir4_layout: '$dir4_layout'"
9704                 echo "dir5_layout: '$dir5_layout'"
9705                 error "$dir5 should inherit the default layout from $dir4"
9706         }
9707
9708         # though subdir under ROOT doesn't inherit default layout, but
9709         # its sub dir/file should be created with default layout.
9710         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9711         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9712                 skip "Need MDS version at least 2.12.59"
9713
9714         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9715         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9716         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9717
9718         if [ $default_lmv_hash == "none" ]; then
9719                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9720         else
9721                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9722                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9723         fi
9724
9725         $LFS setdirstripe -D -c 2 $MOUNT ||
9726                 error "setdirstripe -D -c 2 failed"
9727         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9728         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9729         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9730
9731         # $dir4 layout includes pool
9732         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9733         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9734                 error "pool lost on setstripe"
9735         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9736         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9737                 error "pool lost on compound layout setstripe"
9738 }
9739 run_test 65n "don't inherit default layout from root for new subdirectories"
9740
9741 test_65o() {
9742         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9743                 skip "need MDS version at least 2.14.57"
9744
9745         # set OST pool on root directory
9746         local pool=$TESTNAME
9747
9748         pool_add $pool || error "add $pool failed"
9749         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9750                 error "add targets to $pool failed"
9751
9752         local dir1=$MOUNT/$tdir
9753
9754         mkdir $dir1 || error "mkdir $dir1 failed"
9755
9756         # set a new striping pattern on root directory
9757         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9758
9759         $LFS setstripe -p $pool $dir1 ||
9760                 error "set directory layout on $dir1 failed"
9761
9762         # $dir1 layout includes pool
9763         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9764         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9765                 error "pool lost on setstripe"
9766         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9767         $LFS getstripe $dir1
9768         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9769                 error "pool lost on compound layout setstripe"
9770
9771         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9772                 error "setdirstripe failed on sub-dir with inherited pool"
9773         $LFS getstripe $dir1/dir2
9774         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9775                 error "pool lost on compound layout setdirstripe"
9776
9777         $LFS setstripe -E -1 -c 1 $dir1
9778         $LFS getstripe -d $dir1
9779         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9780                 error "pool lost on setstripe"
9781 }
9782 run_test 65o "pool inheritance for mdt component"
9783
9784 test_65p () { # LU-16152
9785         local src_dir=$DIR/$tdir/src_dir
9786         local dst_dir=$DIR/$tdir/dst_dir
9787         local yaml_file=$DIR/$tdir/layout.yaml
9788         local border
9789
9790         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9791                 skip "Need at least version 2.15.51"
9792
9793         test_mkdir -p $src_dir
9794         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9795                 error "failed to setstripe"
9796         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9797                 error "failed to getstripe"
9798
9799         test_mkdir -p $dst_dir
9800         $LFS setstripe --yaml $yaml_file $dst_dir ||
9801                 error "failed to setstripe with yaml file"
9802         border=$($LFS getstripe -d $dst_dir |
9803                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9804                 error "failed to getstripe"
9805
9806         # 2048M is 0x80000000, or 2147483648
9807         (( $border == 2147483648 )) ||
9808                 error "failed to handle huge number in yaml layout"
9809 }
9810 run_test 65p "setstripe with yaml file and huge number"
9811
9812 # bug 2543 - update blocks count on client
9813 test_66() {
9814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9815
9816         local COUNT=${COUNT:-8}
9817         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9818         sync; sync_all_data; sync; sync_all_data
9819         cancel_lru_locks osc
9820         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9821         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9822 }
9823 run_test 66 "update inode blocks count on client ==============="
9824
9825 meminfo() {
9826         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9827 }
9828
9829 swap_used() {
9830         swapon -s | awk '($1 == "'$1'") { print $4 }'
9831 }
9832
9833 # bug5265, obdfilter oa2dentry return -ENOENT
9834 # #define OBD_FAIL_SRV_ENOENT 0x217
9835 test_69() {
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837         remote_ost_nodsh && skip "remote OST with nodsh"
9838
9839         f="$DIR/$tfile"
9840         $LFS setstripe -c 1 -i 0 $f
9841
9842         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9843
9844         do_facet ost1 lctl set_param fail_loc=0x217
9845         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9846         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9847
9848         do_facet ost1 lctl set_param fail_loc=0
9849         $DIRECTIO write $f 0 2 || error "write error"
9850
9851         cancel_lru_locks osc
9852         $DIRECTIO read $f 0 1 || error "read error"
9853
9854         do_facet ost1 lctl set_param fail_loc=0x217
9855         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9856
9857         do_facet ost1 lctl set_param fail_loc=0
9858         rm -f $f
9859 }
9860 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9861
9862 test_71() {
9863         test_mkdir $DIR/$tdir
9864         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9865         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9866 }
9867 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9868
9869 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9871         [ "$RUNAS_ID" = "$UID" ] &&
9872                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9873         # Check that testing environment is properly set up. Skip if not
9874         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9875                 skip_env "User $RUNAS_ID does not exist - skipping"
9876
9877         touch $DIR/$tfile
9878         chmod 777 $DIR/$tfile
9879         chmod ug+s $DIR/$tfile
9880         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9881                 error "$RUNAS dd $DIR/$tfile failed"
9882         # See if we are still setuid/sgid
9883         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9884                 error "S/gid is not dropped on write"
9885         # Now test that MDS is updated too
9886         cancel_lru_locks mdc
9887         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9888                 error "S/gid is not dropped on MDS"
9889         rm -f $DIR/$tfile
9890 }
9891 run_test 72a "Test that remove suid works properly (bug5695) ===="
9892
9893 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9894         local perm
9895
9896         [ "$RUNAS_ID" = "$UID" ] &&
9897                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9898         [ "$RUNAS_ID" -eq 0 ] &&
9899                 skip_env "RUNAS_ID = 0 -- skipping"
9900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9901         # Check that testing environment is properly set up. Skip if not
9902         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9903                 skip_env "User $RUNAS_ID does not exist - skipping"
9904
9905         touch $DIR/${tfile}-f{g,u}
9906         test_mkdir $DIR/${tfile}-dg
9907         test_mkdir $DIR/${tfile}-du
9908         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9909         chmod g+s $DIR/${tfile}-{f,d}g
9910         chmod u+s $DIR/${tfile}-{f,d}u
9911         for perm in 777 2777 4777; do
9912                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9913                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9914                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9915                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9916         done
9917         true
9918 }
9919 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9920
9921 # bug 3462 - multiple simultaneous MDC requests
9922 test_73() {
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924
9925         test_mkdir $DIR/d73-1
9926         test_mkdir $DIR/d73-2
9927         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9928         pid1=$!
9929
9930         lctl set_param fail_loc=0x80000129
9931         $MULTIOP $DIR/d73-1/f73-2 Oc &
9932         sleep 1
9933         lctl set_param fail_loc=0
9934
9935         $MULTIOP $DIR/d73-2/f73-3 Oc &
9936         pid3=$!
9937
9938         kill -USR1 $pid1
9939         wait $pid1 || return 1
9940
9941         sleep 25
9942
9943         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9944         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9945         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9946
9947         rm -rf $DIR/d73-*
9948 }
9949 run_test 73 "multiple MDC requests (should not deadlock)"
9950
9951 test_74a() { # bug 6149, 6184
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953
9954         touch $DIR/f74a
9955         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9956         #
9957         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9958         # will spin in a tight reconnection loop
9959         $LCTL set_param fail_loc=0x8000030e
9960         # get any lock that won't be difficult - lookup works.
9961         ls $DIR/f74a
9962         $LCTL set_param fail_loc=0
9963         rm -f $DIR/f74a
9964         true
9965 }
9966 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9967
9968 test_74b() { # bug 13310
9969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9970
9971         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9972         #
9973         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9974         # will spin in a tight reconnection loop
9975         $LCTL set_param fail_loc=0x8000030e
9976         # get a "difficult" lock
9977         touch $DIR/f74b
9978         $LCTL set_param fail_loc=0
9979         rm -f $DIR/f74b
9980         true
9981 }
9982 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9983
9984 test_74c() {
9985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9986
9987         #define OBD_FAIL_LDLM_NEW_LOCK
9988         $LCTL set_param fail_loc=0x319
9989         touch $DIR/$tfile && error "touch successful"
9990         $LCTL set_param fail_loc=0
9991         true
9992 }
9993 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9994
9995 slab_lic=/sys/kernel/slab/lustre_inode_cache
9996 num_objects() {
9997         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9998         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9999                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10000 }
10001
10002 test_76a() { # Now for b=20433, added originally in b=1443
10003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10004
10005         cancel_lru_locks osc
10006         # there may be some slab objects cached per core
10007         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10008         local before=$(num_objects)
10009         local count=$((512 * cpus))
10010         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10011         local margin=$((count / 10))
10012         if [[ -f $slab_lic/aliases ]]; then
10013                 local aliases=$(cat $slab_lic/aliases)
10014                 (( aliases > 0 )) && margin=$((margin * aliases))
10015         fi
10016
10017         echo "before slab objects: $before"
10018         for i in $(seq $count); do
10019                 touch $DIR/$tfile
10020                 rm -f $DIR/$tfile
10021         done
10022         cancel_lru_locks osc
10023         local after=$(num_objects)
10024         echo "created: $count, after slab objects: $after"
10025         # shared slab counts are not very accurate, allow significant margin
10026         # the main goal is that the cache growth is not permanently > $count
10027         while (( after > before + margin )); do
10028                 sleep 1
10029                 after=$(num_objects)
10030                 wait=$((wait + 1))
10031                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10032                 if (( wait > 60 )); then
10033                         error "inode slab grew from $before+$margin to $after"
10034                 fi
10035         done
10036 }
10037 run_test 76a "confirm clients recycle inodes properly ===="
10038
10039 test_76b() {
10040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10041         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10042
10043         local count=512
10044         local before=$(num_objects)
10045
10046         for i in $(seq $count); do
10047                 mkdir $DIR/$tdir
10048                 rmdir $DIR/$tdir
10049         done
10050
10051         local after=$(num_objects)
10052         local wait=0
10053
10054         while (( after > before )); do
10055                 sleep 1
10056                 after=$(num_objects)
10057                 wait=$((wait + 1))
10058                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10059                 if (( wait > 60 )); then
10060                         error "inode slab grew from $before to $after"
10061                 fi
10062         done
10063
10064         echo "slab objects before: $before, after: $after"
10065 }
10066 run_test 76b "confirm clients recycle directory inodes properly ===="
10067
10068 export ORIG_CSUM=""
10069 set_checksums()
10070 {
10071         # Note: in sptlrpc modes which enable its own bulk checksum, the
10072         # original crc32_le bulk checksum will be automatically disabled,
10073         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10074         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10075         # In this case set_checksums() will not be no-op, because sptlrpc
10076         # bulk checksum will be enabled all through the test.
10077
10078         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10079         lctl set_param -n osc.*.checksums $1
10080         return 0
10081 }
10082
10083 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10084                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10085 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10086                              tr -d [] | head -n1)}
10087 set_checksum_type()
10088 {
10089         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10090         rc=$?
10091         log "set checksum type to $1, rc = $rc"
10092         return $rc
10093 }
10094
10095 get_osc_checksum_type()
10096 {
10097         # arugment 1: OST name, like OST0000
10098         ost=$1
10099         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10100                         sed 's/.*\[\(.*\)\].*/\1/g')
10101         rc=$?
10102         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10103         echo $checksum_type
10104 }
10105
10106 F77_TMP=$TMP/f77-temp
10107 F77SZ=8
10108 setup_f77() {
10109         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10110                 error "error writing to $F77_TMP"
10111 }
10112
10113 test_77a() { # bug 10889
10114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10115         $GSS && skip_env "could not run with gss"
10116
10117         [ ! -f $F77_TMP ] && setup_f77
10118         set_checksums 1
10119         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10120         set_checksums 0
10121         rm -f $DIR/$tfile
10122 }
10123 run_test 77a "normal checksum read/write operation"
10124
10125 test_77b() { # bug 10889
10126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10127         $GSS && skip_env "could not run with gss"
10128
10129         [ ! -f $F77_TMP ] && setup_f77
10130         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10131         $LCTL set_param fail_loc=0x80000409
10132         set_checksums 1
10133
10134         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10135                 error "dd error: $?"
10136         $LCTL set_param fail_loc=0
10137
10138         for algo in $CKSUM_TYPES; do
10139                 cancel_lru_locks osc
10140                 set_checksum_type $algo
10141                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10142                 $LCTL set_param fail_loc=0x80000408
10143                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10144                 $LCTL set_param fail_loc=0
10145         done
10146         set_checksums 0
10147         set_checksum_type $ORIG_CSUM_TYPE
10148         rm -f $DIR/$tfile
10149 }
10150 run_test 77b "checksum error on client write, read"
10151
10152 cleanup_77c() {
10153         trap 0
10154         set_checksums 0
10155         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10156         $check_ost &&
10157                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10158         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10159         $check_ost && [ -n "$ost_file_prefix" ] &&
10160                 do_facet ost1 rm -f ${ost_file_prefix}\*
10161 }
10162
10163 test_77c() {
10164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10165         $GSS && skip_env "could not run with gss"
10166         remote_ost_nodsh && skip "remote OST with nodsh"
10167
10168         local bad1
10169         local osc_file_prefix
10170         local osc_file
10171         local check_ost=false
10172         local ost_file_prefix
10173         local ost_file
10174         local orig_cksum
10175         local dump_cksum
10176         local fid
10177
10178         # ensure corruption will occur on first OSS/OST
10179         $LFS setstripe -i 0 $DIR/$tfile
10180
10181         [ ! -f $F77_TMP ] && setup_f77
10182         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10183                 error "dd write error: $?"
10184         fid=$($LFS path2fid $DIR/$tfile)
10185
10186         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10187         then
10188                 check_ost=true
10189                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10190                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10191         else
10192                 echo "OSS do not support bulk pages dump upon error"
10193         fi
10194
10195         osc_file_prefix=$($LCTL get_param -n debug_path)
10196         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10197
10198         trap cleanup_77c EXIT
10199
10200         set_checksums 1
10201         # enable bulk pages dump upon error on Client
10202         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10203         # enable bulk pages dump upon error on OSS
10204         $check_ost &&
10205                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10206
10207         # flush Client cache to allow next read to reach OSS
10208         cancel_lru_locks osc
10209
10210         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10211         $LCTL set_param fail_loc=0x80000408
10212         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10213         $LCTL set_param fail_loc=0
10214
10215         rm -f $DIR/$tfile
10216
10217         # check cksum dump on Client
10218         osc_file=$(ls ${osc_file_prefix}*)
10219         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10220         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10221         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10222         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10223         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10224                      cksum)
10225         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10226         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10227                 error "dump content does not match on Client"
10228
10229         $check_ost || skip "No need to check cksum dump on OSS"
10230
10231         # check cksum dump on OSS
10232         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10233         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10234         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10235         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10236         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10237                 error "dump content does not match on OSS"
10238
10239         cleanup_77c
10240 }
10241 run_test 77c "checksum error on client read with debug"
10242
10243 test_77d() { # bug 10889
10244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10245         $GSS && skip_env "could not run with gss"
10246
10247         stack_trap "rm -f $DIR/$tfile"
10248         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10249         $LCTL set_param fail_loc=0x80000409
10250         set_checksums 1
10251         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10252                 error "direct write: rc=$?"
10253         $LCTL set_param fail_loc=0
10254         set_checksums 0
10255
10256         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10257         $LCTL set_param fail_loc=0x80000408
10258         set_checksums 1
10259         cancel_lru_locks osc
10260         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10261                 error "direct read: rc=$?"
10262         $LCTL set_param fail_loc=0
10263         set_checksums 0
10264 }
10265 run_test 77d "checksum error on OST direct write, read"
10266
10267 test_77f() { # bug 10889
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         $GSS && skip_env "could not run with gss"
10270
10271         set_checksums 1
10272         stack_trap "rm -f $DIR/$tfile"
10273         for algo in $CKSUM_TYPES; do
10274                 cancel_lru_locks osc
10275                 set_checksum_type $algo
10276                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10277                 $LCTL set_param fail_loc=0x409
10278                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10279                         error "direct write succeeded"
10280                 $LCTL set_param fail_loc=0
10281         done
10282         set_checksum_type $ORIG_CSUM_TYPE
10283         set_checksums 0
10284 }
10285 run_test 77f "repeat checksum error on write (expect error)"
10286
10287 test_77g() { # bug 10889
10288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10289         $GSS && skip_env "could not run with gss"
10290         remote_ost_nodsh && skip "remote OST with nodsh"
10291
10292         [ ! -f $F77_TMP ] && setup_f77
10293
10294         local file=$DIR/$tfile
10295         stack_trap "rm -f $file" EXIT
10296
10297         $LFS setstripe -c 1 -i 0 $file
10298         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10299         do_facet ost1 lctl set_param fail_loc=0x8000021a
10300         set_checksums 1
10301         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10302                 error "write error: rc=$?"
10303         do_facet ost1 lctl set_param fail_loc=0
10304         set_checksums 0
10305
10306         cancel_lru_locks osc
10307         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10308         do_facet ost1 lctl set_param fail_loc=0x8000021b
10309         set_checksums 1
10310         cmp $F77_TMP $file || error "file compare failed"
10311         do_facet ost1 lctl set_param fail_loc=0
10312         set_checksums 0
10313 }
10314 run_test 77g "checksum error on OST write, read"
10315
10316 test_77k() { # LU-10906
10317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10318         $GSS && skip_env "could not run with gss"
10319
10320         local cksum_param="osc.$FSNAME*.checksums"
10321         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10322         local checksum
10323         local i
10324
10325         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10326         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10327         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10328
10329         for i in 0 1; do
10330                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10331                         error "failed to set checksum=$i on MGS"
10332                 wait_update $HOSTNAME "$get_checksum" $i
10333                 #remount
10334                 echo "remount client, checksum should be $i"
10335                 remount_client $MOUNT || error "failed to remount client"
10336                 checksum=$(eval $get_checksum)
10337                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10338         done
10339         # remove persistent param to avoid races with checksum mountopt below
10340         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10341                 error "failed to delete checksum on MGS"
10342
10343         for opt in "checksum" "nochecksum"; do
10344                 #remount with mount option
10345                 echo "remount client with option $opt, checksum should be $i"
10346                 umount_client $MOUNT || error "failed to umount client"
10347                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10348                         error "failed to mount client with option '$opt'"
10349                 checksum=$(eval $get_checksum)
10350                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10351                 i=$((i - 1))
10352         done
10353
10354         remount_client $MOUNT || error "failed to remount client"
10355 }
10356 run_test 77k "enable/disable checksum correctly"
10357
10358 test_77l() {
10359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10360         $GSS && skip_env "could not run with gss"
10361
10362         set_checksums 1
10363         stack_trap "set_checksums $ORIG_CSUM" EXIT
10364         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10365
10366         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10367
10368         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10369         for algo in $CKSUM_TYPES; do
10370                 set_checksum_type $algo || error "fail to set checksum type $algo"
10371                 osc_algo=$(get_osc_checksum_type OST0000)
10372                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10373
10374                 # no locks, no reqs to let the connection idle
10375                 cancel_lru_locks osc
10376                 lru_resize_disable osc
10377                 wait_osc_import_state client ost1 IDLE
10378
10379                 # ensure ost1 is connected
10380                 stat $DIR/$tfile >/dev/null || error "can't stat"
10381                 wait_osc_import_state client ost1 FULL
10382
10383                 osc_algo=$(get_osc_checksum_type OST0000)
10384                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10385         done
10386         return 0
10387 }
10388 run_test 77l "preferred checksum type is remembered after reconnected"
10389
10390 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10391 rm -f $F77_TMP
10392 unset F77_TMP
10393
10394 test_77m() {
10395         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10396                 skip "Need at least version 2.14.52"
10397         local param=checksum_speed
10398
10399         $LCTL get_param $param || error "reading $param failed"
10400
10401         csum_speeds=$($LCTL get_param -n $param)
10402
10403         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10404                 error "known checksum types are missing"
10405 }
10406 run_test 77m "Verify checksum_speed is correctly read"
10407
10408 check_filefrag_77n() {
10409         local nr_ext=0
10410         local starts=()
10411         local ends=()
10412
10413         while read extidx a b start end rest; do
10414                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10415                         nr_ext=$(( $nr_ext + 1 ))
10416                         starts+=( ${start%..} )
10417                         ends+=( ${end%:} )
10418                 fi
10419         done < <( filefrag -sv $1 )
10420
10421         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10422         return 1
10423 }
10424
10425 test_77n() {
10426         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10427
10428         touch $DIR/$tfile
10429         $TRUNCATE $DIR/$tfile 0
10430         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10431         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10432         check_filefrag_77n $DIR/$tfile ||
10433                 skip "$tfile blocks not contiguous around hole"
10434
10435         set_checksums 1
10436         stack_trap "set_checksums $ORIG_CSUM" EXIT
10437         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10438         stack_trap "rm -f $DIR/$tfile"
10439
10440         for algo in $CKSUM_TYPES; do
10441                 if [[ "$algo" =~ ^t10 ]]; then
10442                         set_checksum_type $algo ||
10443                                 error "fail to set checksum type $algo"
10444                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10445                                 error "fail to read $tfile with $algo"
10446                 fi
10447         done
10448         rm -f $DIR/$tfile
10449         return 0
10450 }
10451 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10452
10453 test_77o() {
10454         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10455                 skip "Need MDS version at least 2.14.55"
10456         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10457                 skip "Need OST version at least 2.14.55"
10458         local ofd=obdfilter
10459         local mdt=mdt
10460
10461         # print OST checksum_type
10462         echo "$ofd.$FSNAME-*.checksum_type:"
10463         do_nodes $(comma_list $(osts_nodes)) \
10464                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10465
10466         # print MDT checksum_type
10467         echo "$mdt.$FSNAME-*.checksum_type:"
10468         do_nodes $(comma_list $(mdts_nodes)) \
10469                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10470
10471         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10472                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10473
10474         (( $o_count == $OSTCOUNT )) ||
10475                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10476
10477         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10478                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10479
10480         (( $m_count == $MDSCOUNT )) ||
10481                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10482 }
10483 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10484
10485 cleanup_test_78() {
10486         trap 0
10487         rm -f $DIR/$tfile
10488 }
10489
10490 test_78() { # bug 10901
10491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10492         remote_ost || skip_env "local OST"
10493
10494         NSEQ=5
10495         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10496         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10497         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10498         echo "MemTotal: $MEMTOTAL"
10499
10500         # reserve 256MB of memory for the kernel and other running processes,
10501         # and then take 1/2 of the remaining memory for the read/write buffers.
10502         if [ $MEMTOTAL -gt 512 ] ;then
10503                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10504         else
10505                 # for those poor memory-starved high-end clusters...
10506                 MEMTOTAL=$((MEMTOTAL / 2))
10507         fi
10508         echo "Mem to use for directio: $MEMTOTAL"
10509
10510         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10511         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10512         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10513         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10514                 head -n1)
10515         echo "Smallest OST: $SMALLESTOST"
10516         [[ $SMALLESTOST -lt 10240 ]] &&
10517                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10518
10519         trap cleanup_test_78 EXIT
10520
10521         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10522                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10523
10524         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10525         echo "File size: $F78SIZE"
10526         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10527         for i in $(seq 1 $NSEQ); do
10528                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10529                 echo directIO rdwr round $i of $NSEQ
10530                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10531         done
10532
10533         cleanup_test_78
10534 }
10535 run_test 78 "handle large O_DIRECT writes correctly ============"
10536
10537 test_79() { # bug 12743
10538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10539
10540         wait_delete_completed
10541
10542         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10543         BKFREE=$(calc_osc_kbytes kbytesfree)
10544         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10545
10546         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10547         DFTOTAL=`echo $STRING | cut -d, -f1`
10548         DFUSED=`echo $STRING  | cut -d, -f2`
10549         DFAVAIL=`echo $STRING | cut -d, -f3`
10550         DFFREE=$(($DFTOTAL - $DFUSED))
10551
10552         ALLOWANCE=$((64 * $OSTCOUNT))
10553
10554         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10555            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10556                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10557         fi
10558         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10559            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10560                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10561         fi
10562         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10563            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10564                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10565         fi
10566 }
10567 run_test 79 "df report consistency check ======================="
10568
10569 test_80() { # bug 10718
10570         remote_ost_nodsh && skip "remote OST with nodsh"
10571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10572
10573         # relax strong synchronous semantics for slow backends like ZFS
10574         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10575                 local soc="obdfilter.*.sync_lock_cancel"
10576                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10577
10578                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10579                 if [ -z "$save" ]; then
10580                         soc="obdfilter.*.sync_on_lock_cancel"
10581                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10582                 fi
10583
10584                 if [ "$save" != "never" ]; then
10585                         local hosts=$(comma_list $(osts_nodes))
10586
10587                         do_nodes $hosts $LCTL set_param $soc=never
10588                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10589                 fi
10590         fi
10591
10592         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10593         sync; sleep 1; sync
10594         local before=$(date +%s)
10595         cancel_lru_locks osc
10596         local after=$(date +%s)
10597         local diff=$((after - before))
10598         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10599
10600         rm -f $DIR/$tfile
10601 }
10602 run_test 80 "Page eviction is equally fast at high offsets too"
10603
10604 test_81a() { # LU-456
10605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10606         remote_ost_nodsh && skip "remote OST with nodsh"
10607
10608         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10609         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10610         do_facet ost1 lctl set_param fail_loc=0x80000228
10611
10612         # write should trigger a retry and success
10613         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10614         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10615         RC=$?
10616         if [ $RC -ne 0 ] ; then
10617                 error "write should success, but failed for $RC"
10618         fi
10619 }
10620 run_test 81a "OST should retry write when get -ENOSPC ==============="
10621
10622 test_81b() { # LU-456
10623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10624         remote_ost_nodsh && skip "remote OST with nodsh"
10625
10626         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10627         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10628         do_facet ost1 lctl set_param fail_loc=0x228
10629
10630         # write should retry several times and return -ENOSPC finally
10631         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10632         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10633         RC=$?
10634         ENOSPC=28
10635         if [ $RC -ne $ENOSPC ] ; then
10636                 error "dd should fail for -ENOSPC, but succeed."
10637         fi
10638 }
10639 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10640
10641 test_99() {
10642         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10643
10644         test_mkdir $DIR/$tdir.cvsroot
10645         chown $RUNAS_ID $DIR/$tdir.cvsroot
10646
10647         cd $TMP
10648         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10649
10650         cd /etc/init.d
10651         # some versions of cvs import exit(1) when asked to import links or
10652         # files they can't read.  ignore those files.
10653         local toignore=$(find . -type l -printf '-I %f\n' -o \
10654                          ! -perm /4 -printf '-I %f\n')
10655         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10656                 $tdir.reposname vtag rtag
10657
10658         cd $DIR
10659         test_mkdir $DIR/$tdir.reposname
10660         chown $RUNAS_ID $DIR/$tdir.reposname
10661         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10662
10663         cd $DIR/$tdir.reposname
10664         $RUNAS touch foo99
10665         $RUNAS cvs add -m 'addmsg' foo99
10666         $RUNAS cvs update
10667         $RUNAS cvs commit -m 'nomsg' foo99
10668         rm -fr $DIR/$tdir.cvsroot
10669 }
10670 run_test 99 "cvs strange file/directory operations"
10671
10672 test_100() {
10673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10674         [[ "$NETTYPE" =~ tcp ]] ||
10675                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10676         remote_ost_nodsh && skip "remote OST with nodsh"
10677         remote_mds_nodsh && skip "remote MDS with nodsh"
10678         remote_servers ||
10679                 skip "useless for local single node setup"
10680
10681         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10682                 [ "$PROT" != "tcp" ] && continue
10683                 RPORT=$(echo $REMOTE | cut -d: -f2)
10684                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10685
10686                 rc=0
10687                 LPORT=`echo $LOCAL | cut -d: -f2`
10688                 if [ $LPORT -ge 1024 ]; then
10689                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10690                         netstat -tna
10691                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10692                 fi
10693         done
10694         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10695 }
10696 run_test 100 "check local port using privileged port ==========="
10697
10698 function get_named_value()
10699 {
10700     local tag=$1
10701
10702     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10703 }
10704
10705 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10706                    awk '/^max_cached_mb/ { print $2 }')
10707
10708 cleanup_101a() {
10709         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10710         trap 0
10711 }
10712
10713 test_101a() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715
10716         local s
10717         local discard
10718         local nreads=10000
10719         local cache_limit=32
10720
10721         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10722         trap cleanup_101a EXIT
10723         $LCTL set_param -n llite.*.read_ahead_stats=0
10724         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10725
10726         #
10727         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10728         #
10729         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10730         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10731
10732         discard=0
10733         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10734                    get_named_value 'read.but.discarded'); do
10735                         discard=$(($discard + $s))
10736         done
10737         cleanup_101a
10738
10739         $LCTL get_param osc.*-osc*.rpc_stats
10740         $LCTL get_param llite.*.read_ahead_stats
10741
10742         # Discard is generally zero, but sometimes a few random reads line up
10743         # and trigger larger readahead, which is wasted & leads to discards.
10744         if [[ $(($discard)) -gt $nreads ]]; then
10745                 error "too many ($discard) discarded pages"
10746         fi
10747         rm -f $DIR/$tfile || true
10748 }
10749 run_test 101a "check read-ahead for random reads"
10750
10751 setup_test101bc() {
10752         test_mkdir $DIR/$tdir
10753         local ssize=$1
10754         local FILE_LENGTH=$2
10755         STRIPE_OFFSET=0
10756
10757         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10758
10759         local list=$(comma_list $(osts_nodes))
10760         set_osd_param $list '' read_cache_enable 0
10761         set_osd_param $list '' writethrough_cache_enable 0
10762
10763         trap cleanup_test101bc EXIT
10764         # prepare the read-ahead file
10765         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10766
10767         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10768                                 count=$FILE_SIZE_MB 2> /dev/null
10769
10770 }
10771
10772 cleanup_test101bc() {
10773         trap 0
10774         rm -rf $DIR/$tdir
10775         rm -f $DIR/$tfile
10776
10777         local list=$(comma_list $(osts_nodes))
10778         set_osd_param $list '' read_cache_enable 1
10779         set_osd_param $list '' writethrough_cache_enable 1
10780 }
10781
10782 calc_total() {
10783         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10784 }
10785
10786 ra_check_101() {
10787         local read_size=$1
10788         local stripe_size=$2
10789         local stride_length=$((stripe_size / read_size))
10790         local stride_width=$((stride_length * OSTCOUNT))
10791         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10792                                 (stride_width - stride_length) ))
10793         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10794                   get_named_value 'read.but.discarded' | calc_total)
10795
10796         if [[ $discard -gt $discard_limit ]]; then
10797                 $LCTL get_param llite.*.read_ahead_stats
10798                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10799         else
10800                 echo "Read-ahead success for size ${read_size}"
10801         fi
10802 }
10803
10804 test_101b() {
10805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10807
10808         local STRIPE_SIZE=1048576
10809         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10810
10811         if [ $SLOW == "yes" ]; then
10812                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10813         else
10814                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10815         fi
10816
10817         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10818
10819         # prepare the read-ahead file
10820         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10821         cancel_lru_locks osc
10822         for BIDX in 2 4 8 16 32 64 128 256
10823         do
10824                 local BSIZE=$((BIDX*4096))
10825                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10826                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10827                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10828                 $LCTL set_param -n llite.*.read_ahead_stats=0
10829                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10830                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10831                 cancel_lru_locks osc
10832                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10833         done
10834         cleanup_test101bc
10835         true
10836 }
10837 run_test 101b "check stride-io mode read-ahead ================="
10838
10839 test_101c() {
10840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10841
10842         local STRIPE_SIZE=1048576
10843         local FILE_LENGTH=$((STRIPE_SIZE*100))
10844         local nreads=10000
10845         local rsize=65536
10846         local osc_rpc_stats
10847
10848         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10849
10850         cancel_lru_locks osc
10851         $LCTL set_param osc.*.rpc_stats=0
10852         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10853         $LCTL get_param osc.*.rpc_stats
10854         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10855                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10856                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10857                 local size
10858
10859                 if [ $lines -le 20 ]; then
10860                         echo "continue debug"
10861                         continue
10862                 fi
10863                 for size in 1 2 4 8; do
10864                         local rpc=$(echo "$stats" |
10865                                     awk '($1 == "'$size':") {print $2; exit; }')
10866                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10867                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10868                 done
10869                 echo "$osc_rpc_stats check passed!"
10870         done
10871         cleanup_test101bc
10872         true
10873 }
10874 run_test 101c "check stripe_size aligned read-ahead"
10875
10876 test_101d() {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878
10879         local file=$DIR/$tfile
10880         local sz_MB=${FILESIZE_101d:-80}
10881         local ra_MB=${READAHEAD_MB:-40}
10882
10883         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10884         [ $free_MB -lt $sz_MB ] &&
10885                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10886
10887         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10888         $LFS setstripe -c -1 $file || error "setstripe failed"
10889
10890         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10891         echo Cancel LRU locks on lustre client to flush the client cache
10892         cancel_lru_locks osc
10893
10894         echo Disable read-ahead
10895         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10896         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10897         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10898         $LCTL get_param -n llite.*.max_read_ahead_mb
10899
10900         echo "Reading the test file $file with read-ahead disabled"
10901         local sz_KB=$((sz_MB * 1024 / 4))
10902         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10903         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10904         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10905                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10906
10907         echo "Cancel LRU locks on lustre client to flush the client cache"
10908         cancel_lru_locks osc
10909         echo Enable read-ahead with ${ra_MB}MB
10910         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10911
10912         echo "Reading the test file $file with read-ahead enabled"
10913         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10914                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10915
10916         echo "read-ahead disabled time read $raOFF"
10917         echo "read-ahead enabled time read $raON"
10918
10919         rm -f $file
10920         wait_delete_completed
10921
10922         # use awk for this check instead of bash because it handles decimals
10923         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10924                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10925 }
10926 run_test 101d "file read with and without read-ahead enabled"
10927
10928 test_101e() {
10929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10930
10931         local file=$DIR/$tfile
10932         local size_KB=500  #KB
10933         local count=100
10934         local bsize=1024
10935
10936         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10937         local need_KB=$((count * size_KB))
10938         [[ $free_KB -le $need_KB ]] &&
10939                 skip_env "Need free space $need_KB, have $free_KB"
10940
10941         echo "Creating $count ${size_KB}K test files"
10942         for ((i = 0; i < $count; i++)); do
10943                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10944         done
10945
10946         echo "Cancel LRU locks on lustre client to flush the client cache"
10947         cancel_lru_locks $OSC
10948
10949         echo "Reset readahead stats"
10950         $LCTL set_param -n llite.*.read_ahead_stats=0
10951
10952         for ((i = 0; i < $count; i++)); do
10953                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10954         done
10955
10956         $LCTL get_param llite.*.max_cached_mb
10957         $LCTL get_param llite.*.read_ahead_stats
10958         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10959                      get_named_value 'misses' | calc_total)
10960
10961         for ((i = 0; i < $count; i++)); do
10962                 rm -rf $file.$i 2>/dev/null
10963         done
10964
10965         #10000 means 20% reads are missing in readahead
10966         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10967 }
10968 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10969
10970 test_101f() {
10971         which iozone || skip_env "no iozone installed"
10972
10973         local old_debug=$($LCTL get_param debug)
10974         old_debug=${old_debug#*=}
10975         $LCTL set_param debug="reada mmap"
10976
10977         # create a test file
10978         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10979
10980         echo Cancel LRU locks on lustre client to flush the client cache
10981         cancel_lru_locks osc
10982
10983         echo Reset readahead stats
10984         $LCTL set_param -n llite.*.read_ahead_stats=0
10985
10986         echo mmap read the file with small block size
10987         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10988                 > /dev/null 2>&1
10989
10990         echo checking missing pages
10991         $LCTL get_param llite.*.read_ahead_stats
10992         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10993                         get_named_value 'misses' | calc_total)
10994
10995         $LCTL set_param debug="$old_debug"
10996         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10997         rm -f $DIR/$tfile
10998 }
10999 run_test 101f "check mmap read performance"
11000
11001 test_101g_brw_size_test() {
11002         local mb=$1
11003         local pages=$((mb * 1048576 / PAGE_SIZE))
11004         local file=$DIR/$tfile
11005
11006         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11007                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11008         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11009                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11010                         return 2
11011         done
11012
11013         stack_trap "rm -f $file" EXIT
11014         $LCTL set_param -n osc.*.rpc_stats=0
11015
11016         # 10 RPCs should be enough for the test
11017         local count=10
11018         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11019                 { error "dd write ${mb} MB blocks failed"; return 3; }
11020         cancel_lru_locks osc
11021         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11022                 { error "dd write ${mb} MB blocks failed"; return 4; }
11023
11024         # calculate number of full-sized read and write RPCs
11025         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11026                 sed -n '/pages per rpc/,/^$/p' |
11027                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11028                 END { print reads,writes }'))
11029         # allow one extra full-sized read RPC for async readahead
11030         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11031                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11032         [[ ${rpcs[1]} == $count ]] ||
11033                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11034 }
11035
11036 test_101g() {
11037         remote_ost_nodsh && skip "remote OST with nodsh"
11038
11039         local rpcs
11040         local osts=$(get_facets OST)
11041         local list=$(comma_list $(osts_nodes))
11042         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11043         local brw_size="obdfilter.*.brw_size"
11044
11045         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11046
11047         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11048
11049         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11050                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11051                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11052            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11053                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11054                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11055
11056                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11057                         suffix="M"
11058
11059                 if [[ $orig_mb -lt 16 ]]; then
11060                         save_lustre_params $osts "$brw_size" > $p
11061                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11062                                 error "set 16MB RPC size failed"
11063
11064                         echo "remount client to enable new RPC size"
11065                         remount_client $MOUNT || error "remount_client failed"
11066                 fi
11067
11068                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11069                 # should be able to set brw_size=12, but no rpc_stats for that
11070                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11071         fi
11072
11073         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11074
11075         if [[ $orig_mb -lt 16 ]]; then
11076                 restore_lustre_params < $p
11077                 remount_client $MOUNT || error "remount_client restore failed"
11078         fi
11079
11080         rm -f $p $DIR/$tfile
11081 }
11082 run_test 101g "Big bulk(4/16 MiB) readahead"
11083
11084 test_101h() {
11085         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11086
11087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11088                 error "dd 70M file failed"
11089         echo Cancel LRU locks on lustre client to flush the client cache
11090         cancel_lru_locks osc
11091
11092         echo "Reset readahead stats"
11093         $LCTL set_param -n llite.*.read_ahead_stats 0
11094
11095         echo "Read 10M of data but cross 64M bundary"
11096         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11097         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11098                      get_named_value 'misses' | calc_total)
11099         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11100         rm -f $p $DIR/$tfile
11101 }
11102 run_test 101h "Readahead should cover current read window"
11103
11104 test_101i() {
11105         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11106                 error "dd 10M file failed"
11107
11108         local max_per_file_mb=$($LCTL get_param -n \
11109                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11110         cancel_lru_locks osc
11111         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11112         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11113                 error "set max_read_ahead_per_file_mb to 1 failed"
11114
11115         echo "Reset readahead stats"
11116         $LCTL set_param llite.*.read_ahead_stats=0
11117
11118         dd if=$DIR/$tfile of=/dev/null bs=2M
11119
11120         $LCTL get_param llite.*.read_ahead_stats
11121         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11122                      awk '/misses/ { print $2 }')
11123         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11124         rm -f $DIR/$tfile
11125 }
11126 run_test 101i "allow current readahead to exceed reservation"
11127
11128 test_101j() {
11129         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11130                 error "setstripe $DIR/$tfile failed"
11131         local file_size=$((1048576 * 16))
11132         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11133         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11134
11135         echo Disable read-ahead
11136         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11137
11138         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11139         for blk in $PAGE_SIZE 1048576 $file_size; do
11140                 cancel_lru_locks osc
11141                 echo "Reset readahead stats"
11142                 $LCTL set_param -n llite.*.read_ahead_stats=0
11143                 local count=$(($file_size / $blk))
11144                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11145                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11146                              get_named_value 'failed.to.fast.read' | calc_total)
11147                 $LCTL get_param -n llite.*.read_ahead_stats
11148                 [ $miss -eq $count ] || error "expected $count got $miss"
11149         done
11150
11151         rm -f $p $DIR/$tfile
11152 }
11153 run_test 101j "A complete read block should be submitted when no RA"
11154
11155 setup_test102() {
11156         test_mkdir $DIR/$tdir
11157         chown $RUNAS_ID $DIR/$tdir
11158         STRIPE_SIZE=65536
11159         STRIPE_OFFSET=1
11160         STRIPE_COUNT=$OSTCOUNT
11161         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11162
11163         trap cleanup_test102 EXIT
11164         cd $DIR
11165         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11166         cd $DIR/$tdir
11167         for num in 1 2 3 4; do
11168                 for count in $(seq 1 $STRIPE_COUNT); do
11169                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11170                                 local size=`expr $STRIPE_SIZE \* $num`
11171                                 local file=file"$num-$idx-$count"
11172                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11173                         done
11174                 done
11175         done
11176
11177         cd $DIR
11178         $1 tar cf $TMP/f102.tar $tdir --xattrs
11179 }
11180
11181 cleanup_test102() {
11182         trap 0
11183         rm -f $TMP/f102.tar
11184         rm -rf $DIR/d0.sanity/d102
11185 }
11186
11187 test_102a() {
11188         [ "$UID" != 0 ] && skip "must run as root"
11189         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11190                 skip_env "must have user_xattr"
11191
11192         [ -z "$(which setfattr 2>/dev/null)" ] &&
11193                 skip_env "could not find setfattr"
11194
11195         local testfile=$DIR/$tfile
11196
11197         touch $testfile
11198         echo "set/get xattr..."
11199         setfattr -n trusted.name1 -v value1 $testfile ||
11200                 error "setfattr -n trusted.name1=value1 $testfile failed"
11201         getfattr -n trusted.name1 $testfile 2> /dev/null |
11202           grep "trusted.name1=.value1" ||
11203                 error "$testfile missing trusted.name1=value1"
11204
11205         setfattr -n user.author1 -v author1 $testfile ||
11206                 error "setfattr -n user.author1=author1 $testfile failed"
11207         getfattr -n user.author1 $testfile 2> /dev/null |
11208           grep "user.author1=.author1" ||
11209                 error "$testfile missing trusted.author1=author1"
11210
11211         echo "listxattr..."
11212         setfattr -n trusted.name2 -v value2 $testfile ||
11213                 error "$testfile unable to set trusted.name2"
11214         setfattr -n trusted.name3 -v value3 $testfile ||
11215                 error "$testfile unable to set trusted.name3"
11216         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11217             grep "trusted.name" | wc -l) -eq 3 ] ||
11218                 error "$testfile missing 3 trusted.name xattrs"
11219
11220         setfattr -n user.author2 -v author2 $testfile ||
11221                 error "$testfile unable to set user.author2"
11222         setfattr -n user.author3 -v author3 $testfile ||
11223                 error "$testfile unable to set user.author3"
11224         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11225             grep "user.author" | wc -l) -eq 3 ] ||
11226                 error "$testfile missing 3 user.author xattrs"
11227
11228         echo "remove xattr..."
11229         setfattr -x trusted.name1 $testfile ||
11230                 error "$testfile error deleting trusted.name1"
11231         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11232                 error "$testfile did not delete trusted.name1 xattr"
11233
11234         setfattr -x user.author1 $testfile ||
11235                 error "$testfile error deleting user.author1"
11236         echo "set lustre special xattr ..."
11237         $LFS setstripe -c1 $testfile
11238         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11239                 awk -F "=" '/trusted.lov/ { print $2 }' )
11240         setfattr -n "trusted.lov" -v $lovea $testfile ||
11241                 error "$testfile doesn't ignore setting trusted.lov again"
11242         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11243                 error "$testfile allow setting invalid trusted.lov"
11244         rm -f $testfile
11245 }
11246 run_test 102a "user xattr test =================================="
11247
11248 check_102b_layout() {
11249         local layout="$*"
11250         local testfile=$DIR/$tfile
11251
11252         echo "test layout '$layout'"
11253         $LFS setstripe $layout $testfile || error "setstripe failed"
11254         $LFS getstripe -y $testfile
11255
11256         echo "get/set/list trusted.lov xattr ..." # b=10930
11257         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11258         [[ "$value" =~ "trusted.lov" ]] ||
11259                 error "can't get trusted.lov from $testfile"
11260         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11261                 error "getstripe failed"
11262
11263         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11264
11265         value=$(cut -d= -f2 <<<$value)
11266         # LU-13168: truncated xattr should fail if short lov_user_md header
11267         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11268                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11269         for len in $lens; do
11270                 echo "setfattr $len $testfile.2"
11271                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11272                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11273         done
11274         local stripe_size=$($LFS getstripe -S $testfile.2)
11275         local stripe_count=$($LFS getstripe -c $testfile.2)
11276         [[ $stripe_size -eq 65536 ]] ||
11277                 error "stripe size $stripe_size != 65536"
11278         [[ $stripe_count -eq $stripe_count_orig ]] ||
11279                 error "stripe count $stripe_count != $stripe_count_orig"
11280         rm $testfile $testfile.2
11281 }
11282
11283 test_102b() {
11284         [ -z "$(which setfattr 2>/dev/null)" ] &&
11285                 skip_env "could not find setfattr"
11286         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11287
11288         # check plain layout
11289         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11290
11291         # and also check composite layout
11292         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11293
11294 }
11295 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11296
11297 test_102c() {
11298         [ -z "$(which setfattr 2>/dev/null)" ] &&
11299                 skip_env "could not find setfattr"
11300         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11301
11302         # b10930: get/set/list lustre.lov xattr
11303         echo "get/set/list lustre.lov xattr ..."
11304         test_mkdir $DIR/$tdir
11305         chown $RUNAS_ID $DIR/$tdir
11306         local testfile=$DIR/$tdir/$tfile
11307         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11308                 error "setstripe failed"
11309         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11310                 error "getstripe failed"
11311         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11312         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11313
11314         local testfile2=${testfile}2
11315         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11316                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11317
11318         $RUNAS $MCREATE $testfile2
11319         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11320         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11321         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11322         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11323         [ $stripe_count -eq $STRIPECOUNT ] ||
11324                 error "stripe count $stripe_count != $STRIPECOUNT"
11325 }
11326 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11327
11328 compare_stripe_info1() {
11329         local stripe_index_all_zero=true
11330
11331         for num in 1 2 3 4; do
11332                 for count in $(seq 1 $STRIPE_COUNT); do
11333                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11334                                 local size=$((STRIPE_SIZE * num))
11335                                 local file=file"$num-$offset-$count"
11336                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11337                                 [[ $stripe_size -ne $size ]] &&
11338                                     error "$file: size $stripe_size != $size"
11339                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11340                                 # allow fewer stripes to be created, ORI-601
11341                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11342                                     error "$file: count $stripe_count != $count"
11343                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11344                                 [[ $stripe_index -ne 0 ]] &&
11345                                         stripe_index_all_zero=false
11346                         done
11347                 done
11348         done
11349         $stripe_index_all_zero &&
11350                 error "all files are being extracted starting from OST index 0"
11351         return 0
11352 }
11353
11354 have_xattrs_include() {
11355         tar --help | grep -q xattrs-include &&
11356                 echo --xattrs-include="lustre.*"
11357 }
11358
11359 test_102d() {
11360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11361         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11362
11363         XINC=$(have_xattrs_include)
11364         setup_test102
11365         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11366         cd $DIR/$tdir/$tdir
11367         compare_stripe_info1
11368 }
11369 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11370
11371 test_102f() {
11372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11373         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11374
11375         XINC=$(have_xattrs_include)
11376         setup_test102
11377         test_mkdir $DIR/$tdir.restore
11378         cd $DIR
11379         tar cf - --xattrs $tdir | tar xf - \
11380                 -C $DIR/$tdir.restore --xattrs $XINC
11381         cd $DIR/$tdir.restore/$tdir
11382         compare_stripe_info1
11383 }
11384 run_test 102f "tar copy files, not keep osts"
11385
11386 grow_xattr() {
11387         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11388                 skip "must have user_xattr"
11389         [ -z "$(which setfattr 2>/dev/null)" ] &&
11390                 skip_env "could not find setfattr"
11391         [ -z "$(which getfattr 2>/dev/null)" ] &&
11392                 skip_env "could not find getfattr"
11393
11394         local xsize=${1:-1024}  # in bytes
11395         local file=$DIR/$tfile
11396         local value="$(generate_string $xsize)"
11397         local xbig=trusted.big
11398         local toobig=$2
11399
11400         touch $file
11401         log "save $xbig on $file"
11402         if [ -z "$toobig" ]
11403         then
11404                 setfattr -n $xbig -v $value $file ||
11405                         error "saving $xbig on $file failed"
11406         else
11407                 setfattr -n $xbig -v $value $file &&
11408                         error "saving $xbig on $file succeeded"
11409                 return 0
11410         fi
11411
11412         local orig=$(get_xattr_value $xbig $file)
11413         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11414
11415         local xsml=trusted.sml
11416         log "save $xsml on $file"
11417         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11418
11419         local new=$(get_xattr_value $xbig $file)
11420         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11421
11422         log "grow $xsml on $file"
11423         setfattr -n $xsml -v "$value" $file ||
11424                 error "growing $xsml on $file failed"
11425
11426         new=$(get_xattr_value $xbig $file)
11427         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11428         log "$xbig still valid after growing $xsml"
11429
11430         rm -f $file
11431 }
11432
11433 test_102h() { # bug 15777
11434         grow_xattr 1024
11435 }
11436 run_test 102h "grow xattr from inside inode to external block"
11437
11438 test_102ha() {
11439         large_xattr_enabled || skip_env "ea_inode feature disabled"
11440
11441         echo "setting xattr of max xattr size: $(max_xattr_size)"
11442         grow_xattr $(max_xattr_size)
11443
11444         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11445         echo "This should fail:"
11446         grow_xattr $(($(max_xattr_size) + 10)) 1
11447 }
11448 run_test 102ha "grow xattr from inside inode to external inode"
11449
11450 test_102i() { # bug 17038
11451         [ -z "$(which getfattr 2>/dev/null)" ] &&
11452                 skip "could not find getfattr"
11453
11454         touch $DIR/$tfile
11455         ln -s $DIR/$tfile $DIR/${tfile}link
11456         getfattr -n trusted.lov $DIR/$tfile ||
11457                 error "lgetxattr on $DIR/$tfile failed"
11458         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11459                 grep -i "no such attr" ||
11460                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11461         rm -f $DIR/$tfile $DIR/${tfile}link
11462 }
11463 run_test 102i "lgetxattr test on symbolic link ============"
11464
11465 test_102j() {
11466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11467         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11468
11469         XINC=$(have_xattrs_include)
11470         setup_test102 "$RUNAS"
11471         chown $RUNAS_ID $DIR/$tdir
11472         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11473         cd $DIR/$tdir/$tdir
11474         compare_stripe_info1 "$RUNAS"
11475 }
11476 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11477
11478 test_102k() {
11479         [ -z "$(which setfattr 2>/dev/null)" ] &&
11480                 skip "could not find setfattr"
11481
11482         touch $DIR/$tfile
11483         # b22187 just check that does not crash for regular file.
11484         setfattr -n trusted.lov $DIR/$tfile
11485         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11486         local test_kdir=$DIR/$tdir
11487         test_mkdir $test_kdir
11488         local default_size=$($LFS getstripe -S $test_kdir)
11489         local default_count=$($LFS getstripe -c $test_kdir)
11490         local default_offset=$($LFS getstripe -i $test_kdir)
11491         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11492                 error 'dir setstripe failed'
11493         setfattr -n trusted.lov $test_kdir
11494         local stripe_size=$($LFS getstripe -S $test_kdir)
11495         local stripe_count=$($LFS getstripe -c $test_kdir)
11496         local stripe_offset=$($LFS getstripe -i $test_kdir)
11497         [ $stripe_size -eq $default_size ] ||
11498                 error "stripe size $stripe_size != $default_size"
11499         [ $stripe_count -eq $default_count ] ||
11500                 error "stripe count $stripe_count != $default_count"
11501         [ $stripe_offset -eq $default_offset ] ||
11502                 error "stripe offset $stripe_offset != $default_offset"
11503         rm -rf $DIR/$tfile $test_kdir
11504 }
11505 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11506
11507 test_102l() {
11508         [ -z "$(which getfattr 2>/dev/null)" ] &&
11509                 skip "could not find getfattr"
11510
11511         # LU-532 trusted. xattr is invisible to non-root
11512         local testfile=$DIR/$tfile
11513
11514         touch $testfile
11515
11516         echo "listxattr as user..."
11517         chown $RUNAS_ID $testfile
11518         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11519             grep -q "trusted" &&
11520                 error "$testfile trusted xattrs are user visible"
11521
11522         return 0;
11523 }
11524 run_test 102l "listxattr size test =================================="
11525
11526 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11527         local path=$DIR/$tfile
11528         touch $path
11529
11530         listxattr_size_check $path || error "listattr_size_check $path failed"
11531 }
11532 run_test 102m "Ensure listxattr fails on small bufffer ========"
11533
11534 cleanup_test102
11535
11536 getxattr() { # getxattr path name
11537         # Return the base64 encoding of the value of xattr name on path.
11538         local path=$1
11539         local name=$2
11540
11541         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11542         # file: $path
11543         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11544         #
11545         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11546
11547         getfattr --absolute-names --encoding=base64 --name=$name $path |
11548                 awk -F= -v name=$name '$1 == name {
11549                         print substr($0, index($0, "=") + 1);
11550         }'
11551 }
11552
11553 test_102n() { # LU-4101 mdt: protect internal xattrs
11554         [ -z "$(which setfattr 2>/dev/null)" ] &&
11555                 skip "could not find setfattr"
11556         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11557         then
11558                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11559         fi
11560
11561         local file0=$DIR/$tfile.0
11562         local file1=$DIR/$tfile.1
11563         local xattr0=$TMP/$tfile.0
11564         local xattr1=$TMP/$tfile.1
11565         local namelist="lov lma lmv link fid version som hsm"
11566         local name
11567         local value
11568
11569         rm -rf $file0 $file1 $xattr0 $xattr1
11570         touch $file0 $file1
11571
11572         # Get 'before' xattrs of $file1.
11573         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11574
11575         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11576                 namelist+=" lfsck_namespace"
11577         for name in $namelist; do
11578                 # Try to copy xattr from $file0 to $file1.
11579                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11580
11581                 setfattr --name=trusted.$name --value="$value" $file1 ||
11582                         error "setxattr 'trusted.$name' failed"
11583
11584                 # Try to set a garbage xattr.
11585                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11586
11587                 if [[ x$name == "xlov" ]]; then
11588                         setfattr --name=trusted.lov --value="$value" $file1 &&
11589                         error "setxattr invalid 'trusted.lov' success"
11590                 else
11591                         setfattr --name=trusted.$name --value="$value" $file1 ||
11592                                 error "setxattr invalid 'trusted.$name' failed"
11593                 fi
11594
11595                 # Try to remove the xattr from $file1. We don't care if this
11596                 # appears to succeed or fail, we just don't want there to be
11597                 # any changes or crashes.
11598                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11599         done
11600
11601         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11602         then
11603                 name="lfsck_ns"
11604                 # Try to copy xattr from $file0 to $file1.
11605                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11606
11607                 setfattr --name=trusted.$name --value="$value" $file1 ||
11608                         error "setxattr 'trusted.$name' failed"
11609
11610                 # Try to set a garbage xattr.
11611                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11612
11613                 setfattr --name=trusted.$name --value="$value" $file1 ||
11614                         error "setxattr 'trusted.$name' failed"
11615
11616                 # Try to remove the xattr from $file1. We don't care if this
11617                 # appears to succeed or fail, we just don't want there to be
11618                 # any changes or crashes.
11619                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11620         fi
11621
11622         # Get 'after' xattrs of file1.
11623         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11624
11625         if ! diff $xattr0 $xattr1; then
11626                 error "before and after xattrs of '$file1' differ"
11627         fi
11628
11629         rm -rf $file0 $file1 $xattr0 $xattr1
11630
11631         return 0
11632 }
11633 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11634
11635 test_102p() { # LU-4703 setxattr did not check ownership
11636         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11637                 skip "MDS needs to be at least 2.5.56"
11638
11639         local testfile=$DIR/$tfile
11640
11641         touch $testfile
11642
11643         echo "setfacl as user..."
11644         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11645         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11646
11647         echo "setfattr as user..."
11648         setfacl -m "u:$RUNAS_ID:---" $testfile
11649         $RUNAS setfattr -x system.posix_acl_access $testfile
11650         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11651 }
11652 run_test 102p "check setxattr(2) correctly fails without permission"
11653
11654 test_102q() {
11655         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11656                 skip "MDS needs to be at least 2.6.92"
11657
11658         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11659 }
11660 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11661
11662 test_102r() {
11663         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11664                 skip "MDS needs to be at least 2.6.93"
11665
11666         touch $DIR/$tfile || error "touch"
11667         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11668         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11669         rm $DIR/$tfile || error "rm"
11670
11671         #normal directory
11672         mkdir -p $DIR/$tdir || error "mkdir"
11673         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11674         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11675         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11676                 error "$testfile error deleting user.author1"
11677         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11678                 grep "user.$(basename $tdir)" &&
11679                 error "$tdir did not delete user.$(basename $tdir)"
11680         rmdir $DIR/$tdir || error "rmdir"
11681
11682         #striped directory
11683         test_mkdir $DIR/$tdir
11684         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11685         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11686         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11687                 error "$testfile error deleting user.author1"
11688         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11689                 grep "user.$(basename $tdir)" &&
11690                 error "$tdir did not delete user.$(basename $tdir)"
11691         rmdir $DIR/$tdir || error "rm striped dir"
11692 }
11693 run_test 102r "set EAs with empty values"
11694
11695 test_102s() {
11696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11697                 skip "MDS needs to be at least 2.11.52"
11698
11699         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11700
11701         save_lustre_params client "llite.*.xattr_cache" > $save
11702
11703         for cache in 0 1; do
11704                 lctl set_param llite.*.xattr_cache=$cache
11705
11706                 rm -f $DIR/$tfile
11707                 touch $DIR/$tfile || error "touch"
11708                 for prefix in lustre security system trusted user; do
11709                         # Note getxattr() may fail with 'Operation not
11710                         # supported' or 'No such attribute' depending
11711                         # on prefix and cache.
11712                         getfattr -n $prefix.n102s $DIR/$tfile &&
11713                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11714                 done
11715         done
11716
11717         restore_lustre_params < $save
11718 }
11719 run_test 102s "getting nonexistent xattrs should fail"
11720
11721 test_102t() {
11722         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11723                 skip "MDS needs to be at least 2.11.52"
11724
11725         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11726
11727         save_lustre_params client "llite.*.xattr_cache" > $save
11728
11729         for cache in 0 1; do
11730                 lctl set_param llite.*.xattr_cache=$cache
11731
11732                 for buf_size in 0 256; do
11733                         rm -f $DIR/$tfile
11734                         touch $DIR/$tfile || error "touch"
11735                         setfattr -n user.multiop $DIR/$tfile
11736                         $MULTIOP $DIR/$tfile oa$buf_size ||
11737                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11738                 done
11739         done
11740
11741         restore_lustre_params < $save
11742 }
11743 run_test 102t "zero length xattr values handled correctly"
11744
11745 run_acl_subtest()
11746 {
11747         local test=$LUSTRE/tests/acl/$1.test
11748         local tmp=$(mktemp -t $1-XXXXXX).test
11749         local bin=$2
11750         local dmn=$3
11751         local grp=$4
11752         local nbd=$5
11753         export LANG=C
11754
11755
11756         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11757         local sedgroups="-e s/:users/:$grp/g"
11758         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11759
11760         sed $sedusers $sedgroups < $test > $tmp
11761         stack_trap "rm -f $tmp"
11762         [[ -s $tmp ]] || error "sed failed to create test script"
11763
11764         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11765         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11766 }
11767
11768 test_103a() {
11769         [ "$UID" != 0 ] && skip "must run as root"
11770         $GSS && skip_env "could not run under gss"
11771         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11772                 skip_env "must have acl enabled"
11773         which setfacl || skip_env "could not find setfacl"
11774         remote_mds_nodsh && skip "remote MDS with nodsh"
11775
11776         ACLBIN=${ACLBIN:-"bin"}
11777         ACLDMN=${ACLDMN:-"daemon"}
11778         ACLGRP=${ACLGRP:-"users"}
11779         ACLNBD=${ACLNBD:-"nobody"}
11780
11781         if ! id $ACLBIN ||
11782            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11783                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11784                 ACLBIN=$USER0
11785                 if ! id $ACLBIN ; then
11786                         cat /etc/passwd
11787                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11788                 fi
11789         fi
11790         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11791            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11792                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11793                 ACLDMN=$USER1
11794                 if ! id $ACLDMN ; then
11795                         cat /etc/passwd
11796                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11797                 fi
11798         fi
11799         if ! getent group $ACLGRP; then
11800                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11801                 ACLGRP="$TSTUSR"
11802                 if ! getent group $ACLGRP; then
11803                         echo "cannot find group '$ACLGRP', adding it"
11804                         cat /etc/group
11805                         add_group 60000 $ACLGRP
11806                 fi
11807         fi
11808
11809         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11810         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11811         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11812
11813         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11814                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11815                 ACLGRP="$TSTUSR"
11816                 if ! getent group $ACLGRP; then
11817                         echo "cannot find group '$ACLGRP', adding it"
11818                         cat /etc/group
11819                         add_group 60000 $ACLGRP
11820                 fi
11821                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11822                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11823                         cat /etc/group
11824                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11825                 fi
11826         fi
11827
11828         gpasswd -a $ACLDMN $ACLBIN ||
11829                 error "setting client group failed"             # LU-5641
11830         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11831                 error "setting MDS group failed"                # LU-5641
11832
11833         declare -a identity_old
11834
11835         for num in $(seq $MDSCOUNT); do
11836                 switch_identity $num true || identity_old[$num]=$?
11837         done
11838
11839         SAVE_UMASK=$(umask)
11840         umask 0022
11841         mkdir -p $DIR/$tdir
11842         cd $DIR/$tdir
11843
11844         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11845         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11846         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11847         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11848         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11849         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11850         if ! id -u $ACLNBD ||
11851            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11852                 ACLNBD="nfsnobody"
11853                 if ! id -u $ACLNBD; then
11854                         ACLNBD=""
11855                 fi
11856         fi
11857         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11858                 add_group $(id -u $ACLNBD) $ACLNBD
11859                 if ! getent group $ACLNBD; then
11860                         ACLNBD=""
11861                 fi
11862         fi
11863         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11864            [[ -n "$ACLNBD" ]] && which setfattr; then
11865                 run_acl_subtest permissions_xattr \
11866                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11867         elif [[ -z "$ACLNBD" ]]; then
11868                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11869         else
11870                 echo "skip 'permission_xattr' test - missing setfattr command"
11871         fi
11872         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11873
11874         # inheritance test got from HP
11875         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11876         chmod +x make-tree || error "chmod +x failed"
11877         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11878         rm -f make-tree
11879
11880         echo "LU-974 ignore umask when acl is enabled..."
11881         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11882         if [ $MDSCOUNT -ge 2 ]; then
11883                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11884         fi
11885
11886         echo "LU-2561 newly created file is same size as directory..."
11887         if [ "$mds1_FSTYPE" != "zfs" ]; then
11888                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11889         else
11890                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11891         fi
11892
11893         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11894
11895         cd $SAVE_PWD
11896         umask $SAVE_UMASK
11897
11898         for num in $(seq $MDSCOUNT); do
11899                 if [ "${identity_old[$num]}" = 1 ]; then
11900                         switch_identity $num false || identity_old[$num]=$?
11901                 fi
11902         done
11903 }
11904 run_test 103a "acl test"
11905
11906 test_103b() {
11907         declare -a pids
11908         local U
11909
11910         for U in {0..511}; do
11911                 {
11912                 local O=$(printf "%04o" $U)
11913
11914                 umask $(printf "%04o" $((511 ^ $O)))
11915                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11916                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11917
11918                 (( $S == ($O & 0666) )) ||
11919                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11920
11921                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11922                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11923                 (( $S == ($O & 0666) )) ||
11924                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11925
11926                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11927                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11928                 (( $S == ($O & 0666) )) ||
11929                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11930                 rm -f $DIR/$tfile.[smp]$0
11931                 } &
11932                 local pid=$!
11933
11934                 # limit the concurrently running threads to 64. LU-11878
11935                 local idx=$((U % 64))
11936                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11937                 pids[idx]=$pid
11938         done
11939         wait
11940 }
11941 run_test 103b "umask lfs setstripe"
11942
11943 test_103c() {
11944         mkdir -p $DIR/$tdir
11945         cp -rp $DIR/$tdir $DIR/$tdir.bak
11946
11947         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11948                 error "$DIR/$tdir shouldn't contain default ACL"
11949         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11950                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11951         true
11952 }
11953 run_test 103c "'cp -rp' won't set empty acl"
11954
11955 test_103e() {
11956         local numacl
11957         local fileacl
11958         local saved_debug=$($LCTL get_param -n debug)
11959
11960         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11961                 skip "MDS needs to be at least 2.14.52"
11962
11963         large_xattr_enabled || skip_env "ea_inode feature disabled"
11964
11965         mkdir -p $DIR/$tdir
11966         # add big LOV EA to cause reply buffer overflow earlier
11967         $LFS setstripe -C 1000 $DIR/$tdir
11968         lctl set_param mdc.*-mdc*.stats=clear
11969
11970         $LCTL set_param debug=0
11971         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11972         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11973
11974         # add a large number of default ACLs (expect 8000+ for 2.13+)
11975         for U in {2..7000}; do
11976                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11977                         error "Able to add just $U default ACLs"
11978         done
11979         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11980         echo "$numacl default ACLs created"
11981
11982         stat $DIR/$tdir || error "Cannot stat directory"
11983         # check file creation
11984         touch $DIR/$tdir/$tfile ||
11985                 error "failed to create $tfile with $numacl default ACLs"
11986         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11987         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11988         echo "$fileacl ACLs were inherited"
11989         (( $fileacl == $numacl )) ||
11990                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11991         # check that new ACLs creation adds new ACLs to inherited ACLs
11992         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11993                 error "Cannot set new ACL"
11994         numacl=$((numacl + 1))
11995         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11996         (( $fileacl == $numacl )) ||
11997                 error "failed to add new ACL: $fileacl != $numacl as expected"
11998         # adds more ACLs to a file to reach their maximum at 8000+
11999         numacl=0
12000         for U in {20000..25000}; do
12001                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12002                 numacl=$((numacl + 1))
12003         done
12004         echo "Added $numacl more ACLs to the file"
12005         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12006         echo "Total $fileacl ACLs in file"
12007         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12008         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12009         rmdir $DIR/$tdir || error "Cannot remove directory"
12010 }
12011 run_test 103e "inheritance of big amount of default ACLs"
12012
12013 test_103f() {
12014         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12015                 skip "MDS needs to be at least 2.14.51"
12016
12017         large_xattr_enabled || skip_env "ea_inode feature disabled"
12018
12019         # enable changelog to consume more internal MDD buffers
12020         changelog_register
12021
12022         mkdir -p $DIR/$tdir
12023         # add big LOV EA
12024         $LFS setstripe -C 1000 $DIR/$tdir
12025         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12026         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12027         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12028         rmdir $DIR/$tdir || error "Cannot remove directory"
12029 }
12030 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12031
12032 test_104a() {
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034
12035         touch $DIR/$tfile
12036         lfs df || error "lfs df failed"
12037         lfs df -ih || error "lfs df -ih failed"
12038         lfs df -h $DIR || error "lfs df -h $DIR failed"
12039         lfs df -i $DIR || error "lfs df -i $DIR failed"
12040         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12041         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12042
12043         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12044         lctl --device %$OSC deactivate
12045         lfs df || error "lfs df with deactivated OSC failed"
12046         lctl --device %$OSC activate
12047         # wait the osc back to normal
12048         wait_osc_import_ready client ost
12049
12050         lfs df || error "lfs df with reactivated OSC failed"
12051         rm -f $DIR/$tfile
12052 }
12053 run_test 104a "lfs df [-ih] [path] test ========================="
12054
12055 test_104b() {
12056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12057         [ $RUNAS_ID -eq $UID ] &&
12058                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12059
12060         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12061                         grep "Permission denied" | wc -l)))
12062         if [ $denied_cnt -ne 0 ]; then
12063                 error "lfs check servers test failed"
12064         fi
12065 }
12066 run_test 104b "$RUNAS lfs check servers test ===================="
12067
12068 #
12069 # Verify $1 is within range of $2.
12070 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12071 # $1 is <= 2% of $2. Else Fail.
12072 #
12073 value_in_range() {
12074         # Strip all units (M, G, T)
12075         actual=$(echo $1 | tr -d A-Z)
12076         expect=$(echo $2 | tr -d A-Z)
12077
12078         expect_lo=$(($expect * 98 / 100)) # 2% below
12079         expect_hi=$(($expect * 102 / 100)) # 2% above
12080
12081         # permit 2% drift above and below
12082         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12083 }
12084
12085 test_104c() {
12086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12087         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12088
12089         local ost_param="osd-zfs.$FSNAME-OST0000."
12090         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12091         local ofacets=$(get_facets OST)
12092         local mfacets=$(get_facets MDS)
12093         local saved_ost_blocks=
12094         local saved_mdt_blocks=
12095
12096         echo "Before recordsize change"
12097         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12098         df=($(df -h | grep "$MOUNT"$))
12099
12100         # For checking.
12101         echo "lfs output : ${lfs_df[*]}"
12102         echo "df  output : ${df[*]}"
12103
12104         for facet in ${ofacets//,/ }; do
12105                 if [ -z $saved_ost_blocks ]; then
12106                         saved_ost_blocks=$(do_facet $facet \
12107                                 lctl get_param -n $ost_param.blocksize)
12108                         echo "OST Blocksize: $saved_ost_blocks"
12109                 fi
12110                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12111                 do_facet $facet zfs set recordsize=32768 $ost
12112         done
12113
12114         # BS too small. Sufficient for functional testing.
12115         for facet in ${mfacets//,/ }; do
12116                 if [ -z $saved_mdt_blocks ]; then
12117                         saved_mdt_blocks=$(do_facet $facet \
12118                                 lctl get_param -n $mdt_param.blocksize)
12119                         echo "MDT Blocksize: $saved_mdt_blocks"
12120                 fi
12121                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12122                 do_facet $facet zfs set recordsize=32768 $mdt
12123         done
12124
12125         # Give new values chance to reflect change
12126         sleep 2
12127
12128         echo "After recordsize change"
12129         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12130         df_after=($(df -h | grep "$MOUNT"$))
12131
12132         # For checking.
12133         echo "lfs output : ${lfs_df_after[*]}"
12134         echo "df  output : ${df_after[*]}"
12135
12136         # Verify lfs df
12137         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12138                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12139         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12140                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12141         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12142                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12143
12144         # Verify df
12145         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12146                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12147         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12148                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12149         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12150                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12151
12152         # Restore MDT recordize back to original
12153         for facet in ${mfacets//,/ }; do
12154                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12155                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12156         done
12157
12158         # Restore OST recordize back to original
12159         for facet in ${ofacets//,/ }; do
12160                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12161                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12162         done
12163
12164         return 0
12165 }
12166 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12167
12168 test_104d() {
12169         (( $RUNAS_ID != $UID )) ||
12170                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12171
12172         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12173                 skip "lustre version doesn't support lctl dl with non-root"
12174
12175         # debugfs only allows root users to access files, so the
12176         # previous move of the "devices" file to debugfs broke
12177         # "lctl dl" for non-root users. The LU-9680 Netlink
12178         # interface again allows non-root users to list devices.
12179         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12180                 error "lctl dl doesn't work for non root"
12181
12182         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12183         [ "$ost_count" -eq $OSTCOUNT ]  ||
12184                 error "lctl dl reports wrong number of OST devices"
12185
12186         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12187         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12188                 error "lctl dl reports wrong number of MDT devices"
12189 }
12190 run_test 104d "$RUNAS lctl dl test"
12191
12192 test_105a() {
12193         # doesn't work on 2.4 kernels
12194         touch $DIR/$tfile
12195         if $(flock_is_enabled); then
12196                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12197         else
12198                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12199         fi
12200         rm -f $DIR/$tfile
12201 }
12202 run_test 105a "flock when mounted without -o flock test ========"
12203
12204 test_105b() {
12205         touch $DIR/$tfile
12206         if $(flock_is_enabled); then
12207                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12208         else
12209                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12210         fi
12211         rm -f $DIR/$tfile
12212 }
12213 run_test 105b "fcntl when mounted without -o flock test ========"
12214
12215 test_105c() {
12216         touch $DIR/$tfile
12217         if $(flock_is_enabled); then
12218                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12219         else
12220                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12221         fi
12222         rm -f $DIR/$tfile
12223 }
12224 run_test 105c "lockf when mounted without -o flock test"
12225
12226 test_105d() { # bug 15924
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228
12229         test_mkdir $DIR/$tdir
12230         flock_is_enabled || skip_env "mount w/o flock enabled"
12231         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12232         $LCTL set_param fail_loc=0x80000315
12233         flocks_test 2 $DIR/$tdir
12234 }
12235 run_test 105d "flock race (should not freeze) ========"
12236
12237 test_105e() { # bug 22660 && 22040
12238         flock_is_enabled || skip_env "mount w/o flock enabled"
12239
12240         touch $DIR/$tfile
12241         flocks_test 3 $DIR/$tfile
12242 }
12243 run_test 105e "Two conflicting flocks from same process"
12244
12245 test_106() { #bug 10921
12246         test_mkdir $DIR/$tdir
12247         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12248         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12249 }
12250 run_test 106 "attempt exec of dir followed by chown of that dir"
12251
12252 test_107() {
12253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12254
12255         CDIR=`pwd`
12256         local file=core
12257
12258         cd $DIR
12259         rm -f $file
12260
12261         local save_pattern=$(sysctl -n kernel.core_pattern)
12262         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12263         sysctl -w kernel.core_pattern=$file
12264         sysctl -w kernel.core_uses_pid=0
12265
12266         ulimit -c unlimited
12267         sleep 60 &
12268         SLEEPPID=$!
12269
12270         sleep 1
12271
12272         kill -s 11 $SLEEPPID
12273         wait $SLEEPPID
12274         if [ -e $file ]; then
12275                 size=`stat -c%s $file`
12276                 [ $size -eq 0 ] && error "Fail to create core file $file"
12277         else
12278                 error "Fail to create core file $file"
12279         fi
12280         rm -f $file
12281         sysctl -w kernel.core_pattern=$save_pattern
12282         sysctl -w kernel.core_uses_pid=$save_uses_pid
12283         cd $CDIR
12284 }
12285 run_test 107 "Coredump on SIG"
12286
12287 test_110() {
12288         test_mkdir $DIR/$tdir
12289         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12290         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12291                 error "mkdir with 256 char should fail, but did not"
12292         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12293                 error "create with 255 char failed"
12294         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12295                 error "create with 256 char should fail, but did not"
12296
12297         ls -l $DIR/$tdir
12298         rm -rf $DIR/$tdir
12299 }
12300 run_test 110 "filename length checking"
12301
12302 test_116a() { # was previously test_116()
12303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12304         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12305         remote_mds_nodsh && skip "remote MDS with nodsh"
12306
12307         echo -n "Free space priority "
12308         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12309                 head -n1
12310         declare -a AVAIL
12311         free_min_max
12312
12313         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12314         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12315         stack_trap simple_cleanup_common
12316
12317         # Check if we need to generate uneven OSTs
12318         test_mkdir -p $DIR/$tdir/OST${MINI}
12319         local FILL=$((MINV / 4))
12320         local DIFF=$((MAXV - MINV))
12321         local DIFF2=$((DIFF * 100 / MINV))
12322
12323         local threshold=$(do_facet $SINGLEMDS \
12324                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12325         threshold=${threshold%%%}
12326         echo -n "Check for uneven OSTs: "
12327         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12328
12329         if [[ $DIFF2 -gt $threshold ]]; then
12330                 echo "ok"
12331                 echo "Don't need to fill OST$MINI"
12332         else
12333                 # generate uneven OSTs. Write 2% over the QOS threshold value
12334                 echo "no"
12335                 DIFF=$((threshold - DIFF2 + 2))
12336                 DIFF2=$((MINV * DIFF / 100))
12337                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12338                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12339                         error "setstripe failed"
12340                 DIFF=$((DIFF2 / 2048))
12341                 i=0
12342                 while [ $i -lt $DIFF ]; do
12343                         i=$((i + 1))
12344                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12345                                 bs=2M count=1 2>/dev/null
12346                         echo -n .
12347                 done
12348                 echo .
12349                 sync
12350                 sleep_maxage
12351                 free_min_max
12352         fi
12353
12354         DIFF=$((MAXV - MINV))
12355         DIFF2=$((DIFF * 100 / MINV))
12356         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12357         if [ $DIFF2 -gt $threshold ]; then
12358                 echo "ok"
12359         else
12360                 skip "QOS imbalance criteria not met"
12361         fi
12362
12363         MINI1=$MINI
12364         MINV1=$MINV
12365         MAXI1=$MAXI
12366         MAXV1=$MAXV
12367
12368         # now fill using QOS
12369         $LFS setstripe -c 1 $DIR/$tdir
12370         FILL=$((FILL / 200))
12371         if [ $FILL -gt 600 ]; then
12372                 FILL=600
12373         fi
12374         echo "writing $FILL files to QOS-assigned OSTs"
12375         i=0
12376         while [ $i -lt $FILL ]; do
12377                 i=$((i + 1))
12378                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12379                         count=1 2>/dev/null
12380                 echo -n .
12381         done
12382         echo "wrote $i 200k files"
12383         sync
12384         sleep_maxage
12385
12386         echo "Note: free space may not be updated, so measurements might be off"
12387         free_min_max
12388         DIFF2=$((MAXV - MINV))
12389         echo "free space delta: orig $DIFF final $DIFF2"
12390         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12391         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12392         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12393         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12394         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12395         if [[ $DIFF -gt 0 ]]; then
12396                 FILL=$((DIFF2 * 100 / DIFF - 100))
12397                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12398         fi
12399
12400         # Figure out which files were written where
12401         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12402                awk '/'$MINI1': / {print $2; exit}')
12403         echo $UUID
12404         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12405         echo "$MINC files created on smaller OST $MINI1"
12406         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12407                awk '/'$MAXI1': / {print $2; exit}')
12408         echo $UUID
12409         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12410         echo "$MAXC files created on larger OST $MAXI1"
12411         if [[ $MINC -gt 0 ]]; then
12412                 FILL=$((MAXC * 100 / MINC - 100))
12413                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12414         fi
12415         [[ $MAXC -gt $MINC ]] ||
12416                 error_ignore LU-9 "stripe QOS didn't balance free space"
12417 }
12418 run_test 116a "stripe QOS: free space balance ==================="
12419
12420 test_116b() { # LU-2093
12421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12422         remote_mds_nodsh && skip "remote MDS with nodsh"
12423
12424 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12425         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12426                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12427         [ -z "$old_rr" ] && skip "no QOS"
12428         do_facet $SINGLEMDS lctl set_param \
12429                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12430         mkdir -p $DIR/$tdir
12431         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12432         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12433         do_facet $SINGLEMDS lctl set_param fail_loc=0
12434         rm -rf $DIR/$tdir
12435         do_facet $SINGLEMDS lctl set_param \
12436                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12437 }
12438 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12439
12440 test_117() # bug 10891
12441 {
12442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12443
12444         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12445         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12446         lctl set_param fail_loc=0x21e
12447         > $DIR/$tfile || error "truncate failed"
12448         lctl set_param fail_loc=0
12449         echo "Truncate succeeded."
12450         rm -f $DIR/$tfile
12451 }
12452 run_test 117 "verify osd extend =========="
12453
12454 NO_SLOW_RESENDCOUNT=4
12455 export OLD_RESENDCOUNT=""
12456 set_resend_count () {
12457         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12458         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12459         lctl set_param -n $PROC_RESENDCOUNT $1
12460         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12461 }
12462
12463 # for reduce test_118* time (b=14842)
12464 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12465
12466 # Reset async IO behavior after error case
12467 reset_async() {
12468         FILE=$DIR/reset_async
12469
12470         # Ensure all OSCs are cleared
12471         $LFS setstripe -c -1 $FILE
12472         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12473         sync
12474         rm $FILE
12475 }
12476
12477 test_118a() #bug 11710
12478 {
12479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12480
12481         reset_async
12482
12483         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12484         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12485         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12486
12487         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12488                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12489                 return 1;
12490         fi
12491         rm -f $DIR/$tfile
12492 }
12493 run_test 118a "verify O_SYNC works =========="
12494
12495 test_118b()
12496 {
12497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12498         remote_ost_nodsh && skip "remote OST with nodsh"
12499
12500         reset_async
12501
12502         #define OBD_FAIL_SRV_ENOENT 0x217
12503         set_nodes_failloc "$(osts_nodes)" 0x217
12504         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12505         RC=$?
12506         set_nodes_failloc "$(osts_nodes)" 0
12507         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12508         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12509                     grep -c writeback)
12510
12511         if [[ $RC -eq 0 ]]; then
12512                 error "Must return error due to dropped pages, rc=$RC"
12513                 return 1;
12514         fi
12515
12516         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12517                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12518                 return 1;
12519         fi
12520
12521         echo "Dirty pages not leaked on ENOENT"
12522
12523         # Due to the above error the OSC will issue all RPCs syncronously
12524         # until a subsequent RPC completes successfully without error.
12525         $MULTIOP $DIR/$tfile Ow4096yc
12526         rm -f $DIR/$tfile
12527
12528         return 0
12529 }
12530 run_test 118b "Reclaim dirty pages on fatal error =========="
12531
12532 test_118c()
12533 {
12534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12535
12536         # for 118c, restore the original resend count, LU-1940
12537         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12538                                 set_resend_count $OLD_RESENDCOUNT
12539         remote_ost_nodsh && skip "remote OST with nodsh"
12540
12541         reset_async
12542
12543         #define OBD_FAIL_OST_EROFS               0x216
12544         set_nodes_failloc "$(osts_nodes)" 0x216
12545
12546         # multiop should block due to fsync until pages are written
12547         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12548         MULTIPID=$!
12549         sleep 1
12550
12551         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12552                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12553         fi
12554
12555         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12556                     grep -c writeback)
12557         if [[ $WRITEBACK -eq 0 ]]; then
12558                 error "No page in writeback, writeback=$WRITEBACK"
12559         fi
12560
12561         set_nodes_failloc "$(osts_nodes)" 0
12562         wait $MULTIPID
12563         RC=$?
12564         if [[ $RC -ne 0 ]]; then
12565                 error "Multiop fsync failed, rc=$RC"
12566         fi
12567
12568         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12569         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12570                     grep -c writeback)
12571         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12572                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12573         fi
12574
12575         rm -f $DIR/$tfile
12576         echo "Dirty pages flushed via fsync on EROFS"
12577         return 0
12578 }
12579 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12580
12581 # continue to use small resend count to reduce test_118* time (b=14842)
12582 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12583
12584 test_118d()
12585 {
12586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12587         remote_ost_nodsh && skip "remote OST with nodsh"
12588
12589         reset_async
12590
12591         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12592         set_nodes_failloc "$(osts_nodes)" 0x214
12593         # multiop should block due to fsync until pages are written
12594         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12595         MULTIPID=$!
12596         sleep 1
12597
12598         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12599                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12600         fi
12601
12602         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12603                     grep -c writeback)
12604         if [[ $WRITEBACK -eq 0 ]]; then
12605                 error "No page in writeback, writeback=$WRITEBACK"
12606         fi
12607
12608         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12609         set_nodes_failloc "$(osts_nodes)" 0
12610
12611         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12612         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12613                     grep -c writeback)
12614         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12615                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12616         fi
12617
12618         rm -f $DIR/$tfile
12619         echo "Dirty pages gaurenteed flushed via fsync"
12620         return 0
12621 }
12622 run_test 118d "Fsync validation inject a delay of the bulk =========="
12623
12624 test_118f() {
12625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12626
12627         reset_async
12628
12629         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12630         lctl set_param fail_loc=0x8000040a
12631
12632         # Should simulate EINVAL error which is fatal
12633         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12634         RC=$?
12635         if [[ $RC -eq 0 ]]; then
12636                 error "Must return error due to dropped pages, rc=$RC"
12637         fi
12638
12639         lctl set_param fail_loc=0x0
12640
12641         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12642         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12643         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12644                     grep -c writeback)
12645         if [[ $LOCKED -ne 0 ]]; then
12646                 error "Locked pages remain in cache, locked=$LOCKED"
12647         fi
12648
12649         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12650                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12651         fi
12652
12653         rm -f $DIR/$tfile
12654         echo "No pages locked after fsync"
12655
12656         reset_async
12657         return 0
12658 }
12659 run_test 118f "Simulate unrecoverable OSC side error =========="
12660
12661 test_118g() {
12662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12663
12664         reset_async
12665
12666         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12667         lctl set_param fail_loc=0x406
12668
12669         # simulate local -ENOMEM
12670         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12671         RC=$?
12672
12673         lctl set_param fail_loc=0
12674         if [[ $RC -eq 0 ]]; then
12675                 error "Must return error due to dropped pages, rc=$RC"
12676         fi
12677
12678         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12679         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12680         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12681                         grep -c writeback)
12682         if [[ $LOCKED -ne 0 ]]; then
12683                 error "Locked pages remain in cache, locked=$LOCKED"
12684         fi
12685
12686         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12687                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12688         fi
12689
12690         rm -f $DIR/$tfile
12691         echo "No pages locked after fsync"
12692
12693         reset_async
12694         return 0
12695 }
12696 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12697
12698 test_118h() {
12699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12700         remote_ost_nodsh && skip "remote OST with nodsh"
12701
12702         reset_async
12703
12704         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12705         set_nodes_failloc "$(osts_nodes)" 0x20e
12706         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12707         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12708         RC=$?
12709
12710         set_nodes_failloc "$(osts_nodes)" 0
12711         if [[ $RC -eq 0 ]]; then
12712                 error "Must return error due to dropped pages, rc=$RC"
12713         fi
12714
12715         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12716         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12717         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12718                     grep -c writeback)
12719         if [[ $LOCKED -ne 0 ]]; then
12720                 error "Locked pages remain in cache, locked=$LOCKED"
12721         fi
12722
12723         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12724                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12725         fi
12726
12727         rm -f $DIR/$tfile
12728         echo "No pages locked after fsync"
12729
12730         return 0
12731 }
12732 run_test 118h "Verify timeout in handling recoverables errors  =========="
12733
12734 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12735
12736 test_118i() {
12737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12738         remote_ost_nodsh && skip "remote OST with nodsh"
12739
12740         reset_async
12741
12742         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12743         set_nodes_failloc "$(osts_nodes)" 0x20e
12744
12745         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12747         PID=$!
12748         sleep 5
12749         set_nodes_failloc "$(osts_nodes)" 0
12750
12751         wait $PID
12752         RC=$?
12753         if [[ $RC -ne 0 ]]; then
12754                 error "got error, but should be not, rc=$RC"
12755         fi
12756
12757         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12758         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12759         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12760         if [[ $LOCKED -ne 0 ]]; then
12761                 error "Locked pages remain in cache, locked=$LOCKED"
12762         fi
12763
12764         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12765                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12766         fi
12767
12768         rm -f $DIR/$tfile
12769         echo "No pages locked after fsync"
12770
12771         return 0
12772 }
12773 run_test 118i "Fix error before timeout in recoverable error  =========="
12774
12775 [ "$SLOW" = "no" ] && set_resend_count 4
12776
12777 test_118j() {
12778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12779         remote_ost_nodsh && skip "remote OST with nodsh"
12780
12781         reset_async
12782
12783         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12784         set_nodes_failloc "$(osts_nodes)" 0x220
12785
12786         # return -EIO from OST
12787         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12788         RC=$?
12789         set_nodes_failloc "$(osts_nodes)" 0x0
12790         if [[ $RC -eq 0 ]]; then
12791                 error "Must return error due to dropped pages, rc=$RC"
12792         fi
12793
12794         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12795         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12796         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12797         if [[ $LOCKED -ne 0 ]]; then
12798                 error "Locked pages remain in cache, locked=$LOCKED"
12799         fi
12800
12801         # in recoverable error on OST we want resend and stay until it finished
12802         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12803                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12804         fi
12805
12806         rm -f $DIR/$tfile
12807         echo "No pages locked after fsync"
12808
12809         return 0
12810 }
12811 run_test 118j "Simulate unrecoverable OST side error =========="
12812
12813 test_118k()
12814 {
12815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12816         remote_ost_nodsh && skip "remote OSTs with nodsh"
12817
12818         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12819         set_nodes_failloc "$(osts_nodes)" 0x20e
12820         test_mkdir $DIR/$tdir
12821
12822         for ((i=0;i<10;i++)); do
12823                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12824                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12825                 SLEEPPID=$!
12826                 sleep 0.500s
12827                 kill $SLEEPPID
12828                 wait $SLEEPPID
12829         done
12830
12831         set_nodes_failloc "$(osts_nodes)" 0
12832         rm -rf $DIR/$tdir
12833 }
12834 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12835
12836 test_118l() # LU-646
12837 {
12838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12839
12840         test_mkdir $DIR/$tdir
12841         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12842         rm -rf $DIR/$tdir
12843 }
12844 run_test 118l "fsync dir"
12845
12846 test_118m() # LU-3066
12847 {
12848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12849
12850         test_mkdir $DIR/$tdir
12851         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12852         rm -rf $DIR/$tdir
12853 }
12854 run_test 118m "fdatasync dir ========="
12855
12856 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12857
12858 test_118n()
12859 {
12860         local begin
12861         local end
12862
12863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12864         remote_ost_nodsh && skip "remote OSTs with nodsh"
12865
12866         # Sleep to avoid a cached response.
12867         #define OBD_STATFS_CACHE_SECONDS 1
12868         sleep 2
12869
12870         # Inject a 10 second delay in the OST_STATFS handler.
12871         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12872         set_nodes_failloc "$(osts_nodes)" 0x242
12873
12874         begin=$SECONDS
12875         stat --file-system $MOUNT > /dev/null
12876         end=$SECONDS
12877
12878         set_nodes_failloc "$(osts_nodes)" 0
12879
12880         if ((end - begin > 20)); then
12881             error "statfs took $((end - begin)) seconds, expected 10"
12882         fi
12883 }
12884 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12885
12886 test_119a() # bug 11737
12887 {
12888         BSIZE=$((512 * 1024))
12889         directio write $DIR/$tfile 0 1 $BSIZE
12890         # We ask to read two blocks, which is more than a file size.
12891         # directio will indicate an error when requested and actual
12892         # sizes aren't equeal (a normal situation in this case) and
12893         # print actual read amount.
12894         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12895         if [ "$NOB" != "$BSIZE" ]; then
12896                 error "read $NOB bytes instead of $BSIZE"
12897         fi
12898         rm -f $DIR/$tfile
12899 }
12900 run_test 119a "Short directIO read must return actual read amount"
12901
12902 test_119b() # bug 11737
12903 {
12904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12905
12906         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12907         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12908         sync
12909         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12910                 error "direct read failed"
12911         rm -f $DIR/$tfile
12912 }
12913 run_test 119b "Sparse directIO read must return actual read amount"
12914
12915 test_119c() # bug 13099
12916 {
12917         BSIZE=1048576
12918         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12919         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12920         rm -f $DIR/$tfile
12921 }
12922 run_test 119c "Testing for direct read hitting hole"
12923
12924 test_119d() # bug 15950
12925 {
12926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12927
12928         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12929         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12930         BSIZE=1048576
12931         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12932         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12933         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12934         lctl set_param fail_loc=0x40d
12935         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12936         pid_dio=$!
12937         sleep 1
12938         cat $DIR/$tfile > /dev/null &
12939         lctl set_param fail_loc=0
12940         pid_reads=$!
12941         wait $pid_dio
12942         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12943         sleep 2
12944         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12945         error "the read rpcs have not completed in 2s"
12946         rm -f $DIR/$tfile
12947         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12948 }
12949 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12950
12951 test_120a() {
12952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12953         remote_mds_nodsh && skip "remote MDS with nodsh"
12954         test_mkdir -i0 -c1 $DIR/$tdir
12955         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12956                 skip_env "no early lock cancel on server"
12957
12958         lru_resize_disable mdc
12959         lru_resize_disable osc
12960         cancel_lru_locks mdc
12961         # asynchronous object destroy at MDT could cause bl ast to client
12962         cancel_lru_locks osc
12963
12964         stat $DIR/$tdir > /dev/null
12965         can1=$(do_facet mds1 \
12966                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12967                awk '/ldlm_cancel/ {print $2}')
12968         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12969                awk '/ldlm_bl_callback/ {print $2}')
12970         test_mkdir -i0 -c1 $DIR/$tdir/d1
12971         can2=$(do_facet mds1 \
12972                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12973                awk '/ldlm_cancel/ {print $2}')
12974         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12975                awk '/ldlm_bl_callback/ {print $2}')
12976         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12977         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12978         lru_resize_enable mdc
12979         lru_resize_enable osc
12980 }
12981 run_test 120a "Early Lock Cancel: mkdir test"
12982
12983 test_120b() {
12984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12985         remote_mds_nodsh && skip "remote MDS with nodsh"
12986         test_mkdir $DIR/$tdir
12987         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12988                 skip_env "no early lock cancel on server"
12989
12990         lru_resize_disable mdc
12991         lru_resize_disable osc
12992         cancel_lru_locks mdc
12993         stat $DIR/$tdir > /dev/null
12994         can1=$(do_facet $SINGLEMDS \
12995                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12996                awk '/ldlm_cancel/ {print $2}')
12997         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12998                awk '/ldlm_bl_callback/ {print $2}')
12999         touch $DIR/$tdir/f1
13000         can2=$(do_facet $SINGLEMDS \
13001                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13002                awk '/ldlm_cancel/ {print $2}')
13003         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13004                awk '/ldlm_bl_callback/ {print $2}')
13005         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13006         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13007         lru_resize_enable mdc
13008         lru_resize_enable osc
13009 }
13010 run_test 120b "Early Lock Cancel: create test"
13011
13012 test_120c() {
13013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13014         remote_mds_nodsh && skip "remote MDS with nodsh"
13015         test_mkdir -i0 -c1 $DIR/$tdir
13016         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13017                 skip "no early lock cancel on server"
13018
13019         lru_resize_disable mdc
13020         lru_resize_disable osc
13021         test_mkdir -i0 -c1 $DIR/$tdir/d1
13022         test_mkdir -i0 -c1 $DIR/$tdir/d2
13023         touch $DIR/$tdir/d1/f1
13024         cancel_lru_locks mdc
13025         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13026         can1=$(do_facet mds1 \
13027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13028                awk '/ldlm_cancel/ {print $2}')
13029         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13030                awk '/ldlm_bl_callback/ {print $2}')
13031         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13032         can2=$(do_facet mds1 \
13033                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13034                awk '/ldlm_cancel/ {print $2}')
13035         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13036                awk '/ldlm_bl_callback/ {print $2}')
13037         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13038         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13039         lru_resize_enable mdc
13040         lru_resize_enable osc
13041 }
13042 run_test 120c "Early Lock Cancel: link test"
13043
13044 test_120d() {
13045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13046         remote_mds_nodsh && skip "remote MDS with nodsh"
13047         test_mkdir -i0 -c1 $DIR/$tdir
13048         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13049                 skip_env "no early lock cancel on server"
13050
13051         lru_resize_disable mdc
13052         lru_resize_disable osc
13053         touch $DIR/$tdir
13054         cancel_lru_locks mdc
13055         stat $DIR/$tdir > /dev/null
13056         can1=$(do_facet mds1 \
13057                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13058                awk '/ldlm_cancel/ {print $2}')
13059         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13060                awk '/ldlm_bl_callback/ {print $2}')
13061         chmod a+x $DIR/$tdir
13062         can2=$(do_facet mds1 \
13063                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13064                awk '/ldlm_cancel/ {print $2}')
13065         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13066                awk '/ldlm_bl_callback/ {print $2}')
13067         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13068         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13069         lru_resize_enable mdc
13070         lru_resize_enable osc
13071 }
13072 run_test 120d "Early Lock Cancel: setattr test"
13073
13074 test_120e() {
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13077                 skip_env "no early lock cancel on server"
13078         remote_mds_nodsh && skip "remote MDS with nodsh"
13079
13080         local dlmtrace_set=false
13081
13082         test_mkdir -i0 -c1 $DIR/$tdir
13083         lru_resize_disable mdc
13084         lru_resize_disable osc
13085         ! $LCTL get_param debug | grep -q dlmtrace &&
13086                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13087         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13088         cancel_lru_locks mdc
13089         cancel_lru_locks osc
13090         dd if=$DIR/$tdir/f1 of=/dev/null
13091         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13092         # XXX client can not do early lock cancel of OST lock
13093         # during unlink (LU-4206), so cancel osc lock now.
13094         sleep 2
13095         cancel_lru_locks osc
13096         can1=$(do_facet mds1 \
13097                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13098                awk '/ldlm_cancel/ {print $2}')
13099         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13100                awk '/ldlm_bl_callback/ {print $2}')
13101         unlink $DIR/$tdir/f1
13102         sleep 5
13103         can2=$(do_facet mds1 \
13104                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13105                awk '/ldlm_cancel/ {print $2}')
13106         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13107                awk '/ldlm_bl_callback/ {print $2}')
13108         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13109                 $LCTL dk $TMP/cancel.debug.txt
13110         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13111                 $LCTL dk $TMP/blocking.debug.txt
13112         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13113         lru_resize_enable mdc
13114         lru_resize_enable osc
13115 }
13116 run_test 120e "Early Lock Cancel: unlink test"
13117
13118 test_120f() {
13119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13120         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13121                 skip_env "no early lock cancel on server"
13122         remote_mds_nodsh && skip "remote MDS with nodsh"
13123
13124         test_mkdir -i0 -c1 $DIR/$tdir
13125         lru_resize_disable mdc
13126         lru_resize_disable osc
13127         test_mkdir -i0 -c1 $DIR/$tdir/d1
13128         test_mkdir -i0 -c1 $DIR/$tdir/d2
13129         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13130         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13131         cancel_lru_locks mdc
13132         cancel_lru_locks osc
13133         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13134         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13135         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13136         # XXX client can not do early lock cancel of OST lock
13137         # during rename (LU-4206), so cancel osc lock now.
13138         sleep 2
13139         cancel_lru_locks osc
13140         can1=$(do_facet mds1 \
13141                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13142                awk '/ldlm_cancel/ {print $2}')
13143         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13144                awk '/ldlm_bl_callback/ {print $2}')
13145         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13146         sleep 5
13147         can2=$(do_facet mds1 \
13148                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13149                awk '/ldlm_cancel/ {print $2}')
13150         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13151                awk '/ldlm_bl_callback/ {print $2}')
13152         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13153         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13154         lru_resize_enable mdc
13155         lru_resize_enable osc
13156 }
13157 run_test 120f "Early Lock Cancel: rename test"
13158
13159 test_120g() {
13160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13161         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13162                 skip_env "no early lock cancel on server"
13163         remote_mds_nodsh && skip "remote MDS with nodsh"
13164
13165         lru_resize_disable mdc
13166         lru_resize_disable osc
13167         count=10000
13168         echo create $count files
13169         test_mkdir $DIR/$tdir
13170         cancel_lru_locks mdc
13171         cancel_lru_locks osc
13172         t0=$(date +%s)
13173
13174         can0=$(do_facet $SINGLEMDS \
13175                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13176                awk '/ldlm_cancel/ {print $2}')
13177         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13178                awk '/ldlm_bl_callback/ {print $2}')
13179         createmany -o $DIR/$tdir/f $count
13180         sync
13181         can1=$(do_facet $SINGLEMDS \
13182                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13183                awk '/ldlm_cancel/ {print $2}')
13184         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13185                awk '/ldlm_bl_callback/ {print $2}')
13186         t1=$(date +%s)
13187         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13188         echo rm $count files
13189         rm -r $DIR/$tdir
13190         sync
13191         can2=$(do_facet $SINGLEMDS \
13192                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13193                awk '/ldlm_cancel/ {print $2}')
13194         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13195                awk '/ldlm_bl_callback/ {print $2}')
13196         t2=$(date +%s)
13197         echo total: $count removes in $((t2-t1))
13198         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13199         sleep 2
13200         # wait for commitment of removal
13201         lru_resize_enable mdc
13202         lru_resize_enable osc
13203 }
13204 run_test 120g "Early Lock Cancel: performance test"
13205
13206 test_121() { #bug #10589
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208
13209         rm -rf $DIR/$tfile
13210         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13211 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13212         lctl set_param fail_loc=0x310
13213         cancel_lru_locks osc > /dev/null
13214         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13215         lctl set_param fail_loc=0
13216         [[ $reads -eq $writes ]] ||
13217                 error "read $reads blocks, must be $writes blocks"
13218 }
13219 run_test 121 "read cancel race ========="
13220
13221 test_123a_base() { # was test 123, statahead(bug 11401)
13222         local lsx="$1"
13223
13224         SLOWOK=0
13225         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13226                 log "testing UP system. Performance may be lower than expected."
13227                 SLOWOK=1
13228         fi
13229         running_in_vm && SLOWOK=1
13230
13231         rm -rf $DIR/$tdir
13232         test_mkdir $DIR/$tdir
13233         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13234         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13235         MULT=10
13236         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13237                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13238
13239                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13240                 lctl set_param -n llite.*.statahead_max 0
13241                 lctl get_param llite.*.statahead_max
13242                 cancel_lru_locks mdc
13243                 cancel_lru_locks osc
13244                 stime=$(date +%s)
13245                 time $lsx $DIR/$tdir | wc -l
13246                 etime=$(date +%s)
13247                 delta=$((etime - stime))
13248                 log "$lsx $i files without statahead: $delta sec"
13249                 lctl set_param llite.*.statahead_max=$max
13250
13251                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13252                          awk '/statahead.wrong:/ { print $NF }')
13253                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13254                 cancel_lru_locks mdc
13255                 cancel_lru_locks osc
13256                 stime=$(date +%s)
13257                 time $lsx $DIR/$tdir | wc -l
13258                 etime=$(date +%s)
13259                 delta_sa=$((etime - stime))
13260                 log "$lsx $i files with statahead: $delta_sa sec"
13261                 lctl get_param -n llite.*.statahead_stats
13262                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13263                          awk '/statahead.wrong:/ { print $NF }')
13264
13265                 [[ $swrong -lt $ewrong ]] &&
13266                         log "statahead was stopped, maybe too many locks held!"
13267                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13268
13269                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13270                         max=$(lctl get_param -n llite.*.statahead_max |
13271                                 head -n 1)
13272                         lctl set_param -n llite.*.statahead_max 0
13273                         lctl get_param llite.*.statahead_max
13274                         cancel_lru_locks mdc
13275                         cancel_lru_locks osc
13276                         stime=$(date +%s)
13277                         time $lsx $DIR/$tdir | wc -l
13278                         etime=$(date +%s)
13279                         delta=$((etime - stime))
13280                         log "$lsx $i files again without statahead: $delta sec"
13281                         lctl set_param llite.*.statahead_max=$max
13282                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13283                                 if [ $SLOWOK -eq 0 ]; then
13284                                         error "$lsx $i files is slower with statahead!"
13285                                 else
13286                                         log "$lsx $i files is slower with statahead!"
13287                                 fi
13288                                 break
13289                         fi
13290                 fi
13291
13292                 [ $delta -gt 20 ] && break
13293                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13294                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13295         done
13296         log "$lsx done"
13297
13298         stime=$(date +%s)
13299         rm -r $DIR/$tdir
13300         sync
13301         etime=$(date +%s)
13302         delta=$((etime - stime))
13303         log "rm -r $DIR/$tdir/: $delta seconds"
13304         log "rm done"
13305         lctl get_param -n llite.*.statahead_stats
13306 }
13307
13308 test_123aa() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310
13311         test_123a_base "ls -l"
13312 }
13313 run_test 123aa "verify statahead work"
13314
13315 test_123ab() {
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317
13318         statx_supported || skip_env "Test must be statx() syscall supported"
13319
13320         test_123a_base "$STATX -l"
13321 }
13322 run_test 123ab "verify statahead work by using statx"
13323
13324 test_123ac() {
13325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13326
13327         statx_supported || skip_env "Test must be statx() syscall supported"
13328
13329         local rpcs_before
13330         local rpcs_after
13331         local agl_before
13332         local agl_after
13333
13334         cancel_lru_locks $OSC
13335         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13336         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13337                      awk '/agl.total:/ { print $NF }')
13338         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13339         test_123a_base "$STATX --cached=always -D"
13340         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13341                     awk '/agl.total:/ { print $NF }')
13342         [ $agl_before -eq $agl_after ] ||
13343                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13344         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13345         [ $rpcs_after -eq $rpcs_before ] ||
13346                 error "$STATX should not send glimpse RPCs to $OSC"
13347 }
13348 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13349
13350 test_123b () { # statahead(bug 15027)
13351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13352
13353         test_mkdir $DIR/$tdir
13354         createmany -o $DIR/$tdir/$tfile-%d 1000
13355
13356         cancel_lru_locks mdc
13357         cancel_lru_locks osc
13358
13359 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13360         lctl set_param fail_loc=0x80000803
13361         ls -lR $DIR/$tdir > /dev/null
13362         log "ls done"
13363         lctl set_param fail_loc=0x0
13364         lctl get_param -n llite.*.statahead_stats
13365         rm -r $DIR/$tdir
13366         sync
13367
13368 }
13369 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13370
13371 test_123c() {
13372         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13373
13374         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13375         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13376         touch $DIR/$tdir.1/{1..3}
13377         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13378
13379         remount_client $MOUNT
13380
13381         $MULTIOP $DIR/$tdir.0 Q
13382
13383         # let statahead to complete
13384         ls -l $DIR/$tdir.0 > /dev/null
13385
13386         testid=$(echo $TESTNAME | tr '_' ' ')
13387         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13388                 error "statahead warning" || true
13389 }
13390 run_test 123c "Can not initialize inode warning on DNE statahead"
13391
13392 test_123d() {
13393         local num=100
13394         local swrong
13395         local ewrong
13396
13397         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13398         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13399                 error "setdirstripe $DIR/$tdir failed"
13400         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13401         remount_client $MOUNT
13402         $LCTL get_param llite.*.statahead_max
13403         $LCTL set_param llite.*.statahead_stats=0 ||
13404                 error "clear statahead_stats failed"
13405         swrong=$(lctl get_param -n llite.*.statahead_stats |
13406                  awk '/statahead.wrong:/ { print $NF }')
13407         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13408         # wait for statahead thread finished to update hit/miss stats.
13409         sleep 1
13410         $LCTL get_param -n llite.*.statahead_stats
13411         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13412                  awk '/statahead.wrong:/ { print $NF }')
13413         (( $swrong == $ewrong )) ||
13414                 log "statahead was stopped, maybe too many locks held!"
13415 }
13416 run_test 123d "Statahead on striped directories works correctly"
13417
13418 test_124a() {
13419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13420         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13421                 skip_env "no lru resize on server"
13422
13423         local NR=2000
13424
13425         test_mkdir $DIR/$tdir
13426
13427         log "create $NR files at $DIR/$tdir"
13428         createmany -o $DIR/$tdir/f $NR ||
13429                 error "failed to create $NR files in $DIR/$tdir"
13430
13431         cancel_lru_locks mdc
13432         ls -l $DIR/$tdir > /dev/null
13433
13434         local NSDIR=""
13435         local LRU_SIZE=0
13436         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13437                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13438                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13439                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13440                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13441                         log "NSDIR=$NSDIR"
13442                         log "NS=$(basename $NSDIR)"
13443                         break
13444                 fi
13445         done
13446
13447         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13448                 skip "Not enough cached locks created!"
13449         fi
13450         log "LRU=$LRU_SIZE"
13451
13452         local SLEEP=30
13453
13454         # We know that lru resize allows one client to hold $LIMIT locks
13455         # for 10h. After that locks begin to be killed by client.
13456         local MAX_HRS=10
13457         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13458         log "LIMIT=$LIMIT"
13459         if [ $LIMIT -lt $LRU_SIZE ]; then
13460                 skip "Limit is too small $LIMIT"
13461         fi
13462
13463         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13464         # killing locks. Some time was spent for creating locks. This means
13465         # that up to the moment of sleep finish we must have killed some of
13466         # them (10-100 locks). This depends on how fast ther were created.
13467         # Many of them were touched in almost the same moment and thus will
13468         # be killed in groups.
13469         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13470
13471         # Use $LRU_SIZE_B here to take into account real number of locks
13472         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13473         local LRU_SIZE_B=$LRU_SIZE
13474         log "LVF=$LVF"
13475         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13476         log "OLD_LVF=$OLD_LVF"
13477         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13478
13479         # Let's make sure that we really have some margin. Client checks
13480         # cached locks every 10 sec.
13481         SLEEP=$((SLEEP+20))
13482         log "Sleep ${SLEEP} sec"
13483         local SEC=0
13484         while ((SEC<$SLEEP)); do
13485                 echo -n "..."
13486                 sleep 5
13487                 SEC=$((SEC+5))
13488                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13489                 echo -n "$LRU_SIZE"
13490         done
13491         echo ""
13492         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13493         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13494
13495         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13496                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13497                 unlinkmany $DIR/$tdir/f $NR
13498                 return
13499         }
13500
13501         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13502         log "unlink $NR files at $DIR/$tdir"
13503         unlinkmany $DIR/$tdir/f $NR
13504 }
13505 run_test 124a "lru resize ======================================="
13506
13507 get_max_pool_limit()
13508 {
13509         local limit=$($LCTL get_param \
13510                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13511         local max=0
13512         for l in $limit; do
13513                 if [[ $l -gt $max ]]; then
13514                         max=$l
13515                 fi
13516         done
13517         echo $max
13518 }
13519
13520 test_124b() {
13521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13522         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13523                 skip_env "no lru resize on server"
13524
13525         LIMIT=$(get_max_pool_limit)
13526
13527         NR=$(($(default_lru_size)*20))
13528         if [[ $NR -gt $LIMIT ]]; then
13529                 log "Limit lock number by $LIMIT locks"
13530                 NR=$LIMIT
13531         fi
13532
13533         IFree=$(mdsrate_inodes_available)
13534         if [ $IFree -lt $NR ]; then
13535                 log "Limit lock number by $IFree inodes"
13536                 NR=$IFree
13537         fi
13538
13539         lru_resize_disable mdc
13540         test_mkdir -p $DIR/$tdir/disable_lru_resize
13541
13542         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13543         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13544         cancel_lru_locks mdc
13545         stime=`date +%s`
13546         PID=""
13547         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13548         PID="$PID $!"
13549         sleep 2
13550         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13551         PID="$PID $!"
13552         sleep 2
13553         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13554         PID="$PID $!"
13555         wait $PID
13556         etime=`date +%s`
13557         nolruresize_delta=$((etime-stime))
13558         log "ls -la time: $nolruresize_delta seconds"
13559         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13560         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13561
13562         lru_resize_enable mdc
13563         test_mkdir -p $DIR/$tdir/enable_lru_resize
13564
13565         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13566         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13567         cancel_lru_locks mdc
13568         stime=`date +%s`
13569         PID=""
13570         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13571         PID="$PID $!"
13572         sleep 2
13573         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13574         PID="$PID $!"
13575         sleep 2
13576         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13577         PID="$PID $!"
13578         wait $PID
13579         etime=`date +%s`
13580         lruresize_delta=$((etime-stime))
13581         log "ls -la time: $lruresize_delta seconds"
13582         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13583
13584         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13585                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13586         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13587                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13588         else
13589                 log "lru resize performs the same with no lru resize"
13590         fi
13591         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13592 }
13593 run_test 124b "lru resize (performance test) ======================="
13594
13595 test_124c() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13598                 skip_env "no lru resize on server"
13599
13600         # cache ununsed locks on client
13601         local nr=100
13602         cancel_lru_locks mdc
13603         test_mkdir $DIR/$tdir
13604         createmany -o $DIR/$tdir/f $nr ||
13605                 error "failed to create $nr files in $DIR/$tdir"
13606         ls -l $DIR/$tdir > /dev/null
13607
13608         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13609         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13610         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13611         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13612         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13613
13614         # set lru_max_age to 1 sec
13615         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13616         echo "sleep $((recalc_p * 2)) seconds..."
13617         sleep $((recalc_p * 2))
13618
13619         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13620         # restore lru_max_age
13621         $LCTL set_param -n $nsdir.lru_max_age $max_age
13622         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13623         unlinkmany $DIR/$tdir/f $nr
13624 }
13625 run_test 124c "LRUR cancel very aged locks"
13626
13627 test_124d() {
13628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13629         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13630                 skip_env "no lru resize on server"
13631
13632         # cache ununsed locks on client
13633         local nr=100
13634
13635         lru_resize_disable mdc
13636         stack_trap "lru_resize_enable mdc" EXIT
13637
13638         cancel_lru_locks mdc
13639
13640         # asynchronous object destroy at MDT could cause bl ast to client
13641         test_mkdir $DIR/$tdir
13642         createmany -o $DIR/$tdir/f $nr ||
13643                 error "failed to create $nr files in $DIR/$tdir"
13644         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13645
13646         ls -l $DIR/$tdir > /dev/null
13647
13648         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13649         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13650         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13651         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13652
13653         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13654
13655         # set lru_max_age to 1 sec
13656         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13657         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13658
13659         echo "sleep $((recalc_p * 2)) seconds..."
13660         sleep $((recalc_p * 2))
13661
13662         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13663
13664         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13665 }
13666 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13667
13668 test_125() { # 13358
13669         $LCTL get_param -n llite.*.client_type | grep -q local ||
13670                 skip "must run as local client"
13671         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13672                 skip_env "must have acl enabled"
13673         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13674
13675         test_mkdir $DIR/$tdir
13676         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13677         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13678                 error "setfacl $DIR/$tdir failed"
13679         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13680 }
13681 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13682
13683 test_126() { # bug 12829/13455
13684         $GSS && skip_env "must run as gss disabled"
13685         $LCTL get_param -n llite.*.client_type | grep -q local ||
13686                 skip "must run as local client"
13687         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13688
13689         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13690         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13691         rm -f $DIR/$tfile
13692         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13693 }
13694 run_test 126 "check that the fsgid provided by the client is taken into account"
13695
13696 test_127a() { # bug 15521
13697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13698         local name count samp unit min max sum sumsq
13699         local tmpfile=$TMP/$tfile.tmp
13700
13701         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13702         echo "stats before reset"
13703         stack_trap "rm -f $tmpfile"
13704         local now=$(date +%s)
13705
13706         $LCTL get_param osc.*.stats | tee $tmpfile
13707
13708         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13709         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13710         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13711         local uptime=$(awk '{ print $1 }' /proc/uptime)
13712
13713         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13714         (( ${snapshot_time%\.*} >= $now - 5 &&
13715            ${snapshot_time%\.*} <= $now + 5 )) ||
13716                 error "snapshot_time=$snapshot_time != now=$now"
13717         # elapsed _should_ be from mount, but at least less than uptime
13718         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13719                 error "elapsed=$elapsed > uptime=$uptime"
13720         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13721            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13722                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13723
13724         $LCTL set_param osc.*.stats=0
13725         local reset=$(date +%s)
13726         local fsize=$((2048 * 1024))
13727
13728         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13729         cancel_lru_locks osc
13730         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13731
13732         now=$(date +%s)
13733         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13734         while read name count samp unit min max sum sumsq; do
13735                 [[ "$samp" == "samples" ]] || continue
13736
13737                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13738                 [ ! $min ] && error "Missing min value for $name proc entry"
13739                 eval $name=$count || error "Wrong proc format"
13740
13741                 case $name in
13742                 read_bytes|write_bytes)
13743                         [[ "$unit" =~ "bytes" ]] ||
13744                                 error "unit is not 'bytes': $unit"
13745                         (( $min >= 4096 )) || error "min is too small: $min"
13746                         (( $min <= $fsize )) || error "min is too big: $min"
13747                         (( $max >= 4096 )) || error "max is too small: $max"
13748                         (( $max <= $fsize )) || error "max is too big: $max"
13749                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13750                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13751                                 error "sumsquare is too small: $sumsq"
13752                         (( $sumsq <= $fsize * $fsize )) ||
13753                                 error "sumsquare is too big: $sumsq"
13754                         ;;
13755                 ost_read|ost_write)
13756                         [[ "$unit" =~ "usec" ]] ||
13757                                 error "unit is not 'usec': $unit"
13758                         ;;
13759                 *)      ;;
13760                 esac
13761         done < $tmpfile
13762
13763         #check that we actually got some stats
13764         [ "$read_bytes" ] || error "Missing read_bytes stats"
13765         [ "$write_bytes" ] || error "Missing write_bytes stats"
13766         [ "$read_bytes" != 0 ] || error "no read done"
13767         [ "$write_bytes" != 0 ] || error "no write done"
13768
13769         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13770         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13771         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13772
13773         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13774         (( ${snapshot_time%\.*} >= $now - 5 &&
13775            ${snapshot_time%\.*} <= $now + 5 )) ||
13776                 error "reset snapshot_time=$snapshot_time != now=$now"
13777         # elapsed should be from time of stats reset
13778         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13779            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13780                 error "reset elapsed=$elapsed > $now - $reset"
13781         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13782            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13783                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13784 }
13785 run_test 127a "verify the client stats are sane"
13786
13787 test_127b() { # bug LU-333
13788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13789         local name count samp unit min max sum sumsq
13790
13791         echo "stats before reset"
13792         $LCTL get_param llite.*.stats
13793         $LCTL set_param llite.*.stats=0
13794
13795         # perform 2 reads and writes so MAX is different from SUM.
13796         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13797         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13798         cancel_lru_locks osc
13799         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13800         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13801
13802         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13803         stack_trap "rm -f $TMP/$tfile.tmp"
13804         while read name count samp unit min max sum sumsq; do
13805                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13806                 eval $name=$count || error "Wrong proc format"
13807
13808                 case $name in
13809                 read_bytes|write_bytes)
13810                         [[ "$unit" =~ "bytes" ]] ||
13811                                 error "unit is not 'bytes': $unit"
13812                         (( $count == 2 )) || error "count is not 2: $count"
13813                         (( $min == $PAGE_SIZE )) ||
13814                                 error "min is not $PAGE_SIZE: $min"
13815                         (( $max == $PAGE_SIZE )) ||
13816                                 error "max is not $PAGE_SIZE: $max"
13817                         (( $sum == $PAGE_SIZE * 2 )) ||
13818                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13819                         ;;
13820                 read|write)
13821                         [[ "$unit" =~ "usec" ]] ||
13822                                 error "unit is not 'usec': $unit"
13823                         ;;
13824                 *)      ;;
13825                 esac
13826         done < $TMP/$tfile.tmp
13827
13828         #check that we actually got some stats
13829         [ "$read_bytes" ] || error "Missing read_bytes stats"
13830         [ "$write_bytes" ] || error "Missing write_bytes stats"
13831         [ "$read_bytes" != 0 ] || error "no read done"
13832         [ "$write_bytes" != 0 ] || error "no write done"
13833 }
13834 run_test 127b "verify the llite client stats are sane"
13835
13836 test_127c() { # LU-12394
13837         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13838         local size
13839         local bsize
13840         local reads
13841         local writes
13842         local count
13843
13844         $LCTL set_param llite.*.extents_stats=1
13845         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13846
13847         # Use two stripes so there is enough space in default config
13848         $LFS setstripe -c 2 $DIR/$tfile
13849
13850         # Extent stats start at 0-4K and go in power of two buckets
13851         # LL_HIST_START = 12 --> 2^12 = 4K
13852         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13853         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13854         # small configs
13855         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13856                 do
13857                 # Write and read, 2x each, second time at a non-zero offset
13858                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13859                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13860                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13861                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13862                 rm -f $DIR/$tfile
13863         done
13864
13865         $LCTL get_param llite.*.extents_stats
13866
13867         count=2
13868         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13869                 do
13870                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13871                                 grep -m 1 $bsize)
13872                 reads=$(echo $bucket | awk '{print $5}')
13873                 writes=$(echo $bucket | awk '{print $9}')
13874                 [ "$reads" -eq $count ] ||
13875                         error "$reads reads in < $bsize bucket, expect $count"
13876                 [ "$writes" -eq $count ] ||
13877                         error "$writes writes in < $bsize bucket, expect $count"
13878         done
13879
13880         # Test mmap write and read
13881         $LCTL set_param llite.*.extents_stats=c
13882         size=512
13883         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13884         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13885         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13886
13887         $LCTL get_param llite.*.extents_stats
13888
13889         count=$(((size*1024) / PAGE_SIZE))
13890
13891         bsize=$((2 * PAGE_SIZE / 1024))K
13892
13893         bucket=$($LCTL get_param -n llite.*.extents_stats |
13894                         grep -m 1 $bsize)
13895         reads=$(echo $bucket | awk '{print $5}')
13896         writes=$(echo $bucket | awk '{print $9}')
13897         # mmap writes fault in the page first, creating an additonal read
13898         [ "$reads" -eq $((2 * count)) ] ||
13899                 error "$reads reads in < $bsize bucket, expect $count"
13900         [ "$writes" -eq $count ] ||
13901                 error "$writes writes in < $bsize bucket, expect $count"
13902 }
13903 run_test 127c "test llite extent stats with regular & mmap i/o"
13904
13905 test_128() { # bug 15212
13906         touch $DIR/$tfile
13907         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13908                 find $DIR/$tfile
13909                 find $DIR/$tfile
13910         EOF
13911
13912         result=$(grep error $TMP/$tfile.log)
13913         rm -f $DIR/$tfile $TMP/$tfile.log
13914         [ -z "$result" ] ||
13915                 error "consecutive find's under interactive lfs failed"
13916 }
13917 run_test 128 "interactive lfs for 2 consecutive find's"
13918
13919 set_dir_limits () {
13920         local mntdev
13921         local canondev
13922         local node
13923
13924         local ldproc=/proc/fs/ldiskfs
13925         local facets=$(get_facets MDS)
13926
13927         for facet in ${facets//,/ }; do
13928                 canondev=$(ldiskfs_canon \
13929                            *.$(convert_facet2label $facet).mntdev $facet)
13930                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13931                         ldproc=/sys/fs/ldiskfs
13932                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13933                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13934         done
13935 }
13936
13937 check_mds_dmesg() {
13938         local facets=$(get_facets MDS)
13939         for facet in ${facets//,/ }; do
13940                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13941         done
13942         return 1
13943 }
13944
13945 test_129() {
13946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13947         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13948                 skip "Need MDS version with at least 2.5.56"
13949         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13950                 skip_env "ldiskfs only test"
13951         fi
13952         remote_mds_nodsh && skip "remote MDS with nodsh"
13953
13954         local ENOSPC=28
13955         local has_warning=false
13956
13957         rm -rf $DIR/$tdir
13958         mkdir -p $DIR/$tdir
13959
13960         # block size of mds1
13961         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13962         set_dir_limits $maxsize $((maxsize * 6 / 8))
13963         stack_trap "set_dir_limits 0 0"
13964         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13965         local dirsize=$(stat -c%s "$DIR/$tdir")
13966         local nfiles=0
13967         while (( $dirsize <= $maxsize )); do
13968                 $MCREATE $DIR/$tdir/file_base_$nfiles
13969                 rc=$?
13970                 # check two errors:
13971                 # ENOSPC for ext4 max_dir_size, which has been used since
13972                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13973                 if (( rc == ENOSPC )); then
13974                         set_dir_limits 0 0
13975                         echo "rc=$rc returned as expected after $nfiles files"
13976
13977                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13978                                 error "create failed w/o dir size limit"
13979
13980                         # messages may be rate limited if test is run repeatedly
13981                         check_mds_dmesg '"is approaching max"' ||
13982                                 echo "warning message should be output"
13983                         check_mds_dmesg '"has reached max"' ||
13984                                 echo "reached message should be output"
13985
13986                         dirsize=$(stat -c%s "$DIR/$tdir")
13987
13988                         [[ $dirsize -ge $maxsize ]] && return 0
13989                         error "dirsize $dirsize < $maxsize after $nfiles files"
13990                 elif (( rc != 0 )); then
13991                         break
13992                 fi
13993                 nfiles=$((nfiles + 1))
13994                 dirsize=$(stat -c%s "$DIR/$tdir")
13995         done
13996
13997         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13998 }
13999 run_test 129 "test directory size limit ========================"
14000
14001 OLDIFS="$IFS"
14002 cleanup_130() {
14003         trap 0
14004         IFS="$OLDIFS"
14005 }
14006
14007 test_130a() {
14008         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14009         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14010
14011         trap cleanup_130 EXIT RETURN
14012
14013         local fm_file=$DIR/$tfile
14014         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14015         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14016                 error "dd failed for $fm_file"
14017
14018         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14019         filefrag -ves $fm_file
14020         local rc=$?
14021         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14022                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14023         (( $rc == 0 )) || error "filefrag $fm_file failed"
14024
14025         filefrag_op=$(filefrag -ve -k $fm_file |
14026                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14027         local lun=$($LFS getstripe -i $fm_file)
14028
14029         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14030         IFS=$'\n'
14031         local tot_len=0
14032         for line in $filefrag_op; do
14033                 local frag_lun=$(echo $line | cut -d: -f5)
14034                 local ext_len=$(echo $line | cut -d: -f4)
14035
14036                 if (( $frag_lun != $lun )); then
14037                         error "FIEMAP on 1-stripe file($fm_file) failed"
14038                         return
14039                 fi
14040                 (( tot_len += ext_len ))
14041         done
14042
14043         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14044                 error "FIEMAP on 1-stripe file($fm_file) failed"
14045                 return
14046         fi
14047
14048         echo "FIEMAP on single striped file succeeded"
14049 }
14050 run_test 130a "FIEMAP (1-stripe file)"
14051
14052 test_130b() {
14053         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14054
14055         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14056         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14057         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14058                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14059
14060         trap cleanup_130 EXIT RETURN
14061
14062         local fm_file=$DIR/$tfile
14063         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14064                 error "setstripe on $fm_file"
14065
14066         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14067                 error "dd failed on $fm_file"
14068
14069         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14070         filefrag_op=$(filefrag -ve -k $fm_file |
14071                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14072
14073         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14074                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14075
14076         IFS=$'\n'
14077         local tot_len=0
14078         local num_luns=1
14079
14080         for line in $filefrag_op; do
14081                 local frag_lun=$(echo $line | cut -d: -f5 |
14082                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14083                 local ext_len=$(echo $line | cut -d: -f4)
14084                 if (( $frag_lun != $last_lun )); then
14085                         if (( tot_len != 1024 )); then
14086                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14087                                 return
14088                         else
14089                                 (( num_luns += 1 ))
14090                                 tot_len=0
14091                         fi
14092                 fi
14093                 (( tot_len += ext_len ))
14094                 last_lun=$frag_lun
14095         done
14096         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14097                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14098                 return
14099         fi
14100
14101         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14102 }
14103 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14104
14105 test_130c() {
14106         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14107
14108         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14109         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14110         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14111                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14112
14113         trap cleanup_130 EXIT RETURN
14114
14115         local fm_file=$DIR/$tfile
14116         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14117
14118         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14119                 error "dd failed on $fm_file"
14120
14121         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14122         filefrag_op=$(filefrag -ve -k $fm_file |
14123                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14124
14125         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14126                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14127
14128         IFS=$'\n'
14129         local tot_len=0
14130         local num_luns=1
14131         for line in $filefrag_op; do
14132                 local frag_lun=$(echo $line | cut -d: -f5 |
14133                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14134                 local ext_len=$(echo $line | cut -d: -f4)
14135                 if (( $frag_lun != $last_lun )); then
14136                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14137                         if (( logical != 512 )); then
14138                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14139                                 return
14140                         fi
14141                         if (( tot_len != 512 )); then
14142                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14143                                 return
14144                         else
14145                                 (( num_luns += 1 ))
14146                                 tot_len=0
14147                         fi
14148                 fi
14149                 (( tot_len += ext_len ))
14150                 last_lun=$frag_lun
14151         done
14152         if (( num_luns != 2 || tot_len != 512 )); then
14153                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14154                 return
14155         fi
14156
14157         echo "FIEMAP on 2-stripe file with hole succeeded"
14158 }
14159 run_test 130c "FIEMAP (2-stripe file with hole)"
14160
14161 test_130d() {
14162         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14163
14164         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14165         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14166         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14167                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14168
14169         trap cleanup_130 EXIT RETURN
14170
14171         local fm_file=$DIR/$tfile
14172         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14173                         error "setstripe on $fm_file"
14174
14175         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14176         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14177                 error "dd failed on $fm_file"
14178
14179         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14180         filefrag_op=$(filefrag -ve -k $fm_file |
14181                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14182
14183         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14184                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14185
14186         IFS=$'\n'
14187         local tot_len=0
14188         local num_luns=1
14189         for line in $filefrag_op; do
14190                 local frag_lun=$(echo $line | cut -d: -f5 |
14191                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14192                 local ext_len=$(echo $line | cut -d: -f4)
14193                 if (( $frag_lun != $last_lun )); then
14194                         if (( tot_len != 1024 )); then
14195                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14196                                 return
14197                         else
14198                                 (( num_luns += 1 ))
14199                                 local tot_len=0
14200                         fi
14201                 fi
14202                 (( tot_len += ext_len ))
14203                 last_lun=$frag_lun
14204         done
14205         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14206                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14207                 return
14208         fi
14209
14210         echo "FIEMAP on N-stripe file succeeded"
14211 }
14212 run_test 130d "FIEMAP (N-stripe file)"
14213
14214 test_130e() {
14215         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14216
14217         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14218         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14219         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14220                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14221
14222         trap cleanup_130 EXIT RETURN
14223
14224         local fm_file=$DIR/$tfile
14225         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14226
14227         local num_blks=512
14228         local expected_len=$(( (num_blks / 2) * 64 ))
14229         for ((i = 0; i < $num_blks; i++)); do
14230                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14231                         conv=notrunc > /dev/null 2>&1
14232         done
14233
14234         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14235         filefrag_op=$(filefrag -ve -k $fm_file |
14236                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14237
14238         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14239
14240         IFS=$'\n'
14241         local tot_len=0
14242         local num_luns=1
14243         for line in $filefrag_op; do
14244                 local frag_lun=$(echo $line | cut -d: -f5)
14245                 local ext_len=$(echo $line | cut -d: -f4)
14246                 if (( $frag_lun != $last_lun )); then
14247                         if (( tot_len != $expected_len )); then
14248                                 error "OST$last_lun $tot_len != $expected_len"
14249                         else
14250                                 (( num_luns += 1 ))
14251                                 tot_len=0
14252                         fi
14253                 fi
14254                 (( tot_len += ext_len ))
14255                 last_lun=$frag_lun
14256         done
14257         if (( num_luns != 2 || tot_len != $expected_len )); then
14258                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14259         fi
14260
14261         echo "FIEMAP with continuation calls succeeded"
14262 }
14263 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14264
14265 test_130f() {
14266         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14267         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14268         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14269                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14270
14271         local fm_file=$DIR/$tfile
14272         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14273                 error "multiop create with lov_delay_create on $fm_file"
14274
14275         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14276         filefrag_extents=$(filefrag -vek $fm_file |
14277                            awk '/extents? found/ { print $2 }')
14278         if (( $filefrag_extents != 0 )); then
14279                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14280         fi
14281
14282         rm -f $fm_file
14283 }
14284 run_test 130f "FIEMAP (unstriped file)"
14285
14286 test_130g() {
14287         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14288                 skip "Need MDS version with at least 2.12.53 for overstriping"
14289         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14290         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14291         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14292                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14293
14294         local file=$DIR/$tfile
14295         local nr=$((OSTCOUNT * 100))
14296
14297         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14298
14299         stack_trap "rm -f $file"
14300         dd if=/dev/zero of=$file count=$nr bs=1M
14301         sync
14302         nr=$($LFS getstripe -c $file)
14303
14304         local extents=$(filefrag -v $file |
14305                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14306
14307         echo "filefrag list $extents extents in file with stripecount $nr"
14308         if (( extents < nr )); then
14309                 $LFS getstripe $file
14310                 filefrag -v $file
14311                 error "filefrag printed $extents < $nr extents"
14312         fi
14313 }
14314 run_test 130g "FIEMAP (overstripe file)"
14315
14316 # Test for writev/readv
14317 test_131a() {
14318         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14319                 error "writev test failed"
14320         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14321                 error "readv failed"
14322         rm -f $DIR/$tfile
14323 }
14324 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14325
14326 test_131b() {
14327         local fsize=$((524288 + 1048576 + 1572864))
14328         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14329                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14330                         error "append writev test failed"
14331
14332         ((fsize += 1572864 + 1048576))
14333         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14334                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14335                         error "append writev test failed"
14336         rm -f $DIR/$tfile
14337 }
14338 run_test 131b "test append writev"
14339
14340 test_131c() {
14341         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14342         error "NOT PASS"
14343 }
14344 run_test 131c "test read/write on file w/o objects"
14345
14346 test_131d() {
14347         rwv -f $DIR/$tfile -w -n 1 1572864
14348         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14349         if [ "$NOB" != 1572864 ]; then
14350                 error "Short read filed: read $NOB bytes instead of 1572864"
14351         fi
14352         rm -f $DIR/$tfile
14353 }
14354 run_test 131d "test short read"
14355
14356 test_131e() {
14357         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14358         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14359         error "read hitting hole failed"
14360         rm -f $DIR/$tfile
14361 }
14362 run_test 131e "test read hitting hole"
14363
14364 check_stats() {
14365         local facet=$1
14366         local op=$2
14367         local want=${3:-0}
14368         local res
14369
14370         # open             11 samples [usecs] 468 4793 13658 35791898
14371         case $facet in
14372         mds*) res=($(do_facet $facet \
14373                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14374                  ;;
14375         ost*) res=($(do_facet $facet \
14376                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14377                  ;;
14378         *) error "Wrong facet '$facet'" ;;
14379         esac
14380         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14381         # if $want is zero, it means any stat increment is ok.
14382         if (( $want > 0 )); then
14383                 local count=${res[1]}
14384
14385                 if (( $count != $want )); then
14386                         if [[ $facet =~ "mds" ]]; then
14387                                 do_nodes $(comma_list $(mdts_nodes)) \
14388                                         $LCTL get_param mdt.*.md_stats
14389                         else
14390                                 do_nodes $(comma_list $(osts-nodes)) \
14391                                         $LCTL get_param obdfilter.*.stats
14392                         fi
14393                         error "The $op counter on $facet is $count, not $want"
14394                 fi
14395         fi
14396 }
14397
14398 test_133a() {
14399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14400         remote_ost_nodsh && skip "remote OST with nodsh"
14401         remote_mds_nodsh && skip "remote MDS with nodsh"
14402         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14403                 skip_env "MDS doesn't support rename stats"
14404
14405         local testdir=$DIR/${tdir}/stats_testdir
14406
14407         mkdir -p $DIR/${tdir}
14408
14409         # clear stats.
14410         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14411         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14412
14413         # verify mdt stats first.
14414         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14415         check_stats $SINGLEMDS "mkdir" 1
14416
14417         # clear "open" from "lfs mkdir" above
14418         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14419         touch ${testdir}/${tfile} || error "touch failed"
14420         check_stats $SINGLEMDS "open" 1
14421         check_stats $SINGLEMDS "close" 1
14422         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14423                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14424                 check_stats $SINGLEMDS "mknod" 2
14425         }
14426         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14427         check_stats $SINGLEMDS "unlink" 1
14428         rm -f ${testdir}/${tfile} || error "file remove failed"
14429         check_stats $SINGLEMDS "unlink" 2
14430
14431         # remove working dir and check mdt stats again.
14432         rmdir ${testdir} || error "rmdir failed"
14433         check_stats $SINGLEMDS "rmdir" 1
14434
14435         local testdir1=$DIR/${tdir}/stats_testdir1
14436         mkdir_on_mdt0 -p ${testdir}
14437         mkdir_on_mdt0 -p ${testdir1}
14438         touch ${testdir1}/test1
14439         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14440         check_stats $SINGLEMDS "crossdir_rename" 1
14441
14442         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14443         check_stats $SINGLEMDS "samedir_rename" 1
14444
14445         rm -rf $DIR/${tdir}
14446 }
14447 run_test 133a "Verifying MDT stats ========================================"
14448
14449 test_133b() {
14450         local res
14451
14452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14453         remote_ost_nodsh && skip "remote OST with nodsh"
14454         remote_mds_nodsh && skip "remote MDS with nodsh"
14455
14456         local testdir=$DIR/${tdir}/stats_testdir
14457
14458         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14459         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14460         touch ${testdir}/${tfile} || error "touch failed"
14461         cancel_lru_locks mdc
14462
14463         # clear stats.
14464         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14465         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14466
14467         # extra mdt stats verification.
14468         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14469         check_stats $SINGLEMDS "setattr" 1
14470         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14471         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14472         then            # LU-1740
14473                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14474                 check_stats $SINGLEMDS "getattr" 1
14475         fi
14476         rm -rf $DIR/${tdir}
14477
14478         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14479         # so the check below is not reliable
14480         [ $MDSCOUNT -eq 1 ] || return 0
14481
14482         # Sleep to avoid a cached response.
14483         #define OBD_STATFS_CACHE_SECONDS 1
14484         sleep 2
14485         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14486         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14487         $LFS df || error "lfs failed"
14488         check_stats $SINGLEMDS "statfs" 1
14489
14490         # check aggregated statfs (LU-10018)
14491         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14492                 return 0
14493         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14494                 return 0
14495         sleep 2
14496         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14497         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14498         df $DIR
14499         check_stats $SINGLEMDS "statfs" 1
14500
14501         # We want to check that the client didn't send OST_STATFS to
14502         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14503         # extra care is needed here.
14504         if remote_mds; then
14505                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14506                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14507
14508                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14509                 [ "$res" ] && error "OST got STATFS"
14510         fi
14511
14512         return 0
14513 }
14514 run_test 133b "Verifying extra MDT stats =================================="
14515
14516 test_133c() {
14517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14518         remote_ost_nodsh && skip "remote OST with nodsh"
14519         remote_mds_nodsh && skip "remote MDS with nodsh"
14520
14521         local testdir=$DIR/$tdir/stats_testdir
14522
14523         test_mkdir -p $testdir
14524
14525         # verify obdfilter stats.
14526         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14527         sync
14528         cancel_lru_locks osc
14529         wait_delete_completed
14530
14531         # clear stats.
14532         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14533         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14534
14535         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14536                 error "dd failed"
14537         sync
14538         cancel_lru_locks osc
14539         check_stats ost1 "write" 1
14540
14541         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14542         check_stats ost1 "read" 1
14543
14544         > $testdir/$tfile || error "truncate failed"
14545         check_stats ost1 "punch" 1
14546
14547         rm -f $testdir/$tfile || error "file remove failed"
14548         wait_delete_completed
14549         check_stats ost1 "destroy" 1
14550
14551         rm -rf $DIR/$tdir
14552 }
14553 run_test 133c "Verifying OST stats ========================================"
14554
14555 order_2() {
14556         local value=$1
14557         local orig=$value
14558         local order=1
14559
14560         while [ $value -ge 2 ]; do
14561                 order=$((order*2))
14562                 value=$((value/2))
14563         done
14564
14565         if [ $orig -gt $order ]; then
14566                 order=$((order*2))
14567         fi
14568         echo $order
14569 }
14570
14571 size_in_KMGT() {
14572     local value=$1
14573     local size=('K' 'M' 'G' 'T');
14574     local i=0
14575     local size_string=$value
14576
14577     while [ $value -ge 1024 ]; do
14578         if [ $i -gt 3 ]; then
14579             #T is the biggest unit we get here, if that is bigger,
14580             #just return XXXT
14581             size_string=${value}T
14582             break
14583         fi
14584         value=$((value >> 10))
14585         if [ $value -lt 1024 ]; then
14586             size_string=${value}${size[$i]}
14587             break
14588         fi
14589         i=$((i + 1))
14590     done
14591
14592     echo $size_string
14593 }
14594
14595 get_rename_size() {
14596         local size=$1
14597         local context=${2:-.}
14598         local sample=$(do_facet $SINGLEMDS $LCTL \
14599                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14600                 grep -A1 $context |
14601                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14602         echo $sample
14603 }
14604
14605 test_133d() {
14606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14607         remote_ost_nodsh && skip "remote OST with nodsh"
14608         remote_mds_nodsh && skip "remote MDS with nodsh"
14609         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14610                 skip_env "MDS doesn't support rename stats"
14611
14612         local testdir1=$DIR/${tdir}/stats_testdir1
14613         local testdir2=$DIR/${tdir}/stats_testdir2
14614         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14615
14616         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14617
14618         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14619         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14620
14621         createmany -o $testdir1/test 512 || error "createmany failed"
14622
14623         # check samedir rename size
14624         mv ${testdir1}/test0 ${testdir1}/test_0
14625
14626         local testdir1_size=$(ls -l $DIR/${tdir} |
14627                 awk '/stats_testdir1/ {print $5}')
14628         local testdir2_size=$(ls -l $DIR/${tdir} |
14629                 awk '/stats_testdir2/ {print $5}')
14630
14631         testdir1_size=$(order_2 $testdir1_size)
14632         testdir2_size=$(order_2 $testdir2_size)
14633
14634         testdir1_size=$(size_in_KMGT $testdir1_size)
14635         testdir2_size=$(size_in_KMGT $testdir2_size)
14636
14637         echo "source rename dir size: ${testdir1_size}"
14638         echo "target rename dir size: ${testdir2_size}"
14639
14640         local cmd="do_facet $SINGLEMDS $LCTL "
14641         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14642
14643         eval $cmd || error "$cmd failed"
14644         local samedir=$($cmd | grep 'same_dir')
14645         local same_sample=$(get_rename_size $testdir1_size)
14646         [ -z "$samedir" ] && error "samedir_rename_size count error"
14647         [[ $same_sample -eq 1 ]] ||
14648                 error "samedir_rename_size error $same_sample"
14649         echo "Check same dir rename stats success"
14650
14651         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14652
14653         # check crossdir rename size
14654         mv ${testdir1}/test_0 ${testdir2}/test_0
14655
14656         testdir1_size=$(ls -l $DIR/${tdir} |
14657                 awk '/stats_testdir1/ {print $5}')
14658         testdir2_size=$(ls -l $DIR/${tdir} |
14659                 awk '/stats_testdir2/ {print $5}')
14660
14661         testdir1_size=$(order_2 $testdir1_size)
14662         testdir2_size=$(order_2 $testdir2_size)
14663
14664         testdir1_size=$(size_in_KMGT $testdir1_size)
14665         testdir2_size=$(size_in_KMGT $testdir2_size)
14666
14667         echo "source rename dir size: ${testdir1_size}"
14668         echo "target rename dir size: ${testdir2_size}"
14669
14670         eval $cmd || error "$cmd failed"
14671         local crossdir=$($cmd | grep 'crossdir')
14672         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14673         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14674         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14675         [[ $src_sample -eq 1 ]] ||
14676                 error "crossdir_rename_size error $src_sample"
14677         [[ $tgt_sample -eq 1 ]] ||
14678                 error "crossdir_rename_size error $tgt_sample"
14679         echo "Check cross dir rename stats success"
14680         rm -rf $DIR/${tdir}
14681 }
14682 run_test 133d "Verifying rename_stats ========================================"
14683
14684 test_133e() {
14685         remote_mds_nodsh && skip "remote MDS with nodsh"
14686         remote_ost_nodsh && skip "remote OST with nodsh"
14687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14688
14689         local testdir=$DIR/${tdir}/stats_testdir
14690         local ctr f0 f1 bs=32768 count=42 sum
14691
14692         mkdir -p ${testdir} || error "mkdir failed"
14693
14694         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14695
14696         for ctr in {write,read}_bytes; do
14697                 sync
14698                 cancel_lru_locks osc
14699
14700                 do_facet ost1 $LCTL set_param -n \
14701                         "obdfilter.*.exports.clear=clear"
14702
14703                 if [ $ctr = write_bytes ]; then
14704                         f0=/dev/zero
14705                         f1=${testdir}/${tfile}
14706                 else
14707                         f0=${testdir}/${tfile}
14708                         f1=/dev/null
14709                 fi
14710
14711                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14712                         error "dd failed"
14713                 sync
14714                 cancel_lru_locks osc
14715
14716                 sum=$(do_facet ost1 $LCTL get_param \
14717                         "obdfilter.*.exports.*.stats" |
14718                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14719                                 $1 == ctr { sum += $7 }
14720                                 END { printf("%0.0f", sum) }')
14721
14722                 if ((sum != bs * count)); then
14723                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14724                 fi
14725         done
14726
14727         rm -rf $DIR/${tdir}
14728 }
14729 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14730
14731 test_133f() {
14732         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14733                 skip "too old lustre for get_param -R ($facet_ver)"
14734
14735         # verifying readability.
14736         $LCTL get_param -R '*' &> /dev/null
14737
14738         # Verifing writability with badarea_io.
14739         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14740         local skipped_params='force_lbug|changelog_mask|daemon_file'
14741         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14742                 egrep -v "$skipped_params" |
14743                 xargs -n 1 find $proc_dirs -name |
14744                 xargs -n 1 badarea_io ||
14745                 error "client badarea_io failed"
14746
14747         # remount the FS in case writes/reads /proc break the FS
14748         cleanup || error "failed to unmount"
14749         setup || error "failed to setup"
14750 }
14751 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14752
14753 test_133g() {
14754         remote_mds_nodsh && skip "remote MDS with nodsh"
14755         remote_ost_nodsh && skip "remote OST with nodsh"
14756
14757         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14758         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14759         local facet
14760         for facet in mds1 ost1; do
14761                 local facet_ver=$(lustre_version_code $facet)
14762                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14763                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14764                 else
14765                         log "$facet: too old lustre for get_param -R"
14766                 fi
14767                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14768                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14769                                 tr -d = | egrep -v $skipped_params |
14770                                 xargs -n 1 find $proc_dirs -name |
14771                                 xargs -n 1 badarea_io" ||
14772                                         error "$facet badarea_io failed"
14773                 else
14774                         skip_noexit "$facet: too old lustre for get_param -R"
14775                 fi
14776         done
14777
14778         # remount the FS in case writes/reads /proc break the FS
14779         cleanup || error "failed to unmount"
14780         setup || error "failed to setup"
14781 }
14782 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14783
14784 test_133h() {
14785         remote_mds_nodsh && skip "remote MDS with nodsh"
14786         remote_ost_nodsh && skip "remote OST with nodsh"
14787         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14788                 skip "Need MDS version at least 2.9.54"
14789
14790         local facet
14791         for facet in client mds1 ost1; do
14792                 # Get the list of files that are missing the terminating newline
14793                 local plist=$(do_facet $facet
14794                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14795                 local ent
14796                 for ent in $plist; do
14797                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14798                                 awk -v FS='\v' -v RS='\v\v' \
14799                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14800                                         print FILENAME}'" 2>/dev/null)
14801                         [ -z $missing ] || {
14802                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14803                                 error "file does not end with newline: $facet-$ent"
14804                         }
14805                 done
14806         done
14807 }
14808 run_test 133h "Proc files should end with newlines"
14809
14810 test_134a() {
14811         remote_mds_nodsh && skip "remote MDS with nodsh"
14812         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14813                 skip "Need MDS version at least 2.7.54"
14814
14815         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14816         cancel_lru_locks mdc
14817
14818         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14819         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14820         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14821
14822         local nr=1000
14823         createmany -o $DIR/$tdir/f $nr ||
14824                 error "failed to create $nr files in $DIR/$tdir"
14825         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14826
14827         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14828         do_facet mds1 $LCTL set_param fail_loc=0x327
14829         do_facet mds1 $LCTL set_param fail_val=500
14830         touch $DIR/$tdir/m
14831
14832         echo "sleep 10 seconds ..."
14833         sleep 10
14834         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14835
14836         do_facet mds1 $LCTL set_param fail_loc=0
14837         do_facet mds1 $LCTL set_param fail_val=0
14838         [ $lck_cnt -lt $unused ] ||
14839                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14840
14841         rm $DIR/$tdir/m
14842         unlinkmany $DIR/$tdir/f $nr
14843 }
14844 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14845
14846 test_134b() {
14847         remote_mds_nodsh && skip "remote MDS with nodsh"
14848         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14849                 skip "Need MDS version at least 2.7.54"
14850
14851         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14852         cancel_lru_locks mdc
14853
14854         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14855                         ldlm.lock_reclaim_threshold_mb)
14856         # disable reclaim temporarily
14857         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14858
14859         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14860         do_facet mds1 $LCTL set_param fail_loc=0x328
14861         do_facet mds1 $LCTL set_param fail_val=500
14862
14863         $LCTL set_param debug=+trace
14864
14865         local nr=600
14866         createmany -o $DIR/$tdir/f $nr &
14867         local create_pid=$!
14868
14869         echo "Sleep $TIMEOUT seconds ..."
14870         sleep $TIMEOUT
14871         if ! ps -p $create_pid  > /dev/null 2>&1; then
14872                 do_facet mds1 $LCTL set_param fail_loc=0
14873                 do_facet mds1 $LCTL set_param fail_val=0
14874                 do_facet mds1 $LCTL set_param \
14875                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14876                 error "createmany finished incorrectly!"
14877         fi
14878         do_facet mds1 $LCTL set_param fail_loc=0
14879         do_facet mds1 $LCTL set_param fail_val=0
14880         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14881         wait $create_pid || return 1
14882
14883         unlinkmany $DIR/$tdir/f $nr
14884 }
14885 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14886
14887 test_135() {
14888         remote_mds_nodsh && skip "remote MDS with nodsh"
14889         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14890                 skip "Need MDS version at least 2.13.50"
14891         local fname
14892
14893         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14894
14895 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14896         #set only one record at plain llog
14897         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14898
14899         #fill already existed plain llog each 64767
14900         #wrapping whole catalog
14901         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14902
14903         createmany -o $DIR/$tdir/$tfile_ 64700
14904         for (( i = 0; i < 64700; i = i + 2 ))
14905         do
14906                 rm $DIR/$tdir/$tfile_$i &
14907                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14908                 local pid=$!
14909                 wait $pid
14910         done
14911
14912         #waiting osp synchronization
14913         wait_delete_completed
14914 }
14915 run_test 135 "Race catalog processing"
14916
14917 test_136() {
14918         remote_mds_nodsh && skip "remote MDS with nodsh"
14919         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14920                 skip "Need MDS version at least 2.13.50"
14921         local fname
14922
14923         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14924         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14925         #set only one record at plain llog
14926 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14928
14929         #fill already existed 2 plain llogs each 64767
14930         #wrapping whole catalog
14931         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14932         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14933         wait_delete_completed
14934
14935         createmany -o $DIR/$tdir/$tfile_ 10
14936         sleep 25
14937
14938         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14939         for (( i = 0; i < 10; i = i + 3 ))
14940         do
14941                 rm $DIR/$tdir/$tfile_$i &
14942                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14943                 local pid=$!
14944                 wait $pid
14945                 sleep 7
14946                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14947         done
14948
14949         #waiting osp synchronization
14950         wait_delete_completed
14951 }
14952 run_test 136 "Race catalog processing 2"
14953
14954 test_140() { #bug-17379
14955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14956
14957         test_mkdir $DIR/$tdir
14958         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14959         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14960
14961         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14962         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14963         local i=0
14964         while i=$((i + 1)); do
14965                 test_mkdir $i
14966                 cd $i || error "Changing to $i"
14967                 ln -s ../stat stat || error "Creating stat symlink"
14968                 # Read the symlink until ELOOP present,
14969                 # not LBUGing the system is considered success,
14970                 # we didn't overrun the stack.
14971                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14972                 if [ $ret -ne 0 ]; then
14973                         if [ $ret -eq 40 ]; then
14974                                 break  # -ELOOP
14975                         else
14976                                 error "Open stat symlink"
14977                                         return
14978                         fi
14979                 fi
14980         done
14981         i=$((i - 1))
14982         echo "The symlink depth = $i"
14983         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14984                 error "Invalid symlink depth"
14985
14986         # Test recursive symlink
14987         ln -s symlink_self symlink_self
14988         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14989         echo "open symlink_self returns $ret"
14990         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14991 }
14992 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14993
14994 test_150a() {
14995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14996
14997         local TF="$TMP/$tfile"
14998
14999         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15000         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15001         cp $TF $DIR/$tfile
15002         cancel_lru_locks $OSC
15003         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15004         remount_client $MOUNT
15005         df -P $MOUNT
15006         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15007
15008         $TRUNCATE $TF 6000
15009         $TRUNCATE $DIR/$tfile 6000
15010         cancel_lru_locks $OSC
15011         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15012
15013         echo "12345" >>$TF
15014         echo "12345" >>$DIR/$tfile
15015         cancel_lru_locks $OSC
15016         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15017
15018         echo "12345" >>$TF
15019         echo "12345" >>$DIR/$tfile
15020         cancel_lru_locks $OSC
15021         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15022 }
15023 run_test 150a "truncate/append tests"
15024
15025 test_150b() {
15026         check_set_fallocate_or_skip
15027         local out
15028
15029         touch $DIR/$tfile
15030         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15031         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15032                 skip_eopnotsupp "$out|check_fallocate failed"
15033 }
15034 run_test 150b "Verify fallocate (prealloc) functionality"
15035
15036 test_150bb() {
15037         check_set_fallocate_or_skip
15038
15039         touch $DIR/$tfile
15040         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15041         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15042         > $DIR/$tfile
15043         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15044         # precomputed md5sum for 20MB of zeroes
15045         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15046         local sum=($(md5sum $DIR/$tfile))
15047
15048         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15049
15050         check_set_fallocate 1
15051
15052         > $DIR/$tfile
15053         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15054         sum=($(md5sum $DIR/$tfile))
15055
15056         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15057 }
15058 run_test 150bb "Verify fallocate modes both zero space"
15059
15060 test_150c() {
15061         check_set_fallocate_or_skip
15062         local striping="-c2"
15063
15064         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15065         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15066         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15067         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15068         local want=$((OSTCOUNT * 1048576))
15069
15070         # Must allocate all requested space, not more than 5% extra
15071         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15072                 error "bytes $bytes is not $want"
15073
15074         rm -f $DIR/$tfile
15075
15076         echo "verify fallocate on PFL file"
15077
15078         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15079
15080         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15081                 error "Create $DIR/$tfile failed"
15082         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15083         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15084         want=$((512 * 1048576))
15085
15086         # Must allocate all requested space, not more than 5% extra
15087         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15088                 error "bytes $bytes is not $want"
15089 }
15090 run_test 150c "Verify fallocate Size and Blocks"
15091
15092 test_150d() {
15093         check_set_fallocate_or_skip
15094         local striping="-c2"
15095
15096         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15097
15098         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15099         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15100                 error "setstripe failed"
15101         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15102         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15103         local want=$((OSTCOUNT * 1048576))
15104
15105         # Must allocate all requested space, not more than 5% extra
15106         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15107                 error "bytes $bytes is not $want"
15108 }
15109 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15110
15111 test_150e() {
15112         check_set_fallocate_or_skip
15113
15114         echo "df before:"
15115         $LFS df
15116         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15117         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15118                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15119
15120         # Find OST with Minimum Size
15121         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15122                        sort -un | head -1)
15123
15124         # Get 100MB per OST of the available space to reduce run time
15125         # else 60% of the available space if we are running SLOW tests
15126         if [ $SLOW == "no" ]; then
15127                 local space=$((1024 * 100 * OSTCOUNT))
15128         else
15129                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15130         fi
15131
15132         fallocate -l${space}k $DIR/$tfile ||
15133                 error "fallocate ${space}k $DIR/$tfile failed"
15134         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15135
15136         # get size immediately after fallocate. This should be correctly
15137         # updated
15138         local size=$(stat -c '%s' $DIR/$tfile)
15139         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15140
15141         # Sleep for a while for statfs to get updated. And not pull from cache.
15142         sleep 2
15143
15144         echo "df after fallocate:"
15145         $LFS df
15146
15147         (( size / 1024 == space )) || error "size $size != requested $space"
15148         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15149                 error "used $used < space $space"
15150
15151         rm $DIR/$tfile || error "rm failed"
15152         sync
15153         wait_delete_completed
15154
15155         echo "df after unlink:"
15156         $LFS df
15157 }
15158 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15159
15160 test_150f() {
15161         local size
15162         local blocks
15163         local want_size_before=20480 # in bytes
15164         local want_blocks_before=40 # 512 sized blocks
15165         local want_blocks_after=24  # 512 sized blocks
15166         local length=$(((want_blocks_before - want_blocks_after) * 512))
15167
15168         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15169                 skip "need at least 2.14.0 for fallocate punch"
15170
15171         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15172                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15173         fi
15174
15175         check_set_fallocate_or_skip
15176         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15177
15178         [[ "x$DOM" == "xyes" ]] &&
15179                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15180
15181         echo "Verify fallocate punch: Range within the file range"
15182         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15183                 error "dd failed for bs 4096 and count 5"
15184
15185         # Call fallocate with punch range which is within the file range
15186         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15187                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15188         # client must see changes immediately after fallocate
15189         size=$(stat -c '%s' $DIR/$tfile)
15190         blocks=$(stat -c '%b' $DIR/$tfile)
15191
15192         # Verify punch worked.
15193         (( blocks == want_blocks_after )) ||
15194                 error "punch failed: blocks $blocks != $want_blocks_after"
15195
15196         (( size == want_size_before )) ||
15197                 error "punch failed: size $size != $want_size_before"
15198
15199         # Verify there is hole in file
15200         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15201         # precomputed md5sum
15202         local expect="4a9a834a2db02452929c0a348273b4aa"
15203
15204         cksum=($(md5sum $DIR/$tfile))
15205         [[ "${cksum[0]}" == "$expect" ]] ||
15206                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15207
15208         # Start second sub-case for fallocate punch.
15209         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15210         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15211                 error "dd failed for bs 4096 and count 5"
15212
15213         # Punch range less than block size will have no change in block count
15214         want_blocks_after=40  # 512 sized blocks
15215
15216         # Punch overlaps two blocks and less than blocksize
15217         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15218                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15219         size=$(stat -c '%s' $DIR/$tfile)
15220         blocks=$(stat -c '%b' $DIR/$tfile)
15221
15222         # Verify punch worked.
15223         (( blocks == want_blocks_after )) ||
15224                 error "punch failed: blocks $blocks != $want_blocks_after"
15225
15226         (( size == want_size_before )) ||
15227                 error "punch failed: size $size != $want_size_before"
15228
15229         # Verify if range is really zero'ed out. We expect Zeros.
15230         # precomputed md5sum
15231         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15232         cksum=($(md5sum $DIR/$tfile))
15233         [[ "${cksum[0]}" == "$expect" ]] ||
15234                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15235 }
15236 run_test 150f "Verify fallocate punch functionality"
15237
15238 test_150g() {
15239         local space
15240         local size
15241         local blocks
15242         local blocks_after
15243         local size_after
15244         local BS=4096 # Block size in bytes
15245
15246         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15247                 skip "need at least 2.14.0 for fallocate punch"
15248
15249         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15250                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15251         fi
15252
15253         check_set_fallocate_or_skip
15254         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15255
15256         if [[ "x$DOM" == "xyes" ]]; then
15257                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15258                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15259         else
15260                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15261                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15262         fi
15263
15264         # Get 100MB per OST of the available space to reduce run time
15265         # else 60% of the available space if we are running SLOW tests
15266         if [ $SLOW == "no" ]; then
15267                 space=$((1024 * 100 * OSTCOUNT))
15268         else
15269                 # Find OST with Minimum Size
15270                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15271                         sort -un | head -1)
15272                 echo "min size OST: $space"
15273                 space=$(((space * 60)/100 * OSTCOUNT))
15274         fi
15275         # space in 1k units, round to 4k blocks
15276         local blkcount=$((space * 1024 / $BS))
15277
15278         echo "Verify fallocate punch: Very large Range"
15279         fallocate -l${space}k $DIR/$tfile ||
15280                 error "fallocate ${space}k $DIR/$tfile failed"
15281         # write 1M at the end, start and in the middle
15282         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15283                 error "dd failed: bs $BS count 256"
15284         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15285                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15286         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15287                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15288
15289         # Gather stats.
15290         size=$(stat -c '%s' $DIR/$tfile)
15291
15292         # gather punch length.
15293         local punch_size=$((size - (BS * 2)))
15294
15295         echo "punch_size = $punch_size"
15296         echo "size - punch_size: $((size - punch_size))"
15297         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15298
15299         # Call fallocate to punch all except 2 blocks. We leave the
15300         # first and the last block
15301         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15302         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15303                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15304
15305         size_after=$(stat -c '%s' $DIR/$tfile)
15306         blocks_after=$(stat -c '%b' $DIR/$tfile)
15307
15308         # Verify punch worked.
15309         # Size should be kept
15310         (( size == size_after )) ||
15311                 error "punch failed: size $size != $size_after"
15312
15313         # two 4k data blocks to remain plus possible 1 extra extent block
15314         (( blocks_after <= ((BS / 512) * 3) )) ||
15315                 error "too many blocks remains: $blocks_after"
15316
15317         # Verify that file has hole between the first and the last blocks
15318         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15319         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15320
15321         echo "Hole at [$hole_start, $hole_end)"
15322         (( hole_start == BS )) ||
15323                 error "no hole at offset $BS after punch"
15324
15325         (( hole_end == BS + punch_size )) ||
15326                 error "data at offset $hole_end < $((BS + punch_size))"
15327 }
15328 run_test 150g "Verify fallocate punch on large range"
15329
15330 test_150h() {
15331         local file=$DIR/$tfile
15332         local size
15333
15334         check_set_fallocate_or_skip
15335         statx_supported || skip_env "Test must be statx() syscall supported"
15336
15337         # fallocate() does not update the size information on the MDT
15338         fallocate -l 16K $file || error "failed to fallocate $file"
15339         cancel_lru_locks $OSC
15340         # STATX with cached-always mode will not send glimpse RPCs to OST,
15341         # it uses the caching attrs on the client side as much as possible.
15342         size=$($STATX --cached=always -c %s $file)
15343         [ $size == 16384 ] ||
15344                 error "size after fallocate() is $size, expected 16384"
15345 }
15346 run_test 150h "Verify extend fallocate updates the file size"
15347
15348 #LU-2902 roc_hit was not able to read all values from lproc
15349 function roc_hit_init() {
15350         local list=$(comma_list $(osts_nodes))
15351         local dir=$DIR/$tdir-check
15352         local file=$dir/$tfile
15353         local BEFORE
15354         local AFTER
15355         local idx
15356
15357         test_mkdir $dir
15358         #use setstripe to do a write to every ost
15359         for i in $(seq 0 $((OSTCOUNT-1))); do
15360                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15361                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15362                 idx=$(printf %04x $i)
15363                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15364                         awk '$1 == "cache_access" {sum += $7}
15365                                 END { printf("%0.0f", sum) }')
15366
15367                 cancel_lru_locks osc
15368                 cat $file >/dev/null
15369
15370                 AFTER=$(get_osd_param $list *OST*$idx stats |
15371                         awk '$1 == "cache_access" {sum += $7}
15372                                 END { printf("%0.0f", sum) }')
15373
15374                 echo BEFORE:$BEFORE AFTER:$AFTER
15375                 if ! let "AFTER - BEFORE == 4"; then
15376                         rm -rf $dir
15377                         error "roc_hit is not safe to use"
15378                 fi
15379                 rm $file
15380         done
15381
15382         rm -rf $dir
15383 }
15384
15385 function roc_hit() {
15386         local list=$(comma_list $(osts_nodes))
15387         echo $(get_osd_param $list '' stats |
15388                 awk '$1 == "cache_hit" {sum += $7}
15389                         END { printf("%0.0f", sum) }')
15390 }
15391
15392 function set_cache() {
15393         local on=1
15394
15395         if [ "$2" == "off" ]; then
15396                 on=0;
15397         fi
15398         local list=$(comma_list $(osts_nodes))
15399         set_osd_param $list '' $1_cache_enable $on
15400
15401         cancel_lru_locks osc
15402 }
15403
15404 test_151() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         remote_ost_nodsh && skip "remote OST with nodsh"
15407
15408         local CPAGES=3
15409         local list=$(comma_list $(osts_nodes))
15410
15411         # check whether obdfilter is cache capable at all
15412         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15413                 skip "not cache-capable obdfilter"
15414         fi
15415
15416         # check cache is enabled on all obdfilters
15417         if get_osd_param $list '' read_cache_enable | grep 0; then
15418                 skip "oss cache is disabled"
15419         fi
15420
15421         set_osd_param $list '' writethrough_cache_enable 1
15422
15423         # check write cache is enabled on all obdfilters
15424         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15425                 skip "oss write cache is NOT enabled"
15426         fi
15427
15428         roc_hit_init
15429
15430         #define OBD_FAIL_OBD_NO_LRU  0x609
15431         do_nodes $list $LCTL set_param fail_loc=0x609
15432
15433         # pages should be in the case right after write
15434         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15435                 error "dd failed"
15436
15437         local BEFORE=$(roc_hit)
15438         cancel_lru_locks osc
15439         cat $DIR/$tfile >/dev/null
15440         local AFTER=$(roc_hit)
15441
15442         do_nodes $list $LCTL set_param fail_loc=0
15443
15444         if ! let "AFTER - BEFORE == CPAGES"; then
15445                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15446         fi
15447
15448         cancel_lru_locks osc
15449         # invalidates OST cache
15450         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15451         set_osd_param $list '' read_cache_enable 0
15452         cat $DIR/$tfile >/dev/null
15453
15454         # now data shouldn't be found in the cache
15455         BEFORE=$(roc_hit)
15456         cancel_lru_locks osc
15457         cat $DIR/$tfile >/dev/null
15458         AFTER=$(roc_hit)
15459         if let "AFTER - BEFORE != 0"; then
15460                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15461         fi
15462
15463         set_osd_param $list '' read_cache_enable 1
15464         rm -f $DIR/$tfile
15465 }
15466 run_test 151 "test cache on oss and controls ==============================="
15467
15468 test_152() {
15469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15470
15471         local TF="$TMP/$tfile"
15472
15473         # simulate ENOMEM during write
15474 #define OBD_FAIL_OST_NOMEM      0x226
15475         lctl set_param fail_loc=0x80000226
15476         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15477         cp $TF $DIR/$tfile
15478         sync || error "sync failed"
15479         lctl set_param fail_loc=0
15480
15481         # discard client's cache
15482         cancel_lru_locks osc
15483
15484         # simulate ENOMEM during read
15485         lctl set_param fail_loc=0x80000226
15486         cmp $TF $DIR/$tfile || error "cmp failed"
15487         lctl set_param fail_loc=0
15488
15489         rm -f $TF
15490 }
15491 run_test 152 "test read/write with enomem ============================"
15492
15493 test_153() {
15494         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15495 }
15496 run_test 153 "test if fdatasync does not crash ======================="
15497
15498 dot_lustre_fid_permission_check() {
15499         local fid=$1
15500         local ffid=$MOUNT/.lustre/fid/$fid
15501         local test_dir=$2
15502
15503         echo "stat fid $fid"
15504         stat $ffid || error "stat $ffid failed."
15505         echo "touch fid $fid"
15506         touch $ffid || error "touch $ffid failed."
15507         echo "write to fid $fid"
15508         cat /etc/hosts > $ffid || error "write $ffid failed."
15509         echo "read fid $fid"
15510         diff /etc/hosts $ffid || error "read $ffid failed."
15511         echo "append write to fid $fid"
15512         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15513         echo "rename fid $fid"
15514         mv $ffid $test_dir/$tfile.1 &&
15515                 error "rename $ffid to $tfile.1 should fail."
15516         touch $test_dir/$tfile.1
15517         mv $test_dir/$tfile.1 $ffid &&
15518                 error "rename $tfile.1 to $ffid should fail."
15519         rm -f $test_dir/$tfile.1
15520         echo "truncate fid $fid"
15521         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15522         echo "link fid $fid"
15523         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15524         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15525                 echo "setfacl fid $fid"
15526                 setfacl -R -m u:$USER0:rwx $ffid ||
15527                         error "setfacl $ffid failed"
15528                 echo "getfacl fid $fid"
15529                 getfacl $ffid || error "getfacl $ffid failed."
15530         fi
15531         echo "unlink fid $fid"
15532         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15533         echo "mknod fid $fid"
15534         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15535
15536         fid=[0xf00000400:0x1:0x0]
15537         ffid=$MOUNT/.lustre/fid/$fid
15538
15539         echo "stat non-exist fid $fid"
15540         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15541         echo "write to non-exist fid $fid"
15542         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15543         echo "link new fid $fid"
15544         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15545
15546         mkdir -p $test_dir/$tdir
15547         touch $test_dir/$tdir/$tfile
15548         fid=$($LFS path2fid $test_dir/$tdir)
15549         rc=$?
15550         [ $rc -ne 0 ] &&
15551                 error "error: could not get fid for $test_dir/$dir/$tfile."
15552
15553         ffid=$MOUNT/.lustre/fid/$fid
15554
15555         echo "ls $fid"
15556         ls $ffid || error "ls $ffid failed."
15557         echo "touch $fid/$tfile.1"
15558         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15559
15560         echo "touch $MOUNT/.lustre/fid/$tfile"
15561         touch $MOUNT/.lustre/fid/$tfile && \
15562                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15563
15564         echo "setxattr to $MOUNT/.lustre/fid"
15565         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15566
15567         echo "listxattr for $MOUNT/.lustre/fid"
15568         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15569
15570         echo "delxattr from $MOUNT/.lustre/fid"
15571         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15572
15573         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15574         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15575                 error "touch invalid fid should fail."
15576
15577         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15578         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15579                 error "touch non-normal fid should fail."
15580
15581         echo "rename $tdir to $MOUNT/.lustre/fid"
15582         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15583                 error "rename to $MOUNT/.lustre/fid should fail."
15584
15585         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15586         then            # LU-3547
15587                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15588                 local new_obf_mode=777
15589
15590                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15591                 chmod $new_obf_mode $DIR/.lustre/fid ||
15592                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15593
15594                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15595                 [ $obf_mode -eq $new_obf_mode ] ||
15596                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15597
15598                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15599                 chmod $old_obf_mode $DIR/.lustre/fid ||
15600                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15601         fi
15602
15603         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15604         fid=$($LFS path2fid $test_dir/$tfile-2)
15605
15606         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15607         then # LU-5424
15608                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15609                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15610                         error "create lov data thru .lustre failed"
15611         fi
15612         echo "cp /etc/passwd $test_dir/$tfile-2"
15613         cp /etc/passwd $test_dir/$tfile-2 ||
15614                 error "copy to $test_dir/$tfile-2 failed."
15615         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15616         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15617                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15618
15619         rm -rf $test_dir/tfile.lnk
15620         rm -rf $test_dir/$tfile-2
15621 }
15622
15623 test_154A() {
15624         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15625                 skip "Need MDS version at least 2.4.1"
15626
15627         local tf=$DIR/$tfile
15628         touch $tf
15629
15630         local fid=$($LFS path2fid $tf)
15631         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15632
15633         # check that we get the same pathname back
15634         local rootpath
15635         local found
15636         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15637                 echo "$rootpath $fid"
15638                 found=$($LFS fid2path $rootpath "$fid")
15639                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15640                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15641         done
15642
15643         # check wrong root path format
15644         rootpath=$MOUNT"_wrong"
15645         found=$($LFS fid2path $rootpath "$fid")
15646         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15647 }
15648 run_test 154A "lfs path2fid and fid2path basic checks"
15649
15650 test_154B() {
15651         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15652                 skip "Need MDS version at least 2.4.1"
15653
15654         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15655         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15656         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15657         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15658
15659         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15660         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15661
15662         # check that we get the same pathname
15663         echo "PFID: $PFID, name: $name"
15664         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15665         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15666         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15667                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15668
15669         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15670 }
15671 run_test 154B "verify the ll_decode_linkea tool"
15672
15673 test_154a() {
15674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15675         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15676         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15677                 skip "Need MDS version at least 2.2.51"
15678         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15679
15680         cp /etc/hosts $DIR/$tfile
15681
15682         fid=$($LFS path2fid $DIR/$tfile)
15683         rc=$?
15684         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15685
15686         dot_lustre_fid_permission_check "$fid" $DIR ||
15687                 error "dot lustre permission check $fid failed"
15688
15689         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15690
15691         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15692
15693         touch $MOUNT/.lustre/file &&
15694                 error "creation is not allowed under .lustre"
15695
15696         mkdir $MOUNT/.lustre/dir &&
15697                 error "mkdir is not allowed under .lustre"
15698
15699         rm -rf $DIR/$tfile
15700 }
15701 run_test 154a "Open-by-FID"
15702
15703 test_154b() {
15704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15705         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15707         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15708                 skip "Need MDS version at least 2.2.51"
15709
15710         local remote_dir=$DIR/$tdir/remote_dir
15711         local MDTIDX=1
15712         local rc=0
15713
15714         mkdir -p $DIR/$tdir
15715         $LFS mkdir -i $MDTIDX $remote_dir ||
15716                 error "create remote directory failed"
15717
15718         cp /etc/hosts $remote_dir/$tfile
15719
15720         fid=$($LFS path2fid $remote_dir/$tfile)
15721         rc=$?
15722         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15723
15724         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15725                 error "dot lustre permission check $fid failed"
15726         rm -rf $DIR/$tdir
15727 }
15728 run_test 154b "Open-by-FID for remote directory"
15729
15730 test_154c() {
15731         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15732                 skip "Need MDS version at least 2.4.1"
15733
15734         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15735         local FID1=$($LFS path2fid $DIR/$tfile.1)
15736         local FID2=$($LFS path2fid $DIR/$tfile.2)
15737         local FID3=$($LFS path2fid $DIR/$tfile.3)
15738
15739         local N=1
15740         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15741                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15742                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15743                 local want=FID$N
15744                 [ "$FID" = "${!want}" ] ||
15745                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15746                 N=$((N + 1))
15747         done
15748
15749         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15750         do
15751                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15752                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15753                 N=$((N + 1))
15754         done
15755 }
15756 run_test 154c "lfs path2fid and fid2path multiple arguments"
15757
15758 test_154d() {
15759         remote_mds_nodsh && skip "remote MDS with nodsh"
15760         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15761                 skip "Need MDS version at least 2.5.53"
15762
15763         if remote_mds; then
15764                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15765         else
15766                 nid="0@lo"
15767         fi
15768         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15769         local fd
15770         local cmd
15771
15772         rm -f $DIR/$tfile
15773         touch $DIR/$tfile
15774
15775         local fid=$($LFS path2fid $DIR/$tfile)
15776         # Open the file
15777         fd=$(free_fd)
15778         cmd="exec $fd<$DIR/$tfile"
15779         eval $cmd
15780         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15781         echo "$fid_list" | grep "$fid"
15782         rc=$?
15783
15784         cmd="exec $fd>/dev/null"
15785         eval $cmd
15786         if [ $rc -ne 0 ]; then
15787                 error "FID $fid not found in open files list $fid_list"
15788         fi
15789 }
15790 run_test 154d "Verify open file fid"
15791
15792 test_154e()
15793 {
15794         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15795                 skip "Need MDS version at least 2.6.50"
15796
15797         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15798                 error ".lustre returned by readdir"
15799         fi
15800 }
15801 run_test 154e ".lustre is not returned by readdir"
15802
15803 test_154f() {
15804         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15805
15806         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15807         mkdir_on_mdt0 $DIR/$tdir
15808         # test dirs inherit from its stripe
15809         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15810         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15811         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15812         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15813         touch $DIR/f
15814
15815         # get fid of parents
15816         local FID0=$($LFS path2fid $DIR/$tdir)
15817         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15818         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15819         local FID3=$($LFS path2fid $DIR)
15820
15821         # check that path2fid --parents returns expected <parent_fid>/name
15822         # 1) test for a directory (single parent)
15823         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15824         [ "$parent" == "$FID0/foo1" ] ||
15825                 error "expected parent: $FID0/foo1, got: $parent"
15826
15827         # 2) test for a file with nlink > 1 (multiple parents)
15828         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15829         echo "$parent" | grep -F "$FID1/$tfile" ||
15830                 error "$FID1/$tfile not returned in parent list"
15831         echo "$parent" | grep -F "$FID2/link" ||
15832                 error "$FID2/link not returned in parent list"
15833
15834         # 3) get parent by fid
15835         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15836         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15837         echo "$parent" | grep -F "$FID1/$tfile" ||
15838                 error "$FID1/$tfile not returned in parent list (by fid)"
15839         echo "$parent" | grep -F "$FID2/link" ||
15840                 error "$FID2/link not returned in parent list (by fid)"
15841
15842         # 4) test for entry in root directory
15843         parent=$($LFS path2fid --parents $DIR/f)
15844         echo "$parent" | grep -F "$FID3/f" ||
15845                 error "$FID3/f not returned in parent list"
15846
15847         # 5) test it on root directory
15848         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15849                 error "$MOUNT should not have parents"
15850
15851         # enable xattr caching and check that linkea is correctly updated
15852         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15853         save_lustre_params client "llite.*.xattr_cache" > $save
15854         lctl set_param llite.*.xattr_cache 1
15855
15856         # 6.1) linkea update on rename
15857         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15858
15859         # get parents by fid
15860         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15861         # foo1 should no longer be returned in parent list
15862         echo "$parent" | grep -F "$FID1" &&
15863                 error "$FID1 should no longer be in parent list"
15864         # the new path should appear
15865         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15866                 error "$FID2/$tfile.moved is not in parent list"
15867
15868         # 6.2) linkea update on unlink
15869         rm -f $DIR/$tdir/foo2/link
15870         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15871         # foo2/link should no longer be returned in parent list
15872         echo "$parent" | grep -F "$FID2/link" &&
15873                 error "$FID2/link should no longer be in parent list"
15874         true
15875
15876         rm -f $DIR/f
15877         restore_lustre_params < $save
15878         rm -f $save
15879 }
15880 run_test 154f "get parent fids by reading link ea"
15881
15882 test_154g()
15883 {
15884         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15885            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15886                 skip "Need MDS version at least 2.6.92"
15887
15888         mkdir_on_mdt0 $DIR/$tdir
15889         llapi_fid_test -d $DIR/$tdir
15890 }
15891 run_test 154g "various llapi FID tests"
15892
15893 test_155_small_load() {
15894     local temp=$TMP/$tfile
15895     local file=$DIR/$tfile
15896
15897     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15898         error "dd of=$temp bs=6096 count=1 failed"
15899     cp $temp $file
15900     cancel_lru_locks $OSC
15901     cmp $temp $file || error "$temp $file differ"
15902
15903     $TRUNCATE $temp 6000
15904     $TRUNCATE $file 6000
15905     cmp $temp $file || error "$temp $file differ (truncate1)"
15906
15907     echo "12345" >>$temp
15908     echo "12345" >>$file
15909     cmp $temp $file || error "$temp $file differ (append1)"
15910
15911     echo "12345" >>$temp
15912     echo "12345" >>$file
15913     cmp $temp $file || error "$temp $file differ (append2)"
15914
15915     rm -f $temp $file
15916     true
15917 }
15918
15919 test_155_big_load() {
15920         remote_ost_nodsh && skip "remote OST with nodsh"
15921
15922         local temp=$TMP/$tfile
15923         local file=$DIR/$tfile
15924
15925         free_min_max
15926         local cache_size=$(do_facet ost$((MAXI+1)) \
15927                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15928
15929         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15930         # pre-set value
15931         if [ -z "$cache_size" ]; then
15932                 cache_size=256
15933         fi
15934         local large_file_size=$((cache_size * 2))
15935
15936         echo "OSS cache size: $cache_size KB"
15937         echo "Large file size: $large_file_size KB"
15938
15939         [ $MAXV -le $large_file_size ] &&
15940                 skip_env "max available OST size needs > $large_file_size KB"
15941
15942         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15943
15944         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15945                 error "dd of=$temp bs=$large_file_size count=1k failed"
15946         cp $temp $file
15947         ls -lh $temp $file
15948         cancel_lru_locks osc
15949         cmp $temp $file || error "$temp $file differ"
15950
15951         rm -f $temp $file
15952         true
15953 }
15954
15955 save_writethrough() {
15956         local facets=$(get_facets OST)
15957
15958         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15959 }
15960
15961 test_155a() {
15962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15963
15964         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15965
15966         save_writethrough $p
15967
15968         set_cache read on
15969         set_cache writethrough on
15970         test_155_small_load
15971         restore_lustre_params < $p
15972         rm -f $p
15973 }
15974 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15975
15976 test_155b() {
15977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15978
15979         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15980
15981         save_writethrough $p
15982
15983         set_cache read on
15984         set_cache writethrough off
15985         test_155_small_load
15986         restore_lustre_params < $p
15987         rm -f $p
15988 }
15989 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15990
15991 test_155c() {
15992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15993
15994         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15995
15996         save_writethrough $p
15997
15998         set_cache read off
15999         set_cache writethrough on
16000         test_155_small_load
16001         restore_lustre_params < $p
16002         rm -f $p
16003 }
16004 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16005
16006 test_155d() {
16007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16008
16009         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16010
16011         save_writethrough $p
16012
16013         set_cache read off
16014         set_cache writethrough off
16015         test_155_small_load
16016         restore_lustre_params < $p
16017         rm -f $p
16018 }
16019 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16020
16021 test_155e() {
16022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16023
16024         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16025
16026         save_writethrough $p
16027
16028         set_cache read on
16029         set_cache writethrough on
16030         test_155_big_load
16031         restore_lustre_params < $p
16032         rm -f $p
16033 }
16034 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16035
16036 test_155f() {
16037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16038
16039         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16040
16041         save_writethrough $p
16042
16043         set_cache read on
16044         set_cache writethrough off
16045         test_155_big_load
16046         restore_lustre_params < $p
16047         rm -f $p
16048 }
16049 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16050
16051 test_155g() {
16052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16053
16054         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16055
16056         save_writethrough $p
16057
16058         set_cache read off
16059         set_cache writethrough on
16060         test_155_big_load
16061         restore_lustre_params < $p
16062         rm -f $p
16063 }
16064 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16065
16066 test_155h() {
16067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16068
16069         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16070
16071         save_writethrough $p
16072
16073         set_cache read off
16074         set_cache writethrough off
16075         test_155_big_load
16076         restore_lustre_params < $p
16077         rm -f $p
16078 }
16079 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16080
16081 test_156() {
16082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16083         remote_ost_nodsh && skip "remote OST with nodsh"
16084         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16085                 skip "stats not implemented on old servers"
16086         [ "$ost1_FSTYPE" = "zfs" ] &&
16087                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16088
16089         local CPAGES=3
16090         local BEFORE
16091         local AFTER
16092         local file="$DIR/$tfile"
16093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16094
16095         save_writethrough $p
16096         roc_hit_init
16097
16098         log "Turn on read and write cache"
16099         set_cache read on
16100         set_cache writethrough on
16101
16102         log "Write data and read it back."
16103         log "Read should be satisfied from the cache."
16104         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16105         BEFORE=$(roc_hit)
16106         cancel_lru_locks osc
16107         cat $file >/dev/null
16108         AFTER=$(roc_hit)
16109         if ! let "AFTER - BEFORE == CPAGES"; then
16110                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16111         else
16112                 log "cache hits: before: $BEFORE, after: $AFTER"
16113         fi
16114
16115         log "Read again; it should be satisfied from the cache."
16116         BEFORE=$AFTER
16117         cancel_lru_locks osc
16118         cat $file >/dev/null
16119         AFTER=$(roc_hit)
16120         if ! let "AFTER - BEFORE == CPAGES"; then
16121                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16122         else
16123                 log "cache hits:: before: $BEFORE, after: $AFTER"
16124         fi
16125
16126         log "Turn off the read cache and turn on the write cache"
16127         set_cache read off
16128         set_cache writethrough on
16129
16130         log "Read again; it should be satisfied from the cache."
16131         BEFORE=$(roc_hit)
16132         cancel_lru_locks osc
16133         cat $file >/dev/null
16134         AFTER=$(roc_hit)
16135         if ! let "AFTER - BEFORE == CPAGES"; then
16136                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16137         else
16138                 log "cache hits:: before: $BEFORE, after: $AFTER"
16139         fi
16140
16141         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16142                 # > 2.12.56 uses pagecache if cached
16143                 log "Read again; it should not be satisfied from the cache."
16144                 BEFORE=$AFTER
16145                 cancel_lru_locks osc
16146                 cat $file >/dev/null
16147                 AFTER=$(roc_hit)
16148                 if ! let "AFTER - BEFORE == 0"; then
16149                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16150                 else
16151                         log "cache hits:: before: $BEFORE, after: $AFTER"
16152                 fi
16153         fi
16154
16155         log "Write data and read it back."
16156         log "Read should be satisfied from the cache."
16157         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16158         BEFORE=$(roc_hit)
16159         cancel_lru_locks osc
16160         cat $file >/dev/null
16161         AFTER=$(roc_hit)
16162         if ! let "AFTER - BEFORE == CPAGES"; then
16163                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16164         else
16165                 log "cache hits:: before: $BEFORE, after: $AFTER"
16166         fi
16167
16168         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16169                 # > 2.12.56 uses pagecache if cached
16170                 log "Read again; it should not be satisfied from the cache."
16171                 BEFORE=$AFTER
16172                 cancel_lru_locks osc
16173                 cat $file >/dev/null
16174                 AFTER=$(roc_hit)
16175                 if ! let "AFTER - BEFORE == 0"; then
16176                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16177                 else
16178                         log "cache hits:: before: $BEFORE, after: $AFTER"
16179                 fi
16180         fi
16181
16182         log "Turn off read and write cache"
16183         set_cache read off
16184         set_cache writethrough off
16185
16186         log "Write data and read it back"
16187         log "It should not be satisfied from the cache."
16188         rm -f $file
16189         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16190         cancel_lru_locks osc
16191         BEFORE=$(roc_hit)
16192         cat $file >/dev/null
16193         AFTER=$(roc_hit)
16194         if ! let "AFTER - BEFORE == 0"; then
16195                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16196         else
16197                 log "cache hits:: before: $BEFORE, after: $AFTER"
16198         fi
16199
16200         log "Turn on the read cache and turn off the write cache"
16201         set_cache read on
16202         set_cache writethrough off
16203
16204         log "Write data and read it back"
16205         log "It should not be satisfied from the cache."
16206         rm -f $file
16207         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16208         BEFORE=$(roc_hit)
16209         cancel_lru_locks osc
16210         cat $file >/dev/null
16211         AFTER=$(roc_hit)
16212         if ! let "AFTER - BEFORE == 0"; then
16213                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16214         else
16215                 log "cache hits:: before: $BEFORE, after: $AFTER"
16216         fi
16217
16218         log "Read again; it should be satisfied from the cache."
16219         BEFORE=$(roc_hit)
16220         cancel_lru_locks osc
16221         cat $file >/dev/null
16222         AFTER=$(roc_hit)
16223         if ! let "AFTER - BEFORE == CPAGES"; then
16224                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16225         else
16226                 log "cache hits:: before: $BEFORE, after: $AFTER"
16227         fi
16228
16229         restore_lustre_params < $p
16230         rm -f $p $file
16231 }
16232 run_test 156 "Verification of tunables"
16233
16234 test_160a() {
16235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16236         remote_mds_nodsh && skip "remote MDS with nodsh"
16237         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16238                 skip "Need MDS version at least 2.2.0"
16239
16240         changelog_register || error "changelog_register failed"
16241         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16242         changelog_users $SINGLEMDS | grep -q $cl_user ||
16243                 error "User $cl_user not found in changelog_users"
16244
16245         mkdir_on_mdt0 $DIR/$tdir
16246
16247         # change something
16248         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16249         changelog_clear 0 || error "changelog_clear failed"
16250         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16251         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16252         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16253         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16254         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16255         rm $DIR/$tdir/pics/desktop.jpg
16256
16257         echo "verifying changelog mask"
16258         changelog_chmask "-MKDIR"
16259         changelog_chmask "-CLOSE"
16260
16261         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16262         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16263
16264         changelog_chmask "+MKDIR"
16265         changelog_chmask "+CLOSE"
16266
16267         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16268         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16269
16270         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16271         CLOSES=$(changelog_dump | grep -c "CLOSE")
16272         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16273         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16274
16275         # verify contents
16276         echo "verifying target fid"
16277         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16278         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16279         [ "$fidc" == "$fidf" ] ||
16280                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16281         echo "verifying parent fid"
16282         # The FID returned from the Changelog may be the directory shard on
16283         # a different MDT, and not the FID returned by path2fid on the parent.
16284         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16285         # since this is what will matter when recreating this file in the tree.
16286         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16287         local pathp=$($LFS fid2path $MOUNT "$fidp")
16288         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16289                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16290
16291         echo "getting records for $cl_user"
16292         changelog_users $SINGLEMDS
16293         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16294         local nclr=3
16295         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16296                 error "changelog_clear failed"
16297         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16298         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16299         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16300                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16301
16302         local min0_rec=$(changelog_users $SINGLEMDS |
16303                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16304         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16305                           awk '{ print $1; exit; }')
16306
16307         changelog_dump | tail -n 5
16308         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16309         [ $first_rec == $((min0_rec + 1)) ] ||
16310                 error "first index should be $min0_rec + 1 not $first_rec"
16311
16312         # LU-3446 changelog index reset on MDT restart
16313         local cur_rec1=$(changelog_users $SINGLEMDS |
16314                          awk '/^current.index:/ { print $NF }')
16315         changelog_clear 0 ||
16316                 error "clear all changelog records for $cl_user failed"
16317         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16318         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16319                 error "Fail to start $SINGLEMDS"
16320         local cur_rec2=$(changelog_users $SINGLEMDS |
16321                          awk '/^current.index:/ { print $NF }')
16322         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16323         [ $cur_rec1 == $cur_rec2 ] ||
16324                 error "current index should be $cur_rec1 not $cur_rec2"
16325
16326         echo "verifying users from this test are deregistered"
16327         changelog_deregister || error "changelog_deregister failed"
16328         changelog_users $SINGLEMDS | grep -q $cl_user &&
16329                 error "User '$cl_user' still in changelog_users"
16330
16331         # lctl get_param -n mdd.*.changelog_users
16332         # current_index: 144
16333         # ID    index (idle seconds)
16334         # cl3   144   (2) mask=<list>
16335         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16336                 # this is the normal case where all users were deregistered
16337                 # make sure no new records are added when no users are present
16338                 local last_rec1=$(changelog_users $SINGLEMDS |
16339                                   awk '/^current.index:/ { print $NF }')
16340                 touch $DIR/$tdir/chloe
16341                 local last_rec2=$(changelog_users $SINGLEMDS |
16342                                   awk '/^current.index:/ { print $NF }')
16343                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16344                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16345         else
16346                 # any changelog users must be leftovers from a previous test
16347                 changelog_users $SINGLEMDS
16348                 echo "other changelog users; can't verify off"
16349         fi
16350 }
16351 run_test 160a "changelog sanity"
16352
16353 test_160b() { # LU-3587
16354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16355         remote_mds_nodsh && skip "remote MDS with nodsh"
16356         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16357                 skip "Need MDS version at least 2.2.0"
16358
16359         changelog_register || error "changelog_register failed"
16360         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16361         changelog_users $SINGLEMDS | grep -q $cl_user ||
16362                 error "User '$cl_user' not found in changelog_users"
16363
16364         local longname1=$(str_repeat a 255)
16365         local longname2=$(str_repeat b 255)
16366
16367         cd $DIR
16368         echo "creating very long named file"
16369         touch $longname1 || error "create of '$longname1' failed"
16370         echo "renaming very long named file"
16371         mv $longname1 $longname2
16372
16373         changelog_dump | grep RENME | tail -n 5
16374         rm -f $longname2
16375 }
16376 run_test 160b "Verify that very long rename doesn't crash in changelog"
16377
16378 test_160c() {
16379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16380         remote_mds_nodsh && skip "remote MDS with nodsh"
16381
16382         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16383                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16384                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16385                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16386
16387         local rc=0
16388
16389         # Registration step
16390         changelog_register || error "changelog_register failed"
16391
16392         rm -rf $DIR/$tdir
16393         mkdir -p $DIR/$tdir
16394         $MCREATE $DIR/$tdir/foo_160c
16395         changelog_chmask "-TRUNC"
16396         $TRUNCATE $DIR/$tdir/foo_160c 200
16397         changelog_chmask "+TRUNC"
16398         $TRUNCATE $DIR/$tdir/foo_160c 199
16399         changelog_dump | tail -n 5
16400         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16401         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16402 }
16403 run_test 160c "verify that changelog log catch the truncate event"
16404
16405 test_160d() {
16406         remote_mds_nodsh && skip "remote MDS with nodsh"
16407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16409         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16410                 skip "Need MDS version at least 2.7.60"
16411
16412         # Registration step
16413         changelog_register || error "changelog_register failed"
16414
16415         mkdir -p $DIR/$tdir/migrate_dir
16416         changelog_clear 0 || error "changelog_clear failed"
16417
16418         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16419         changelog_dump | tail -n 5
16420         local migrates=$(changelog_dump | grep -c "MIGRT")
16421         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16422 }
16423 run_test 160d "verify that changelog log catch the migrate event"
16424
16425 test_160e() {
16426         remote_mds_nodsh && skip "remote MDS with nodsh"
16427
16428         # Create a user
16429         changelog_register || error "changelog_register failed"
16430
16431         local MDT0=$(facet_svc $SINGLEMDS)
16432         local rc
16433
16434         # No user (expect fail)
16435         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16436         rc=$?
16437         if [ $rc -eq 0 ]; then
16438                 error "Should fail without user"
16439         elif [ $rc -ne 4 ]; then
16440                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16441         fi
16442
16443         # Delete a future user (expect fail)
16444         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16445         rc=$?
16446         if [ $rc -eq 0 ]; then
16447                 error "Deleted non-existant user cl77"
16448         elif [ $rc -ne 2 ]; then
16449                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16450         fi
16451
16452         # Clear to a bad index (1 billion should be safe)
16453         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16454         rc=$?
16455
16456         if [ $rc -eq 0 ]; then
16457                 error "Successfully cleared to invalid CL index"
16458         elif [ $rc -ne 22 ]; then
16459                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16460         fi
16461 }
16462 run_test 160e "changelog negative testing (should return errors)"
16463
16464 test_160f() {
16465         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16466         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16467                 skip "Need MDS version at least 2.10.56"
16468
16469         local mdts=$(comma_list $(mdts_nodes))
16470
16471         # Create a user
16472         changelog_register || error "first changelog_register failed"
16473         changelog_register || error "second changelog_register failed"
16474         local cl_users
16475         declare -A cl_user1
16476         declare -A cl_user2
16477         local user_rec1
16478         local user_rec2
16479         local i
16480
16481         # generate some changelog records to accumulate on each MDT
16482         # use all_char because created files should be evenly distributed
16483         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16484                 error "test_mkdir $tdir failed"
16485         log "$(date +%s): creating first files"
16486         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16487                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16488                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16489         done
16490
16491         # check changelogs have been generated
16492         local start=$SECONDS
16493         local idle_time=$((MDSCOUNT * 5 + 5))
16494         local nbcl=$(changelog_dump | wc -l)
16495         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16496
16497         for param in "changelog_max_idle_time=$idle_time" \
16498                      "changelog_gc=1" \
16499                      "changelog_min_gc_interval=2" \
16500                      "changelog_min_free_cat_entries=3"; do
16501                 local MDT0=$(facet_svc $SINGLEMDS)
16502                 local var="${param%=*}"
16503                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16504
16505                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16506                 do_nodes $mdts $LCTL set_param mdd.*.$param
16507         done
16508
16509         # force cl_user2 to be idle (1st part), but also cancel the
16510         # cl_user1 records so that it is not evicted later in the test.
16511         local sleep1=$((idle_time / 2))
16512         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16513         sleep $sleep1
16514
16515         # simulate changelog catalog almost full
16516         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16517         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16518
16519         for i in $(seq $MDSCOUNT); do
16520                 cl_users=(${CL_USERS[mds$i]})
16521                 cl_user1[mds$i]="${cl_users[0]}"
16522                 cl_user2[mds$i]="${cl_users[1]}"
16523
16524                 [ -n "${cl_user1[mds$i]}" ] ||
16525                         error "mds$i: no user registered"
16526                 [ -n "${cl_user2[mds$i]}" ] ||
16527                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16528
16529                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16530                 [ -n "$user_rec1" ] ||
16531                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16532                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16533                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16534                 [ -n "$user_rec2" ] ||
16535                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16536                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16537                      "$user_rec1 + 2 == $user_rec2"
16538                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16539                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16540                               "$user_rec1 + 2, but is $user_rec2"
16541                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16542                 [ -n "$user_rec2" ] ||
16543                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16544                 [ $user_rec1 == $user_rec2 ] ||
16545                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16546                               "$user_rec1, but is $user_rec2"
16547         done
16548
16549         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16550         local sleep2=$((idle_time - (SECONDS - start) + 1))
16551         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16552         sleep $sleep2
16553
16554         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16555         # cl_user1 should be OK because it recently processed records.
16556         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16557         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16558                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16559                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16560         done
16561
16562         # ensure gc thread is done
16563         for i in $(mdts_nodes); do
16564                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16565                         error "$i: GC-thread not done"
16566         done
16567
16568         local first_rec
16569         for (( i = 1; i <= MDSCOUNT; i++ )); do
16570                 # check cl_user1 still registered
16571                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16572                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16573                 # check cl_user2 unregistered
16574                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16575                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16576
16577                 # check changelogs are present and starting at $user_rec1 + 1
16578                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16579                 [ -n "$user_rec1" ] ||
16580                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16581                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16582                             awk '{ print $1; exit; }')
16583
16584                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16585                 [ $((user_rec1 + 1)) == $first_rec ] ||
16586                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16587         done
16588 }
16589 run_test 160f "changelog garbage collect (timestamped users)"
16590
16591 test_160g() {
16592         remote_mds_nodsh && skip "remote MDS with nodsh"
16593         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16594                 skip "Need MDS version at least 2.14.55"
16595
16596         local mdts=$(comma_list $(mdts_nodes))
16597
16598         # Create a user
16599         changelog_register || error "first changelog_register failed"
16600         changelog_register || error "second changelog_register failed"
16601         local cl_users
16602         declare -A cl_user1
16603         declare -A cl_user2
16604         local user_rec1
16605         local user_rec2
16606         local i
16607
16608         # generate some changelog records to accumulate on each MDT
16609         # use all_char because created files should be evenly distributed
16610         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16611                 error "test_mkdir $tdir failed"
16612         for ((i = 0; i < MDSCOUNT; i++)); do
16613                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16614                         error "create $DIR/$tdir/d$i.1 failed"
16615         done
16616
16617         # check changelogs have been generated
16618         local nbcl=$(changelog_dump | wc -l)
16619         (( $nbcl > 0 )) || error "no changelogs found"
16620
16621         # reduce the max_idle_indexes value to make sure we exceed it
16622         for param in "changelog_max_idle_indexes=2" \
16623                      "changelog_gc=1" \
16624                      "changelog_min_gc_interval=2"; do
16625                 local MDT0=$(facet_svc $SINGLEMDS)
16626                 local var="${param%=*}"
16627                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16628
16629                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16630                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16631                         error "unable to set mdd.*.$param"
16632         done
16633
16634         local start=$SECONDS
16635         for i in $(seq $MDSCOUNT); do
16636                 cl_users=(${CL_USERS[mds$i]})
16637                 cl_user1[mds$i]="${cl_users[0]}"
16638                 cl_user2[mds$i]="${cl_users[1]}"
16639
16640                 [ -n "${cl_user1[mds$i]}" ] ||
16641                         error "mds$i: user1 is not registered"
16642                 [ -n "${cl_user2[mds$i]}" ] ||
16643                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16644
16645                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16646                 [ -n "$user_rec1" ] ||
16647                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16648                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16649                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16650                 [ -n "$user_rec2" ] ||
16651                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16652                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16653                      "$user_rec1 + 2 == $user_rec2"
16654                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16655                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16656                               "expected $user_rec1 + 2, but is $user_rec2"
16657                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16658                 [ -n "$user_rec2" ] ||
16659                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16660                 [ $user_rec1 == $user_rec2 ] ||
16661                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16662                               "expected $user_rec1, but is $user_rec2"
16663         done
16664
16665         # ensure we are past the previous changelog_min_gc_interval set above
16666         local sleep2=$((start + 2 - SECONDS))
16667         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16668         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16669         # cl_user1 should be OK because it recently processed records.
16670         for ((i = 0; i < MDSCOUNT; i++)); do
16671                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16672                         error "create $DIR/$tdir/d$i.3 failed"
16673         done
16674
16675         # ensure gc thread is done
16676         for i in $(mdts_nodes); do
16677                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16678                         error "$i: GC-thread not done"
16679         done
16680
16681         local first_rec
16682         for (( i = 1; i <= MDSCOUNT; i++ )); do
16683                 # check cl_user1 still registered
16684                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16685                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16686                 # check cl_user2 unregistered
16687                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16688                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16689
16690                 # check changelogs are present and starting at $user_rec1 + 1
16691                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16692                 [ -n "$user_rec1" ] ||
16693                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16694                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16695                             awk '{ print $1; exit; }')
16696
16697                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16698                 [ $((user_rec1 + 1)) == $first_rec ] ||
16699                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16700         done
16701 }
16702 run_test 160g "changelog garbage collect on idle records"
16703
16704 test_160h() {
16705         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16706         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16707                 skip "Need MDS version at least 2.10.56"
16708
16709         local mdts=$(comma_list $(mdts_nodes))
16710
16711         # Create a user
16712         changelog_register || error "first changelog_register failed"
16713         changelog_register || error "second changelog_register failed"
16714         local cl_users
16715         declare -A cl_user1
16716         declare -A cl_user2
16717         local user_rec1
16718         local user_rec2
16719         local i
16720
16721         # generate some changelog records to accumulate on each MDT
16722         # use all_char because created files should be evenly distributed
16723         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16724                 error "test_mkdir $tdir failed"
16725         for ((i = 0; i < MDSCOUNT; i++)); do
16726                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16727                         error "create $DIR/$tdir/d$i.1 failed"
16728         done
16729
16730         # check changelogs have been generated
16731         local nbcl=$(changelog_dump | wc -l)
16732         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16733
16734         for param in "changelog_max_idle_time=10" \
16735                      "changelog_gc=1" \
16736                      "changelog_min_gc_interval=2"; do
16737                 local MDT0=$(facet_svc $SINGLEMDS)
16738                 local var="${param%=*}"
16739                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16740
16741                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16742                 do_nodes $mdts $LCTL set_param mdd.*.$param
16743         done
16744
16745         # force cl_user2 to be idle (1st part)
16746         sleep 9
16747
16748         for i in $(seq $MDSCOUNT); do
16749                 cl_users=(${CL_USERS[mds$i]})
16750                 cl_user1[mds$i]="${cl_users[0]}"
16751                 cl_user2[mds$i]="${cl_users[1]}"
16752
16753                 [ -n "${cl_user1[mds$i]}" ] ||
16754                         error "mds$i: no user registered"
16755                 [ -n "${cl_user2[mds$i]}" ] ||
16756                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16757
16758                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16759                 [ -n "$user_rec1" ] ||
16760                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16761                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16762                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16763                 [ -n "$user_rec2" ] ||
16764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16765                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16766                      "$user_rec1 + 2 == $user_rec2"
16767                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16768                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16769                               "$user_rec1 + 2, but is $user_rec2"
16770                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16771                 [ -n "$user_rec2" ] ||
16772                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16773                 [ $user_rec1 == $user_rec2 ] ||
16774                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16775                               "$user_rec1, but is $user_rec2"
16776         done
16777
16778         # force cl_user2 to be idle (2nd part) and to reach
16779         # changelog_max_idle_time
16780         sleep 2
16781
16782         # force each GC-thread start and block then
16783         # one per MDT/MDD, set fail_val accordingly
16784         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16785         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16786
16787         # generate more changelogs to trigger fail_loc
16788         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16789                 error "create $DIR/$tdir/${tfile}bis failed"
16790
16791         # stop MDT to stop GC-thread, should be done in back-ground as it will
16792         # block waiting for the thread to be released and exit
16793         declare -A stop_pids
16794         for i in $(seq $MDSCOUNT); do
16795                 stop mds$i &
16796                 stop_pids[mds$i]=$!
16797         done
16798
16799         for i in $(mdts_nodes); do
16800                 local facet
16801                 local nb=0
16802                 local facets=$(facets_up_on_host $i)
16803
16804                 for facet in ${facets//,/ }; do
16805                         if [[ $facet == mds* ]]; then
16806                                 nb=$((nb + 1))
16807                         fi
16808                 done
16809                 # ensure each MDS's gc threads are still present and all in "R"
16810                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16811                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16812                         error "$i: expected $nb GC-thread"
16813                 wait_update $i \
16814                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16815                         "R" 20 ||
16816                         error "$i: GC-thread not found in R-state"
16817                 # check umounts of each MDT on MDS have reached kthread_stop()
16818                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16819                         error "$i: expected $nb umount"
16820                 wait_update $i \
16821                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16822                         error "$i: umount not found in D-state"
16823         done
16824
16825         # release all GC-threads
16826         do_nodes $mdts $LCTL set_param fail_loc=0
16827
16828         # wait for MDT stop to complete
16829         for i in $(seq $MDSCOUNT); do
16830                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16831         done
16832
16833         # XXX
16834         # may try to check if any orphan changelog records are present
16835         # via ldiskfs/zfs and llog_reader...
16836
16837         # re-start/mount MDTs
16838         for i in $(seq $MDSCOUNT); do
16839                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16840                         error "Fail to start mds$i"
16841         done
16842
16843         local first_rec
16844         for i in $(seq $MDSCOUNT); do
16845                 # check cl_user1 still registered
16846                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16847                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16848                 # check cl_user2 unregistered
16849                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16850                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16851
16852                 # check changelogs are present and starting at $user_rec1 + 1
16853                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16854                 [ -n "$user_rec1" ] ||
16855                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16856                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16857                             awk '{ print $1; exit; }')
16858
16859                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16860                 [ $((user_rec1 + 1)) == $first_rec ] ||
16861                         error "mds$i: first index should be $user_rec1 + 1, " \
16862                               "but is $first_rec"
16863         done
16864 }
16865 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16866               "during mount"
16867
16868 test_160i() {
16869
16870         local mdts=$(comma_list $(mdts_nodes))
16871
16872         changelog_register || error "first changelog_register failed"
16873
16874         # generate some changelog records to accumulate on each MDT
16875         # use all_char because created files should be evenly distributed
16876         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16877                 error "test_mkdir $tdir failed"
16878         for ((i = 0; i < MDSCOUNT; i++)); do
16879                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16880                         error "create $DIR/$tdir/d$i.1 failed"
16881         done
16882
16883         # check changelogs have been generated
16884         local nbcl=$(changelog_dump | wc -l)
16885         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16886
16887         # simulate race between register and unregister
16888         # XXX as fail_loc is set per-MDS, with DNE configs the race
16889         # simulation will only occur for one MDT per MDS and for the
16890         # others the normal race scenario will take place
16891         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16892         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16893         do_nodes $mdts $LCTL set_param fail_val=1
16894
16895         # unregister 1st user
16896         changelog_deregister &
16897         local pid1=$!
16898         # wait some time for deregister work to reach race rdv
16899         sleep 2
16900         # register 2nd user
16901         changelog_register || error "2nd user register failed"
16902
16903         wait $pid1 || error "1st user deregister failed"
16904
16905         local i
16906         local last_rec
16907         declare -A LAST_REC
16908         for i in $(seq $MDSCOUNT); do
16909                 if changelog_users mds$i | grep "^cl"; then
16910                         # make sure new records are added with one user present
16911                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16912                                           awk '/^current.index:/ { print $NF }')
16913                 else
16914                         error "mds$i has no user registered"
16915                 fi
16916         done
16917
16918         # generate more changelog records to accumulate on each MDT
16919         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16920                 error "create $DIR/$tdir/${tfile}bis failed"
16921
16922         for i in $(seq $MDSCOUNT); do
16923                 last_rec=$(changelog_users $SINGLEMDS |
16924                            awk '/^current.index:/ { print $NF }')
16925                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16926                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16927                         error "changelogs are off on mds$i"
16928         done
16929 }
16930 run_test 160i "changelog user register/unregister race"
16931
16932 test_160j() {
16933         remote_mds_nodsh && skip "remote MDS with nodsh"
16934         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16935                 skip "Need MDS version at least 2.12.56"
16936
16937         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16938         stack_trap "umount $MOUNT2" EXIT
16939
16940         changelog_register || error "first changelog_register failed"
16941         stack_trap "changelog_deregister" EXIT
16942
16943         # generate some changelog
16944         # use all_char because created files should be evenly distributed
16945         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16946                 error "mkdir $tdir failed"
16947         for ((i = 0; i < MDSCOUNT; i++)); do
16948                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16949                         error "create $DIR/$tdir/d$i.1 failed"
16950         done
16951
16952         # open the changelog device
16953         exec 3>/dev/changelog-$FSNAME-MDT0000
16954         stack_trap "exec 3>&-" EXIT
16955         exec 4</dev/changelog-$FSNAME-MDT0000
16956         stack_trap "exec 4<&-" EXIT
16957
16958         # umount the first lustre mount
16959         umount $MOUNT
16960         stack_trap "mount_client $MOUNT" EXIT
16961
16962         # read changelog, which may or may not fail, but should not crash
16963         cat <&4 >/dev/null
16964
16965         # clear changelog
16966         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16967         changelog_users $SINGLEMDS | grep -q $cl_user ||
16968                 error "User $cl_user not found in changelog_users"
16969
16970         printf 'clear:'$cl_user':0' >&3
16971 }
16972 run_test 160j "client can be umounted while its chanangelog is being used"
16973
16974 test_160k() {
16975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16976         remote_mds_nodsh && skip "remote MDS with nodsh"
16977
16978         mkdir -p $DIR/$tdir/1/1
16979
16980         changelog_register || error "changelog_register failed"
16981         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16982
16983         changelog_users $SINGLEMDS | grep -q $cl_user ||
16984                 error "User '$cl_user' not found in changelog_users"
16985 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16986         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16987         rmdir $DIR/$tdir/1/1 & sleep 1
16988         mkdir $DIR/$tdir/2
16989         touch $DIR/$tdir/2/2
16990         rm -rf $DIR/$tdir/2
16991
16992         wait
16993         sleep 4
16994
16995         changelog_dump | grep rmdir || error "rmdir not recorded"
16996 }
16997 run_test 160k "Verify that changelog records are not lost"
16998
16999 # Verifies that a file passed as a parameter has recently had an operation
17000 # performed on it that has generated an MTIME changelog which contains the
17001 # correct parent FID. As files might reside on a different MDT from the
17002 # parent directory in DNE configurations, the FIDs are translated to paths
17003 # before being compared, which should be identical
17004 compare_mtime_changelog() {
17005         local file="${1}"
17006         local mdtidx
17007         local mtime
17008         local cl_fid
17009         local pdir
17010         local dir
17011
17012         mdtidx=$($LFS getstripe --mdt-index $file)
17013         mdtidx=$(printf "%04x" $mdtidx)
17014
17015         # Obtain the parent FID from the MTIME changelog
17016         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17017         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17018
17019         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17020         [ -z "$cl_fid" ] && error "parent FID not present"
17021
17022         # Verify that the path for the parent FID is the same as the path for
17023         # the test directory
17024         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17025
17026         dir=$(dirname $1)
17027
17028         [[ "${pdir%/}" == "$dir" ]] ||
17029                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17030 }
17031
17032 test_160l() {
17033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17034
17035         remote_mds_nodsh && skip "remote MDS with nodsh"
17036         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17037                 skip "Need MDS version at least 2.13.55"
17038
17039         local cl_user
17040
17041         changelog_register || error "changelog_register failed"
17042         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17043
17044         changelog_users $SINGLEMDS | grep -q $cl_user ||
17045                 error "User '$cl_user' not found in changelog_users"
17046
17047         # Clear some types so that MTIME changelogs are generated
17048         changelog_chmask "-CREAT"
17049         changelog_chmask "-CLOSE"
17050
17051         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17052
17053         # Test CL_MTIME during setattr
17054         touch $DIR/$tdir/$tfile
17055         compare_mtime_changelog $DIR/$tdir/$tfile
17056
17057         # Test CL_MTIME during close
17058         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17059         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17060 }
17061 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17062
17063 test_160m() {
17064         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17065         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17066                 skip "Need MDS version at least 2.14.51"
17067         local cl_users
17068         local cl_user1
17069         local cl_user2
17070         local pid1
17071
17072         # Create a user
17073         changelog_register || error "first changelog_register failed"
17074         changelog_register || error "second changelog_register failed"
17075
17076         cl_users=(${CL_USERS[mds1]})
17077         cl_user1="${cl_users[0]}"
17078         cl_user2="${cl_users[1]}"
17079         # generate some changelog records to accumulate on MDT0
17080         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17081         createmany -m $DIR/$tdir/$tfile 50 ||
17082                 error "create $DIR/$tdir/$tfile failed"
17083         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17084         rm -f $DIR/$tdir
17085
17086         # check changelogs have been generated
17087         local nbcl=$(changelog_dump | wc -l)
17088         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17089
17090 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17091         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17092
17093         __changelog_clear mds1 $cl_user1 +10
17094         __changelog_clear mds1 $cl_user2 0 &
17095         pid1=$!
17096         sleep 2
17097         __changelog_clear mds1 $cl_user1 0 ||
17098                 error "fail to cancel record for $cl_user1"
17099         wait $pid1
17100         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17101 }
17102 run_test 160m "Changelog clear race"
17103
17104 test_160n() {
17105         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17106         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17107                 skip "Need MDS version at least 2.14.51"
17108         local cl_users
17109         local cl_user1
17110         local cl_user2
17111         local pid1
17112         local first_rec
17113         local last_rec=0
17114
17115         # Create a user
17116         changelog_register || error "first changelog_register failed"
17117
17118         cl_users=(${CL_USERS[mds1]})
17119         cl_user1="${cl_users[0]}"
17120
17121         # generate some changelog records to accumulate on MDT0
17122         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17123         first_rec=$(changelog_users $SINGLEMDS |
17124                         awk '/^current.index:/ { print $NF }')
17125         while (( last_rec < (( first_rec + 65000)) )); do
17126                 createmany -m $DIR/$tdir/$tfile 10000 ||
17127                         error "create $DIR/$tdir/$tfile failed"
17128
17129                 for i in $(seq 0 10000); do
17130                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17131                                 > /dev/null
17132                 done
17133
17134                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17135                         error "unlinkmany failed unlink"
17136                 last_rec=$(changelog_users $SINGLEMDS |
17137                         awk '/^current.index:/ { print $NF }')
17138                 echo last record $last_rec
17139                 (( last_rec == 0 )) && error "no changelog found"
17140         done
17141
17142 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17143         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17144
17145         __changelog_clear mds1 $cl_user1 0 &
17146         pid1=$!
17147         sleep 2
17148         __changelog_clear mds1 $cl_user1 0 ||
17149                 error "fail to cancel record for $cl_user1"
17150         wait $pid1
17151         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17152 }
17153 run_test 160n "Changelog destroy race"
17154
17155 test_160o() {
17156         local mdt="$(facet_svc $SINGLEMDS)"
17157
17158         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17159         remote_mds_nodsh && skip "remote MDS with nodsh"
17160         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17161                 skip "Need MDS version at least 2.14.52"
17162
17163         changelog_register --user test_160o -m unlnk+close+open ||
17164                 error "changelog_register failed"
17165
17166         do_facet $SINGLEMDS $LCTL --device $mdt \
17167                                 changelog_register -u "Tt3_-#" &&
17168                 error "bad symbols in name should fail"
17169
17170         do_facet $SINGLEMDS $LCTL --device $mdt \
17171                                 changelog_register -u test_160o &&
17172                 error "the same name registration should fail"
17173
17174         do_facet $SINGLEMDS $LCTL --device $mdt \
17175                         changelog_register -u test_160toolongname &&
17176                 error "too long name registration should fail"
17177
17178         changelog_chmask "MARK+HSM"
17179         lctl get_param mdd.*.changelog*mask
17180         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17181         changelog_users $SINGLEMDS | grep -q $cl_user ||
17182                 error "User $cl_user not found in changelog_users"
17183         #verify username
17184         echo $cl_user | grep -q test_160o ||
17185                 error "User $cl_user has no specific name 'test160o'"
17186
17187         # change something
17188         changelog_clear 0 || error "changelog_clear failed"
17189         # generate some changelog records to accumulate on MDT0
17190         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17191         touch $DIR/$tdir/$tfile                 # open 1
17192
17193         OPENS=$(changelog_dump | grep -c "OPEN")
17194         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17195
17196         # must be no MKDIR it wasn't set as user mask
17197         MKDIR=$(changelog_dump | grep -c "MKDIR")
17198         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17199
17200         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17201                                 mdd.$mdt.changelog_current_mask -n)
17202         # register maskless user
17203         changelog_register || error "changelog_register failed"
17204         # effective mask should be not changed because it is not minimal
17205         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17206                                 mdd.$mdt.changelog_current_mask -n)
17207         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17208         # set server mask to minimal value
17209         changelog_chmask "MARK"
17210         # check effective mask again, should be treated as DEFMASK now
17211         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17212                                 mdd.$mdt.changelog_current_mask -n)
17213         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17214
17215         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17216                 # set server mask back to some value
17217                 changelog_chmask "CLOSE,UNLNK"
17218                 # check effective mask again, should not remain as DEFMASK
17219                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17220                                 mdd.$mdt.changelog_current_mask -n)
17221                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17222         fi
17223
17224         do_facet $SINGLEMDS $LCTL --device $mdt \
17225                                 changelog_deregister -u test_160o ||
17226                 error "cannot deregister by name"
17227 }
17228 run_test 160o "changelog user name and mask"
17229
17230 test_160p() {
17231         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17232         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17233                 skip "Need MDS version at least 2.14.51"
17234         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17235         local cl_users
17236         local cl_user1
17237         local entry_count
17238
17239         # Create a user
17240         changelog_register || error "first changelog_register failed"
17241
17242         cl_users=(${CL_USERS[mds1]})
17243         cl_user1="${cl_users[0]}"
17244
17245         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17246         createmany -m $DIR/$tdir/$tfile 50 ||
17247                 error "create $DIR/$tdir/$tfile failed"
17248         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17249         rm -rf $DIR/$tdir
17250
17251         # check changelogs have been generated
17252         entry_count=$(changelog_dump | wc -l)
17253         ((entry_count != 0)) || error "no changelog entries found"
17254
17255         # remove changelog_users and check that orphan entries are removed
17256         stop mds1
17257         local dev=$(mdsdevname 1)
17258         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17259         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17260         entry_count=$(changelog_dump | wc -l)
17261         ((entry_count == 0)) ||
17262                 error "found $entry_count changelog entries, expected none"
17263 }
17264 run_test 160p "Changelog orphan cleanup with no users"
17265
17266 test_160q() {
17267         local mdt="$(facet_svc $SINGLEMDS)"
17268         local clu
17269
17270         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17271         remote_mds_nodsh && skip "remote MDS with nodsh"
17272         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17273                 skip "Need MDS version at least 2.14.54"
17274
17275         # set server mask to minimal value like server init does
17276         changelog_chmask "MARK"
17277         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17278                 error "changelog_register failed"
17279         # check effective mask again, should be treated as DEFMASK now
17280         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17281                                 mdd.$mdt.changelog_current_mask -n)
17282         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17283                 error "changelog_deregister failed"
17284         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17285 }
17286 run_test 160q "changelog effective mask is DEFMASK if not set"
17287
17288 test_160s() {
17289         remote_mds_nodsh && skip "remote MDS with nodsh"
17290         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17291                 skip "Need MDS version at least 2.14.55"
17292
17293         local mdts=$(comma_list $(mdts_nodes))
17294
17295         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17296         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17297                                        fail_val=$((24 * 3600 * 10))
17298
17299         # Create a user which is 10 days old
17300         changelog_register || error "first changelog_register failed"
17301         local cl_users
17302         declare -A cl_user1
17303         local i
17304
17305         # generate some changelog records to accumulate on each MDT
17306         # use all_char because created files should be evenly distributed
17307         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17308                 error "test_mkdir $tdir failed"
17309         for ((i = 0; i < MDSCOUNT; i++)); do
17310                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17311                         error "create $DIR/$tdir/d$i.1 failed"
17312         done
17313
17314         # check changelogs have been generated
17315         local nbcl=$(changelog_dump | wc -l)
17316         (( nbcl > 0 )) || error "no changelogs found"
17317
17318         # reduce the max_idle_indexes value to make sure we exceed it
17319         for param in "changelog_max_idle_indexes=2097446912" \
17320                      "changelog_max_idle_time=2592000" \
17321                      "changelog_gc=1" \
17322                      "changelog_min_gc_interval=2"; do
17323                 local MDT0=$(facet_svc $SINGLEMDS)
17324                 local var="${param%=*}"
17325                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17326
17327                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17328                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17329                         error "unable to set mdd.*.$param"
17330         done
17331
17332         local start=$SECONDS
17333         for i in $(seq $MDSCOUNT); do
17334                 cl_users=(${CL_USERS[mds$i]})
17335                 cl_user1[mds$i]="${cl_users[0]}"
17336
17337                 [[ -n "${cl_user1[mds$i]}" ]] ||
17338                         error "mds$i: no user registered"
17339         done
17340
17341         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17342         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17343
17344         # ensure we are past the previous changelog_min_gc_interval set above
17345         local sleep2=$((start + 2 - SECONDS))
17346         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17347
17348         # Generate one more changelog to trigger GC
17349         for ((i = 0; i < MDSCOUNT; i++)); do
17350                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17351                         error "create $DIR/$tdir/d$i.3 failed"
17352         done
17353
17354         # ensure gc thread is done
17355         for node in $(mdts_nodes); do
17356                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17357                         error "$node: GC-thread not done"
17358         done
17359
17360         do_nodes $mdts $LCTL set_param fail_loc=0
17361
17362         for (( i = 1; i <= MDSCOUNT; i++ )); do
17363                 # check cl_user1 is purged
17364                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17365                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17366         done
17367         return 0
17368 }
17369 run_test 160s "changelog garbage collect on idle records * time"
17370
17371 test_160t() {
17372         remote_mds_nodsh && skip "remote MDS with nodsh"
17373         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17374                 skip "Need MDS version at least 2.15.50"
17375
17376         local MDT0=$(facet_svc $SINGLEMDS)
17377         local cl_users
17378         local cl_user1
17379         local cl_user2
17380         local start
17381
17382         changelog_register --user user1 -m all ||
17383                 error "user1 failed to register"
17384
17385         mkdir_on_mdt0 $DIR/$tdir
17386         # create default overstripe to maximize changelog size
17387         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17388         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17389         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17390
17391         # user2 consumes less records so less space
17392         changelog_register --user user2 || error "user2 failed to register"
17393         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17394         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17395
17396         # check changelogs have been generated
17397         local nbcl=$(changelog_dump | wc -l)
17398         (( nbcl > 0 )) || error "no changelogs found"
17399
17400         # reduce the changelog_min_gc_interval to force check
17401         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17402                 local var="${param%=*}"
17403                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17404
17405                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17406                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17407                         error "unable to set mdd.*.$param"
17408         done
17409
17410         start=$SECONDS
17411         cl_users=(${CL_USERS[mds1]})
17412         cl_user1="${cl_users[0]}"
17413         cl_user2="${cl_users[1]}"
17414
17415         [[ -n $cl_user1 ]] ||
17416                 error "mds1: user #1 isn't registered"
17417         [[ -n $cl_user2 ]] ||
17418                 error "mds1: user #2 isn't registered"
17419
17420         # ensure we are past the previous changelog_min_gc_interval set above
17421         local sleep2=$((start + 2 - SECONDS))
17422         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17423
17424         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17425         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17426                         fail_val=$(((llog_size1 + llog_size2) / 2))
17427
17428         # Generate more changelog to trigger GC
17429         createmany -o $DIR/$tdir/u3_ 4 ||
17430                 error "create failed for more files"
17431
17432         # ensure gc thread is done
17433         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17434                 error "mds1: GC-thread not done"
17435
17436         do_facet mds1 $LCTL set_param fail_loc=0
17437
17438         # check cl_user1 is purged
17439         changelog_users mds1 | grep -q "$cl_user1" &&
17440                 error "User $cl_user1 is registered"
17441         # check cl_user2 is not purged
17442         changelog_users mds1 | grep -q "$cl_user2" ||
17443                 error "User $cl_user2 is not registered"
17444 }
17445 run_test 160t "changelog garbage collect on lack of space"
17446
17447 test_161a() {
17448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17449
17450         test_mkdir -c1 $DIR/$tdir
17451         cp /etc/hosts $DIR/$tdir/$tfile
17452         test_mkdir -c1 $DIR/$tdir/foo1
17453         test_mkdir -c1 $DIR/$tdir/foo2
17454         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17455         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17456         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17457         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17458         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17459         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17460                 $LFS fid2path $DIR $FID
17461                 error "bad link ea"
17462         fi
17463         # middle
17464         rm $DIR/$tdir/foo2/zachary
17465         # last
17466         rm $DIR/$tdir/foo2/thor
17467         # first
17468         rm $DIR/$tdir/$tfile
17469         # rename
17470         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17471         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17472                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17473         rm $DIR/$tdir/foo2/maggie
17474
17475         # overflow the EA
17476         local longname=$tfile.avg_len_is_thirty_two_
17477         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17478                 error_noexit 'failed to unlink many hardlinks'" EXIT
17479         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17480                 error "failed to hardlink many files"
17481         links=$($LFS fid2path $DIR $FID | wc -l)
17482         echo -n "${links}/1000 links in link EA"
17483         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17484 }
17485 run_test 161a "link ea sanity"
17486
17487 test_161b() {
17488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17489         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17490
17491         local MDTIDX=1
17492         local remote_dir=$DIR/$tdir/remote_dir
17493
17494         mkdir -p $DIR/$tdir
17495         $LFS mkdir -i $MDTIDX $remote_dir ||
17496                 error "create remote directory failed"
17497
17498         cp /etc/hosts $remote_dir/$tfile
17499         mkdir -p $remote_dir/foo1
17500         mkdir -p $remote_dir/foo2
17501         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17502         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17503         ln $remote_dir/$tfile $remote_dir/foo1/luna
17504         ln $remote_dir/$tfile $remote_dir/foo2/thor
17505
17506         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17507                      tr -d ']')
17508         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17509                 $LFS fid2path $DIR $FID
17510                 error "bad link ea"
17511         fi
17512         # middle
17513         rm $remote_dir/foo2/zachary
17514         # last
17515         rm $remote_dir/foo2/thor
17516         # first
17517         rm $remote_dir/$tfile
17518         # rename
17519         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17520         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17521         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17522                 $LFS fid2path $DIR $FID
17523                 error "bad link rename"
17524         fi
17525         rm $remote_dir/foo2/maggie
17526
17527         # overflow the EA
17528         local longname=filename_avg_len_is_thirty_two_
17529         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17530                 error "failed to hardlink many files"
17531         links=$($LFS fid2path $DIR $FID | wc -l)
17532         echo -n "${links}/1000 links in link EA"
17533         [[ ${links} -gt 60 ]] ||
17534                 error "expected at least 60 links in link EA"
17535         unlinkmany $remote_dir/foo2/$longname 1000 ||
17536         error "failed to unlink many hardlinks"
17537 }
17538 run_test 161b "link ea sanity under remote directory"
17539
17540 test_161c() {
17541         remote_mds_nodsh && skip "remote MDS with nodsh"
17542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17543         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17544                 skip "Need MDS version at least 2.1.5"
17545
17546         # define CLF_RENAME_LAST 0x0001
17547         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17548         changelog_register || error "changelog_register failed"
17549
17550         rm -rf $DIR/$tdir
17551         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17552         touch $DIR/$tdir/foo_161c
17553         touch $DIR/$tdir/bar_161c
17554         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17555         changelog_dump | grep RENME | tail -n 5
17556         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17557         changelog_clear 0 || error "changelog_clear failed"
17558         if [ x$flags != "x0x1" ]; then
17559                 error "flag $flags is not 0x1"
17560         fi
17561
17562         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17563         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17564         touch $DIR/$tdir/foo_161c
17565         touch $DIR/$tdir/bar_161c
17566         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17567         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17568         changelog_dump | grep RENME | tail -n 5
17569         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17570         changelog_clear 0 || error "changelog_clear failed"
17571         if [ x$flags != "x0x0" ]; then
17572                 error "flag $flags is not 0x0"
17573         fi
17574         echo "rename overwrite a target having nlink > 1," \
17575                 "changelog record has flags of $flags"
17576
17577         # rename doesn't overwrite a target (changelog flag 0x0)
17578         touch $DIR/$tdir/foo_161c
17579         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17580         changelog_dump | grep RENME | tail -n 5
17581         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17582         changelog_clear 0 || error "changelog_clear failed"
17583         if [ x$flags != "x0x0" ]; then
17584                 error "flag $flags is not 0x0"
17585         fi
17586         echo "rename doesn't overwrite a target," \
17587                 "changelog record has flags of $flags"
17588
17589         # define CLF_UNLINK_LAST 0x0001
17590         # unlink a file having nlink = 1 (changelog flag 0x1)
17591         rm -f $DIR/$tdir/foo2_161c
17592         changelog_dump | grep UNLNK | tail -n 5
17593         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17594         changelog_clear 0 || error "changelog_clear failed"
17595         if [ x$flags != "x0x1" ]; then
17596                 error "flag $flags is not 0x1"
17597         fi
17598         echo "unlink a file having nlink = 1," \
17599                 "changelog record has flags of $flags"
17600
17601         # unlink a file having nlink > 1 (changelog flag 0x0)
17602         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17603         rm -f $DIR/$tdir/foobar_161c
17604         changelog_dump | grep UNLNK | tail -n 5
17605         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17606         changelog_clear 0 || error "changelog_clear failed"
17607         if [ x$flags != "x0x0" ]; then
17608                 error "flag $flags is not 0x0"
17609         fi
17610         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17611 }
17612 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17613
17614 test_161d() {
17615         remote_mds_nodsh && skip "remote MDS with nodsh"
17616         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17617
17618         local pid
17619         local fid
17620
17621         changelog_register || error "changelog_register failed"
17622
17623         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17624         # interfer with $MOUNT/.lustre/fid/ access
17625         mkdir $DIR/$tdir
17626         [[ $? -eq 0 ]] || error "mkdir failed"
17627
17628         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17629         $LCTL set_param fail_loc=0x8000140c
17630         # 5s pause
17631         $LCTL set_param fail_val=5
17632
17633         # create file
17634         echo foofoo > $DIR/$tdir/$tfile &
17635         pid=$!
17636
17637         # wait for create to be delayed
17638         sleep 2
17639
17640         ps -p $pid
17641         [[ $? -eq 0 ]] || error "create should be blocked"
17642
17643         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17644         stack_trap "rm -f $tempfile"
17645         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17646         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17647         # some delay may occur during ChangeLog publishing and file read just
17648         # above, that could allow file write to happen finally
17649         [[ -s $tempfile ]] && echo "file should be empty"
17650
17651         $LCTL set_param fail_loc=0
17652
17653         wait $pid
17654         [[ $? -eq 0 ]] || error "create failed"
17655 }
17656 run_test 161d "create with concurrent .lustre/fid access"
17657
17658 check_path() {
17659         local expected="$1"
17660         shift
17661         local fid="$2"
17662
17663         local path
17664         path=$($LFS fid2path "$@")
17665         local rc=$?
17666
17667         if [ $rc -ne 0 ]; then
17668                 error "path looked up of '$expected' failed: rc=$rc"
17669         elif [ "$path" != "$expected" ]; then
17670                 error "path looked up '$path' instead of '$expected'"
17671         else
17672                 echo "FID '$fid' resolves to path '$path' as expected"
17673         fi
17674 }
17675
17676 test_162a() { # was test_162
17677         test_mkdir -p -c1 $DIR/$tdir/d2
17678         touch $DIR/$tdir/d2/$tfile
17679         touch $DIR/$tdir/d2/x1
17680         touch $DIR/$tdir/d2/x2
17681         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17682         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17683         # regular file
17684         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17685         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17686
17687         # softlink
17688         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17689         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17690         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17691
17692         # softlink to wrong file
17693         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17694         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17695         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17696
17697         # hardlink
17698         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17699         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17700         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17701         # fid2path dir/fsname should both work
17702         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17703         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17704
17705         # hardlink count: check that there are 2 links
17706         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17707         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17708
17709         # hardlink indexing: remove the first link
17710         rm $DIR/$tdir/d2/p/q/r/hlink
17711         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17712 }
17713 run_test 162a "path lookup sanity"
17714
17715 test_162b() {
17716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17718
17719         mkdir $DIR/$tdir
17720         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17721                                 error "create striped dir failed"
17722
17723         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17724                                         tail -n 1 | awk '{print $2}')
17725         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17726
17727         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17728         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17729
17730         # regular file
17731         for ((i=0;i<5;i++)); do
17732                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17733                         error "get fid for f$i failed"
17734                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17735
17736                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17737                         error "get fid for d$i failed"
17738                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17739         done
17740
17741         return 0
17742 }
17743 run_test 162b "striped directory path lookup sanity"
17744
17745 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17746 test_162c() {
17747         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17748                 skip "Need MDS version at least 2.7.51"
17749
17750         local lpath=$tdir.local
17751         local rpath=$tdir.remote
17752
17753         test_mkdir $DIR/$lpath
17754         test_mkdir $DIR/$rpath
17755
17756         for ((i = 0; i <= 101; i++)); do
17757                 lpath="$lpath/$i"
17758                 mkdir $DIR/$lpath
17759                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17760                         error "get fid for local directory $DIR/$lpath failed"
17761                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17762
17763                 rpath="$rpath/$i"
17764                 test_mkdir $DIR/$rpath
17765                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17766                         error "get fid for remote directory $DIR/$rpath failed"
17767                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17768         done
17769
17770         return 0
17771 }
17772 run_test 162c "fid2path works with paths 100 or more directories deep"
17773
17774 oalr_event_count() {
17775         local event="${1}"
17776         local trace="${2}"
17777
17778         awk -v name="${FSNAME}-OST0000" \
17779             -v event="${event}" \
17780             '$1 == "TRACE" && $2 == event && $3 == name' \
17781             "${trace}" |
17782         wc -l
17783 }
17784
17785 oalr_expect_event_count() {
17786         local event="${1}"
17787         local trace="${2}"
17788         local expect="${3}"
17789         local count
17790
17791         count=$(oalr_event_count "${event}" "${trace}")
17792         if ((count == expect)); then
17793                 return 0
17794         fi
17795
17796         error_noexit "${event} event count was '${count}', expected ${expect}"
17797         cat "${trace}" >&2
17798         exit 1
17799 }
17800
17801 cleanup_165() {
17802         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17803         stop ost1
17804         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17805 }
17806
17807 setup_165() {
17808         sync # Flush previous IOs so we can count log entries.
17809         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17810         stack_trap cleanup_165 EXIT
17811 }
17812
17813 test_165a() {
17814         local trace="/tmp/${tfile}.trace"
17815         local rc
17816         local count
17817
17818         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17819                 skip "OFD access log unsupported"
17820
17821         setup_165
17822         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17823         sleep 5
17824
17825         do_facet ost1 ofd_access_log_reader --list
17826         stop ost1
17827
17828         do_facet ost1 killall -TERM ofd_access_log_reader
17829         wait
17830         rc=$?
17831
17832         if ((rc != 0)); then
17833                 error "ofd_access_log_reader exited with rc = '${rc}'"
17834         fi
17835
17836         # Parse trace file for discovery events:
17837         oalr_expect_event_count alr_log_add "${trace}" 1
17838         oalr_expect_event_count alr_log_eof "${trace}" 1
17839         oalr_expect_event_count alr_log_free "${trace}" 1
17840 }
17841 run_test 165a "ofd access log discovery"
17842
17843 test_165b() {
17844         local trace="/tmp/${tfile}.trace"
17845         local file="${DIR}/${tfile}"
17846         local pfid1
17847         local pfid2
17848         local -a entry
17849         local rc
17850         local count
17851         local size
17852         local flags
17853
17854         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17855                 skip "OFD access log unsupported"
17856
17857         setup_165
17858         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17859         sleep 5
17860
17861         do_facet ost1 ofd_access_log_reader --list
17862
17863         lfs setstripe -c 1 -i 0 "${file}"
17864         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17865                 error "cannot create '${file}'"
17866
17867         sleep 5
17868         do_facet ost1 killall -TERM ofd_access_log_reader
17869         wait
17870         rc=$?
17871
17872         if ((rc != 0)); then
17873                 error "ofd_access_log_reader exited with rc = '${rc}'"
17874         fi
17875
17876         oalr_expect_event_count alr_log_entry "${trace}" 1
17877
17878         pfid1=$($LFS path2fid "${file}")
17879
17880         # 1     2             3   4    5     6   7    8    9     10
17881         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17882         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17883
17884         echo "entry = '${entry[*]}'" >&2
17885
17886         pfid2=${entry[4]}
17887         if [[ "${pfid1}" != "${pfid2}" ]]; then
17888                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17889         fi
17890
17891         size=${entry[8]}
17892         if ((size != 1048576)); then
17893                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17894         fi
17895
17896         flags=${entry[10]}
17897         if [[ "${flags}" != "w" ]]; then
17898                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17899         fi
17900
17901         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17902         sleep 5
17903
17904         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17905                 error "cannot read '${file}'"
17906         sleep 5
17907
17908         do_facet ost1 killall -TERM ofd_access_log_reader
17909         wait
17910         rc=$?
17911
17912         if ((rc != 0)); then
17913                 error "ofd_access_log_reader exited with rc = '${rc}'"
17914         fi
17915
17916         oalr_expect_event_count alr_log_entry "${trace}" 1
17917
17918         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17919         echo "entry = '${entry[*]}'" >&2
17920
17921         pfid2=${entry[4]}
17922         if [[ "${pfid1}" != "${pfid2}" ]]; then
17923                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17924         fi
17925
17926         size=${entry[8]}
17927         if ((size != 524288)); then
17928                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17929         fi
17930
17931         flags=${entry[10]}
17932         if [[ "${flags}" != "r" ]]; then
17933                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17934         fi
17935 }
17936 run_test 165b "ofd access log entries are produced and consumed"
17937
17938 test_165c() {
17939         local trace="/tmp/${tfile}.trace"
17940         local file="${DIR}/${tdir}/${tfile}"
17941
17942         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17943                 skip "OFD access log unsupported"
17944
17945         test_mkdir "${DIR}/${tdir}"
17946
17947         setup_165
17948         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17949         sleep 5
17950
17951         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17952
17953         # 4096 / 64 = 64. Create twice as many entries.
17954         for ((i = 0; i < 128; i++)); do
17955                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17956                         error "cannot create file"
17957         done
17958
17959         sync
17960
17961         do_facet ost1 killall -TERM ofd_access_log_reader
17962         wait
17963         rc=$?
17964         if ((rc != 0)); then
17965                 error "ofd_access_log_reader exited with rc = '${rc}'"
17966         fi
17967
17968         unlinkmany  "${file}-%d" 128
17969 }
17970 run_test 165c "full ofd access logs do not block IOs"
17971
17972 oal_get_read_count() {
17973         local stats="$1"
17974
17975         # STATS lustre-OST0001 alr_read_count 1
17976
17977         do_facet ost1 cat "${stats}" |
17978         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17979              END { print count; }'
17980 }
17981
17982 oal_expect_read_count() {
17983         local stats="$1"
17984         local count
17985         local expect="$2"
17986
17987         # Ask ofd_access_log_reader to write stats.
17988         do_facet ost1 killall -USR1 ofd_access_log_reader
17989
17990         # Allow some time for things to happen.
17991         sleep 1
17992
17993         count=$(oal_get_read_count "${stats}")
17994         if ((count == expect)); then
17995                 return 0
17996         fi
17997
17998         error_noexit "bad read count, got ${count}, expected ${expect}"
17999         do_facet ost1 cat "${stats}" >&2
18000         exit 1
18001 }
18002
18003 test_165d() {
18004         local stats="/tmp/${tfile}.stats"
18005         local file="${DIR}/${tdir}/${tfile}"
18006         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18007
18008         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18009                 skip "OFD access log unsupported"
18010
18011         test_mkdir "${DIR}/${tdir}"
18012
18013         setup_165
18014         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18015         sleep 5
18016
18017         lfs setstripe -c 1 -i 0 "${file}"
18018
18019         do_facet ost1 lctl set_param "${param}=rw"
18020         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18021                 error "cannot create '${file}'"
18022         oal_expect_read_count "${stats}" 1
18023
18024         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18025                 error "cannot read '${file}'"
18026         oal_expect_read_count "${stats}" 2
18027
18028         do_facet ost1 lctl set_param "${param}=r"
18029         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18030                 error "cannot create '${file}'"
18031         oal_expect_read_count "${stats}" 2
18032
18033         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18034                 error "cannot read '${file}'"
18035         oal_expect_read_count "${stats}" 3
18036
18037         do_facet ost1 lctl set_param "${param}=w"
18038         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18039                 error "cannot create '${file}'"
18040         oal_expect_read_count "${stats}" 4
18041
18042         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18043                 error "cannot read '${file}'"
18044         oal_expect_read_count "${stats}" 4
18045
18046         do_facet ost1 lctl set_param "${param}=0"
18047         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18048                 error "cannot create '${file}'"
18049         oal_expect_read_count "${stats}" 4
18050
18051         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18052                 error "cannot read '${file}'"
18053         oal_expect_read_count "${stats}" 4
18054
18055         do_facet ost1 killall -TERM ofd_access_log_reader
18056         wait
18057         rc=$?
18058         if ((rc != 0)); then
18059                 error "ofd_access_log_reader exited with rc = '${rc}'"
18060         fi
18061 }
18062 run_test 165d "ofd_access_log mask works"
18063
18064 test_165e() {
18065         local stats="/tmp/${tfile}.stats"
18066         local file0="${DIR}/${tdir}-0/${tfile}"
18067         local file1="${DIR}/${tdir}-1/${tfile}"
18068
18069         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18070                 skip "OFD access log unsupported"
18071
18072         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18073
18074         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18075         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18076
18077         lfs setstripe -c 1 -i 0 "${file0}"
18078         lfs setstripe -c 1 -i 0 "${file1}"
18079
18080         setup_165
18081         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18082         sleep 5
18083
18084         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18085                 error "cannot create '${file0}'"
18086         sync
18087         oal_expect_read_count "${stats}" 0
18088
18089         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18090                 error "cannot create '${file1}'"
18091         sync
18092         oal_expect_read_count "${stats}" 1
18093
18094         do_facet ost1 killall -TERM ofd_access_log_reader
18095         wait
18096         rc=$?
18097         if ((rc != 0)); then
18098                 error "ofd_access_log_reader exited with rc = '${rc}'"
18099         fi
18100 }
18101 run_test 165e "ofd_access_log MDT index filter works"
18102
18103 test_165f() {
18104         local trace="/tmp/${tfile}.trace"
18105         local rc
18106         local count
18107
18108         setup_165
18109         do_facet ost1 timeout 60 ofd_access_log_reader \
18110                 --exit-on-close --debug=- --trace=- > "${trace}" &
18111         sleep 5
18112         stop ost1
18113
18114         wait
18115         rc=$?
18116
18117         if ((rc != 0)); then
18118                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18119                 cat "${trace}"
18120                 exit 1
18121         fi
18122 }
18123 run_test 165f "ofd_access_log_reader --exit-on-close works"
18124
18125 test_169() {
18126         # do directio so as not to populate the page cache
18127         log "creating a 10 Mb file"
18128         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18129                 error "multiop failed while creating a file"
18130         log "starting reads"
18131         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18132         log "truncating the file"
18133         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18134                 error "multiop failed while truncating the file"
18135         log "killing dd"
18136         kill %+ || true # reads might have finished
18137         echo "wait until dd is finished"
18138         wait
18139         log "removing the temporary file"
18140         rm -rf $DIR/$tfile || error "tmp file removal failed"
18141 }
18142 run_test 169 "parallel read and truncate should not deadlock"
18143
18144 test_170() {
18145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18146
18147         $LCTL clear     # bug 18514
18148         $LCTL debug_daemon start $TMP/${tfile}_log_good
18149         touch $DIR/$tfile
18150         $LCTL debug_daemon stop
18151         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18152                 error "sed failed to read log_good"
18153
18154         $LCTL debug_daemon start $TMP/${tfile}_log_good
18155         rm -rf $DIR/$tfile
18156         $LCTL debug_daemon stop
18157
18158         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18159                error "lctl df log_bad failed"
18160
18161         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18162         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18163
18164         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18165         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18166
18167         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18168                 error "bad_line good_line1 good_line2 are empty"
18169
18170         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18171         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18172         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18173
18174         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18175         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18176         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18177
18178         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18179                 error "bad_line_new good_line_new are empty"
18180
18181         local expected_good=$((good_line1 + good_line2*2))
18182
18183         rm -f $TMP/${tfile}*
18184         # LU-231, short malformed line may not be counted into bad lines
18185         if [ $bad_line -ne $bad_line_new ] &&
18186                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18187                 error "expected $bad_line bad lines, but got $bad_line_new"
18188                 return 1
18189         fi
18190
18191         if [ $expected_good -ne $good_line_new ]; then
18192                 error "expected $expected_good good lines, but got $good_line_new"
18193                 return 2
18194         fi
18195         true
18196 }
18197 run_test 170 "test lctl df to handle corrupted log ====================="
18198
18199 test_171() { # bug20592
18200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18201
18202         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18203         $LCTL set_param fail_loc=0x50e
18204         $LCTL set_param fail_val=3000
18205         multiop_bg_pause $DIR/$tfile O_s || true
18206         local MULTIPID=$!
18207         kill -USR1 $MULTIPID
18208         # cause log dump
18209         sleep 3
18210         wait $MULTIPID
18211         if dmesg | grep "recursive fault"; then
18212                 error "caught a recursive fault"
18213         fi
18214         $LCTL set_param fail_loc=0
18215         true
18216 }
18217 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18218
18219 test_172() {
18220
18221         #define OBD_FAIL_OBD_CLEANUP  0x60e
18222         $LCTL set_param fail_loc=0x60e
18223         umount $MOUNT || error "umount $MOUNT failed"
18224         stack_trap "mount_client $MOUNT"
18225
18226         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18227                 error "no client OBDs are remained"
18228
18229         $LCTL dl | while read devno state type name foo; do
18230                 case $type in
18231                 lov|osc|lmv|mdc)
18232                         $LCTL --device $name cleanup
18233                         $LCTL --device $name detach
18234                         ;;
18235                 *)
18236                         # skip server devices
18237                         ;;
18238                 esac
18239         done
18240
18241         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18242                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18243                 error "some client OBDs are still remained"
18244         fi
18245
18246 }
18247 run_test 172 "manual device removal with lctl cleanup/detach ======"
18248
18249 # it would be good to share it with obdfilter-survey/iokit-libecho code
18250 setup_obdecho_osc () {
18251         local rc=0
18252         local ost_nid=$1
18253         local obdfilter_name=$2
18254         echo "Creating new osc for $obdfilter_name on $ost_nid"
18255         # make sure we can find loopback nid
18256         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18257
18258         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18259                            ${obdfilter_name}_osc_UUID || rc=2; }
18260         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18261                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18262         return $rc
18263 }
18264
18265 cleanup_obdecho_osc () {
18266         local obdfilter_name=$1
18267         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18268         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18269         return 0
18270 }
18271
18272 obdecho_test() {
18273         local OBD=$1
18274         local node=$2
18275         local pages=${3:-64}
18276         local rc=0
18277         local id
18278
18279         local count=10
18280         local obd_size=$(get_obd_size $node $OBD)
18281         local page_size=$(get_page_size $node)
18282         if [[ -n "$obd_size" ]]; then
18283                 local new_count=$((obd_size / (pages * page_size / 1024)))
18284                 [[ $new_count -ge $count ]] || count=$new_count
18285         fi
18286
18287         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18288         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18289                            rc=2; }
18290         if [ $rc -eq 0 ]; then
18291             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18292             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18293         fi
18294         echo "New object id is $id"
18295         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18296                            rc=4; }
18297         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18298                            "test_brw $count w v $pages $id" || rc=4; }
18299         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18300                            rc=4; }
18301         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18302                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18303         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18304                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18305         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18306         return $rc
18307 }
18308
18309 test_180a() {
18310         skip "obdecho on osc is no longer supported"
18311 }
18312 run_test 180a "test obdecho on osc"
18313
18314 test_180b() {
18315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18316         remote_ost_nodsh && skip "remote OST with nodsh"
18317
18318         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18319                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18320                 error "failed to load module obdecho"
18321
18322         local target=$(do_facet ost1 $LCTL dl |
18323                        awk '/obdfilter/ { print $4; exit; }')
18324
18325         if [ -n "$target" ]; then
18326                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18327         else
18328                 do_facet ost1 $LCTL dl
18329                 error "there is no obdfilter target on ost1"
18330         fi
18331 }
18332 run_test 180b "test obdecho directly on obdfilter"
18333
18334 test_180c() { # LU-2598
18335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18336         remote_ost_nodsh && skip "remote OST with nodsh"
18337         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18338                 skip "Need MDS version at least 2.4.0"
18339
18340         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18341                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18342                 error "failed to load module obdecho"
18343
18344         local target=$(do_facet ost1 $LCTL dl |
18345                        awk '/obdfilter/ { print $4; exit; }')
18346
18347         if [ -n "$target" ]; then
18348                 local pages=16384 # 64MB bulk I/O RPC size
18349
18350                 obdecho_test "$target" ost1 "$pages" ||
18351                         error "obdecho_test with pages=$pages failed with $?"
18352         else
18353                 do_facet ost1 $LCTL dl
18354                 error "there is no obdfilter target on ost1"
18355         fi
18356 }
18357 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18358
18359 test_181() { # bug 22177
18360         test_mkdir $DIR/$tdir
18361         # create enough files to index the directory
18362         createmany -o $DIR/$tdir/foobar 4000
18363         # print attributes for debug purpose
18364         lsattr -d .
18365         # open dir
18366         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18367         MULTIPID=$!
18368         # remove the files & current working dir
18369         unlinkmany $DIR/$tdir/foobar 4000
18370         rmdir $DIR/$tdir
18371         kill -USR1 $MULTIPID
18372         wait $MULTIPID
18373         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18374         return 0
18375 }
18376 run_test 181 "Test open-unlinked dir ========================"
18377
18378 test_182a() {
18379         local fcount=1000
18380         local tcount=10
18381
18382         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18383
18384         $LCTL set_param mdc.*.rpc_stats=clear
18385
18386         for (( i = 0; i < $tcount; i++ )) ; do
18387                 mkdir $DIR/$tdir/$i
18388         done
18389
18390         for (( i = 0; i < $tcount; i++ )) ; do
18391                 createmany -o $DIR/$tdir/$i/f- $fcount &
18392         done
18393         wait
18394
18395         for (( i = 0; i < $tcount; i++ )) ; do
18396                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18397         done
18398         wait
18399
18400         $LCTL get_param mdc.*.rpc_stats
18401
18402         rm -rf $DIR/$tdir
18403 }
18404 run_test 182a "Test parallel modify metadata operations from mdc"
18405
18406 test_182b() {
18407         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18408         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18409         local dcount=1000
18410         local tcount=10
18411         local stime
18412         local etime
18413         local delta
18414
18415         do_facet mds1 $LCTL list_param \
18416                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18417                 skip "MDS lacks parallel RPC handling"
18418
18419         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18420
18421         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18422                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18423
18424         stime=$(date +%s)
18425         createmany -i 0 -d $DIR/$tdir/t- $tcount
18426
18427         for (( i = 0; i < $tcount; i++ )) ; do
18428                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18429         done
18430         wait
18431         etime=$(date +%s)
18432         delta=$((etime - stime))
18433         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18434
18435         stime=$(date +%s)
18436         for (( i = 0; i < $tcount; i++ )) ; do
18437                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18438         done
18439         wait
18440         etime=$(date +%s)
18441         delta=$((etime - stime))
18442         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18443
18444         rm -rf $DIR/$tdir
18445
18446         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18447
18448         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18449
18450         stime=$(date +%s)
18451         createmany -i 0 -d $DIR/$tdir/t- $tcount
18452
18453         for (( i = 0; i < $tcount; i++ )) ; do
18454                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18455         done
18456         wait
18457         etime=$(date +%s)
18458         delta=$((etime - stime))
18459         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18460
18461         stime=$(date +%s)
18462         for (( i = 0; i < $tcount; i++ )) ; do
18463                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18464         done
18465         wait
18466         etime=$(date +%s)
18467         delta=$((etime - stime))
18468         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18469
18470         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18471 }
18472 run_test 182b "Test parallel modify metadata operations from osp"
18473
18474 test_183() { # LU-2275
18475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18476         remote_mds_nodsh && skip "remote MDS with nodsh"
18477         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18478                 skip "Need MDS version at least 2.3.56"
18479
18480         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18481         echo aaa > $DIR/$tdir/$tfile
18482
18483 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18484         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18485
18486         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18487         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18488
18489         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18490
18491         # Flush negative dentry cache
18492         touch $DIR/$tdir/$tfile
18493
18494         # We are not checking for any leaked references here, they'll
18495         # become evident next time we do cleanup with module unload.
18496         rm -rf $DIR/$tdir
18497 }
18498 run_test 183 "No crash or request leak in case of strange dispositions ========"
18499
18500 # test suite 184 is for LU-2016, LU-2017
18501 test_184a() {
18502         check_swap_layouts_support
18503
18504         dir0=$DIR/$tdir/$testnum
18505         test_mkdir -p -c1 $dir0
18506         ref1=/etc/passwd
18507         ref2=/etc/group
18508         file1=$dir0/f1
18509         file2=$dir0/f2
18510         $LFS setstripe -c1 $file1
18511         cp $ref1 $file1
18512         $LFS setstripe -c2 $file2
18513         cp $ref2 $file2
18514         gen1=$($LFS getstripe -g $file1)
18515         gen2=$($LFS getstripe -g $file2)
18516
18517         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18518         gen=$($LFS getstripe -g $file1)
18519         [[ $gen1 != $gen ]] ||
18520                 error "Layout generation on $file1 does not change"
18521         gen=$($LFS getstripe -g $file2)
18522         [[ $gen2 != $gen ]] ||
18523                 error "Layout generation on $file2 does not change"
18524
18525         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18526         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18527
18528         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18529 }
18530 run_test 184a "Basic layout swap"
18531
18532 test_184b() {
18533         check_swap_layouts_support
18534
18535         dir0=$DIR/$tdir/$testnum
18536         mkdir -p $dir0 || error "creating dir $dir0"
18537         file1=$dir0/f1
18538         file2=$dir0/f2
18539         file3=$dir0/f3
18540         dir1=$dir0/d1
18541         dir2=$dir0/d2
18542         mkdir $dir1 $dir2
18543         $LFS setstripe -c1 $file1
18544         $LFS setstripe -c2 $file2
18545         $LFS setstripe -c1 $file3
18546         chown $RUNAS_ID $file3
18547         gen1=$($LFS getstripe -g $file1)
18548         gen2=$($LFS getstripe -g $file2)
18549
18550         $LFS swap_layouts $dir1 $dir2 &&
18551                 error "swap of directories layouts should fail"
18552         $LFS swap_layouts $dir1 $file1 &&
18553                 error "swap of directory and file layouts should fail"
18554         $RUNAS $LFS swap_layouts $file1 $file2 &&
18555                 error "swap of file we cannot write should fail"
18556         $LFS swap_layouts $file1 $file3 &&
18557                 error "swap of file with different owner should fail"
18558         /bin/true # to clear error code
18559 }
18560 run_test 184b "Forbidden layout swap (will generate errors)"
18561
18562 test_184c() {
18563         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18564         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18565         check_swap_layouts_support
18566         check_swap_layout_no_dom $DIR
18567
18568         local dir0=$DIR/$tdir/$testnum
18569         mkdir -p $dir0 || error "creating dir $dir0"
18570
18571         local ref1=$dir0/ref1
18572         local ref2=$dir0/ref2
18573         local file1=$dir0/file1
18574         local file2=$dir0/file2
18575         # create a file large enough for the concurrent test
18576         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18577         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18578         echo "ref file size: ref1($(stat -c %s $ref1))," \
18579              "ref2($(stat -c %s $ref2))"
18580
18581         cp $ref2 $file2
18582         dd if=$ref1 of=$file1 bs=16k &
18583         local DD_PID=$!
18584
18585         # Make sure dd starts to copy file, but wait at most 5 seconds
18586         local loops=0
18587         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18588
18589         $LFS swap_layouts $file1 $file2
18590         local rc=$?
18591         wait $DD_PID
18592         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18593         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18594
18595         # how many bytes copied before swapping layout
18596         local copied=$(stat -c %s $file2)
18597         local remaining=$(stat -c %s $ref1)
18598         remaining=$((remaining - copied))
18599         echo "Copied $copied bytes before swapping layout..."
18600
18601         cmp -n $copied $file1 $ref2 | grep differ &&
18602                 error "Content mismatch [0, $copied) of ref2 and file1"
18603         cmp -n $copied $file2 $ref1 ||
18604                 error "Content mismatch [0, $copied) of ref1 and file2"
18605         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18606                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18607
18608         # clean up
18609         rm -f $ref1 $ref2 $file1 $file2
18610 }
18611 run_test 184c "Concurrent write and layout swap"
18612
18613 test_184d() {
18614         check_swap_layouts_support
18615         check_swap_layout_no_dom $DIR
18616         [ -z "$(which getfattr 2>/dev/null)" ] &&
18617                 skip_env "no getfattr command"
18618
18619         local file1=$DIR/$tdir/$tfile-1
18620         local file2=$DIR/$tdir/$tfile-2
18621         local file3=$DIR/$tdir/$tfile-3
18622         local lovea1
18623         local lovea2
18624
18625         mkdir -p $DIR/$tdir
18626         touch $file1 || error "create $file1 failed"
18627         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18628                 error "create $file2 failed"
18629         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18630                 error "create $file3 failed"
18631         lovea1=$(get_layout_param $file1)
18632
18633         $LFS swap_layouts $file2 $file3 ||
18634                 error "swap $file2 $file3 layouts failed"
18635         $LFS swap_layouts $file1 $file2 ||
18636                 error "swap $file1 $file2 layouts failed"
18637
18638         lovea2=$(get_layout_param $file2)
18639         echo "$lovea1"
18640         echo "$lovea2"
18641         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18642
18643         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18644         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18645 }
18646 run_test 184d "allow stripeless layouts swap"
18647
18648 test_184e() {
18649         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18650                 skip "Need MDS version at least 2.6.94"
18651         check_swap_layouts_support
18652         check_swap_layout_no_dom $DIR
18653         [ -z "$(which getfattr 2>/dev/null)" ] &&
18654                 skip_env "no getfattr command"
18655
18656         local file1=$DIR/$tdir/$tfile-1
18657         local file2=$DIR/$tdir/$tfile-2
18658         local file3=$DIR/$tdir/$tfile-3
18659         local lovea
18660
18661         mkdir -p $DIR/$tdir
18662         touch $file1 || error "create $file1 failed"
18663         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18664                 error "create $file2 failed"
18665         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18666                 error "create $file3 failed"
18667
18668         $LFS swap_layouts $file1 $file2 ||
18669                 error "swap $file1 $file2 layouts failed"
18670
18671         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18672         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18673
18674         echo 123 > $file1 || error "Should be able to write into $file1"
18675
18676         $LFS swap_layouts $file1 $file3 ||
18677                 error "swap $file1 $file3 layouts failed"
18678
18679         echo 123 > $file1 || error "Should be able to write into $file1"
18680
18681         rm -rf $file1 $file2 $file3
18682 }
18683 run_test 184e "Recreate layout after stripeless layout swaps"
18684
18685 test_184f() {
18686         # Create a file with name longer than sizeof(struct stat) ==
18687         # 144 to see if we can get chars from the file name to appear
18688         # in the returned striping. Note that 'f' == 0x66.
18689         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18690
18691         mkdir -p $DIR/$tdir
18692         mcreate $DIR/$tdir/$file
18693         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18694                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18695         fi
18696 }
18697 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18698
18699 test_185() { # LU-2441
18700         # LU-3553 - no volatile file support in old servers
18701         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18702                 skip "Need MDS version at least 2.3.60"
18703
18704         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18705         touch $DIR/$tdir/spoo
18706         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18707         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18708                 error "cannot create/write a volatile file"
18709         [ "$FILESET" == "" ] &&
18710         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18711                 error "FID is still valid after close"
18712
18713         multiop_bg_pause $DIR/$tdir vVw4096_c
18714         local multi_pid=$!
18715
18716         local OLD_IFS=$IFS
18717         IFS=":"
18718         local fidv=($fid)
18719         IFS=$OLD_IFS
18720         # assume that the next FID for this client is sequential, since stdout
18721         # is unfortunately eaten by multiop_bg_pause
18722         local n=$((${fidv[1]} + 1))
18723         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18724         if [ "$FILESET" == "" ]; then
18725                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18726                         error "FID is missing before close"
18727         fi
18728         kill -USR1 $multi_pid
18729         # 1 second delay, so if mtime change we will see it
18730         sleep 1
18731         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18732         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18733 }
18734 run_test 185 "Volatile file support"
18735
18736 function create_check_volatile() {
18737         local idx=$1
18738         local tgt
18739
18740         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18741         local PID=$!
18742         sleep 1
18743         local FID=$(cat /tmp/${tfile}.fid)
18744         [ "$FID" == "" ] && error "can't get FID for volatile"
18745         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18746         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18747         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18748         kill -USR1 $PID
18749         wait
18750         sleep 1
18751         cancel_lru_locks mdc # flush opencache
18752         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18753         return 0
18754 }
18755
18756 test_185a(){
18757         # LU-12516 - volatile creation via .lustre
18758         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18759                 skip "Need MDS version at least 2.3.55"
18760
18761         create_check_volatile 0
18762         [ $MDSCOUNT -lt 2 ] && return 0
18763
18764         # DNE case
18765         create_check_volatile 1
18766
18767         return 0
18768 }
18769 run_test 185a "Volatile file creation in .lustre/fid/"
18770
18771 test_187a() {
18772         remote_mds_nodsh && skip "remote MDS with nodsh"
18773         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18774                 skip "Need MDS version at least 2.3.0"
18775
18776         local dir0=$DIR/$tdir/$testnum
18777         mkdir -p $dir0 || error "creating dir $dir0"
18778
18779         local file=$dir0/file1
18780         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18781         local dv1=$($LFS data_version $file)
18782         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18783         local dv2=$($LFS data_version $file)
18784         [[ $dv1 != $dv2 ]] ||
18785                 error "data version did not change on write $dv1 == $dv2"
18786
18787         # clean up
18788         rm -f $file1
18789 }
18790 run_test 187a "Test data version change"
18791
18792 test_187b() {
18793         remote_mds_nodsh && skip "remote MDS with nodsh"
18794         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18795                 skip "Need MDS version at least 2.3.0"
18796
18797         local dir0=$DIR/$tdir/$testnum
18798         mkdir -p $dir0 || error "creating dir $dir0"
18799
18800         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18801         [[ ${DV[0]} != ${DV[1]} ]] ||
18802                 error "data version did not change on write"\
18803                       " ${DV[0]} == ${DV[1]}"
18804
18805         # clean up
18806         rm -f $file1
18807 }
18808 run_test 187b "Test data version change on volatile file"
18809
18810 test_200() {
18811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18812         remote_mgs_nodsh && skip "remote MGS with nodsh"
18813         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18814
18815         local POOL=${POOL:-cea1}
18816         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18817         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18818         # Pool OST targets
18819         local first_ost=0
18820         local last_ost=$(($OSTCOUNT - 1))
18821         local ost_step=2
18822         local ost_list=$(seq $first_ost $ost_step $last_ost)
18823         local ost_range="$first_ost $last_ost $ost_step"
18824         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18825         local file_dir=$POOL_ROOT/file_tst
18826         local subdir=$test_path/subdir
18827         local rc=0
18828
18829         while : ; do
18830                 # former test_200a test_200b
18831                 pool_add $POOL                          || { rc=$? ; break; }
18832                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18833                 # former test_200c test_200d
18834                 mkdir -p $test_path
18835                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18836                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18837                 mkdir -p $subdir
18838                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18839                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18840                                                         || { rc=$? ; break; }
18841                 # former test_200e test_200f
18842                 local files=$((OSTCOUNT*3))
18843                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18844                                                         || { rc=$? ; break; }
18845                 pool_create_files $POOL $file_dir $files "$ost_list" \
18846                                                         || { rc=$? ; break; }
18847                 # former test_200g test_200h
18848                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18849                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18850
18851                 # former test_201a test_201b test_201c
18852                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18853
18854                 local f=$test_path/$tfile
18855                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18856                 pool_remove $POOL $f                    || { rc=$? ; break; }
18857                 break
18858         done
18859
18860         destroy_test_pools
18861
18862         return $rc
18863 }
18864 run_test 200 "OST pools"
18865
18866 # usage: default_attr <count | size | offset>
18867 default_attr() {
18868         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18869 }
18870
18871 # usage: check_default_stripe_attr
18872 check_default_stripe_attr() {
18873         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18874         case $1 in
18875         --stripe-count|-c)
18876                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18877         --stripe-size|-S)
18878                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18879         --stripe-index|-i)
18880                 EXPECTED=-1;;
18881         *)
18882                 error "unknown getstripe attr '$1'"
18883         esac
18884
18885         [ $ACTUAL == $EXPECTED ] ||
18886                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18887 }
18888
18889 test_204a() {
18890         test_mkdir $DIR/$tdir
18891         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18892
18893         check_default_stripe_attr --stripe-count
18894         check_default_stripe_attr --stripe-size
18895         check_default_stripe_attr --stripe-index
18896 }
18897 run_test 204a "Print default stripe attributes"
18898
18899 test_204b() {
18900         test_mkdir $DIR/$tdir
18901         $LFS setstripe --stripe-count 1 $DIR/$tdir
18902
18903         check_default_stripe_attr --stripe-size
18904         check_default_stripe_attr --stripe-index
18905 }
18906 run_test 204b "Print default stripe size and offset"
18907
18908 test_204c() {
18909         test_mkdir $DIR/$tdir
18910         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18911
18912         check_default_stripe_attr --stripe-count
18913         check_default_stripe_attr --stripe-index
18914 }
18915 run_test 204c "Print default stripe count and offset"
18916
18917 test_204d() {
18918         test_mkdir $DIR/$tdir
18919         $LFS setstripe --stripe-index 0 $DIR/$tdir
18920
18921         check_default_stripe_attr --stripe-count
18922         check_default_stripe_attr --stripe-size
18923 }
18924 run_test 204d "Print default stripe count and size"
18925
18926 test_204e() {
18927         test_mkdir $DIR/$tdir
18928         $LFS setstripe -d $DIR/$tdir
18929
18930         check_default_stripe_attr --stripe-count --raw
18931         check_default_stripe_attr --stripe-size --raw
18932         check_default_stripe_attr --stripe-index --raw
18933 }
18934 run_test 204e "Print raw stripe attributes"
18935
18936 test_204f() {
18937         test_mkdir $DIR/$tdir
18938         $LFS setstripe --stripe-count 1 $DIR/$tdir
18939
18940         check_default_stripe_attr --stripe-size --raw
18941         check_default_stripe_attr --stripe-index --raw
18942 }
18943 run_test 204f "Print raw stripe size and offset"
18944
18945 test_204g() {
18946         test_mkdir $DIR/$tdir
18947         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18948
18949         check_default_stripe_attr --stripe-count --raw
18950         check_default_stripe_attr --stripe-index --raw
18951 }
18952 run_test 204g "Print raw stripe count and offset"
18953
18954 test_204h() {
18955         test_mkdir $DIR/$tdir
18956         $LFS setstripe --stripe-index 0 $DIR/$tdir
18957
18958         check_default_stripe_attr --stripe-count --raw
18959         check_default_stripe_attr --stripe-size --raw
18960 }
18961 run_test 204h "Print raw stripe count and size"
18962
18963 # Figure out which job scheduler is being used, if any,
18964 # or use a fake one
18965 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18966         JOBENV=SLURM_JOB_ID
18967 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18968         JOBENV=LSB_JOBID
18969 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18970         JOBENV=PBS_JOBID
18971 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18972         JOBENV=LOADL_STEP_ID
18973 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18974         JOBENV=JOB_ID
18975 else
18976         $LCTL list_param jobid_name > /dev/null 2>&1
18977         if [ $? -eq 0 ]; then
18978                 JOBENV=nodelocal
18979         else
18980                 JOBENV=FAKE_JOBID
18981         fi
18982 fi
18983 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18984
18985 verify_jobstats() {
18986         local cmd=($1)
18987         shift
18988         local facets="$@"
18989
18990 # we don't really need to clear the stats for this test to work, since each
18991 # command has a unique jobid, but it makes debugging easier if needed.
18992 #       for facet in $facets; do
18993 #               local dev=$(convert_facet2label $facet)
18994 #               # clear old jobstats
18995 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18996 #       done
18997
18998         # use a new JobID for each test, or we might see an old one
18999         [ "$JOBENV" = "FAKE_JOBID" ] &&
19000                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19001
19002         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19003
19004         [ "$JOBENV" = "nodelocal" ] && {
19005                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19006                 $LCTL set_param jobid_name=$FAKE_JOBID
19007                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19008         }
19009
19010         log "Test: ${cmd[*]}"
19011         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19012
19013         if [ $JOBENV = "FAKE_JOBID" ]; then
19014                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19015         else
19016                 ${cmd[*]}
19017         fi
19018
19019         # all files are created on OST0000
19020         for facet in $facets; do
19021                 local stats="*.$(convert_facet2label $facet).job_stats"
19022
19023                 # strip out libtool wrappers for in-tree executables
19024                 if (( $(do_facet $facet lctl get_param $stats |
19025                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19026                         do_facet $facet lctl get_param $stats
19027                         error "No jobstats for $JOBVAL found on $facet::$stats"
19028                 fi
19029         done
19030 }
19031
19032 jobstats_set() {
19033         local new_jobenv=$1
19034
19035         set_persistent_param_and_check client "jobid_var" \
19036                 "$FSNAME.sys.jobid_var" $new_jobenv
19037 }
19038
19039 test_205a() { # Job stats
19040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19041         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19042                 skip "Need MDS version with at least 2.7.1"
19043         remote_mgs_nodsh && skip "remote MGS with nodsh"
19044         remote_mds_nodsh && skip "remote MDS with nodsh"
19045         remote_ost_nodsh && skip "remote OST with nodsh"
19046         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19047                 skip "Server doesn't support jobstats"
19048         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19049
19050         local old_jobenv=$($LCTL get_param -n jobid_var)
19051         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19052
19053         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19054                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19055         else
19056                 stack_trap "do_facet mgs $PERM_CMD \
19057                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19058         fi
19059         changelog_register
19060
19061         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19062                                 mdt.*.job_cleanup_interval | head -n 1)
19063         local new_interval=5
19064         do_facet $SINGLEMDS \
19065                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19066         stack_trap "do_facet $SINGLEMDS \
19067                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19068         local start=$SECONDS
19069
19070         local cmd
19071         # mkdir
19072         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19073         verify_jobstats "$cmd" "$SINGLEMDS"
19074         # rmdir
19075         cmd="rmdir $DIR/$tdir"
19076         verify_jobstats "$cmd" "$SINGLEMDS"
19077         # mkdir on secondary MDT
19078         if [ $MDSCOUNT -gt 1 ]; then
19079                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19080                 verify_jobstats "$cmd" "mds2"
19081         fi
19082         # mknod
19083         cmd="mknod $DIR/$tfile c 1 3"
19084         verify_jobstats "$cmd" "$SINGLEMDS"
19085         # unlink
19086         cmd="rm -f $DIR/$tfile"
19087         verify_jobstats "$cmd" "$SINGLEMDS"
19088         # create all files on OST0000 so verify_jobstats can find OST stats
19089         # open & close
19090         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19091         verify_jobstats "$cmd" "$SINGLEMDS"
19092         # setattr
19093         cmd="touch $DIR/$tfile"
19094         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19095         # write
19096         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19097         verify_jobstats "$cmd" "ost1"
19098         # read
19099         cancel_lru_locks osc
19100         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19101         verify_jobstats "$cmd" "ost1"
19102         # truncate
19103         cmd="$TRUNCATE $DIR/$tfile 0"
19104         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19105         # rename
19106         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19107         verify_jobstats "$cmd" "$SINGLEMDS"
19108         # jobstats expiry - sleep until old stats should be expired
19109         local left=$((new_interval + 5 - (SECONDS - start)))
19110         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19111                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19112                         "0" $left
19113         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19114         verify_jobstats "$cmd" "$SINGLEMDS"
19115         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19116             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19117
19118         # Ensure that jobid are present in changelog (if supported by MDS)
19119         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19120                 changelog_dump | tail -10
19121                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19122                 [ $jobids -eq 9 ] ||
19123                         error "Wrong changelog jobid count $jobids != 9"
19124
19125                 # LU-5862
19126                 JOBENV="disable"
19127                 jobstats_set $JOBENV
19128                 touch $DIR/$tfile
19129                 changelog_dump | grep $tfile
19130                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19131                 [ $jobids -eq 0 ] ||
19132                         error "Unexpected jobids when jobid_var=$JOBENV"
19133         fi
19134
19135         # test '%j' access to environment variable - if supported
19136         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19137                 JOBENV="JOBCOMPLEX"
19138                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19139
19140                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19141         fi
19142
19143         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19144                 JOBENV="JOBCOMPLEX"
19145                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19146
19147                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19148         fi
19149
19150         # test '%j' access to per-session jobid - if supported
19151         if lctl list_param jobid_this_session > /dev/null 2>&1
19152         then
19153                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19154                 lctl set_param jobid_this_session=$USER
19155
19156                 JOBENV="JOBCOMPLEX"
19157                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19158
19159                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19160         fi
19161 }
19162 run_test 205a "Verify job stats"
19163
19164 # LU-13117, LU-13597
19165 test_205b() {
19166         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19167                 skip "Need MDS version at least 2.13.54.91"
19168
19169         local job_stats="mdt.*.job_stats"
19170         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19171
19172         do_facet mds1 $LCTL set_param $job_stats=clear
19173
19174         # Setting jobid_var to USER might not be supported
19175         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19176         $LCTL set_param jobid_var=USER || true
19177         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19178         $LCTL set_param jobid_name="%j.%e.%u"
19179
19180         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19181         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19182                 { do_facet mds1 $LCTL get_param $job_stats;
19183                   error "Unexpected jobid found"; }
19184         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19185                 { do_facet mds1 $LCTL get_param $job_stats;
19186                   error "wrong job_stats format found"; }
19187
19188         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19189                 echo "MDS does not yet escape jobid" && return 0
19190         $LCTL set_param jobid_var=TEST205b
19191         env -i TEST205b="has sp" touch $DIR/$tfile.2
19192         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19193                 { do_facet mds1 $LCTL get_param $job_stats;
19194                   error "jobid not escaped"; }
19195 }
19196 run_test 205b "Verify job stats jobid and output format"
19197
19198 # LU-13733
19199 test_205c() {
19200         $LCTL set_param llite.*.stats=0
19201         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19202         $LCTL get_param llite.*.stats
19203         $LCTL get_param llite.*.stats | grep \
19204                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19205                         error "wrong client stats format found"
19206 }
19207 run_test 205c "Verify client stats format"
19208
19209 test_205d() {
19210         local file=$DIR/$tdir/$tfile
19211
19212         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19213                 skip "need lustre >= 2.15.53 for lljobstat"
19214         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19215                 skip "need lustre >= 2.15.53 for lljobstat"
19216         verify_yaml_available || skip_env "YAML verification not installed"
19217
19218         test_mkdir -i 0 $DIR/$tdir
19219         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19220
19221         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19222                 error "failed to write data to $file"
19223         mv $file $file.2
19224
19225         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19226         echo -n 'verify rename_stats...'
19227         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19228                 verify_yaml || error "rename_stats is not valid YAML"
19229         echo " OK"
19230
19231         echo -n 'verify mdt job_stats...'
19232         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19233                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19234         echo " OK"
19235
19236         echo -n 'verify ost job_stats...'
19237         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19238                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19239         echo " OK"
19240 }
19241 run_test 205d "verify the format of some stats files"
19242
19243 test_205e() {
19244         local ops_comma
19245         local file=$DIR/$tdir/$tfile
19246
19247         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19248                 skip "need lustre >= 2.15.53 for lljobstat"
19249         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19250                 skip "need lustre >= 2.15.53 for lljobstat"
19251         verify_yaml_available || skip_env "YAML verification not installed"
19252
19253         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19254
19255         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19256                 error "failed to create $file on ost1"
19257         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19258                 error "failed to write data to $file"
19259
19260         do_facet mds1 "$LCTL get_param *.*.job_stats"
19261         do_facet ost1 "$LCTL get_param *.*.job_stats"
19262
19263         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19264         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19265                 error "The output of lljobstat is not an valid YAML"
19266
19267         # verify that job dd.0 does exist and has some ops on ost1
19268         # typically this line is like:
19269         # - dd.0:            {ops: 20, ...}
19270         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19271                     awk '$2=="dd.0:" {print $4}')
19272
19273         (( ${ops_comma%,} >= 10 )) ||
19274                 error "cannot find job dd.0 with ops >= 10"
19275 }
19276 run_test 205e "verify the output of lljobstat"
19277
19278 # LU-1480, LU-1773 and LU-1657
19279 test_206() {
19280         mkdir -p $DIR/$tdir
19281         $LFS setstripe -c -1 $DIR/$tdir
19282 #define OBD_FAIL_LOV_INIT 0x1403
19283         $LCTL set_param fail_loc=0xa0001403
19284         $LCTL set_param fail_val=1
19285         touch $DIR/$tdir/$tfile || true
19286 }
19287 run_test 206 "fail lov_init_raid0() doesn't lbug"
19288
19289 test_207a() {
19290         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19291         local fsz=`stat -c %s $DIR/$tfile`
19292         cancel_lru_locks mdc
19293
19294         # do not return layout in getattr intent
19295 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19296         $LCTL set_param fail_loc=0x170
19297         local sz=`stat -c %s $DIR/$tfile`
19298
19299         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19300
19301         rm -rf $DIR/$tfile
19302 }
19303 run_test 207a "can refresh layout at glimpse"
19304
19305 test_207b() {
19306         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19307         local cksum=`md5sum $DIR/$tfile`
19308         local fsz=`stat -c %s $DIR/$tfile`
19309         cancel_lru_locks mdc
19310         cancel_lru_locks osc
19311
19312         # do not return layout in getattr intent
19313 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19314         $LCTL set_param fail_loc=0x171
19315
19316         # it will refresh layout after the file is opened but before read issues
19317         echo checksum is "$cksum"
19318         echo "$cksum" |md5sum -c --quiet || error "file differs"
19319
19320         rm -rf $DIR/$tfile
19321 }
19322 run_test 207b "can refresh layout at open"
19323
19324 test_208() {
19325         # FIXME: in this test suite, only RD lease is used. This is okay
19326         # for now as only exclusive open is supported. After generic lease
19327         # is done, this test suite should be revised. - Jinshan
19328
19329         remote_mds_nodsh && skip "remote MDS with nodsh"
19330         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19331                 skip "Need MDS version at least 2.4.52"
19332
19333         echo "==== test 1: verify get lease work"
19334         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19335
19336         echo "==== test 2: verify lease can be broken by upcoming open"
19337         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19338         local PID=$!
19339         sleep 2
19340
19341         $MULTIOP $DIR/$tfile oO_RDWR:c
19342         kill -USR1 $PID && wait $PID || error "break lease error"
19343
19344         echo "==== test 3: verify lease can't be granted if an open already exists"
19345         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19346         local PID=$!
19347         sleep 2
19348
19349         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19350         kill -USR1 $PID && wait $PID || error "open file error"
19351
19352         echo "==== test 4: lease can sustain over recovery"
19353         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19354         PID=$!
19355         sleep 2
19356
19357         fail mds1
19358
19359         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19360
19361         echo "==== test 5: lease broken can't be regained by replay"
19362         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19363         PID=$!
19364         sleep 2
19365
19366         # open file to break lease and then recovery
19367         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19368         fail mds1
19369
19370         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19371
19372         rm -f $DIR/$tfile
19373 }
19374 run_test 208 "Exclusive open"
19375
19376 test_209() {
19377         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19378                 skip_env "must have disp_stripe"
19379
19380         touch $DIR/$tfile
19381         sync; sleep 5; sync;
19382
19383         echo 3 > /proc/sys/vm/drop_caches
19384         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19385                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19386         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19387
19388         # open/close 500 times
19389         for i in $(seq 500); do
19390                 cat $DIR/$tfile
19391         done
19392
19393         echo 3 > /proc/sys/vm/drop_caches
19394         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19395                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19396         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19397
19398         echo "before: $req_before, after: $req_after"
19399         [ $((req_after - req_before)) -ge 300 ] &&
19400                 error "open/close requests are not freed"
19401         return 0
19402 }
19403 run_test 209 "read-only open/close requests should be freed promptly"
19404
19405 test_210() {
19406         local pid
19407
19408         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19409         pid=$!
19410         sleep 1
19411
19412         $LFS getstripe $DIR/$tfile
19413         kill -USR1 $pid
19414         wait $pid || error "multiop failed"
19415
19416         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19417         pid=$!
19418         sleep 1
19419
19420         $LFS getstripe $DIR/$tfile
19421         kill -USR1 $pid
19422         wait $pid || error "multiop failed"
19423 }
19424 run_test 210 "lfs getstripe does not break leases"
19425
19426 test_212() {
19427         size=`date +%s`
19428         size=$((size % 8192 + 1))
19429         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19430         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19431         rm -f $DIR/f212 $DIR/f212.xyz
19432 }
19433 run_test 212 "Sendfile test ============================================"
19434
19435 test_213() {
19436         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19437         cancel_lru_locks osc
19438         lctl set_param fail_loc=0x8000040f
19439         # generate a read lock
19440         cat $DIR/$tfile > /dev/null
19441         # write to the file, it will try to cancel the above read lock.
19442         cat /etc/hosts >> $DIR/$tfile
19443 }
19444 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19445
19446 test_214() { # for bug 20133
19447         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19448         for (( i=0; i < 340; i++ )) ; do
19449                 touch $DIR/$tdir/d214c/a$i
19450         done
19451
19452         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19453         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19454         ls $DIR/d214c || error "ls $DIR/d214c failed"
19455         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19456         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19457 }
19458 run_test 214 "hash-indexed directory test - bug 20133"
19459
19460 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19461 create_lnet_proc_files() {
19462         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19463 }
19464
19465 # counterpart of create_lnet_proc_files
19466 remove_lnet_proc_files() {
19467         rm -f $TMP/lnet_$1.sys
19468 }
19469
19470 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19471 # 3rd arg as regexp for body
19472 check_lnet_proc_stats() {
19473         local l=$(cat "$TMP/lnet_$1" |wc -l)
19474         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19475
19476         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19477 }
19478
19479 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19480 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19481 # optional and can be regexp for 2nd line (lnet.routes case)
19482 check_lnet_proc_entry() {
19483         local blp=2          # blp stands for 'position of 1st line of body'
19484         [ -z "$5" ] || blp=3 # lnet.routes case
19485
19486         local l=$(cat "$TMP/lnet_$1" |wc -l)
19487         # subtracting one from $blp because the body can be empty
19488         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19489
19490         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19491                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19492
19493         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19494                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19495
19496         # bail out if any unexpected line happened
19497         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19498         [ "$?" != 0 ] || error "$2 misformatted"
19499 }
19500
19501 test_215() { # for bugs 18102, 21079, 21517
19502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19503
19504         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19505         local P='[1-9][0-9]*'           # positive numeric
19506         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19507         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19508         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19509         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19510
19511         local L1 # regexp for 1st line
19512         local L2 # regexp for 2nd line (optional)
19513         local BR # regexp for the rest (body)
19514
19515         # lnet.stats should look as 11 space-separated non-negative numerics
19516         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19517         create_lnet_proc_files "stats"
19518         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19519         remove_lnet_proc_files "stats"
19520
19521         # lnet.routes should look like this:
19522         # Routing disabled/enabled
19523         # net hops priority state router
19524         # where net is a string like tcp0, hops > 0, priority >= 0,
19525         # state is up/down,
19526         # router is a string like 192.168.1.1@tcp2
19527         L1="^Routing (disabled|enabled)$"
19528         L2="^net +hops +priority +state +router$"
19529         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19530         create_lnet_proc_files "routes"
19531         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19532         remove_lnet_proc_files "routes"
19533
19534         # lnet.routers should look like this:
19535         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19536         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19537         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19538         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19539         L1="^ref +rtr_ref +alive +router$"
19540         BR="^$P +$P +(up|down) +$NID$"
19541         create_lnet_proc_files "routers"
19542         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19543         remove_lnet_proc_files "routers"
19544
19545         # lnet.peers should look like this:
19546         # nid refs state last max rtr min tx min queue
19547         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19548         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19549         # numeric (0 or >0 or <0), queue >= 0.
19550         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19551         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19552         create_lnet_proc_files "peers"
19553         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19554         remove_lnet_proc_files "peers"
19555
19556         # lnet.buffers  should look like this:
19557         # pages count credits min
19558         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19559         L1="^pages +count +credits +min$"
19560         BR="^ +$N +$N +$I +$I$"
19561         create_lnet_proc_files "buffers"
19562         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19563         remove_lnet_proc_files "buffers"
19564
19565         # lnet.nis should look like this:
19566         # nid status alive refs peer rtr max tx min
19567         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19568         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19569         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19570         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19571         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19572         create_lnet_proc_files "nis"
19573         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19574         remove_lnet_proc_files "nis"
19575
19576         # can we successfully write to lnet.stats?
19577         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19578 }
19579 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19580
19581 test_216() { # bug 20317
19582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19583         remote_ost_nodsh && skip "remote OST with nodsh"
19584
19585         local node
19586         local facets=$(get_facets OST)
19587         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19588
19589         save_lustre_params client "osc.*.contention_seconds" > $p
19590         save_lustre_params $facets \
19591                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19592         save_lustre_params $facets \
19593                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19594         save_lustre_params $facets \
19595                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19596         clear_stats osc.*.osc_stats
19597
19598         # agressive lockless i/o settings
19599         do_nodes $(comma_list $(osts_nodes)) \
19600                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19601                         ldlm.namespaces.filter-*.contended_locks=0 \
19602                         ldlm.namespaces.filter-*.contention_seconds=60"
19603         lctl set_param -n osc.*.contention_seconds=60
19604
19605         $DIRECTIO write $DIR/$tfile 0 10 4096
19606         $CHECKSTAT -s 40960 $DIR/$tfile
19607
19608         # disable lockless i/o
19609         do_nodes $(comma_list $(osts_nodes)) \
19610                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19611                         ldlm.namespaces.filter-*.contended_locks=32 \
19612                         ldlm.namespaces.filter-*.contention_seconds=0"
19613         lctl set_param -n osc.*.contention_seconds=0
19614         clear_stats osc.*.osc_stats
19615
19616         dd if=/dev/zero of=$DIR/$tfile count=0
19617         $CHECKSTAT -s 0 $DIR/$tfile
19618
19619         restore_lustre_params <$p
19620         rm -f $p
19621         rm $DIR/$tfile
19622 }
19623 run_test 216 "check lockless direct write updates file size and kms correctly"
19624
19625 test_217() { # bug 22430
19626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19627
19628         local node
19629         local nid
19630
19631         for node in $(nodes_list); do
19632                 nid=$(host_nids_address $node $NETTYPE)
19633                 if [[ $nid = *-* ]] ; then
19634                         echo "lctl ping $(h2nettype $nid)"
19635                         lctl ping $(h2nettype $nid)
19636                 else
19637                         echo "skipping $node (no hyphen detected)"
19638                 fi
19639         done
19640 }
19641 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19642
19643 test_218() {
19644        # do directio so as not to populate the page cache
19645        log "creating a 10 Mb file"
19646        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19647        log "starting reads"
19648        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19649        log "truncating the file"
19650        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19651        log "killing dd"
19652        kill %+ || true # reads might have finished
19653        echo "wait until dd is finished"
19654        wait
19655        log "removing the temporary file"
19656        rm -rf $DIR/$tfile || error "tmp file removal failed"
19657 }
19658 run_test 218 "parallel read and truncate should not deadlock"
19659
19660 test_219() {
19661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19662
19663         # write one partial page
19664         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19665         # set no grant so vvp_io_commit_write will do sync write
19666         $LCTL set_param fail_loc=0x411
19667         # write a full page at the end of file
19668         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19669
19670         $LCTL set_param fail_loc=0
19671         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19672         $LCTL set_param fail_loc=0x411
19673         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19674
19675         # LU-4201
19676         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19677         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19678 }
19679 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19680
19681 test_220() { #LU-325
19682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19683         remote_ost_nodsh && skip "remote OST with nodsh"
19684         remote_mds_nodsh && skip "remote MDS with nodsh"
19685         remote_mgs_nodsh && skip "remote MGS with nodsh"
19686
19687         local OSTIDX=0
19688
19689         # create on MDT0000 so the last_id and next_id are correct
19690         mkdir_on_mdt0 $DIR/$tdir
19691         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19692         OST=${OST%_UUID}
19693
19694         # on the mdt's osc
19695         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19696         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19697                         osp.$mdtosc_proc1.prealloc_last_id)
19698         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19699                         osp.$mdtosc_proc1.prealloc_next_id)
19700
19701         $LFS df -i
19702
19703         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19704         #define OBD_FAIL_OST_ENOINO              0x229
19705         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19706         create_pool $FSNAME.$TESTNAME || return 1
19707         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19708
19709         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19710
19711         MDSOBJS=$((last_id - next_id))
19712         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19713
19714         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19715         echo "OST still has $count kbytes free"
19716
19717         echo "create $MDSOBJS files @next_id..."
19718         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19719
19720         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19721                         osp.$mdtosc_proc1.prealloc_last_id)
19722         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19723                         osp.$mdtosc_proc1.prealloc_next_id)
19724
19725         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19726         $LFS df -i
19727
19728         echo "cleanup..."
19729
19730         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19731         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19732
19733         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19734                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19735         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19736                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19737         echo "unlink $MDSOBJS files @$next_id..."
19738         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19739 }
19740 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19741
19742 test_221() {
19743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19744
19745         dd if=`which date` of=$MOUNT/date oflag=sync
19746         chmod +x $MOUNT/date
19747
19748         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19749         $LCTL set_param fail_loc=0x80001401
19750
19751         $MOUNT/date > /dev/null
19752         rm -f $MOUNT/date
19753 }
19754 run_test 221 "make sure fault and truncate race to not cause OOM"
19755
19756 test_222a () {
19757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19758
19759         rm -rf $DIR/$tdir
19760         test_mkdir $DIR/$tdir
19761         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19762         createmany -o $DIR/$tdir/$tfile 10
19763         cancel_lru_locks mdc
19764         cancel_lru_locks osc
19765         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19766         $LCTL set_param fail_loc=0x31a
19767         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19768         $LCTL set_param fail_loc=0
19769         rm -r $DIR/$tdir
19770 }
19771 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19772
19773 test_222b () {
19774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19775
19776         rm -rf $DIR/$tdir
19777         test_mkdir $DIR/$tdir
19778         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19779         createmany -o $DIR/$tdir/$tfile 10
19780         cancel_lru_locks mdc
19781         cancel_lru_locks osc
19782         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19783         $LCTL set_param fail_loc=0x31a
19784         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19785         $LCTL set_param fail_loc=0
19786 }
19787 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19788
19789 test_223 () {
19790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19791
19792         rm -rf $DIR/$tdir
19793         test_mkdir $DIR/$tdir
19794         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19795         createmany -o $DIR/$tdir/$tfile 10
19796         cancel_lru_locks mdc
19797         cancel_lru_locks osc
19798         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19799         $LCTL set_param fail_loc=0x31b
19800         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19801         $LCTL set_param fail_loc=0
19802         rm -r $DIR/$tdir
19803 }
19804 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19805
19806 test_224a() { # LU-1039, MRP-303
19807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19808         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19809         $LCTL set_param fail_loc=0x508
19810         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19811         $LCTL set_param fail_loc=0
19812         df $DIR
19813 }
19814 run_test 224a "Don't panic on bulk IO failure"
19815
19816 test_224bd_sub() { # LU-1039, MRP-303
19817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19818         local timeout=$1
19819
19820         shift
19821         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19822
19823         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19824
19825         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19826         cancel_lru_locks osc
19827         set_checksums 0
19828         stack_trap "set_checksums $ORIG_CSUM" EXIT
19829         local at_max_saved=0
19830
19831         # adaptive timeouts may prevent seeing the issue
19832         if at_is_enabled; then
19833                 at_max_saved=$(at_max_get mds)
19834                 at_max_set 0 mds client
19835                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19836         fi
19837
19838         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19839         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19840         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19841
19842         do_facet ost1 $LCTL set_param fail_loc=0
19843         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19844         df $DIR
19845 }
19846
19847 test_224b() {
19848         test_224bd_sub 3 error "dd failed"
19849 }
19850 run_test 224b "Don't panic on bulk IO failure"
19851
19852 test_224c() { # LU-6441
19853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19854         remote_mds_nodsh && skip "remote MDS with nodsh"
19855
19856         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19857         save_writethrough $p
19858         set_cache writethrough on
19859
19860         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19861         local at_max=$($LCTL get_param -n at_max)
19862         local timeout=$($LCTL get_param -n timeout)
19863         local test_at="at_max"
19864         local param_at="$FSNAME.sys.at_max"
19865         local test_timeout="timeout"
19866         local param_timeout="$FSNAME.sys.timeout"
19867
19868         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19869
19870         set_persistent_param_and_check client "$test_at" "$param_at" 0
19871         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19872
19873         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19874         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19875         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19876         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19877         sync
19878         do_facet ost1 "$LCTL set_param fail_loc=0"
19879
19880         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19881         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19882                 $timeout
19883
19884         $LCTL set_param -n $pages_per_rpc
19885         restore_lustre_params < $p
19886         rm -f $p
19887 }
19888 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19889
19890 test_224d() { # LU-11169
19891         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19892 }
19893 run_test 224d "Don't corrupt data on bulk IO timeout"
19894
19895 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19896 test_225a () {
19897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19898         if [ -z ${MDSSURVEY} ]; then
19899                 skip_env "mds-survey not found"
19900         fi
19901         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19902                 skip "Need MDS version at least 2.2.51"
19903
19904         local mds=$(facet_host $SINGLEMDS)
19905         local target=$(do_nodes $mds 'lctl dl' |
19906                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19907
19908         local cmd1="file_count=1000 thrhi=4"
19909         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19910         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19911         local cmd="$cmd1 $cmd2 $cmd3"
19912
19913         rm -f ${TMP}/mds_survey*
19914         echo + $cmd
19915         eval $cmd || error "mds-survey with zero-stripe failed"
19916         cat ${TMP}/mds_survey*
19917         rm -f ${TMP}/mds_survey*
19918 }
19919 run_test 225a "Metadata survey sanity with zero-stripe"
19920
19921 test_225b () {
19922         if [ -z ${MDSSURVEY} ]; then
19923                 skip_env "mds-survey not found"
19924         fi
19925         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19926                 skip "Need MDS version at least 2.2.51"
19927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19928         remote_mds_nodsh && skip "remote MDS with nodsh"
19929         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19930                 skip_env "Need to mount OST to test"
19931         fi
19932
19933         local mds=$(facet_host $SINGLEMDS)
19934         local target=$(do_nodes $mds 'lctl dl' |
19935                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19936
19937         local cmd1="file_count=1000 thrhi=4"
19938         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19939         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19940         local cmd="$cmd1 $cmd2 $cmd3"
19941
19942         rm -f ${TMP}/mds_survey*
19943         echo + $cmd
19944         eval $cmd || error "mds-survey with stripe_count failed"
19945         cat ${TMP}/mds_survey*
19946         rm -f ${TMP}/mds_survey*
19947 }
19948 run_test 225b "Metadata survey sanity with stripe_count = 1"
19949
19950 mcreate_path2fid () {
19951         local mode=$1
19952         local major=$2
19953         local minor=$3
19954         local name=$4
19955         local desc=$5
19956         local path=$DIR/$tdir/$name
19957         local fid
19958         local rc
19959         local fid_path
19960
19961         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19962                 error "cannot create $desc"
19963
19964         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19965         rc=$?
19966         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19967
19968         fid_path=$($LFS fid2path $MOUNT $fid)
19969         rc=$?
19970         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19971
19972         [ "$path" == "$fid_path" ] ||
19973                 error "fid2path returned $fid_path, expected $path"
19974
19975         echo "pass with $path and $fid"
19976 }
19977
19978 test_226a () {
19979         rm -rf $DIR/$tdir
19980         mkdir -p $DIR/$tdir
19981
19982         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19983         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19984         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19985         mcreate_path2fid 0040666 0 0 dir "directory"
19986         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19987         mcreate_path2fid 0100666 0 0 file "regular file"
19988         mcreate_path2fid 0120666 0 0 link "symbolic link"
19989         mcreate_path2fid 0140666 0 0 sock "socket"
19990 }
19991 run_test 226a "call path2fid and fid2path on files of all type"
19992
19993 test_226b () {
19994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19995
19996         local MDTIDX=1
19997
19998         rm -rf $DIR/$tdir
19999         mkdir -p $DIR/$tdir
20000         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20001                 error "create remote directory failed"
20002         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20003         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20004                                 "character special file (null)"
20005         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20006                                 "character special file (no device)"
20007         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20008         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20009                                 "block special file (loop)"
20010         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20011         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20012         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20013 }
20014 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20015
20016 test_226c () {
20017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20018         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20019                 skip "Need MDS version at least 2.13.55"
20020
20021         local submnt=/mnt/submnt
20022         local srcfile=/etc/passwd
20023         local dstfile=$submnt/passwd
20024         local path
20025         local fid
20026
20027         rm -rf $DIR/$tdir
20028         rm -rf $submnt
20029         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20030                 error "create remote directory failed"
20031         mkdir -p $submnt || error "create $submnt failed"
20032         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20033                 error "mount $submnt failed"
20034         stack_trap "umount $submnt" EXIT
20035
20036         cp $srcfile $dstfile
20037         fid=$($LFS path2fid $dstfile)
20038         path=$($LFS fid2path $submnt "$fid")
20039         [ "$path" = "$dstfile" ] ||
20040                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20041 }
20042 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20043
20044 # LU-1299 Executing or running ldd on a truncated executable does not
20045 # cause an out-of-memory condition.
20046 test_227() {
20047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20048         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20049
20050         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20051         chmod +x $MOUNT/date
20052
20053         $MOUNT/date > /dev/null
20054         ldd $MOUNT/date > /dev/null
20055         rm -f $MOUNT/date
20056 }
20057 run_test 227 "running truncated executable does not cause OOM"
20058
20059 # LU-1512 try to reuse idle OI blocks
20060 test_228a() {
20061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20062         remote_mds_nodsh && skip "remote MDS with nodsh"
20063         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20064
20065         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20066         local myDIR=$DIR/$tdir
20067
20068         mkdir -p $myDIR
20069         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20070         $LCTL set_param fail_loc=0x80001002
20071         createmany -o $myDIR/t- 10000
20072         $LCTL set_param fail_loc=0
20073         # The guard is current the largest FID holder
20074         touch $myDIR/guard
20075         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20076                     tr -d '[')
20077         local IDX=$(($SEQ % 64))
20078
20079         do_facet $SINGLEMDS sync
20080         # Make sure journal flushed.
20081         sleep 6
20082         local blk1=$(do_facet $SINGLEMDS \
20083                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20084                      grep Blockcount | awk '{print $4}')
20085
20086         # Remove old files, some OI blocks will become idle.
20087         unlinkmany $myDIR/t- 10000
20088         # Create new files, idle OI blocks should be reused.
20089         createmany -o $myDIR/t- 2000
20090         do_facet $SINGLEMDS sync
20091         # Make sure journal flushed.
20092         sleep 6
20093         local blk2=$(do_facet $SINGLEMDS \
20094                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20095                      grep Blockcount | awk '{print $4}')
20096
20097         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20098 }
20099 run_test 228a "try to reuse idle OI blocks"
20100
20101 test_228b() {
20102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20103         remote_mds_nodsh && skip "remote MDS with nodsh"
20104         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20105
20106         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20107         local myDIR=$DIR/$tdir
20108
20109         mkdir -p $myDIR
20110         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20111         $LCTL set_param fail_loc=0x80001002
20112         createmany -o $myDIR/t- 10000
20113         $LCTL set_param fail_loc=0
20114         # The guard is current the largest FID holder
20115         touch $myDIR/guard
20116         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20117                     tr -d '[')
20118         local IDX=$(($SEQ % 64))
20119
20120         do_facet $SINGLEMDS sync
20121         # Make sure journal flushed.
20122         sleep 6
20123         local blk1=$(do_facet $SINGLEMDS \
20124                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20125                      grep Blockcount | awk '{print $4}')
20126
20127         # Remove old files, some OI blocks will become idle.
20128         unlinkmany $myDIR/t- 10000
20129
20130         # stop the MDT
20131         stop $SINGLEMDS || error "Fail to stop MDT."
20132         # remount the MDT
20133         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20134                 error "Fail to start MDT."
20135
20136         client_up || error "Fail to df."
20137         # Create new files, idle OI blocks should be reused.
20138         createmany -o $myDIR/t- 2000
20139         do_facet $SINGLEMDS sync
20140         # Make sure journal flushed.
20141         sleep 6
20142         local blk2=$(do_facet $SINGLEMDS \
20143                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20144                      grep Blockcount | awk '{print $4}')
20145
20146         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20147 }
20148 run_test 228b "idle OI blocks can be reused after MDT restart"
20149
20150 #LU-1881
20151 test_228c() {
20152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20153         remote_mds_nodsh && skip "remote MDS with nodsh"
20154         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20155
20156         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20157         local myDIR=$DIR/$tdir
20158
20159         mkdir -p $myDIR
20160         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20161         $LCTL set_param fail_loc=0x80001002
20162         # 20000 files can guarantee there are index nodes in the OI file
20163         createmany -o $myDIR/t- 20000
20164         $LCTL set_param fail_loc=0
20165         # The guard is current the largest FID holder
20166         touch $myDIR/guard
20167         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20168                     tr -d '[')
20169         local IDX=$(($SEQ % 64))
20170
20171         do_facet $SINGLEMDS sync
20172         # Make sure journal flushed.
20173         sleep 6
20174         local blk1=$(do_facet $SINGLEMDS \
20175                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20176                      grep Blockcount | awk '{print $4}')
20177
20178         # Remove old files, some OI blocks will become idle.
20179         unlinkmany $myDIR/t- 20000
20180         rm -f $myDIR/guard
20181         # The OI file should become empty now
20182
20183         # Create new files, idle OI blocks should be reused.
20184         createmany -o $myDIR/t- 2000
20185         do_facet $SINGLEMDS sync
20186         # Make sure journal flushed.
20187         sleep 6
20188         local blk2=$(do_facet $SINGLEMDS \
20189                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20190                      grep Blockcount | awk '{print $4}')
20191
20192         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20193 }
20194 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20195
20196 test_229() { # LU-2482, LU-3448
20197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20198         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20199         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20200                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20201
20202         rm -f $DIR/$tfile
20203
20204         # Create a file with a released layout and stripe count 2.
20205         $MULTIOP $DIR/$tfile H2c ||
20206                 error "failed to create file with released layout"
20207
20208         $LFS getstripe -v $DIR/$tfile
20209
20210         local pattern=$($LFS getstripe -L $DIR/$tfile)
20211         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20212
20213         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20214                 error "getstripe"
20215         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20216         stat $DIR/$tfile || error "failed to stat released file"
20217
20218         chown $RUNAS_ID $DIR/$tfile ||
20219                 error "chown $RUNAS_ID $DIR/$tfile failed"
20220
20221         chgrp $RUNAS_ID $DIR/$tfile ||
20222                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20223
20224         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20225         rm $DIR/$tfile || error "failed to remove released file"
20226 }
20227 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20228
20229 test_230a() {
20230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20232         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20233                 skip "Need MDS version at least 2.11.52"
20234
20235         local MDTIDX=1
20236
20237         test_mkdir $DIR/$tdir
20238         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20239         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20240         [ $mdt_idx -ne 0 ] &&
20241                 error "create local directory on wrong MDT $mdt_idx"
20242
20243         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20244                         error "create remote directory failed"
20245         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20246         [ $mdt_idx -ne $MDTIDX ] &&
20247                 error "create remote directory on wrong MDT $mdt_idx"
20248
20249         createmany -o $DIR/$tdir/test_230/t- 10 ||
20250                 error "create files on remote directory failed"
20251         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20252         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20253         rm -r $DIR/$tdir || error "unlink remote directory failed"
20254 }
20255 run_test 230a "Create remote directory and files under the remote directory"
20256
20257 test_230b() {
20258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20259         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20260         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20261                 skip "Need MDS version at least 2.11.52"
20262
20263         local MDTIDX=1
20264         local mdt_index
20265         local i
20266         local file
20267         local pid
20268         local stripe_count
20269         local migrate_dir=$DIR/$tdir/migrate_dir
20270         local other_dir=$DIR/$tdir/other_dir
20271
20272         test_mkdir $DIR/$tdir
20273         test_mkdir -i0 -c1 $migrate_dir
20274         test_mkdir -i0 -c1 $other_dir
20275         for ((i=0; i<10; i++)); do
20276                 mkdir -p $migrate_dir/dir_${i}
20277                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20278                         error "create files under remote dir failed $i"
20279         done
20280
20281         cp /etc/passwd $migrate_dir/$tfile
20282         cp /etc/passwd $other_dir/$tfile
20283         chattr +SAD $migrate_dir
20284         chattr +SAD $migrate_dir/$tfile
20285
20286         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20287         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20288         local old_dir_mode=$(stat -c%f $migrate_dir)
20289         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20290
20291         mkdir -p $migrate_dir/dir_default_stripe2
20292         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20293         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20294
20295         mkdir -p $other_dir
20296         ln $migrate_dir/$tfile $other_dir/luna
20297         ln $migrate_dir/$tfile $migrate_dir/sofia
20298         ln $other_dir/$tfile $migrate_dir/david
20299         ln -s $migrate_dir/$tfile $other_dir/zachary
20300         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20301         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20302
20303         local len
20304         local lnktgt
20305
20306         # inline symlink
20307         for len in 58 59 60; do
20308                 lnktgt=$(str_repeat 'l' $len)
20309                 touch $migrate_dir/$lnktgt
20310                 ln -s $lnktgt $migrate_dir/${len}char_ln
20311         done
20312
20313         # PATH_MAX
20314         for len in 4094 4095; do
20315                 lnktgt=$(str_repeat 'l' $len)
20316                 ln -s $lnktgt $migrate_dir/${len}char_ln
20317         done
20318
20319         # NAME_MAX
20320         for len in 254 255; do
20321                 touch $migrate_dir/$(str_repeat 'l' $len)
20322         done
20323
20324         $LFS migrate -m $MDTIDX $migrate_dir ||
20325                 error "fails on migrating remote dir to MDT1"
20326
20327         echo "migratate to MDT1, then checking.."
20328         for ((i = 0; i < 10; i++)); do
20329                 for file in $(find $migrate_dir/dir_${i}); do
20330                         mdt_index=$($LFS getstripe -m $file)
20331                         # broken symlink getstripe will fail
20332                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20333                                 error "$file is not on MDT${MDTIDX}"
20334                 done
20335         done
20336
20337         # the multiple link file should still in MDT0
20338         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20339         [ $mdt_index == 0 ] ||
20340                 error "$file is not on MDT${MDTIDX}"
20341
20342         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20343         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20344                 error " expect $old_dir_flag get $new_dir_flag"
20345
20346         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20347         [ "$old_file_flag" = "$new_file_flag" ] ||
20348                 error " expect $old_file_flag get $new_file_flag"
20349
20350         local new_dir_mode=$(stat -c%f $migrate_dir)
20351         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20352                 error "expect mode $old_dir_mode get $new_dir_mode"
20353
20354         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20355         [ "$old_file_mode" = "$new_file_mode" ] ||
20356                 error "expect mode $old_file_mode get $new_file_mode"
20357
20358         diff /etc/passwd $migrate_dir/$tfile ||
20359                 error "$tfile different after migration"
20360
20361         diff /etc/passwd $other_dir/luna ||
20362                 error "luna different after migration"
20363
20364         diff /etc/passwd $migrate_dir/sofia ||
20365                 error "sofia different after migration"
20366
20367         diff /etc/passwd $migrate_dir/david ||
20368                 error "david different after migration"
20369
20370         diff /etc/passwd $other_dir/zachary ||
20371                 error "zachary different after migration"
20372
20373         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20374                 error "${tfile}_ln different after migration"
20375
20376         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20377                 error "${tfile}_ln_other different after migration"
20378
20379         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20380         [ $stripe_count = 2 ] ||
20381                 error "dir strpe_count $d != 2 after migration."
20382
20383         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20384         [ $stripe_count = 2 ] ||
20385                 error "file strpe_count $d != 2 after migration."
20386
20387         #migrate back to MDT0
20388         MDTIDX=0
20389
20390         $LFS migrate -m $MDTIDX $migrate_dir ||
20391                 error "fails on migrating remote dir to MDT0"
20392
20393         echo "migrate back to MDT0, checking.."
20394         for file in $(find $migrate_dir); do
20395                 mdt_index=$($LFS getstripe -m $file)
20396                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20397                         error "$file is not on MDT${MDTIDX}"
20398         done
20399
20400         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20401         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20402                 error " expect $old_dir_flag get $new_dir_flag"
20403
20404         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20405         [ "$old_file_flag" = "$new_file_flag" ] ||
20406                 error " expect $old_file_flag get $new_file_flag"
20407
20408         local new_dir_mode=$(stat -c%f $migrate_dir)
20409         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20410                 error "expect mode $old_dir_mode get $new_dir_mode"
20411
20412         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20413         [ "$old_file_mode" = "$new_file_mode" ] ||
20414                 error "expect mode $old_file_mode get $new_file_mode"
20415
20416         diff /etc/passwd ${migrate_dir}/$tfile ||
20417                 error "$tfile different after migration"
20418
20419         diff /etc/passwd ${other_dir}/luna ||
20420                 error "luna different after migration"
20421
20422         diff /etc/passwd ${migrate_dir}/sofia ||
20423                 error "sofia different after migration"
20424
20425         diff /etc/passwd ${other_dir}/zachary ||
20426                 error "zachary different after migration"
20427
20428         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20429                 error "${tfile}_ln different after migration"
20430
20431         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20432                 error "${tfile}_ln_other different after migration"
20433
20434         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20435         [ $stripe_count = 2 ] ||
20436                 error "dir strpe_count $d != 2 after migration."
20437
20438         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20439         [ $stripe_count = 2 ] ||
20440                 error "file strpe_count $d != 2 after migration."
20441
20442         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20443 }
20444 run_test 230b "migrate directory"
20445
20446 test_230c() {
20447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20449         remote_mds_nodsh && skip "remote MDS with nodsh"
20450         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20451                 skip "Need MDS version at least 2.11.52"
20452
20453         local MDTIDX=1
20454         local total=3
20455         local mdt_index
20456         local file
20457         local migrate_dir=$DIR/$tdir/migrate_dir
20458
20459         #If migrating directory fails in the middle, all entries of
20460         #the directory is still accessiable.
20461         test_mkdir $DIR/$tdir
20462         test_mkdir -i0 -c1 $migrate_dir
20463         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20464         stat $migrate_dir
20465         createmany -o $migrate_dir/f $total ||
20466                 error "create files under ${migrate_dir} failed"
20467
20468         # fail after migrating top dir, and this will fail only once, so the
20469         # first sub file migration will fail (currently f3), others succeed.
20470         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20471         do_facet mds1 lctl set_param fail_loc=0x1801
20472         local t=$(ls $migrate_dir | wc -l)
20473         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20474                 error "migrate should fail"
20475         local u=$(ls $migrate_dir | wc -l)
20476         [ "$u" == "$t" ] || error "$u != $t during migration"
20477
20478         # add new dir/file should succeed
20479         mkdir $migrate_dir/dir ||
20480                 error "mkdir failed under migrating directory"
20481         touch $migrate_dir/file ||
20482                 error "create file failed under migrating directory"
20483
20484         # add file with existing name should fail
20485         for file in $migrate_dir/f*; do
20486                 stat $file > /dev/null || error "stat $file failed"
20487                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20488                         error "open(O_CREAT|O_EXCL) $file should fail"
20489                 $MULTIOP $file m && error "create $file should fail"
20490                 touch $DIR/$tdir/remote_dir/$tfile ||
20491                         error "touch $tfile failed"
20492                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20493                         error "link $file should fail"
20494                 mdt_index=$($LFS getstripe -m $file)
20495                 if [ $mdt_index == 0 ]; then
20496                         # file failed to migrate is not allowed to rename to
20497                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20498                                 error "rename to $file should fail"
20499                 else
20500                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20501                                 error "rename to $file failed"
20502                 fi
20503                 echo hello >> $file || error "write $file failed"
20504         done
20505
20506         # resume migration with different options should fail
20507         $LFS migrate -m 0 $migrate_dir &&
20508                 error "migrate -m 0 $migrate_dir should fail"
20509
20510         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20511                 error "migrate -c 2 $migrate_dir should fail"
20512
20513         # resume migration should succeed
20514         $LFS migrate -m $MDTIDX $migrate_dir ||
20515                 error "migrate $migrate_dir failed"
20516
20517         echo "Finish migration, then checking.."
20518         for file in $(find $migrate_dir); do
20519                 mdt_index=$($LFS getstripe -m $file)
20520                 [ $mdt_index == $MDTIDX ] ||
20521                         error "$file is not on MDT${MDTIDX}"
20522         done
20523
20524         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20525 }
20526 run_test 230c "check directory accessiblity if migration failed"
20527
20528 test_230d() {
20529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20531         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20532                 skip "Need MDS version at least 2.11.52"
20533         # LU-11235
20534         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20535
20536         local migrate_dir=$DIR/$tdir/migrate_dir
20537         local old_index
20538         local new_index
20539         local old_count
20540         local new_count
20541         local new_hash
20542         local mdt_index
20543         local i
20544         local j
20545
20546         old_index=$((RANDOM % MDSCOUNT))
20547         old_count=$((MDSCOUNT - old_index))
20548         new_index=$((RANDOM % MDSCOUNT))
20549         new_count=$((MDSCOUNT - new_index))
20550         new_hash=1 # for all_char
20551
20552         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20553         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20554
20555         test_mkdir $DIR/$tdir
20556         test_mkdir -i $old_index -c $old_count $migrate_dir
20557
20558         for ((i=0; i<100; i++)); do
20559                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20560                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20561                         error "create files under remote dir failed $i"
20562         done
20563
20564         echo -n "Migrate from MDT$old_index "
20565         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20566         echo -n "to MDT$new_index"
20567         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20568         echo
20569
20570         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20571         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20572                 error "migrate remote dir error"
20573
20574         echo "Finish migration, then checking.."
20575         for file in $(find $migrate_dir -maxdepth 1); do
20576                 mdt_index=$($LFS getstripe -m $file)
20577                 if [ $mdt_index -lt $new_index ] ||
20578                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20579                         error "$file is on MDT$mdt_index"
20580                 fi
20581         done
20582
20583         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20584 }
20585 run_test 230d "check migrate big directory"
20586
20587 test_230e() {
20588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20590         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20591                 skip "Need MDS version at least 2.11.52"
20592
20593         local i
20594         local j
20595         local a_fid
20596         local b_fid
20597
20598         mkdir_on_mdt0 $DIR/$tdir
20599         mkdir $DIR/$tdir/migrate_dir
20600         mkdir $DIR/$tdir/other_dir
20601         touch $DIR/$tdir/migrate_dir/a
20602         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20603         ls $DIR/$tdir/other_dir
20604
20605         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20606                 error "migrate dir fails"
20607
20608         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20609         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20610
20611         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20612         [ $mdt_index == 0 ] || error "a is not on MDT0"
20613
20614         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20615                 error "migrate dir fails"
20616
20617         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20618         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20619
20620         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20621         [ $mdt_index == 1 ] || error "a is not on MDT1"
20622
20623         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20624         [ $mdt_index == 1 ] || error "b is not on MDT1"
20625
20626         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20627         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20628
20629         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20630
20631         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20632 }
20633 run_test 230e "migrate mulitple local link files"
20634
20635 test_230f() {
20636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20638         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20639                 skip "Need MDS version at least 2.11.52"
20640
20641         local a_fid
20642         local ln_fid
20643
20644         mkdir -p $DIR/$tdir
20645         mkdir $DIR/$tdir/migrate_dir
20646         $LFS mkdir -i1 $DIR/$tdir/other_dir
20647         touch $DIR/$tdir/migrate_dir/a
20648         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20649         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20650         ls $DIR/$tdir/other_dir
20651
20652         # a should be migrated to MDT1, since no other links on MDT0
20653         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20654                 error "#1 migrate dir fails"
20655         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20656         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20657         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20658         [ $mdt_index == 1 ] || error "a is not on MDT1"
20659
20660         # a should stay on MDT1, because it is a mulitple link file
20661         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20662                 error "#2 migrate dir fails"
20663         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20664         [ $mdt_index == 1 ] || error "a is not on MDT1"
20665
20666         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20667                 error "#3 migrate dir fails"
20668
20669         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20670         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20671         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20672
20673         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20674         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20675
20676         # a should be migrated to MDT0, since no other links on MDT1
20677         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20678                 error "#4 migrate dir fails"
20679         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20680         [ $mdt_index == 0 ] || error "a is not on MDT0"
20681
20682         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20683 }
20684 run_test 230f "migrate mulitple remote link files"
20685
20686 test_230g() {
20687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20688         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20689         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20690                 skip "Need MDS version at least 2.11.52"
20691
20692         mkdir -p $DIR/$tdir/migrate_dir
20693
20694         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20695                 error "migrating dir to non-exist MDT succeeds"
20696         true
20697 }
20698 run_test 230g "migrate dir to non-exist MDT"
20699
20700 test_230h() {
20701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20703         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20704                 skip "Need MDS version at least 2.11.52"
20705
20706         local mdt_index
20707
20708         mkdir -p $DIR/$tdir/migrate_dir
20709
20710         $LFS migrate -m1 $DIR &&
20711                 error "migrating mountpoint1 should fail"
20712
20713         $LFS migrate -m1 $DIR/$tdir/.. &&
20714                 error "migrating mountpoint2 should fail"
20715
20716         # same as mv
20717         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20718                 error "migrating $tdir/migrate_dir/.. should fail"
20719
20720         true
20721 }
20722 run_test 230h "migrate .. and root"
20723
20724 test_230i() {
20725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20726         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20727         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20728                 skip "Need MDS version at least 2.11.52"
20729
20730         mkdir -p $DIR/$tdir/migrate_dir
20731
20732         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20733                 error "migration fails with a tailing slash"
20734
20735         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20736                 error "migration fails with two tailing slashes"
20737 }
20738 run_test 230i "lfs migrate -m tolerates trailing slashes"
20739
20740 test_230j() {
20741         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20742         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20743                 skip "Need MDS version at least 2.11.52"
20744
20745         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20746         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20747                 error "create $tfile failed"
20748         cat /etc/passwd > $DIR/$tdir/$tfile
20749
20750         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20751
20752         cmp /etc/passwd $DIR/$tdir/$tfile ||
20753                 error "DoM file mismatch after migration"
20754 }
20755 run_test 230j "DoM file data not changed after dir migration"
20756
20757 test_230k() {
20758         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20759         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20760                 skip "Need MDS version at least 2.11.56"
20761
20762         local total=20
20763         local files_on_starting_mdt=0
20764
20765         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20766         $LFS getdirstripe $DIR/$tdir
20767         for i in $(seq $total); do
20768                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20769                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20770                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20771         done
20772
20773         echo "$files_on_starting_mdt files on MDT0"
20774
20775         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20776         $LFS getdirstripe $DIR/$tdir
20777
20778         files_on_starting_mdt=0
20779         for i in $(seq $total); do
20780                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20781                         error "file $tfile.$i mismatch after migration"
20782                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20783                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20784         done
20785
20786         echo "$files_on_starting_mdt files on MDT1 after migration"
20787         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20788
20789         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20790         $LFS getdirstripe $DIR/$tdir
20791
20792         files_on_starting_mdt=0
20793         for i in $(seq $total); do
20794                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20795                         error "file $tfile.$i mismatch after 2nd migration"
20796                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20797                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20798         done
20799
20800         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20801         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20802
20803         true
20804 }
20805 run_test 230k "file data not changed after dir migration"
20806
20807 test_230l() {
20808         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20809         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20810                 skip "Need MDS version at least 2.11.56"
20811
20812         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20813         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20814                 error "create files under remote dir failed $i"
20815         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20816 }
20817 run_test 230l "readdir between MDTs won't crash"
20818
20819 test_230m() {
20820         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20821         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20822                 skip "Need MDS version at least 2.11.56"
20823
20824         local MDTIDX=1
20825         local mig_dir=$DIR/$tdir/migrate_dir
20826         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20827         local shortstr="b"
20828         local val
20829
20830         echo "Creating files and dirs with xattrs"
20831         test_mkdir $DIR/$tdir
20832         test_mkdir -i0 -c1 $mig_dir
20833         mkdir $mig_dir/dir
20834         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20835                 error "cannot set xattr attr1 on dir"
20836         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20837                 error "cannot set xattr attr2 on dir"
20838         touch $mig_dir/dir/f0
20839         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20840                 error "cannot set xattr attr1 on file"
20841         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20842                 error "cannot set xattr attr2 on file"
20843         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20844         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20845         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20846         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20847         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20848         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20849         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20850         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20851         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20852
20853         echo "Migrating to MDT1"
20854         $LFS migrate -m $MDTIDX $mig_dir ||
20855                 error "fails on migrating dir to MDT1"
20856
20857         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20858         echo "Checking xattrs"
20859         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20860         [ "$val" = $longstr ] ||
20861                 error "expecting xattr1 $longstr on dir, found $val"
20862         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20863         [ "$val" = $shortstr ] ||
20864                 error "expecting xattr2 $shortstr on dir, found $val"
20865         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20866         [ "$val" = $longstr ] ||
20867                 error "expecting xattr1 $longstr on file, found $val"
20868         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20869         [ "$val" = $shortstr ] ||
20870                 error "expecting xattr2 $shortstr on file, found $val"
20871 }
20872 run_test 230m "xattrs not changed after dir migration"
20873
20874 test_230n() {
20875         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20876         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20877                 skip "Need MDS version at least 2.13.53"
20878
20879         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20880         cat /etc/hosts > $DIR/$tdir/$tfile
20881         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20882         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20883
20884         cmp /etc/hosts $DIR/$tdir/$tfile ||
20885                 error "File data mismatch after migration"
20886 }
20887 run_test 230n "Dir migration with mirrored file"
20888
20889 test_230o() {
20890         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20891         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20892                 skip "Need MDS version at least 2.13.52"
20893
20894         local mdts=$(comma_list $(mdts_nodes))
20895         local timeout=100
20896         local restripe_status
20897         local delta
20898         local i
20899
20900         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20901
20902         # in case "crush" hash type is not set
20903         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20904
20905         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20906                            mdt.*MDT0000.enable_dir_restripe)
20907         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20908         stack_trap "do_nodes $mdts $LCTL set_param \
20909                     mdt.*.enable_dir_restripe=$restripe_status"
20910
20911         mkdir $DIR/$tdir
20912         createmany -m $DIR/$tdir/f 100 ||
20913                 error "create files under remote dir failed $i"
20914         createmany -d $DIR/$tdir/d 100 ||
20915                 error "create dirs under remote dir failed $i"
20916
20917         for i in $(seq 2 $MDSCOUNT); do
20918                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20919                 $LFS setdirstripe -c $i $DIR/$tdir ||
20920                         error "split -c $i $tdir failed"
20921                 wait_update $HOSTNAME \
20922                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20923                         error "dir split not finished"
20924                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20925                         awk '/migrate/ {sum += $2} END { print sum }')
20926                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20927                 # delta is around total_files/stripe_count
20928                 (( $delta < 200 / (i - 1) + 4 )) ||
20929                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20930         done
20931 }
20932 run_test 230o "dir split"
20933
20934 test_230p() {
20935         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20936         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20937                 skip "Need MDS version at least 2.13.52"
20938
20939         local mdts=$(comma_list $(mdts_nodes))
20940         local timeout=100
20941         local restripe_status
20942         local delta
20943         local c
20944
20945         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20946
20947         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20948
20949         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20950                            mdt.*MDT0000.enable_dir_restripe)
20951         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20952         stack_trap "do_nodes $mdts $LCTL set_param \
20953                     mdt.*.enable_dir_restripe=$restripe_status"
20954
20955         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20956         createmany -m $DIR/$tdir/f 100 ||
20957                 error "create files under remote dir failed"
20958         createmany -d $DIR/$tdir/d 100 ||
20959                 error "create dirs under remote dir failed"
20960
20961         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20962                 local mdt_hash="crush"
20963
20964                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20965                 $LFS setdirstripe -c $c $DIR/$tdir ||
20966                         error "split -c $c $tdir failed"
20967                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20968                         mdt_hash="$mdt_hash,fixed"
20969                 elif [ $c -eq 1 ]; then
20970                         mdt_hash="none"
20971                 fi
20972                 wait_update $HOSTNAME \
20973                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20974                         error "dir merge not finished"
20975                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20976                         awk '/migrate/ {sum += $2} END { print sum }')
20977                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20978                 # delta is around total_files/stripe_count
20979                 (( delta < 200 / c + 4 )) ||
20980                         error "$delta files migrated >= $((200 / c + 4))"
20981         done
20982 }
20983 run_test 230p "dir merge"
20984
20985 test_230q() {
20986         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20987         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20988                 skip "Need MDS version at least 2.13.52"
20989
20990         local mdts=$(comma_list $(mdts_nodes))
20991         local saved_threshold=$(do_facet mds1 \
20992                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20993         local saved_delta=$(do_facet mds1 \
20994                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20995         local threshold=100
20996         local delta=2
20997         local total=0
20998         local stripe_count=0
20999         local stripe_index
21000         local nr_files
21001         local create
21002
21003         # test with fewer files on ZFS
21004         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21005
21006         stack_trap "do_nodes $mdts $LCTL set_param \
21007                     mdt.*.dir_split_count=$saved_threshold"
21008         stack_trap "do_nodes $mdts $LCTL set_param \
21009                     mdt.*.dir_split_delta=$saved_delta"
21010         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21011         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21012         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21013         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21014         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21015         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21016
21017         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21018         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21019
21020         create=$((threshold * 3 / 2))
21021         while [ $stripe_count -lt $MDSCOUNT ]; do
21022                 createmany -m $DIR/$tdir/f $total $create ||
21023                         error "create sub files failed"
21024                 stat $DIR/$tdir > /dev/null
21025                 total=$((total + create))
21026                 stripe_count=$((stripe_count + delta))
21027                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21028
21029                 wait_update $HOSTNAME \
21030                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21031                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21032
21033                 wait_update $HOSTNAME \
21034                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21035                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21036
21037                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21038                 echo "$nr_files/$total files on MDT$stripe_index after split"
21039                 # allow 10% margin of imbalance with crush hash
21040                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21041                         error "$nr_files files on MDT$stripe_index after split"
21042
21043                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21044                 [ $nr_files -eq $total ] ||
21045                         error "total sub files $nr_files != $total"
21046         done
21047
21048         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21049
21050         echo "fixed layout directory won't auto split"
21051         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21052         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21053                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21054         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21055                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21056 }
21057 run_test 230q "dir auto split"
21058
21059 test_230r() {
21060         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21061         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21062         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21063                 skip "Need MDS version at least 2.13.54"
21064
21065         # maximum amount of local locks:
21066         # parent striped dir - 2 locks
21067         # new stripe in parent to migrate to - 1 lock
21068         # source and target - 2 locks
21069         # Total 5 locks for regular file
21070         mkdir -p $DIR/$tdir
21071         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21072         touch $DIR/$tdir/dir1/eee
21073
21074         # create 4 hardlink for 4 more locks
21075         # Total: 9 locks > RS_MAX_LOCKS (8)
21076         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21077         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21078         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21079         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21080         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21081         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21082         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21083         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21084
21085         cancel_lru_locks mdc
21086
21087         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21088                 error "migrate dir fails"
21089
21090         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21091 }
21092 run_test 230r "migrate with too many local locks"
21093
21094 test_230s() {
21095         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21096                 skip "Need MDS version at least 2.14.52"
21097
21098         local mdts=$(comma_list $(mdts_nodes))
21099         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21100                                 mdt.*MDT0000.enable_dir_restripe)
21101
21102         stack_trap "do_nodes $mdts $LCTL set_param \
21103                     mdt.*.enable_dir_restripe=$restripe_status"
21104
21105         local st
21106         for st in 0 1; do
21107                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21108                 test_mkdir $DIR/$tdir
21109                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21110                         error "$LFS mkdir should return EEXIST if target exists"
21111                 rmdir $DIR/$tdir
21112         done
21113 }
21114 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21115
21116 test_230t()
21117 {
21118         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21119         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21120                 skip "Need MDS version at least 2.14.50"
21121
21122         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21123         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21124         $LFS project -p 1 -s $DIR/$tdir ||
21125                 error "set $tdir project id failed"
21126         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21127                 error "set subdir project id failed"
21128         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21129 }
21130 run_test 230t "migrate directory with project ID set"
21131
21132 test_230u()
21133 {
21134         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21135         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21136                 skip "Need MDS version at least 2.14.53"
21137
21138         local count
21139
21140         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21141         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21142         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21143         for i in $(seq 0 $((MDSCOUNT - 1))); do
21144                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21145                 echo "$count dirs migrated to MDT$i"
21146         done
21147         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21148         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21149 }
21150 run_test 230u "migrate directory by QOS"
21151
21152 test_230v()
21153 {
21154         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21155         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21156                 skip "Need MDS version at least 2.14.53"
21157
21158         local count
21159
21160         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21161         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21162         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21163         for i in $(seq 0 $((MDSCOUNT - 1))); do
21164                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21165                 echo "$count subdirs migrated to MDT$i"
21166                 (( i == 3 )) && (( count > 0 )) &&
21167                         error "subdir shouldn't be migrated to MDT3"
21168         done
21169         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21170         (( count == 3 )) || error "dirs migrated to $count MDTs"
21171 }
21172 run_test 230v "subdir migrated to the MDT where its parent is located"
21173
21174 test_230w() {
21175         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21176         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21177                 skip "Need MDS version at least 2.15.0"
21178
21179         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21180         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21181         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21182
21183         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21184                 error "migrate failed"
21185
21186         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21187                 error "$tdir stripe count mismatch"
21188
21189         for i in $(seq 0 9); do
21190                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21191                         error "d$i is striped"
21192         done
21193 }
21194 run_test 230w "non-recursive mode dir migration"
21195
21196 test_230x() {
21197         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21198         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21199                 skip "Need MDS version at least 2.15.0"
21200
21201         mkdir -p $DIR/$tdir || error "mkdir failed"
21202         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21203
21204         local mdt_name=$(mdtname_from_index 0)
21205         local low=$(do_facet mds2 $LCTL get_param -n \
21206                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21207         local high=$(do_facet mds2 $LCTL get_param -n \
21208                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21209         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21210         local maxage=$(do_facet mds2 $LCTL get_param -n \
21211                 osp.*$mdt_name-osp-MDT0001.maxage)
21212
21213         stack_trap "do_facet mds2 $LCTL set_param -n \
21214                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21215                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21216         stack_trap "do_facet mds2 $LCTL set_param -n \
21217                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21218
21219         do_facet mds2 $LCTL set_param -n \
21220                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21221         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21222         sleep 4
21223         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21224                 error "migrate $tdir should fail"
21225
21226         do_facet mds2 $LCTL set_param -n \
21227                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21228         do_facet mds2 $LCTL set_param -n \
21229                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21230         sleep 4
21231         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21232                 error "migrate failed"
21233         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21234                 error "$tdir stripe count mismatch"
21235 }
21236 run_test 230x "dir migration check space"
21237
21238 test_231a()
21239 {
21240         # For simplicity this test assumes that max_pages_per_rpc
21241         # is the same across all OSCs
21242         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21243         local bulk_size=$((max_pages * PAGE_SIZE))
21244         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21245                                        head -n 1)
21246
21247         mkdir -p $DIR/$tdir
21248         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21249                 error "failed to set stripe with -S ${brw_size}M option"
21250
21251         # clear the OSC stats
21252         $LCTL set_param osc.*.stats=0 &>/dev/null
21253         stop_writeback
21254
21255         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21256         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21257                 oflag=direct &>/dev/null || error "dd failed"
21258
21259         sync; sleep 1; sync # just to be safe
21260         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21261         if [ x$nrpcs != "x1" ]; then
21262                 $LCTL get_param osc.*.stats
21263                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21264         fi
21265
21266         start_writeback
21267         # Drop the OSC cache, otherwise we will read from it
21268         cancel_lru_locks osc
21269
21270         # clear the OSC stats
21271         $LCTL set_param osc.*.stats=0 &>/dev/null
21272
21273         # Client reads $bulk_size.
21274         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21275                 iflag=direct &>/dev/null || error "dd failed"
21276
21277         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21278         if [ x$nrpcs != "x1" ]; then
21279                 $LCTL get_param osc.*.stats
21280                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21281         fi
21282 }
21283 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21284
21285 test_231b() {
21286         mkdir -p $DIR/$tdir
21287         local i
21288         for i in {0..1023}; do
21289                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21290                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21291                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21292         done
21293         sync
21294 }
21295 run_test 231b "must not assert on fully utilized OST request buffer"
21296
21297 test_232a() {
21298         mkdir -p $DIR/$tdir
21299         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21300
21301         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21302         do_facet ost1 $LCTL set_param fail_loc=0x31c
21303
21304         # ignore dd failure
21305         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21306
21307         do_facet ost1 $LCTL set_param fail_loc=0
21308         umount_client $MOUNT || error "umount failed"
21309         mount_client $MOUNT || error "mount failed"
21310         stop ost1 || error "cannot stop ost1"
21311         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21312 }
21313 run_test 232a "failed lock should not block umount"
21314
21315 test_232b() {
21316         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21317                 skip "Need MDS version at least 2.10.58"
21318
21319         mkdir -p $DIR/$tdir
21320         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21321         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21322         sync
21323         cancel_lru_locks osc
21324
21325         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21326         do_facet ost1 $LCTL set_param fail_loc=0x31c
21327
21328         # ignore failure
21329         $LFS data_version $DIR/$tdir/$tfile || true
21330
21331         do_facet ost1 $LCTL set_param fail_loc=0
21332         umount_client $MOUNT || error "umount failed"
21333         mount_client $MOUNT || error "mount failed"
21334         stop ost1 || error "cannot stop ost1"
21335         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21336 }
21337 run_test 232b "failed data version lock should not block umount"
21338
21339 test_233a() {
21340         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21341                 skip "Need MDS version at least 2.3.64"
21342         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21343
21344         local fid=$($LFS path2fid $MOUNT)
21345
21346         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21347                 error "cannot access $MOUNT using its FID '$fid'"
21348 }
21349 run_test 233a "checking that OBF of the FS root succeeds"
21350
21351 test_233b() {
21352         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21353                 skip "Need MDS version at least 2.5.90"
21354         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21355
21356         local fid=$($LFS path2fid $MOUNT/.lustre)
21357
21358         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21359                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21360
21361         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21362         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21363                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21364 }
21365 run_test 233b "checking that OBF of the FS .lustre succeeds"
21366
21367 test_234() {
21368         local p="$TMP/sanityN-$TESTNAME.parameters"
21369         save_lustre_params client "llite.*.xattr_cache" > $p
21370         lctl set_param llite.*.xattr_cache 1 ||
21371                 skip_env "xattr cache is not supported"
21372
21373         mkdir -p $DIR/$tdir || error "mkdir failed"
21374         touch $DIR/$tdir/$tfile || error "touch failed"
21375         # OBD_FAIL_LLITE_XATTR_ENOMEM
21376         $LCTL set_param fail_loc=0x1405
21377         getfattr -n user.attr $DIR/$tdir/$tfile &&
21378                 error "getfattr should have failed with ENOMEM"
21379         $LCTL set_param fail_loc=0x0
21380         rm -rf $DIR/$tdir
21381
21382         restore_lustre_params < $p
21383         rm -f $p
21384 }
21385 run_test 234 "xattr cache should not crash on ENOMEM"
21386
21387 test_235() {
21388         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21389                 skip "Need MDS version at least 2.4.52"
21390
21391         flock_deadlock $DIR/$tfile
21392         local RC=$?
21393         case $RC in
21394                 0)
21395                 ;;
21396                 124) error "process hangs on a deadlock"
21397                 ;;
21398                 *) error "error executing flock_deadlock $DIR/$tfile"
21399                 ;;
21400         esac
21401 }
21402 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21403
21404 #LU-2935
21405 test_236() {
21406         check_swap_layouts_support
21407
21408         local ref1=/etc/passwd
21409         local ref2=/etc/group
21410         local file1=$DIR/$tdir/f1
21411         local file2=$DIR/$tdir/f2
21412
21413         test_mkdir -c1 $DIR/$tdir
21414         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21415         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21416         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21417         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21418         local fd=$(free_fd)
21419         local cmd="exec $fd<>$file2"
21420         eval $cmd
21421         rm $file2
21422         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21423                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21424         cmd="exec $fd>&-"
21425         eval $cmd
21426         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21427
21428         #cleanup
21429         rm -rf $DIR/$tdir
21430 }
21431 run_test 236 "Layout swap on open unlinked file"
21432
21433 # LU-4659 linkea consistency
21434 test_238() {
21435         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21436                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21437                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21438                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21439
21440         touch $DIR/$tfile
21441         ln $DIR/$tfile $DIR/$tfile.lnk
21442         touch $DIR/$tfile.new
21443         mv $DIR/$tfile.new $DIR/$tfile
21444         local fid1=$($LFS path2fid $DIR/$tfile)
21445         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21446         local path1=$($LFS fid2path $FSNAME "$fid1")
21447         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21448         local path2=$($LFS fid2path $FSNAME "$fid2")
21449         [ $tfile.lnk == $path2 ] ||
21450                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21451         rm -f $DIR/$tfile*
21452 }
21453 run_test 238 "Verify linkea consistency"
21454
21455 test_239A() { # was test_239
21456         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21457                 skip "Need MDS version at least 2.5.60"
21458
21459         local list=$(comma_list $(mdts_nodes))
21460
21461         mkdir -p $DIR/$tdir
21462         createmany -o $DIR/$tdir/f- 5000
21463         unlinkmany $DIR/$tdir/f- 5000
21464         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21465                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21466         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21467                         osp.*MDT*.sync_in_flight" | calc_sum)
21468         [ "$changes" -eq 0 ] || error "$changes not synced"
21469 }
21470 run_test 239A "osp_sync test"
21471
21472 test_239a() { #LU-5297
21473         remote_mds_nodsh && skip "remote MDS with nodsh"
21474
21475         touch $DIR/$tfile
21476         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21477         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21478         chgrp $RUNAS_GID $DIR/$tfile
21479         wait_delete_completed
21480 }
21481 run_test 239a "process invalid osp sync record correctly"
21482
21483 test_239b() { #LU-5297
21484         remote_mds_nodsh && skip "remote MDS with nodsh"
21485
21486         touch $DIR/$tfile1
21487         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21488         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21489         chgrp $RUNAS_GID $DIR/$tfile1
21490         wait_delete_completed
21491         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21492         touch $DIR/$tfile2
21493         chgrp $RUNAS_GID $DIR/$tfile2
21494         wait_delete_completed
21495 }
21496 run_test 239b "process osp sync record with ENOMEM error correctly"
21497
21498 test_240() {
21499         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21500         remote_mds_nodsh && skip "remote MDS with nodsh"
21501
21502         mkdir -p $DIR/$tdir
21503
21504         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21505                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21506         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21507                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21508
21509         umount_client $MOUNT || error "umount failed"
21510         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21511         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21512         mount_client $MOUNT || error "failed to mount client"
21513
21514         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21515         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21516 }
21517 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21518
21519 test_241_bio() {
21520         local count=$1
21521         local bsize=$2
21522
21523         for LOOP in $(seq $count); do
21524                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21525                 cancel_lru_locks $OSC || true
21526         done
21527 }
21528
21529 test_241_dio() {
21530         local count=$1
21531         local bsize=$2
21532
21533         for LOOP in $(seq $1); do
21534                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21535                         2>/dev/null
21536         done
21537 }
21538
21539 test_241a() { # was test_241
21540         local bsize=$PAGE_SIZE
21541
21542         (( bsize < 40960 )) && bsize=40960
21543         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21544         ls -la $DIR/$tfile
21545         cancel_lru_locks $OSC
21546         test_241_bio 1000 $bsize &
21547         PID=$!
21548         test_241_dio 1000 $bsize
21549         wait $PID
21550 }
21551 run_test 241a "bio vs dio"
21552
21553 test_241b() {
21554         local bsize=$PAGE_SIZE
21555
21556         (( bsize < 40960 )) && bsize=40960
21557         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21558         ls -la $DIR/$tfile
21559         test_241_dio 1000 $bsize &
21560         PID=$!
21561         test_241_dio 1000 $bsize
21562         wait $PID
21563 }
21564 run_test 241b "dio vs dio"
21565
21566 test_242() {
21567         remote_mds_nodsh && skip "remote MDS with nodsh"
21568
21569         mkdir_on_mdt0 $DIR/$tdir
21570         touch $DIR/$tdir/$tfile
21571
21572         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21573         do_facet mds1 lctl set_param fail_loc=0x105
21574         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21575
21576         do_facet mds1 lctl set_param fail_loc=0
21577         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21578 }
21579 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21580
21581 test_243()
21582 {
21583         test_mkdir $DIR/$tdir
21584         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21585 }
21586 run_test 243 "various group lock tests"
21587
21588 test_244a()
21589 {
21590         test_mkdir $DIR/$tdir
21591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21592         sendfile_grouplock $DIR/$tdir/$tfile || \
21593                 error "sendfile+grouplock failed"
21594         rm -rf $DIR/$tdir
21595 }
21596 run_test 244a "sendfile with group lock tests"
21597
21598 test_244b()
21599 {
21600         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21601
21602         local threads=50
21603         local size=$((1024*1024))
21604
21605         test_mkdir $DIR/$tdir
21606         for i in $(seq 1 $threads); do
21607                 local file=$DIR/$tdir/file_$((i / 10))
21608                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21609                 local pids[$i]=$!
21610         done
21611         for i in $(seq 1 $threads); do
21612                 wait ${pids[$i]}
21613         done
21614 }
21615 run_test 244b "multi-threaded write with group lock"
21616
21617 test_245a() {
21618         local flagname="multi_mod_rpcs"
21619         local connect_data_name="max_mod_rpcs"
21620         local out
21621
21622         # check if multiple modify RPCs flag is set
21623         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21624                 grep "connect_flags:")
21625         echo "$out"
21626
21627         echo "$out" | grep -qw $flagname
21628         if [ $? -ne 0 ]; then
21629                 echo "connect flag $flagname is not set"
21630                 return
21631         fi
21632
21633         # check if multiple modify RPCs data is set
21634         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21635         echo "$out"
21636
21637         echo "$out" | grep -qw $connect_data_name ||
21638                 error "import should have connect data $connect_data_name"
21639 }
21640 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21641
21642 test_245b() {
21643         local flagname="multi_mod_rpcs"
21644         local connect_data_name="max_mod_rpcs"
21645         local out
21646
21647         remote_mds_nodsh && skip "remote MDS with nodsh"
21648         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21649
21650         # check if multiple modify RPCs flag is set
21651         out=$(do_facet mds1 \
21652               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21653               grep "connect_flags:")
21654         echo "$out"
21655
21656         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21657
21658         # check if multiple modify RPCs data is set
21659         out=$(do_facet mds1 \
21660               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21661
21662         [[ "$out" =~ $connect_data_name ]] ||
21663                 {
21664                         echo "$out"
21665                         error "missing connect data $connect_data_name"
21666                 }
21667 }
21668 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21669
21670 cleanup_247() {
21671         local submount=$1
21672
21673         trap 0
21674         umount_client $submount
21675         rmdir $submount
21676 }
21677
21678 test_247a() {
21679         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21680                 grep -q subtree ||
21681                 skip_env "Fileset feature is not supported"
21682
21683         local submount=${MOUNT}_$tdir
21684
21685         mkdir $MOUNT/$tdir
21686         mkdir -p $submount || error "mkdir $submount failed"
21687         FILESET="$FILESET/$tdir" mount_client $submount ||
21688                 error "mount $submount failed"
21689         trap "cleanup_247 $submount" EXIT
21690         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21691         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21692                 error "read $MOUNT/$tdir/$tfile failed"
21693         cleanup_247 $submount
21694 }
21695 run_test 247a "mount subdir as fileset"
21696
21697 test_247b() {
21698         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21699                 skip_env "Fileset feature is not supported"
21700
21701         local submount=${MOUNT}_$tdir
21702
21703         rm -rf $MOUNT/$tdir
21704         mkdir -p $submount || error "mkdir $submount failed"
21705         SKIP_FILESET=1
21706         FILESET="$FILESET/$tdir" mount_client $submount &&
21707                 error "mount $submount should fail"
21708         rmdir $submount
21709 }
21710 run_test 247b "mount subdir that dose not exist"
21711
21712 test_247c() {
21713         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21714                 skip_env "Fileset feature is not supported"
21715
21716         local submount=${MOUNT}_$tdir
21717
21718         mkdir -p $MOUNT/$tdir/dir1
21719         mkdir -p $submount || error "mkdir $submount failed"
21720         trap "cleanup_247 $submount" EXIT
21721         FILESET="$FILESET/$tdir" mount_client $submount ||
21722                 error "mount $submount failed"
21723         local fid=$($LFS path2fid $MOUNT/)
21724         $LFS fid2path $submount $fid && error "fid2path should fail"
21725         cleanup_247 $submount
21726 }
21727 run_test 247c "running fid2path outside subdirectory root"
21728
21729 test_247d() {
21730         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21731                 skip "Fileset feature is not supported"
21732
21733         local submount=${MOUNT}_$tdir
21734
21735         mkdir -p $MOUNT/$tdir/dir1
21736         mkdir -p $submount || error "mkdir $submount failed"
21737         FILESET="$FILESET/$tdir" mount_client $submount ||
21738                 error "mount $submount failed"
21739         trap "cleanup_247 $submount" EXIT
21740
21741         local td=$submount/dir1
21742         local fid=$($LFS path2fid $td)
21743         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21744
21745         # check that we get the same pathname back
21746         local rootpath
21747         local found
21748         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21749                 echo "$rootpath $fid"
21750                 found=$($LFS fid2path $rootpath "$fid")
21751                 [ -n "$found" ] || error "fid2path should succeed"
21752                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21753         done
21754         # check wrong root path format
21755         rootpath=$submount"_wrong"
21756         found=$($LFS fid2path $rootpath "$fid")
21757         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21758
21759         cleanup_247 $submount
21760 }
21761 run_test 247d "running fid2path inside subdirectory root"
21762
21763 # LU-8037
21764 test_247e() {
21765         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21766                 grep -q subtree ||
21767                 skip "Fileset feature is not supported"
21768
21769         local submount=${MOUNT}_$tdir
21770
21771         mkdir $MOUNT/$tdir
21772         mkdir -p $submount || error "mkdir $submount failed"
21773         FILESET="$FILESET/.." mount_client $submount &&
21774                 error "mount $submount should fail"
21775         rmdir $submount
21776 }
21777 run_test 247e "mount .. as fileset"
21778
21779 test_247f() {
21780         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21781         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21782                 skip "Need at least version 2.14.50.162"
21783         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21784                 skip "Fileset feature is not supported"
21785
21786         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21787         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21788                 error "mkdir remote failed"
21789         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21790                 error "mkdir remote/subdir failed"
21791         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21792                 error "mkdir striped failed"
21793         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21794
21795         local submount=${MOUNT}_$tdir
21796
21797         mkdir -p $submount || error "mkdir $submount failed"
21798         stack_trap "rmdir $submount"
21799
21800         local dir
21801         local fileset=$FILESET
21802         local mdts=$(comma_list $(mdts_nodes))
21803
21804         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21805         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
21806                 $tdir/striped/subdir $tdir/striped/.; do
21807                 FILESET="$fileset/$dir" mount_client $submount ||
21808                         error "mount $dir failed"
21809                 umount_client $submount
21810         done
21811 }
21812 run_test 247f "mount striped or remote directory as fileset"
21813
21814 test_subdir_mount_lock()
21815 {
21816         local testdir=$1
21817         local submount=${MOUNT}_$(basename $testdir)
21818
21819         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
21820
21821         mkdir -p $submount || error "mkdir $submount failed"
21822         stack_trap "rmdir $submount"
21823
21824         FILESET="$fileset/$testdir" mount_client $submount ||
21825                 error "mount $FILESET failed"
21826         stack_trap "umount $submount"
21827
21828         local mdts=$(comma_list $(mdts_nodes))
21829
21830         local nrpcs
21831
21832         stat $submount > /dev/null || error "stat $submount failed"
21833         cancel_lru_locks $MDC
21834         stat $submount > /dev/null || error "stat $submount failed"
21835         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21836         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21837         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21838         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21839                 awk '/getattr/ {sum += $2} END {print sum}')
21840
21841         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21842 }
21843
21844 test_247g() {
21845         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21846
21847         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21848                 error "mkdir $tdir failed"
21849         test_subdir_mount_lock $tdir
21850 }
21851 run_test 247g "striped directory submount revalidate ROOT from cache"
21852
21853 test_247h() {
21854         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21855         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
21856                 skip "Need MDS version at least 2.15.51"
21857
21858         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21859         test_subdir_mount_lock $tdir
21860         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
21861         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
21862                 error "mkdir $tdir.1 failed"
21863         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
21864 }
21865 run_test 247h "remote directory submount revalidate ROOT from cache"
21866
21867 test_248a() {
21868         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21869         [ -z "$fast_read_sav" ] && skip "no fast read support"
21870
21871         # create a large file for fast read verification
21872         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21873
21874         # make sure the file is created correctly
21875         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21876                 { rm -f $DIR/$tfile; skip "file creation error"; }
21877
21878         echo "Test 1: verify that fast read is 4 times faster on cache read"
21879
21880         # small read with fast read enabled
21881         $LCTL set_param -n llite.*.fast_read=1
21882         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21883                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21884                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21885         # small read with fast read disabled
21886         $LCTL set_param -n llite.*.fast_read=0
21887         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21888                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21889                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21890
21891         # verify that fast read is 4 times faster for cache read
21892         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21893                 error_not_in_vm "fast read was not 4 times faster: " \
21894                            "$t_fast vs $t_slow"
21895
21896         echo "Test 2: verify the performance between big and small read"
21897         $LCTL set_param -n llite.*.fast_read=1
21898
21899         # 1k non-cache read
21900         cancel_lru_locks osc
21901         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21902                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21903                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21904
21905         # 1M non-cache read
21906         cancel_lru_locks osc
21907         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21908                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21909                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21910
21911         # verify that big IO is not 4 times faster than small IO
21912         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21913                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21914
21915         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21916         rm -f $DIR/$tfile
21917 }
21918 run_test 248a "fast read verification"
21919
21920 test_248b() {
21921         # Default short_io_bytes=16384, try both smaller and larger sizes.
21922         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21923         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21924         echo "bs=53248 count=113 normal buffered write"
21925         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21926                 error "dd of initial data file failed"
21927         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21928
21929         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21930         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21931                 error "dd with sync normal writes failed"
21932         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21933
21934         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21935         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21936                 error "dd with sync small writes failed"
21937         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21938
21939         cancel_lru_locks osc
21940
21941         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21942         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21943         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21944         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21945                 iflag=direct || error "dd with O_DIRECT small read failed"
21946         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21947         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21948                 error "compare $TMP/$tfile.1 failed"
21949
21950         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21951         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21952
21953         # just to see what the maximum tunable value is, and test parsing
21954         echo "test invalid parameter 2MB"
21955         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21956                 error "too-large short_io_bytes allowed"
21957         echo "test maximum parameter 512KB"
21958         # if we can set a larger short_io_bytes, run test regardless of version
21959         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21960                 # older clients may not allow setting it this large, that's OK
21961                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21962                         skip "Need at least client version 2.13.50"
21963                 error "medium short_io_bytes failed"
21964         fi
21965         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21966         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21967
21968         echo "test large parameter 64KB"
21969         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21970         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21971
21972         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21973         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21974                 error "dd with sync large writes failed"
21975         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21976
21977         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21978         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21979         num=$((113 * 4096 / PAGE_SIZE))
21980         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21981         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21982                 error "dd with O_DIRECT large writes failed"
21983         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21984                 error "compare $DIR/$tfile.3 failed"
21985
21986         cancel_lru_locks osc
21987
21988         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21989         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21990                 error "dd with O_DIRECT large read failed"
21991         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21992                 error "compare $TMP/$tfile.2 failed"
21993
21994         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21995         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21996                 error "dd with O_DIRECT large read failed"
21997         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21998                 error "compare $TMP/$tfile.3 failed"
21999 }
22000 run_test 248b "test short_io read and write for both small and large sizes"
22001
22002 test_249() { # LU-7890
22003         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22004                 skip "Need at least version 2.8.54"
22005
22006         rm -f $DIR/$tfile
22007         $LFS setstripe -c 1 $DIR/$tfile
22008         # Offset 2T == 4k * 512M
22009         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22010                 error "dd to 2T offset failed"
22011 }
22012 run_test 249 "Write above 2T file size"
22013
22014 test_250() {
22015         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22016          && skip "no 16TB file size limit on ZFS"
22017
22018         $LFS setstripe -c 1 $DIR/$tfile
22019         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22020         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22021         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22022         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22023                 conv=notrunc,fsync && error "append succeeded"
22024         return 0
22025 }
22026 run_test 250 "Write above 16T limit"
22027
22028 test_251() {
22029         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22030
22031         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22032         #Skip once - writing the first stripe will succeed
22033         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22034         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22035                 error "short write happened"
22036
22037         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22038         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22039                 error "short read happened"
22040
22041         rm -f $DIR/$tfile
22042 }
22043 run_test 251 "Handling short read and write correctly"
22044
22045 test_252() {
22046         remote_mds_nodsh && skip "remote MDS with nodsh"
22047         remote_ost_nodsh && skip "remote OST with nodsh"
22048         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22049                 skip_env "ldiskfs only test"
22050         fi
22051
22052         local tgt
22053         local dev
22054         local out
22055         local uuid
22056         local num
22057         local gen
22058
22059         # check lr_reader on OST0000
22060         tgt=ost1
22061         dev=$(facet_device $tgt)
22062         out=$(do_facet $tgt $LR_READER $dev)
22063         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22064         echo "$out"
22065         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22066         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22067                 error "Invalid uuid returned by $LR_READER on target $tgt"
22068         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22069
22070         # check lr_reader -c on MDT0000
22071         tgt=mds1
22072         dev=$(facet_device $tgt)
22073         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22074                 skip "$LR_READER does not support additional options"
22075         fi
22076         out=$(do_facet $tgt $LR_READER -c $dev)
22077         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22078         echo "$out"
22079         num=$(echo "$out" | grep -c "mdtlov")
22080         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22081                 error "Invalid number of mdtlov clients returned by $LR_READER"
22082         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22083
22084         # check lr_reader -cr on MDT0000
22085         out=$(do_facet $tgt $LR_READER -cr $dev)
22086         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22087         echo "$out"
22088         echo "$out" | grep -q "^reply_data:$" ||
22089                 error "$LR_READER should have returned 'reply_data' section"
22090         num=$(echo "$out" | grep -c "client_generation")
22091         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22092 }
22093 run_test 252 "check lr_reader tool"
22094
22095 test_253() {
22096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22097         remote_mds_nodsh && skip "remote MDS with nodsh"
22098         remote_mgs_nodsh && skip "remote MGS with nodsh"
22099
22100         local ostidx=0
22101         local rc=0
22102         local ost_name=$(ostname_from_index $ostidx)
22103
22104         # on the mdt's osc
22105         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22106         do_facet $SINGLEMDS $LCTL get_param -n \
22107                 osp.$mdtosc_proc1.reserved_mb_high ||
22108                 skip  "remote MDS does not support reserved_mb_high"
22109
22110         rm -rf $DIR/$tdir
22111         wait_mds_ost_sync
22112         wait_delete_completed
22113         mkdir $DIR/$tdir
22114
22115         pool_add $TESTNAME || error "Pool creation failed"
22116         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22117
22118         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22119                 error "Setstripe failed"
22120
22121         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22122
22123         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22124                     grep "watermarks")
22125         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22126
22127         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22128                         osp.$mdtosc_proc1.prealloc_status)
22129         echo "prealloc_status $oa_status"
22130
22131         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22132                 error "File creation should fail"
22133
22134         #object allocation was stopped, but we still able to append files
22135         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22136                 oflag=append || error "Append failed"
22137
22138         rm -f $DIR/$tdir/$tfile.0
22139
22140         # For this test, we want to delete the files we created to go out of
22141         # space but leave the watermark, so we remain nearly out of space
22142         ost_watermarks_enospc_delete_files $tfile $ostidx
22143
22144         wait_delete_completed
22145
22146         sleep_maxage
22147
22148         for i in $(seq 10 12); do
22149                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22150                         2>/dev/null || error "File creation failed after rm"
22151         done
22152
22153         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22154                         osp.$mdtosc_proc1.prealloc_status)
22155         echo "prealloc_status $oa_status"
22156
22157         if (( oa_status != 0 )); then
22158                 error "Object allocation still disable after rm"
22159         fi
22160 }
22161 run_test 253 "Check object allocation limit"
22162
22163 test_254() {
22164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22165         remote_mds_nodsh && skip "remote MDS with nodsh"
22166
22167         local mdt=$(facet_svc $SINGLEMDS)
22168
22169         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22170                 skip "MDS does not support changelog_size"
22171
22172         local cl_user
22173
22174         changelog_register || error "changelog_register failed"
22175
22176         changelog_clear 0 || error "changelog_clear failed"
22177
22178         local size1=$(do_facet $SINGLEMDS \
22179                       $LCTL get_param -n mdd.$mdt.changelog_size)
22180         echo "Changelog size $size1"
22181
22182         rm -rf $DIR/$tdir
22183         $LFS mkdir -i 0 $DIR/$tdir
22184         # change something
22185         mkdir -p $DIR/$tdir/pics/2008/zachy
22186         touch $DIR/$tdir/pics/2008/zachy/timestamp
22187         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22188         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22189         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22190         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22191         rm $DIR/$tdir/pics/desktop.jpg
22192
22193         local size2=$(do_facet $SINGLEMDS \
22194                       $LCTL get_param -n mdd.$mdt.changelog_size)
22195         echo "Changelog size after work $size2"
22196
22197         (( $size2 > $size1 )) ||
22198                 error "new Changelog size=$size2 less than old size=$size1"
22199 }
22200 run_test 254 "Check changelog size"
22201
22202 ladvise_no_type()
22203 {
22204         local type=$1
22205         local file=$2
22206
22207         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22208                 awk -F: '{print $2}' | grep $type > /dev/null
22209         if [ $? -ne 0 ]; then
22210                 return 0
22211         fi
22212         return 1
22213 }
22214
22215 ladvise_no_ioctl()
22216 {
22217         local file=$1
22218
22219         lfs ladvise -a willread $file > /dev/null 2>&1
22220         if [ $? -eq 0 ]; then
22221                 return 1
22222         fi
22223
22224         lfs ladvise -a willread $file 2>&1 |
22225                 grep "Inappropriate ioctl for device" > /dev/null
22226         if [ $? -eq 0 ]; then
22227                 return 0
22228         fi
22229         return 1
22230 }
22231
22232 percent() {
22233         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22234 }
22235
22236 # run a random read IO workload
22237 # usage: random_read_iops <filename> <filesize> <iosize>
22238 random_read_iops() {
22239         local file=$1
22240         local fsize=$2
22241         local iosize=${3:-4096}
22242
22243         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22244                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22245 }
22246
22247 drop_file_oss_cache() {
22248         local file="$1"
22249         local nodes="$2"
22250
22251         $LFS ladvise -a dontneed $file 2>/dev/null ||
22252                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22253 }
22254
22255 ladvise_willread_performance()
22256 {
22257         local repeat=10
22258         local average_origin=0
22259         local average_cache=0
22260         local average_ladvise=0
22261
22262         for ((i = 1; i <= $repeat; i++)); do
22263                 echo "Iter $i/$repeat: reading without willread hint"
22264                 cancel_lru_locks osc
22265                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22266                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22267                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22268                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22269
22270                 cancel_lru_locks osc
22271                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22272                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22273                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22274
22275                 cancel_lru_locks osc
22276                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22277                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22278                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22279                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22280                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22281         done
22282         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22283         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22284         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22285
22286         speedup_cache=$(percent $average_cache $average_origin)
22287         speedup_ladvise=$(percent $average_ladvise $average_origin)
22288
22289         echo "Average uncached read: $average_origin"
22290         echo "Average speedup with OSS cached read: " \
22291                 "$average_cache = +$speedup_cache%"
22292         echo "Average speedup with ladvise willread: " \
22293                 "$average_ladvise = +$speedup_ladvise%"
22294
22295         local lowest_speedup=20
22296         if (( ${average_cache%.*} < $lowest_speedup )); then
22297                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22298                      " got $average_cache%. Skipping ladvise willread check."
22299                 return 0
22300         fi
22301
22302         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22303         # it is still good to run until then to exercise 'ladvise willread'
22304         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22305                 [ "$ost1_FSTYPE" = "zfs" ] &&
22306                 echo "osd-zfs does not support dontneed or drop_caches" &&
22307                 return 0
22308
22309         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22310         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22311                 error_not_in_vm "Speedup with willread is less than " \
22312                         "$lowest_speedup%, got $average_ladvise%"
22313 }
22314
22315 test_255a() {
22316         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22317                 skip "lustre < 2.8.54 does not support ladvise "
22318         remote_ost_nodsh && skip "remote OST with nodsh"
22319
22320         stack_trap "rm -f $DIR/$tfile"
22321         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22322
22323         ladvise_no_type willread $DIR/$tfile &&
22324                 skip "willread ladvise is not supported"
22325
22326         ladvise_no_ioctl $DIR/$tfile &&
22327                 skip "ladvise ioctl is not supported"
22328
22329         local size_mb=100
22330         local size=$((size_mb * 1048576))
22331         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22332                 error "dd to $DIR/$tfile failed"
22333
22334         lfs ladvise -a willread $DIR/$tfile ||
22335                 error "Ladvise failed with no range argument"
22336
22337         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22338                 error "Ladvise failed with no -l or -e argument"
22339
22340         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22341                 error "Ladvise failed with only -e argument"
22342
22343         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22344                 error "Ladvise failed with only -l argument"
22345
22346         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22347                 error "End offset should not be smaller than start offset"
22348
22349         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22350                 error "End offset should not be equal to start offset"
22351
22352         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22353                 error "Ladvise failed with overflowing -s argument"
22354
22355         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22356                 error "Ladvise failed with overflowing -e argument"
22357
22358         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22359                 error "Ladvise failed with overflowing -l argument"
22360
22361         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22362                 error "Ladvise succeeded with conflicting -l and -e arguments"
22363
22364         echo "Synchronous ladvise should wait"
22365         local delay=4
22366 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22367         do_nodes $(comma_list $(osts_nodes)) \
22368                 $LCTL set_param fail_val=$delay fail_loc=0x237
22369
22370         local start_ts=$SECONDS
22371         lfs ladvise -a willread $DIR/$tfile ||
22372                 error "Ladvise failed with no range argument"
22373         local end_ts=$SECONDS
22374         local inteval_ts=$((end_ts - start_ts))
22375
22376         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22377                 error "Synchronous advice didn't wait reply"
22378         fi
22379
22380         echo "Asynchronous ladvise shouldn't wait"
22381         local start_ts=$SECONDS
22382         lfs ladvise -a willread -b $DIR/$tfile ||
22383                 error "Ladvise failed with no range argument"
22384         local end_ts=$SECONDS
22385         local inteval_ts=$((end_ts - start_ts))
22386
22387         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22388                 error "Asynchronous advice blocked"
22389         fi
22390
22391         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22392         ladvise_willread_performance
22393 }
22394 run_test 255a "check 'lfs ladvise -a willread'"
22395
22396 facet_meminfo() {
22397         local facet=$1
22398         local info=$2
22399
22400         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22401 }
22402
22403 test_255b() {
22404         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22405                 skip "lustre < 2.8.54 does not support ladvise "
22406         remote_ost_nodsh && skip "remote OST with nodsh"
22407
22408         stack_trap "rm -f $DIR/$tfile"
22409         lfs setstripe -c 1 -i 0 $DIR/$tfile
22410
22411         ladvise_no_type dontneed $DIR/$tfile &&
22412                 skip "dontneed ladvise is not supported"
22413
22414         ladvise_no_ioctl $DIR/$tfile &&
22415                 skip "ladvise ioctl is not supported"
22416
22417         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22418                 [ "$ost1_FSTYPE" = "zfs" ] &&
22419                 skip "zfs-osd does not support 'ladvise dontneed'"
22420
22421         local size_mb=100
22422         local size=$((size_mb * 1048576))
22423         # In order to prevent disturbance of other processes, only check 3/4
22424         # of the memory usage
22425         local kibibytes=$((size_mb * 1024 * 3 / 4))
22426
22427         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22428                 error "dd to $DIR/$tfile failed"
22429
22430         #force write to complete before dropping OST cache & checking memory
22431         sync
22432
22433         local total=$(facet_meminfo ost1 MemTotal)
22434         echo "Total memory: $total KiB"
22435
22436         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22437         local before_read=$(facet_meminfo ost1 Cached)
22438         echo "Cache used before read: $before_read KiB"
22439
22440         lfs ladvise -a willread $DIR/$tfile ||
22441                 error "Ladvise willread failed"
22442         local after_read=$(facet_meminfo ost1 Cached)
22443         echo "Cache used after read: $after_read KiB"
22444
22445         lfs ladvise -a dontneed $DIR/$tfile ||
22446                 error "Ladvise dontneed again failed"
22447         local no_read=$(facet_meminfo ost1 Cached)
22448         echo "Cache used after dontneed ladvise: $no_read KiB"
22449
22450         if [ $total -lt $((before_read + kibibytes)) ]; then
22451                 echo "Memory is too small, abort checking"
22452                 return 0
22453         fi
22454
22455         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22456                 error "Ladvise willread should use more memory" \
22457                         "than $kibibytes KiB"
22458         fi
22459
22460         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22461                 error "Ladvise dontneed should release more memory" \
22462                         "than $kibibytes KiB"
22463         fi
22464 }
22465 run_test 255b "check 'lfs ladvise -a dontneed'"
22466
22467 test_255c() {
22468         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22469                 skip "lustre < 2.10.50 does not support lockahead"
22470
22471         local ost1_imp=$(get_osc_import_name client ost1)
22472         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22473                          cut -d'.' -f2)
22474         local count
22475         local new_count
22476         local difference
22477         local i
22478         local rc
22479
22480         test_mkdir -p $DIR/$tdir
22481         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22482
22483         #test 10 returns only success/failure
22484         i=10
22485         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22486         rc=$?
22487         if [ $rc -eq 255 ]; then
22488                 error "Ladvise test${i} failed, ${rc}"
22489         fi
22490
22491         #test 11 counts lock enqueue requests, all others count new locks
22492         i=11
22493         count=$(do_facet ost1 \
22494                 $LCTL get_param -n ost.OSS.ost.stats)
22495         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22496
22497         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22498         rc=$?
22499         if [ $rc -eq 255 ]; then
22500                 error "Ladvise test${i} failed, ${rc}"
22501         fi
22502
22503         new_count=$(do_facet ost1 \
22504                 $LCTL get_param -n ost.OSS.ost.stats)
22505         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22506                    awk '{ print $2 }')
22507
22508         difference="$((new_count - count))"
22509         if [ $difference -ne $rc ]; then
22510                 error "Ladvise test${i}, bad enqueue count, returned " \
22511                       "${rc}, actual ${difference}"
22512         fi
22513
22514         for i in $(seq 12 21); do
22515                 # If we do not do this, we run the risk of having too many
22516                 # locks and starting lock cancellation while we are checking
22517                 # lock counts.
22518                 cancel_lru_locks osc
22519
22520                 count=$($LCTL get_param -n \
22521                        ldlm.namespaces.$imp_name.lock_unused_count)
22522
22523                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22524                 rc=$?
22525                 if [ $rc -eq 255 ]; then
22526                         error "Ladvise test ${i} failed, ${rc}"
22527                 fi
22528
22529                 new_count=$($LCTL get_param -n \
22530                        ldlm.namespaces.$imp_name.lock_unused_count)
22531                 difference="$((new_count - count))"
22532
22533                 # Test 15 output is divided by 100 to map down to valid return
22534                 if [ $i -eq 15 ]; then
22535                         rc="$((rc * 100))"
22536                 fi
22537
22538                 if [ $difference -ne $rc ]; then
22539                         error "Ladvise test ${i}, bad lock count, returned " \
22540                               "${rc}, actual ${difference}"
22541                 fi
22542         done
22543
22544         #test 22 returns only success/failure
22545         i=22
22546         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22547         rc=$?
22548         if [ $rc -eq 255 ]; then
22549                 error "Ladvise test${i} failed, ${rc}"
22550         fi
22551 }
22552 run_test 255c "suite of ladvise lockahead tests"
22553
22554 test_256() {
22555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22556         remote_mds_nodsh && skip "remote MDS with nodsh"
22557         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22558         changelog_users $SINGLEMDS | grep "^cl" &&
22559                 skip "active changelog user"
22560
22561         local cl_user
22562         local cat_sl
22563         local mdt_dev
22564
22565         mdt_dev=$(facet_device $SINGLEMDS)
22566         echo $mdt_dev
22567
22568         changelog_register || error "changelog_register failed"
22569
22570         rm -rf $DIR/$tdir
22571         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22572
22573         changelog_clear 0 || error "changelog_clear failed"
22574
22575         # change something
22576         touch $DIR/$tdir/{1..10}
22577
22578         # stop the MDT
22579         stop $SINGLEMDS || error "Fail to stop MDT"
22580
22581         # remount the MDT
22582         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22583                 error "Fail to start MDT"
22584
22585         #after mount new plainllog is used
22586         touch $DIR/$tdir/{11..19}
22587         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22588         stack_trap "rm -f $tmpfile"
22589         cat_sl=$(do_facet $SINGLEMDS "sync; \
22590                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22591                  llog_reader $tmpfile | grep -c type=1064553b")
22592         do_facet $SINGLEMDS llog_reader $tmpfile
22593
22594         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22595
22596         changelog_clear 0 || error "changelog_clear failed"
22597
22598         cat_sl=$(do_facet $SINGLEMDS "sync; \
22599                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22600                  llog_reader $tmpfile | grep -c type=1064553b")
22601
22602         if (( cat_sl == 2 )); then
22603                 error "Empty plain llog was not deleted from changelog catalog"
22604         elif (( cat_sl != 1 )); then
22605                 error "Active plain llog shouldn't be deleted from catalog"
22606         fi
22607 }
22608 run_test 256 "Check llog delete for empty and not full state"
22609
22610 test_257() {
22611         remote_mds_nodsh && skip "remote MDS with nodsh"
22612         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22613                 skip "Need MDS version at least 2.8.55"
22614
22615         test_mkdir $DIR/$tdir
22616
22617         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22618                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22619         stat $DIR/$tdir
22620
22621 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22622         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22623         local facet=mds$((mdtidx + 1))
22624         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22625         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22626
22627         stop $facet || error "stop MDS failed"
22628         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22629                 error "start MDS fail"
22630         wait_recovery_complete $facet
22631 }
22632 run_test 257 "xattr locks are not lost"
22633
22634 # Verify we take the i_mutex when security requires it
22635 test_258a() {
22636 #define OBD_FAIL_IMUTEX_SEC 0x141c
22637         $LCTL set_param fail_loc=0x141c
22638         touch $DIR/$tfile
22639         chmod u+s $DIR/$tfile
22640         chmod a+rwx $DIR/$tfile
22641         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22642         RC=$?
22643         if [ $RC -ne 0 ]; then
22644                 error "error, failed to take i_mutex, rc=$?"
22645         fi
22646         rm -f $DIR/$tfile
22647 }
22648 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22649
22650 # Verify we do NOT take the i_mutex in the normal case
22651 test_258b() {
22652 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22653         $LCTL set_param fail_loc=0x141d
22654         touch $DIR/$tfile
22655         chmod a+rwx $DIR
22656         chmod a+rw $DIR/$tfile
22657         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22658         RC=$?
22659         if [ $RC -ne 0 ]; then
22660                 error "error, took i_mutex unnecessarily, rc=$?"
22661         fi
22662         rm -f $DIR/$tfile
22663
22664 }
22665 run_test 258b "verify i_mutex security behavior"
22666
22667 test_259() {
22668         local file=$DIR/$tfile
22669         local before
22670         local after
22671
22672         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22673
22674         stack_trap "rm -f $file" EXIT
22675
22676         wait_delete_completed
22677         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22678         echo "before: $before"
22679
22680         $LFS setstripe -i 0 -c 1 $file
22681         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22682         sync_all_data
22683         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22684         echo "after write: $after"
22685
22686 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22687         do_facet ost1 $LCTL set_param fail_loc=0x2301
22688         $TRUNCATE $file 0
22689         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22690         echo "after truncate: $after"
22691
22692         stop ost1
22693         do_facet ost1 $LCTL set_param fail_loc=0
22694         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22695         sleep 2
22696         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22697         echo "after restart: $after"
22698         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22699                 error "missing truncate?"
22700
22701         return 0
22702 }
22703 run_test 259 "crash at delayed truncate"
22704
22705 test_260() {
22706 #define OBD_FAIL_MDC_CLOSE               0x806
22707         $LCTL set_param fail_loc=0x80000806
22708         touch $DIR/$tfile
22709
22710 }
22711 run_test 260 "Check mdc_close fail"
22712
22713 ### Data-on-MDT sanity tests ###
22714 test_270a() {
22715         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22716                 skip "Need MDS version at least 2.10.55 for DoM"
22717
22718         # create DoM file
22719         local dom=$DIR/$tdir/dom_file
22720         local tmp=$DIR/$tdir/tmp_file
22721
22722         mkdir_on_mdt0 $DIR/$tdir
22723
22724         # basic checks for DoM component creation
22725         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22726                 error "Can set MDT layout to non-first entry"
22727
22728         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22729                 error "Can define multiple entries as MDT layout"
22730
22731         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22732
22733         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22734         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22735         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22736
22737         local mdtidx=$($LFS getstripe -m $dom)
22738         local mdtname=MDT$(printf %04x $mdtidx)
22739         local facet=mds$((mdtidx + 1))
22740         local space_check=1
22741
22742         # Skip free space checks with ZFS
22743         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22744
22745         # write
22746         sync
22747         local size_tmp=$((65536 * 3))
22748         local mdtfree1=$(do_facet $facet \
22749                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22750
22751         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22752         # check also direct IO along write
22753         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22754         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22755         sync
22756         cmp $tmp $dom || error "file data is different"
22757         [ $(stat -c%s $dom) == $size_tmp ] ||
22758                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22759         if [ $space_check == 1 ]; then
22760                 local mdtfree2=$(do_facet $facet \
22761                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22762
22763                 # increase in usage from by $size_tmp
22764                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22765                         error "MDT free space wrong after write: " \
22766                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22767         fi
22768
22769         # truncate
22770         local size_dom=10000
22771
22772         $TRUNCATE $dom $size_dom
22773         [ $(stat -c%s $dom) == $size_dom ] ||
22774                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22775         if [ $space_check == 1 ]; then
22776                 mdtfree1=$(do_facet $facet \
22777                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22778                 # decrease in usage from $size_tmp to new $size_dom
22779                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22780                   $(((size_tmp - size_dom) / 1024)) ] ||
22781                         error "MDT free space is wrong after truncate: " \
22782                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22783         fi
22784
22785         # append
22786         cat $tmp >> $dom
22787         sync
22788         size_dom=$((size_dom + size_tmp))
22789         [ $(stat -c%s $dom) == $size_dom ] ||
22790                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22791         if [ $space_check == 1 ]; then
22792                 mdtfree2=$(do_facet $facet \
22793                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22794                 # increase in usage by $size_tmp from previous
22795                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22796                         error "MDT free space is wrong after append: " \
22797                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22798         fi
22799
22800         # delete
22801         rm $dom
22802         if [ $space_check == 1 ]; then
22803                 mdtfree1=$(do_facet $facet \
22804                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22805                 # decrease in usage by $size_dom from previous
22806                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22807                         error "MDT free space is wrong after removal: " \
22808                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22809         fi
22810
22811         # combined striping
22812         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22813                 error "Can't create DoM + OST striping"
22814
22815         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22816         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22817         # check also direct IO along write
22818         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22819         sync
22820         cmp $tmp $dom || error "file data is different"
22821         [ $(stat -c%s $dom) == $size_tmp ] ||
22822                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22823         rm $dom $tmp
22824
22825         return 0
22826 }
22827 run_test 270a "DoM: basic functionality tests"
22828
22829 test_270b() {
22830         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22831                 skip "Need MDS version at least 2.10.55"
22832
22833         local dom=$DIR/$tdir/dom_file
22834         local max_size=1048576
22835
22836         mkdir -p $DIR/$tdir
22837         $LFS setstripe -E $max_size -L mdt $dom
22838
22839         # truncate over the limit
22840         $TRUNCATE $dom $(($max_size + 1)) &&
22841                 error "successful truncate over the maximum size"
22842         # write over the limit
22843         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22844                 error "successful write over the maximum size"
22845         # append over the limit
22846         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22847         echo "12345" >> $dom && error "successful append over the maximum size"
22848         rm $dom
22849
22850         return 0
22851 }
22852 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22853
22854 test_270c() {
22855         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22856                 skip "Need MDS version at least 2.10.55"
22857
22858         mkdir -p $DIR/$tdir
22859         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22860
22861         # check files inherit DoM EA
22862         touch $DIR/$tdir/first
22863         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22864                 error "bad pattern"
22865         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22866                 error "bad stripe count"
22867         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22868                 error "bad stripe size"
22869
22870         # check directory inherits DoM EA and uses it as default
22871         mkdir $DIR/$tdir/subdir
22872         touch $DIR/$tdir/subdir/second
22873         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22874                 error "bad pattern in sub-directory"
22875         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22876                 error "bad stripe count in sub-directory"
22877         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22878                 error "bad stripe size in sub-directory"
22879         return 0
22880 }
22881 run_test 270c "DoM: DoM EA inheritance tests"
22882
22883 test_270d() {
22884         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22885                 skip "Need MDS version at least 2.10.55"
22886
22887         mkdir -p $DIR/$tdir
22888         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22889
22890         # inherit default DoM striping
22891         mkdir $DIR/$tdir/subdir
22892         touch $DIR/$tdir/subdir/f1
22893
22894         # change default directory striping
22895         $LFS setstripe -c 1 $DIR/$tdir/subdir
22896         touch $DIR/$tdir/subdir/f2
22897         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22898                 error "wrong default striping in file 2"
22899         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22900                 error "bad pattern in file 2"
22901         return 0
22902 }
22903 run_test 270d "DoM: change striping from DoM to RAID0"
22904
22905 test_270e() {
22906         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22907                 skip "Need MDS version at least 2.10.55"
22908
22909         mkdir -p $DIR/$tdir/dom
22910         mkdir -p $DIR/$tdir/norm
22911         DOMFILES=20
22912         NORMFILES=10
22913         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22914         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22915
22916         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22917         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22918
22919         # find DoM files by layout
22920         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22921         [ $NUM -eq  $DOMFILES ] ||
22922                 error "lfs find -L: found $NUM, expected $DOMFILES"
22923         echo "Test 1: lfs find 20 DOM files by layout: OK"
22924
22925         # there should be 1 dir with default DOM striping
22926         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22927         [ $NUM -eq  1 ] ||
22928                 error "lfs find -L: found $NUM, expected 1 dir"
22929         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22930
22931         # find DoM files by stripe size
22932         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22933         [ $NUM -eq  $DOMFILES ] ||
22934                 error "lfs find -S: found $NUM, expected $DOMFILES"
22935         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22936
22937         # find files by stripe offset except DoM files
22938         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22939         [ $NUM -eq  $NORMFILES ] ||
22940                 error "lfs find -i: found $NUM, expected $NORMFILES"
22941         echo "Test 5: lfs find no DOM files by stripe index: OK"
22942         return 0
22943 }
22944 run_test 270e "DoM: lfs find with DoM files test"
22945
22946 test_270f() {
22947         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22948                 skip "Need MDS version at least 2.10.55"
22949
22950         local mdtname=${FSNAME}-MDT0000-mdtlov
22951         local dom=$DIR/$tdir/dom_file
22952         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22953                                                 lod.$mdtname.dom_stripesize)
22954         local dom_limit=131072
22955
22956         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22957         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22958                                                 lod.$mdtname.dom_stripesize)
22959         [ ${dom_limit} -eq ${dom_current} ] ||
22960                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22961
22962         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22963         $LFS setstripe -d $DIR/$tdir
22964         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22965                 error "Can't set directory default striping"
22966
22967         # exceed maximum stripe size
22968         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22969                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22970         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22971                 error "Able to create DoM component size more than LOD limit"
22972
22973         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22974         dom_current=$(do_facet mds1 $LCTL get_param -n \
22975                                                 lod.$mdtname.dom_stripesize)
22976         [ 0 -eq ${dom_current} ] ||
22977                 error "Can't set zero DoM stripe limit"
22978         rm $dom
22979
22980         # attempt to create DoM file on server with disabled DoM should
22981         # remove DoM entry from layout and be succeed
22982         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22983                 error "Can't create DoM file (DoM is disabled)"
22984         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22985                 error "File has DoM component while DoM is disabled"
22986         rm $dom
22987
22988         # attempt to create DoM file with only DoM stripe should return error
22989         $LFS setstripe -E $dom_limit -L mdt $dom &&
22990                 error "Able to create DoM-only file while DoM is disabled"
22991
22992         # too low values to be aligned with smallest stripe size 64K
22993         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22994         dom_current=$(do_facet mds1 $LCTL get_param -n \
22995                                                 lod.$mdtname.dom_stripesize)
22996         [ 30000 -eq ${dom_current} ] &&
22997                 error "Can set too small DoM stripe limit"
22998
22999         # 64K is a minimal stripe size in Lustre, expect limit of that size
23000         [ 65536 -eq ${dom_current} ] ||
23001                 error "Limit is not set to 64K but ${dom_current}"
23002
23003         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23004         dom_current=$(do_facet mds1 $LCTL get_param -n \
23005                                                 lod.$mdtname.dom_stripesize)
23006         echo $dom_current
23007         [ 2147483648 -eq ${dom_current} ] &&
23008                 error "Can set too large DoM stripe limit"
23009
23010         do_facet mds1 $LCTL set_param -n \
23011                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23012         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23013                 error "Can't create DoM component size after limit change"
23014         do_facet mds1 $LCTL set_param -n \
23015                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23016         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23017                 error "Can't create DoM file after limit decrease"
23018         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23019                 error "Can create big DoM component after limit decrease"
23020         touch ${dom}_def ||
23021                 error "Can't create file with old default layout"
23022
23023         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23024         return 0
23025 }
23026 run_test 270f "DoM: maximum DoM stripe size checks"
23027
23028 test_270g() {
23029         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23030                 skip "Need MDS version at least 2.13.52"
23031         local dom=$DIR/$tdir/$tfile
23032
23033         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23034         local lodname=${FSNAME}-MDT0000-mdtlov
23035
23036         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23037         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23038         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23039         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23040
23041         local dom_limit=1024
23042         local dom_threshold="50%"
23043
23044         $LFS setstripe -d $DIR/$tdir
23045         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23046                 error "Can't set directory default striping"
23047
23048         do_facet mds1 $LCTL set_param -n \
23049                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23050         # set 0 threshold and create DOM file to change tunable stripesize
23051         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23052         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23053                 error "Failed to create $dom file"
23054         # now tunable dom_cur_stripesize should reach maximum
23055         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23056                                         lod.${lodname}.dom_stripesize_cur_kb)
23057         [[ $dom_current == $dom_limit ]] ||
23058                 error "Current DOM stripesize is not maximum"
23059         rm $dom
23060
23061         # set threshold for further tests
23062         do_facet mds1 $LCTL set_param -n \
23063                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23064         echo "DOM threshold is $dom_threshold free space"
23065         local dom_def
23066         local dom_set
23067         # Spoof bfree to exceed threshold
23068         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23069         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23070         for spfree in 40 20 0 15 30 55; do
23071                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23072                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23073                         error "Failed to create $dom file"
23074                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23075                                         lod.${lodname}.dom_stripesize_cur_kb)
23076                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23077                 [[ $dom_def != $dom_current ]] ||
23078                         error "Default stripe size was not changed"
23079                 if (( spfree > 0 )) ; then
23080                         dom_set=$($LFS getstripe -S $dom)
23081                         (( dom_set == dom_def * 1024 )) ||
23082                                 error "DOM component size is still old"
23083                 else
23084                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23085                                 error "DoM component is set with no free space"
23086                 fi
23087                 rm $dom
23088                 dom_current=$dom_def
23089         done
23090 }
23091 run_test 270g "DoM: default DoM stripe size depends on free space"
23092
23093 test_270h() {
23094         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23095                 skip "Need MDS version at least 2.13.53"
23096
23097         local mdtname=${FSNAME}-MDT0000-mdtlov
23098         local dom=$DIR/$tdir/$tfile
23099         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23100
23101         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23102         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23103
23104         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23105         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23106                 error "can't create OST file"
23107         # mirrored file with DOM entry in the second mirror
23108         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23109                 error "can't create mirror with DoM component"
23110
23111         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23112
23113         # DOM component in the middle and has other enries in the same mirror,
23114         # should succeed but lost DoM component
23115         $LFS setstripe --copy=${dom}_1 $dom ||
23116                 error "Can't create file from OST|DOM mirror layout"
23117         # check new file has no DoM layout after all
23118         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23119                 error "File has DoM component while DoM is disabled"
23120 }
23121 run_test 270h "DoM: DoM stripe removal when disabled on server"
23122
23123 test_270i() {
23124         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23125                 skip "Need MDS version at least 2.14.54"
23126
23127         mkdir $DIR/$tdir
23128         # DoM with plain layout
23129         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23130                 error "default plain layout with DoM must fail"
23131         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23132                 error "setstripe plain file layout with DoM must fail"
23133         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23134                 error "default DoM layout with bad striping must fail"
23135         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23136                 error "setstripe to DoM layout with bad striping must fail"
23137         return 0
23138 }
23139 run_test 270i "DoM: setting invalid DoM striping should fail"
23140
23141 test_271a() {
23142         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23143                 skip "Need MDS version at least 2.10.55"
23144
23145         local dom=$DIR/$tdir/dom
23146
23147         mkdir -p $DIR/$tdir
23148
23149         $LFS setstripe -E 1024K -L mdt $dom
23150
23151         lctl set_param -n mdc.*.stats=clear
23152         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23153         cat $dom > /dev/null
23154         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23155         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23156         ls $dom
23157         rm -f $dom
23158 }
23159 run_test 271a "DoM: data is cached for read after write"
23160
23161 test_271b() {
23162         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23163                 skip "Need MDS version at least 2.10.55"
23164
23165         local dom=$DIR/$tdir/dom
23166
23167         mkdir -p $DIR/$tdir
23168
23169         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23170
23171         lctl set_param -n mdc.*.stats=clear
23172         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23173         cancel_lru_locks mdc
23174         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23175         # second stat to check size is cached on client
23176         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23177         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23178         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23179         rm -f $dom
23180 }
23181 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23182
23183 test_271ba() {
23184         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23185                 skip "Need MDS version at least 2.10.55"
23186
23187         local dom=$DIR/$tdir/dom
23188
23189         mkdir -p $DIR/$tdir
23190
23191         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23192
23193         lctl set_param -n mdc.*.stats=clear
23194         lctl set_param -n osc.*.stats=clear
23195         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23196         cancel_lru_locks mdc
23197         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23198         # second stat to check size is cached on client
23199         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23200         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23201         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23202         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23203         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23204         rm -f $dom
23205 }
23206 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23207
23208
23209 get_mdc_stats() {
23210         local mdtidx=$1
23211         local param=$2
23212         local mdt=MDT$(printf %04x $mdtidx)
23213
23214         if [ -z $param ]; then
23215                 lctl get_param -n mdc.*$mdt*.stats
23216         else
23217                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23218         fi
23219 }
23220
23221 test_271c() {
23222         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23223                 skip "Need MDS version at least 2.10.55"
23224
23225         local dom=$DIR/$tdir/dom
23226
23227         mkdir -p $DIR/$tdir
23228
23229         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23230
23231         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23232         local facet=mds$((mdtidx + 1))
23233
23234         cancel_lru_locks mdc
23235         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23236         createmany -o $dom 1000
23237         lctl set_param -n mdc.*.stats=clear
23238         smalliomany -w $dom 1000 200
23239         get_mdc_stats $mdtidx
23240         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23241         # Each file has 1 open, 1 IO enqueues, total 2000
23242         # but now we have also +1 getxattr for security.capability, total 3000
23243         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23244         unlinkmany $dom 1000
23245
23246         cancel_lru_locks mdc
23247         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23248         createmany -o $dom 1000
23249         lctl set_param -n mdc.*.stats=clear
23250         smalliomany -w $dom 1000 200
23251         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23252         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23253         # for OPEN and IO lock.
23254         [ $((enq - enq_2)) -ge 1000 ] ||
23255                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23256         unlinkmany $dom 1000
23257         return 0
23258 }
23259 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23260
23261 cleanup_271def_tests() {
23262         trap 0
23263         rm -f $1
23264 }
23265
23266 test_271d() {
23267         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23268                 skip "Need MDS version at least 2.10.57"
23269
23270         local dom=$DIR/$tdir/dom
23271         local tmp=$TMP/$tfile
23272         trap "cleanup_271def_tests $tmp" EXIT
23273
23274         mkdir -p $DIR/$tdir
23275
23276         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23277
23278         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23279
23280         cancel_lru_locks mdc
23281         dd if=/dev/urandom of=$tmp bs=1000 count=1
23282         dd if=$tmp of=$dom bs=1000 count=1
23283         cancel_lru_locks mdc
23284
23285         cat /etc/hosts >> $tmp
23286         lctl set_param -n mdc.*.stats=clear
23287
23288         # append data to the same file it should update local page
23289         echo "Append to the same page"
23290         cat /etc/hosts >> $dom
23291         local num=$(get_mdc_stats $mdtidx ost_read)
23292         local ra=$(get_mdc_stats $mdtidx req_active)
23293         local rw=$(get_mdc_stats $mdtidx req_waittime)
23294
23295         [ -z $num ] || error "$num READ RPC occured"
23296         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23297         echo "... DONE"
23298
23299         # compare content
23300         cmp $tmp $dom || error "file miscompare"
23301
23302         cancel_lru_locks mdc
23303         lctl set_param -n mdc.*.stats=clear
23304
23305         echo "Open and read file"
23306         cat $dom > /dev/null
23307         local num=$(get_mdc_stats $mdtidx ost_read)
23308         local ra=$(get_mdc_stats $mdtidx req_active)
23309         local rw=$(get_mdc_stats $mdtidx req_waittime)
23310
23311         [ -z $num ] || error "$num READ RPC occured"
23312         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23313         echo "... DONE"
23314
23315         # compare content
23316         cmp $tmp $dom || error "file miscompare"
23317
23318         return 0
23319 }
23320 run_test 271d "DoM: read on open (1K file in reply buffer)"
23321
23322 test_271f() {
23323         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23324                 skip "Need MDS version at least 2.10.57"
23325
23326         local dom=$DIR/$tdir/dom
23327         local tmp=$TMP/$tfile
23328         trap "cleanup_271def_tests $tmp" EXIT
23329
23330         mkdir -p $DIR/$tdir
23331
23332         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23333
23334         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23335
23336         cancel_lru_locks mdc
23337         dd if=/dev/urandom of=$tmp bs=265000 count=1
23338         dd if=$tmp of=$dom bs=265000 count=1
23339         cancel_lru_locks mdc
23340         cat /etc/hosts >> $tmp
23341         lctl set_param -n mdc.*.stats=clear
23342
23343         echo "Append to the same page"
23344         cat /etc/hosts >> $dom
23345         local num=$(get_mdc_stats $mdtidx ost_read)
23346         local ra=$(get_mdc_stats $mdtidx req_active)
23347         local rw=$(get_mdc_stats $mdtidx req_waittime)
23348
23349         [ -z $num ] || error "$num READ RPC occured"
23350         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23351         echo "... DONE"
23352
23353         # compare content
23354         cmp $tmp $dom || error "file miscompare"
23355
23356         cancel_lru_locks mdc
23357         lctl set_param -n mdc.*.stats=clear
23358
23359         echo "Open and read file"
23360         cat $dom > /dev/null
23361         local num=$(get_mdc_stats $mdtidx ost_read)
23362         local ra=$(get_mdc_stats $mdtidx req_active)
23363         local rw=$(get_mdc_stats $mdtidx req_waittime)
23364
23365         [ -z $num ] && num=0
23366         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23367         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23368         echo "... DONE"
23369
23370         # compare content
23371         cmp $tmp $dom || error "file miscompare"
23372
23373         return 0
23374 }
23375 run_test 271f "DoM: read on open (200K file and read tail)"
23376
23377 test_271g() {
23378         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23379                 skip "Skipping due to old client or server version"
23380
23381         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23382         # to get layout
23383         $CHECKSTAT -t file $DIR1/$tfile
23384
23385         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23386         MULTIOP_PID=$!
23387         sleep 1
23388         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23389         $LCTL set_param fail_loc=0x80000314
23390         rm $DIR1/$tfile || error "Unlink fails"
23391         RC=$?
23392         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23393         [ $RC -eq 0 ] || error "Failed write to stale object"
23394 }
23395 run_test 271g "Discard DoM data vs client flush race"
23396
23397 test_272a() {
23398         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23399                 skip "Need MDS version at least 2.11.50"
23400
23401         local dom=$DIR/$tdir/dom
23402         mkdir -p $DIR/$tdir
23403
23404         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23405         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23406                 error "failed to write data into $dom"
23407         local old_md5=$(md5sum $dom)
23408
23409         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23410                 error "failed to migrate to the same DoM component"
23411
23412         local new_md5=$(md5sum $dom)
23413
23414         [ "$old_md5" == "$new_md5" ] ||
23415                 error "md5sum differ: $old_md5, $new_md5"
23416
23417         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23418                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23419 }
23420 run_test 272a "DoM migration: new layout with the same DOM component"
23421
23422 test_272b() {
23423         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23424                 skip "Need MDS version at least 2.11.50"
23425
23426         local dom=$DIR/$tdir/dom
23427         mkdir -p $DIR/$tdir
23428         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23429
23430         local mdtidx=$($LFS getstripe -m $dom)
23431         local mdtname=MDT$(printf %04x $mdtidx)
23432         local facet=mds$((mdtidx + 1))
23433
23434         local mdtfree1=$(do_facet $facet \
23435                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23436         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23437                 error "failed to write data into $dom"
23438         local old_md5=$(md5sum $dom)
23439         cancel_lru_locks mdc
23440         local mdtfree1=$(do_facet $facet \
23441                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23442
23443         $LFS migrate -c2 $dom ||
23444                 error "failed to migrate to the new composite layout"
23445         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23446                 error "MDT stripe was not removed"
23447
23448         cancel_lru_locks mdc
23449         local new_md5=$(md5sum $dom)
23450         [ "$old_md5" == "$new_md5" ] ||
23451                 error "$old_md5 != $new_md5"
23452
23453         # Skip free space checks with ZFS
23454         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23455                 local mdtfree2=$(do_facet $facet \
23456                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23457                 [ $mdtfree2 -gt $mdtfree1 ] ||
23458                         error "MDT space is not freed after migration"
23459         fi
23460         return 0
23461 }
23462 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23463
23464 test_272c() {
23465         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23466                 skip "Need MDS version at least 2.11.50"
23467
23468         local dom=$DIR/$tdir/$tfile
23469         mkdir -p $DIR/$tdir
23470         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23471
23472         local mdtidx=$($LFS getstripe -m $dom)
23473         local mdtname=MDT$(printf %04x $mdtidx)
23474         local facet=mds$((mdtidx + 1))
23475
23476         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23477                 error "failed to write data into $dom"
23478         local old_md5=$(md5sum $dom)
23479         cancel_lru_locks mdc
23480         local mdtfree1=$(do_facet $facet \
23481                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23482
23483         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23484                 error "failed to migrate to the new composite layout"
23485         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23486                 error "MDT stripe was not removed"
23487
23488         cancel_lru_locks mdc
23489         local new_md5=$(md5sum $dom)
23490         [ "$old_md5" == "$new_md5" ] ||
23491                 error "$old_md5 != $new_md5"
23492
23493         # Skip free space checks with ZFS
23494         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23495                 local mdtfree2=$(do_facet $facet \
23496                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23497                 [ $mdtfree2 -gt $mdtfree1 ] ||
23498                         error "MDS space is not freed after migration"
23499         fi
23500         return 0
23501 }
23502 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23503
23504 test_272d() {
23505         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23506                 skip "Need MDS version at least 2.12.55"
23507
23508         local dom=$DIR/$tdir/$tfile
23509         mkdir -p $DIR/$tdir
23510         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23511
23512         local mdtidx=$($LFS getstripe -m $dom)
23513         local mdtname=MDT$(printf %04x $mdtidx)
23514         local facet=mds$((mdtidx + 1))
23515
23516         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23517                 error "failed to write data into $dom"
23518         local old_md5=$(md5sum $dom)
23519         cancel_lru_locks mdc
23520         local mdtfree1=$(do_facet $facet \
23521                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23522
23523         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23524                 error "failed mirroring to the new composite layout"
23525         $LFS mirror resync $dom ||
23526                 error "failed mirror resync"
23527         $LFS mirror split --mirror-id 1 -d $dom ||
23528                 error "failed mirror split"
23529
23530         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23531                 error "MDT stripe was not removed"
23532
23533         cancel_lru_locks mdc
23534         local new_md5=$(md5sum $dom)
23535         [ "$old_md5" == "$new_md5" ] ||
23536                 error "$old_md5 != $new_md5"
23537
23538         # Skip free space checks with ZFS
23539         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23540                 local mdtfree2=$(do_facet $facet \
23541                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23542                 [ $mdtfree2 -gt $mdtfree1 ] ||
23543                         error "MDS space is not freed after DOM mirror deletion"
23544         fi
23545         return 0
23546 }
23547 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23548
23549 test_272e() {
23550         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23551                 skip "Need MDS version at least 2.12.55"
23552
23553         local dom=$DIR/$tdir/$tfile
23554         mkdir -p $DIR/$tdir
23555         $LFS setstripe -c 2 $dom
23556
23557         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23558                 error "failed to write data into $dom"
23559         local old_md5=$(md5sum $dom)
23560         cancel_lru_locks
23561
23562         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23563                 error "failed mirroring to the DOM layout"
23564         $LFS mirror resync $dom ||
23565                 error "failed mirror resync"
23566         $LFS mirror split --mirror-id 1 -d $dom ||
23567                 error "failed mirror split"
23568
23569         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23570                 error "MDT stripe wasn't set"
23571
23572         cancel_lru_locks
23573         local new_md5=$(md5sum $dom)
23574         [ "$old_md5" == "$new_md5" ] ||
23575                 error "$old_md5 != $new_md5"
23576
23577         return 0
23578 }
23579 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23580
23581 test_272f() {
23582         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23583                 skip "Need MDS version at least 2.12.55"
23584
23585         local dom=$DIR/$tdir/$tfile
23586         mkdir -p $DIR/$tdir
23587         $LFS setstripe -c 2 $dom
23588
23589         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23590                 error "failed to write data into $dom"
23591         local old_md5=$(md5sum $dom)
23592         cancel_lru_locks
23593
23594         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23595                 error "failed migrating to the DOM file"
23596
23597         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23598                 error "MDT stripe wasn't set"
23599
23600         cancel_lru_locks
23601         local new_md5=$(md5sum $dom)
23602         [ "$old_md5" != "$new_md5" ] &&
23603                 error "$old_md5 != $new_md5"
23604
23605         return 0
23606 }
23607 run_test 272f "DoM migration: OST-striped file to DOM file"
23608
23609 test_273a() {
23610         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23611                 skip "Need MDS version at least 2.11.50"
23612
23613         # Layout swap cannot be done if either file has DOM component,
23614         # this will never be supported, migration should be used instead
23615
23616         local dom=$DIR/$tdir/$tfile
23617         mkdir -p $DIR/$tdir
23618
23619         $LFS setstripe -c2 ${dom}_plain
23620         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23621         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23622                 error "can swap layout with DoM component"
23623         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23624                 error "can swap layout with DoM component"
23625
23626         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23627         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23628                 error "can swap layout with DoM component"
23629         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23630                 error "can swap layout with DoM component"
23631         return 0
23632 }
23633 run_test 273a "DoM: layout swapping should fail with DOM"
23634
23635 test_273b() {
23636         mkdir -p $DIR/$tdir
23637         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23638
23639 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23640         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23641
23642         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23643 }
23644 run_test 273b "DoM: race writeback and object destroy"
23645
23646 test_275() {
23647         remote_ost_nodsh && skip "remote OST with nodsh"
23648         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23649                 skip "Need OST version >= 2.10.57"
23650
23651         local file=$DIR/$tfile
23652         local oss
23653
23654         oss=$(comma_list $(osts_nodes))
23655
23656         dd if=/dev/urandom of=$file bs=1M count=2 ||
23657                 error "failed to create a file"
23658         cancel_lru_locks osc
23659
23660         #lock 1
23661         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23662                 error "failed to read a file"
23663
23664 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23665         $LCTL set_param fail_loc=0x8000031f
23666
23667         cancel_lru_locks osc &
23668         sleep 1
23669
23670 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23671         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23672         #IO takes another lock, but matches the PENDING one
23673         #and places it to the IO RPC
23674         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23675                 error "failed to read a file with PENDING lock"
23676 }
23677 run_test 275 "Read on a canceled duplicate lock"
23678
23679 test_276() {
23680         remote_ost_nodsh && skip "remote OST with nodsh"
23681         local pid
23682
23683         do_facet ost1 "(while true; do \
23684                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23685                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23686         pid=$!
23687
23688         for LOOP in $(seq 20); do
23689                 stop ost1
23690                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23691         done
23692         kill -9 $pid
23693         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23694                 rm $TMP/sanity_276_pid"
23695 }
23696 run_test 276 "Race between mount and obd_statfs"
23697
23698 test_277() {
23699         $LCTL set_param ldlm.namespaces.*.lru_size=0
23700         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23701         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23702                         grep ^used_mb | awk '{print $2}')
23703         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23704         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23705                 oflag=direct conv=notrunc
23706         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23707                         grep ^used_mb | awk '{print $2}')
23708         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23709 }
23710 run_test 277 "Direct IO shall drop page cache"
23711
23712 test_278() {
23713         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23714         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23715         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23716                 skip "needs the same host for mdt1 mdt2" && return
23717
23718         local pid1
23719         local pid2
23720
23721 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23722         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23723         stop mds2 &
23724         pid2=$!
23725
23726         stop mds1
23727
23728         echo "Starting MDTs"
23729         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23730         wait $pid2
23731 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23732 #will return NULL
23733         do_facet mds2 $LCTL set_param fail_loc=0
23734
23735         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23736         wait_recovery_complete mds2
23737 }
23738 run_test 278 "Race starting MDS between MDTs stop/start"
23739
23740 test_280() {
23741         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23742                 skip "Need MGS version at least 2.13.52"
23743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23744         combined_mgs_mds || skip "needs combined MGS/MDT"
23745
23746         umount_client $MOUNT
23747 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23748         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23749
23750         mount_client $MOUNT &
23751         sleep 1
23752         stop mgs || error "stop mgs failed"
23753         #for a race mgs would crash
23754         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23755         # make sure we unmount client before remounting
23756         wait
23757         umount_client $MOUNT
23758         mount_client $MOUNT || error "mount client failed"
23759 }
23760 run_test 280 "Race between MGS umount and client llog processing"
23761
23762 cleanup_test_300() {
23763         trap 0
23764         umask $SAVE_UMASK
23765 }
23766 test_striped_dir() {
23767         local mdt_index=$1
23768         local stripe_count
23769         local stripe_index
23770
23771         mkdir -p $DIR/$tdir
23772
23773         SAVE_UMASK=$(umask)
23774         trap cleanup_test_300 RETURN EXIT
23775
23776         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23777                                                 $DIR/$tdir/striped_dir ||
23778                 error "set striped dir error"
23779
23780         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23781         [ "$mode" = "755" ] || error "expect 755 got $mode"
23782
23783         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23784                 error "getdirstripe failed"
23785         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23786         if [ "$stripe_count" != "2" ]; then
23787                 error "1:stripe_count is $stripe_count, expect 2"
23788         fi
23789         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23790         if [ "$stripe_count" != "2" ]; then
23791                 error "2:stripe_count is $stripe_count, expect 2"
23792         fi
23793
23794         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23795         if [ "$stripe_index" != "$mdt_index" ]; then
23796                 error "stripe_index is $stripe_index, expect $mdt_index"
23797         fi
23798
23799         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23800                 error "nlink error after create striped dir"
23801
23802         mkdir $DIR/$tdir/striped_dir/a
23803         mkdir $DIR/$tdir/striped_dir/b
23804
23805         stat $DIR/$tdir/striped_dir/a ||
23806                 error "create dir under striped dir failed"
23807         stat $DIR/$tdir/striped_dir/b ||
23808                 error "create dir under striped dir failed"
23809
23810         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23811                 error "nlink error after mkdir"
23812
23813         rmdir $DIR/$tdir/striped_dir/a
23814         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23815                 error "nlink error after rmdir"
23816
23817         rmdir $DIR/$tdir/striped_dir/b
23818         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23819                 error "nlink error after rmdir"
23820
23821         chattr +i $DIR/$tdir/striped_dir
23822         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23823                 error "immutable flags not working under striped dir!"
23824         chattr -i $DIR/$tdir/striped_dir
23825
23826         rmdir $DIR/$tdir/striped_dir ||
23827                 error "rmdir striped dir error"
23828
23829         cleanup_test_300
23830
23831         true
23832 }
23833
23834 test_300a() {
23835         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23836                 skip "skipped for lustre < 2.7.0"
23837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23838         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23839
23840         test_striped_dir 0 || error "failed on striped dir on MDT0"
23841         test_striped_dir 1 || error "failed on striped dir on MDT0"
23842 }
23843 run_test 300a "basic striped dir sanity test"
23844
23845 test_300b() {
23846         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23847                 skip "skipped for lustre < 2.7.0"
23848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23850
23851         local i
23852         local mtime1
23853         local mtime2
23854         local mtime3
23855
23856         test_mkdir $DIR/$tdir || error "mkdir fail"
23857         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23858                 error "set striped dir error"
23859         for i in {0..9}; do
23860                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23861                 sleep 1
23862                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23863                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23864                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23865                 sleep 1
23866                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23867                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23868                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23869         done
23870         true
23871 }
23872 run_test 300b "check ctime/mtime for striped dir"
23873
23874 test_300c() {
23875         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23876                 skip "skipped for lustre < 2.7.0"
23877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23879
23880         local file_count
23881
23882         mkdir_on_mdt0 $DIR/$tdir
23883         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23884                 error "set striped dir error"
23885
23886         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23887                 error "chown striped dir failed"
23888
23889         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23890                 error "create 5k files failed"
23891
23892         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23893
23894         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23895
23896         rm -rf $DIR/$tdir
23897 }
23898 run_test 300c "chown && check ls under striped directory"
23899
23900 test_300d() {
23901         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23902                 skip "skipped for lustre < 2.7.0"
23903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23904         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23905
23906         local stripe_count
23907         local file
23908
23909         mkdir -p $DIR/$tdir
23910         $LFS setstripe -c 2 $DIR/$tdir
23911
23912         #local striped directory
23913         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23914                 error "set striped dir error"
23915         #look at the directories for debug purposes
23916         ls -l $DIR/$tdir
23917         $LFS getdirstripe $DIR/$tdir
23918         ls -l $DIR/$tdir/striped_dir
23919         $LFS getdirstripe $DIR/$tdir/striped_dir
23920         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23921                 error "create 10 files failed"
23922
23923         #remote striped directory
23924         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23925                 error "set striped dir error"
23926         #look at the directories for debug purposes
23927         ls -l $DIR/$tdir
23928         $LFS getdirstripe $DIR/$tdir
23929         ls -l $DIR/$tdir/remote_striped_dir
23930         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23931         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23932                 error "create 10 files failed"
23933
23934         for file in $(find $DIR/$tdir); do
23935                 stripe_count=$($LFS getstripe -c $file)
23936                 [ $stripe_count -eq 2 ] ||
23937                         error "wrong stripe $stripe_count for $file"
23938         done
23939
23940         rm -rf $DIR/$tdir
23941 }
23942 run_test 300d "check default stripe under striped directory"
23943
23944 test_300e() {
23945         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23946                 skip "Need MDS version at least 2.7.55"
23947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23949
23950         local stripe_count
23951         local file
23952
23953         mkdir -p $DIR/$tdir
23954
23955         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23956                 error "set striped dir error"
23957
23958         touch $DIR/$tdir/striped_dir/a
23959         touch $DIR/$tdir/striped_dir/b
23960         touch $DIR/$tdir/striped_dir/c
23961
23962         mkdir $DIR/$tdir/striped_dir/dir_a
23963         mkdir $DIR/$tdir/striped_dir/dir_b
23964         mkdir $DIR/$tdir/striped_dir/dir_c
23965
23966         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23967                 error "set striped adir under striped dir error"
23968
23969         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23970                 error "set striped bdir under striped dir error"
23971
23972         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23973                 error "set striped cdir under striped dir error"
23974
23975         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23976                 error "rename dir under striped dir fails"
23977
23978         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23979                 error "rename dir under different stripes fails"
23980
23981         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23982                 error "rename file under striped dir should succeed"
23983
23984         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23985                 error "rename dir under striped dir should succeed"
23986
23987         rm -rf $DIR/$tdir
23988 }
23989 run_test 300e "check rename under striped directory"
23990
23991 test_300f() {
23992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23994         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23995                 skip "Need MDS version at least 2.7.55"
23996
23997         local stripe_count
23998         local file
23999
24000         rm -rf $DIR/$tdir
24001         mkdir -p $DIR/$tdir
24002
24003         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24004                 error "set striped dir error"
24005
24006         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24007                 error "set striped dir error"
24008
24009         touch $DIR/$tdir/striped_dir/a
24010         mkdir $DIR/$tdir/striped_dir/dir_a
24011         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24012                 error "create striped dir under striped dir fails"
24013
24014         touch $DIR/$tdir/striped_dir1/b
24015         mkdir $DIR/$tdir/striped_dir1/dir_b
24016         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24017                 error "create striped dir under striped dir fails"
24018
24019         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24020                 error "rename dir under different striped dir should fail"
24021
24022         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24023                 error "rename striped dir under diff striped dir should fail"
24024
24025         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24026                 error "rename file under diff striped dirs fails"
24027
24028         rm -rf $DIR/$tdir
24029 }
24030 run_test 300f "check rename cross striped directory"
24031
24032 test_300_check_default_striped_dir()
24033 {
24034         local dirname=$1
24035         local default_count=$2
24036         local default_index=$3
24037         local stripe_count
24038         local stripe_index
24039         local dir_stripe_index
24040         local dir
24041
24042         echo "checking $dirname $default_count $default_index"
24043         $LFS setdirstripe -D -c $default_count -i $default_index \
24044                                 -H all_char $DIR/$tdir/$dirname ||
24045                 error "set default stripe on striped dir error"
24046         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24047         [ $stripe_count -eq $default_count ] ||
24048                 error "expect $default_count get $stripe_count for $dirname"
24049
24050         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24051         [ $stripe_index -eq $default_index ] ||
24052                 error "expect $default_index get $stripe_index for $dirname"
24053
24054         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24055                                                 error "create dirs failed"
24056
24057         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24058         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24059         for dir in $(find $DIR/$tdir/$dirname/*); do
24060                 stripe_count=$($LFS getdirstripe -c $dir)
24061                 (( $stripe_count == $default_count )) ||
24062                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24063                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24064                 error "stripe count $default_count != $stripe_count for $dir"
24065
24066                 stripe_index=$($LFS getdirstripe -i $dir)
24067                 [ $default_index -eq -1 ] ||
24068                         [ $stripe_index -eq $default_index ] ||
24069                         error "$stripe_index != $default_index for $dir"
24070
24071                 #check default stripe
24072                 stripe_count=$($LFS getdirstripe -D -c $dir)
24073                 [ $stripe_count -eq $default_count ] ||
24074                 error "default count $default_count != $stripe_count for $dir"
24075
24076                 stripe_index=$($LFS getdirstripe -D -i $dir)
24077                 [ $stripe_index -eq $default_index ] ||
24078                 error "default index $default_index != $stripe_index for $dir"
24079         done
24080         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24081 }
24082
24083 test_300g() {
24084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24085         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24086                 skip "Need MDS version at least 2.7.55"
24087
24088         local dir
24089         local stripe_count
24090         local stripe_index
24091
24092         mkdir_on_mdt0 $DIR/$tdir
24093         mkdir $DIR/$tdir/normal_dir
24094
24095         #Checking when client cache stripe index
24096         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24097         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24098                 error "create striped_dir failed"
24099
24100         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24101                 error "create dir0 fails"
24102         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24103         [ $stripe_index -eq 0 ] ||
24104                 error "dir0 expect index 0 got $stripe_index"
24105
24106         mkdir $DIR/$tdir/striped_dir/dir1 ||
24107                 error "create dir1 fails"
24108         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24109         [ $stripe_index -eq 1 ] ||
24110                 error "dir1 expect index 1 got $stripe_index"
24111
24112         #check default stripe count/stripe index
24113         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24114         test_300_check_default_striped_dir normal_dir 1 0
24115         test_300_check_default_striped_dir normal_dir -1 1
24116         test_300_check_default_striped_dir normal_dir 2 -1
24117
24118         #delete default stripe information
24119         echo "delete default stripeEA"
24120         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24121                 error "set default stripe on striped dir error"
24122
24123         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24124         for dir in $(find $DIR/$tdir/normal_dir/*); do
24125                 stripe_count=$($LFS getdirstripe -c $dir)
24126                 [ $stripe_count -eq 0 ] ||
24127                         error "expect 1 get $stripe_count for $dir"
24128         done
24129 }
24130 run_test 300g "check default striped directory for normal directory"
24131
24132 test_300h() {
24133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24134         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24135                 skip "Need MDS version at least 2.7.55"
24136
24137         local dir
24138         local stripe_count
24139
24140         mkdir $DIR/$tdir
24141         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24142                 error "set striped dir error"
24143
24144         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24145         test_300_check_default_striped_dir striped_dir 1 0
24146         test_300_check_default_striped_dir striped_dir -1 1
24147         test_300_check_default_striped_dir striped_dir 2 -1
24148
24149         #delete default stripe information
24150         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24151                 error "set default stripe on striped dir error"
24152
24153         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24154         for dir in $(find $DIR/$tdir/striped_dir/*); do
24155                 stripe_count=$($LFS getdirstripe -c $dir)
24156                 [ $stripe_count -eq 0 ] ||
24157                         error "expect 1 get $stripe_count for $dir"
24158         done
24159 }
24160 run_test 300h "check default striped directory for striped directory"
24161
24162 test_300i() {
24163         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24164         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24165         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24166                 skip "Need MDS version at least 2.7.55"
24167
24168         local stripe_count
24169         local file
24170
24171         mkdir $DIR/$tdir
24172
24173         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24174                 error "set striped dir error"
24175
24176         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24177                 error "create files under striped dir failed"
24178
24179         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24180                 error "set striped hashdir error"
24181
24182         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24183                 error "create dir0 under hash dir failed"
24184         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24185                 error "create dir1 under hash dir failed"
24186         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24187                 error "create dir2 under hash dir failed"
24188
24189         # unfortunately, we need to umount to clear dir layout cache for now
24190         # once we fully implement dir layout, we can drop this
24191         umount_client $MOUNT || error "umount failed"
24192         mount_client $MOUNT || error "mount failed"
24193
24194         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24195         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24196         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24197
24198         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24199                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24200                         error "create crush2 dir $tdir/hashdir/d3 failed"
24201                 $LFS find -H crush2 $DIR/$tdir/hashdir
24202                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24203                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24204
24205                 # mkdir with an invalid hash type (hash=fail_val) from client
24206                 # should be replaced on MDS with a valid (default) hash type
24207                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24208                 $LCTL set_param fail_loc=0x1901 fail_val=99
24209                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24210
24211                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24212                 local expect=$(do_facet mds1 \
24213                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24214                 [[ $hash == $expect ]] ||
24215                         error "d99 hash '$hash' != expected hash '$expect'"
24216         fi
24217
24218         #set the stripe to be unknown hash type on read
24219         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24220         $LCTL set_param fail_loc=0x1901 fail_val=99
24221         for ((i = 0; i < 10; i++)); do
24222                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24223                         error "stat f-$i failed"
24224                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24225         done
24226
24227         touch $DIR/$tdir/striped_dir/f0 &&
24228                 error "create under striped dir with unknown hash should fail"
24229
24230         $LCTL set_param fail_loc=0
24231
24232         umount_client $MOUNT || error "umount failed"
24233         mount_client $MOUNT || error "mount failed"
24234
24235         return 0
24236 }
24237 run_test 300i "client handle unknown hash type striped directory"
24238
24239 test_300j() {
24240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24242         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24243                 skip "Need MDS version at least 2.7.55"
24244
24245         local stripe_count
24246         local file
24247
24248         mkdir $DIR/$tdir
24249
24250         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24251         $LCTL set_param fail_loc=0x1702
24252         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24253                 error "set striped dir error"
24254
24255         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24256                 error "create files under striped dir failed"
24257
24258         $LCTL set_param fail_loc=0
24259
24260         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24261
24262         return 0
24263 }
24264 run_test 300j "test large update record"
24265
24266 test_300k() {
24267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24269         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24270                 skip "Need MDS version at least 2.7.55"
24271
24272         # this test needs a huge transaction
24273         local kb
24274         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24275              osd*.$FSNAME-MDT0000.kbytestotal")
24276         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24277
24278         local stripe_count
24279         local file
24280
24281         mkdir $DIR/$tdir
24282
24283         #define OBD_FAIL_LARGE_STRIPE   0x1703
24284         $LCTL set_param fail_loc=0x1703
24285         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24286                 error "set striped dir error"
24287         $LCTL set_param fail_loc=0
24288
24289         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24290                 error "getstripeddir fails"
24291         rm -rf $DIR/$tdir/striped_dir ||
24292                 error "unlink striped dir fails"
24293
24294         return 0
24295 }
24296 run_test 300k "test large striped directory"
24297
24298 test_300l() {
24299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24301         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24302                 skip "Need MDS version at least 2.7.55"
24303
24304         local stripe_index
24305
24306         test_mkdir -p $DIR/$tdir/striped_dir
24307         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24308                         error "chown $RUNAS_ID failed"
24309         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24310                 error "set default striped dir failed"
24311
24312         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24313         $LCTL set_param fail_loc=0x80000158
24314         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24315
24316         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24317         [ $stripe_index -eq 1 ] ||
24318                 error "expect 1 get $stripe_index for $dir"
24319 }
24320 run_test 300l "non-root user to create dir under striped dir with stale layout"
24321
24322 test_300m() {
24323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24324         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24325         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24326                 skip "Need MDS version at least 2.7.55"
24327
24328         mkdir -p $DIR/$tdir/striped_dir
24329         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24330                 error "set default stripes dir error"
24331
24332         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24333
24334         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24335         [ $stripe_count -eq 0 ] ||
24336                         error "expect 0 get $stripe_count for a"
24337
24338         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24339                 error "set default stripes dir error"
24340
24341         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24342
24343         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24344         [ $stripe_count -eq 0 ] ||
24345                         error "expect 0 get $stripe_count for b"
24346
24347         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24348                 error "set default stripes dir error"
24349
24350         mkdir $DIR/$tdir/striped_dir/c &&
24351                 error "default stripe_index is invalid, mkdir c should fails"
24352
24353         rm -rf $DIR/$tdir || error "rmdir fails"
24354 }
24355 run_test 300m "setstriped directory on single MDT FS"
24356
24357 cleanup_300n() {
24358         local list=$(comma_list $(mdts_nodes))
24359
24360         trap 0
24361         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24362 }
24363
24364 test_300n() {
24365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24367         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24368                 skip "Need MDS version at least 2.7.55"
24369         remote_mds_nodsh && skip "remote MDS with nodsh"
24370
24371         local stripe_index
24372         local list=$(comma_list $(mdts_nodes))
24373
24374         trap cleanup_300n RETURN EXIT
24375         mkdir -p $DIR/$tdir
24376         chmod 777 $DIR/$tdir
24377         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24378                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24379                 error "create striped dir succeeds with gid=0"
24380
24381         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24382         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24383                 error "create striped dir fails with gid=-1"
24384
24385         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24386         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24387                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24388                 error "set default striped dir succeeds with gid=0"
24389
24390
24391         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24392         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24393                 error "set default striped dir fails with gid=-1"
24394
24395
24396         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24397         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24398                                         error "create test_dir fails"
24399         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24400                                         error "create test_dir1 fails"
24401         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24402                                         error "create test_dir2 fails"
24403         cleanup_300n
24404 }
24405 run_test 300n "non-root user to create dir under striped dir with default EA"
24406
24407 test_300o() {
24408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24409         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24410         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24411                 skip "Need MDS version at least 2.7.55"
24412
24413         local numfree1
24414         local numfree2
24415
24416         mkdir -p $DIR/$tdir
24417
24418         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24419         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24420         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24421                 skip "not enough free inodes $numfree1 $numfree2"
24422         fi
24423
24424         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24425         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24426         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24427                 skip "not enough free space $numfree1 $numfree2"
24428         fi
24429
24430         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24431                 error "setdirstripe fails"
24432
24433         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24434                 error "create dirs fails"
24435
24436         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24437         ls $DIR/$tdir/striped_dir > /dev/null ||
24438                 error "ls striped dir fails"
24439         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24440                 error "unlink big striped dir fails"
24441 }
24442 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24443
24444 test_300p() {
24445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24446         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24447         remote_mds_nodsh && skip "remote MDS with nodsh"
24448
24449         mkdir_on_mdt0 $DIR/$tdir
24450
24451         #define OBD_FAIL_OUT_ENOSPC     0x1704
24452         do_facet mds2 lctl set_param fail_loc=0x80001704
24453         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24454                  && error "create striped directory should fail"
24455
24456         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24457
24458         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24459         true
24460 }
24461 run_test 300p "create striped directory without space"
24462
24463 test_300q() {
24464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24466
24467         local fd=$(free_fd)
24468         local cmd="exec $fd<$tdir"
24469         cd $DIR
24470         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24471         eval $cmd
24472         cmd="exec $fd<&-"
24473         trap "eval $cmd" EXIT
24474         cd $tdir || error "cd $tdir fails"
24475         rmdir  ../$tdir || error "rmdir $tdir fails"
24476         mkdir local_dir && error "create dir succeeds"
24477         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24478         eval $cmd
24479         return 0
24480 }
24481 run_test 300q "create remote directory under orphan directory"
24482
24483 test_300r() {
24484         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24485                 skip "Need MDS version at least 2.7.55" && return
24486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24487
24488         mkdir $DIR/$tdir
24489
24490         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24491                 error "set striped dir error"
24492
24493         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24494                 error "getstripeddir fails"
24495
24496         local stripe_count
24497         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24498                       awk '/lmv_stripe_count:/ { print $2 }')
24499
24500         [ $MDSCOUNT -ne $stripe_count ] &&
24501                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24502
24503         rm -rf $DIR/$tdir/striped_dir ||
24504                 error "unlink striped dir fails"
24505 }
24506 run_test 300r "test -1 striped directory"
24507
24508 test_300s_helper() {
24509         local count=$1
24510
24511         local stripe_dir=$DIR/$tdir/striped_dir.$count
24512
24513         $LFS mkdir -c $count $stripe_dir ||
24514                 error "lfs mkdir -c error"
24515
24516         $LFS getdirstripe $stripe_dir ||
24517                 error "lfs getdirstripe fails"
24518
24519         local stripe_count
24520         stripe_count=$($LFS getdirstripe $stripe_dir |
24521                       awk '/lmv_stripe_count:/ { print $2 }')
24522
24523         [ $count -ne $stripe_count ] &&
24524                 error_noexit "bad stripe count $stripe_count expected $count"
24525
24526         local dupe_stripes
24527         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24528                 awk '/0x/ {count[$1] += 1}; END {
24529                         for (idx in count) {
24530                                 if (count[idx]>1) {
24531                                         print "index " idx " count " count[idx]
24532                                 }
24533                         }
24534                 }')
24535
24536         if [[ -n "$dupe_stripes" ]] ; then
24537                 lfs getdirstripe $stripe_dir
24538                 error_noexit "Dupe MDT above: $dupe_stripes "
24539         fi
24540
24541         rm -rf $stripe_dir ||
24542                 error_noexit "unlink $stripe_dir fails"
24543 }
24544
24545 test_300s() {
24546         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24547                 skip "Need MDS version at least 2.7.55" && return
24548         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24549
24550         mkdir $DIR/$tdir
24551         for count in $(seq 2 $MDSCOUNT); do
24552                 test_300s_helper $count
24553         done
24554 }
24555 run_test 300s "test lfs mkdir -c without -i"
24556
24557 test_300t() {
24558         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24559                 skip "need MDS 2.14.55 or later"
24560         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24561
24562         local testdir="$DIR/$tdir/striped_dir"
24563         local dir1=$testdir/dir1
24564         local dir2=$testdir/dir2
24565
24566         mkdir -p $testdir
24567
24568         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24569                 error "failed to set default stripe count for $testdir"
24570
24571         mkdir $dir1
24572         local stripe_count=$($LFS getdirstripe -c $dir1)
24573
24574         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24575
24576         local max_count=$((MDSCOUNT - 1))
24577         local mdts=$(comma_list $(mdts_nodes))
24578
24579         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24580         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24581
24582         mkdir $dir2
24583         stripe_count=$($LFS getdirstripe -c $dir2)
24584
24585         (( $stripe_count == $max_count )) || error "wrong stripe count"
24586 }
24587 run_test 300t "test max_mdt_stripecount"
24588
24589 prepare_remote_file() {
24590         mkdir $DIR/$tdir/src_dir ||
24591                 error "create remote source failed"
24592
24593         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24594                  error "cp to remote source failed"
24595         touch $DIR/$tdir/src_dir/a
24596
24597         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24598                 error "create remote target dir failed"
24599
24600         touch $DIR/$tdir/tgt_dir/b
24601
24602         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24603                 error "rename dir cross MDT failed!"
24604
24605         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24606                 error "src_child still exists after rename"
24607
24608         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24609                 error "missing file(a) after rename"
24610
24611         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24612                 error "diff after rename"
24613 }
24614
24615 test_310a() {
24616         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24618
24619         local remote_file=$DIR/$tdir/tgt_dir/b
24620
24621         mkdir -p $DIR/$tdir
24622
24623         prepare_remote_file || error "prepare remote file failed"
24624
24625         #open-unlink file
24626         $OPENUNLINK $remote_file $remote_file ||
24627                 error "openunlink $remote_file failed"
24628         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24629 }
24630 run_test 310a "open unlink remote file"
24631
24632 test_310b() {
24633         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24635
24636         local remote_file=$DIR/$tdir/tgt_dir/b
24637
24638         mkdir -p $DIR/$tdir
24639
24640         prepare_remote_file || error "prepare remote file failed"
24641
24642         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24643         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24644         $CHECKSTAT -t file $remote_file || error "check file failed"
24645 }
24646 run_test 310b "unlink remote file with multiple links while open"
24647
24648 test_310c() {
24649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24650         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24651
24652         local remote_file=$DIR/$tdir/tgt_dir/b
24653
24654         mkdir -p $DIR/$tdir
24655
24656         prepare_remote_file || error "prepare remote file failed"
24657
24658         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24659         multiop_bg_pause $remote_file O_uc ||
24660                         error "mulitop failed for remote file"
24661         MULTIPID=$!
24662         $MULTIOP $DIR/$tfile Ouc
24663         kill -USR1 $MULTIPID
24664         wait $MULTIPID
24665 }
24666 run_test 310c "open-unlink remote file with multiple links"
24667
24668 #LU-4825
24669 test_311() {
24670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24671         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24672         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24673                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24674         remote_mds_nodsh && skip "remote MDS with nodsh"
24675
24676         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24677         local mdts=$(comma_list $(mdts_nodes))
24678
24679         mkdir -p $DIR/$tdir
24680         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24681         createmany -o $DIR/$tdir/$tfile. 1000
24682
24683         # statfs data is not real time, let's just calculate it
24684         old_iused=$((old_iused + 1000))
24685
24686         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24687                         osp.*OST0000*MDT0000.create_count")
24688         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24689                                 osp.*OST0000*MDT0000.max_create_count")
24690         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24691
24692         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24693         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24694         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24695
24696         unlinkmany $DIR/$tdir/$tfile. 1000
24697
24698         do_nodes $mdts "$LCTL set_param -n \
24699                         osp.*OST0000*.max_create_count=$max_count"
24700         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24701                 do_nodes $mdts "$LCTL set_param -n \
24702                                 osp.*OST0000*.create_count=$count"
24703         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24704                         grep "=0" && error "create_count is zero"
24705
24706         local new_iused
24707         for i in $(seq 120); do
24708                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24709                 # system may be too busy to destroy all objs in time, use
24710                 # a somewhat small value to not fail autotest
24711                 [ $((old_iused - new_iused)) -gt 400 ] && break
24712                 sleep 1
24713         done
24714
24715         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24716         [ $((old_iused - new_iused)) -gt 400 ] ||
24717                 error "objs not destroyed after unlink"
24718 }
24719 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24720
24721 zfs_get_objid()
24722 {
24723         local ost=$1
24724         local tf=$2
24725         local fid=($($LFS getstripe $tf | grep 0x))
24726         local seq=${fid[3]#0x}
24727         local objid=${fid[1]}
24728
24729         local vdevdir=$(dirname $(facet_vdevice $ost))
24730         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24731         local zfs_zapid=$(do_facet $ost $cmd |
24732                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24733                           awk '/Object/{getline; print $1}')
24734         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24735                           awk "/$objid = /"'{printf $3}')
24736
24737         echo $zfs_objid
24738 }
24739
24740 zfs_object_blksz() {
24741         local ost=$1
24742         local objid=$2
24743
24744         local vdevdir=$(dirname $(facet_vdevice $ost))
24745         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24746         local blksz=$(do_facet $ost $cmd $objid |
24747                       awk '/dblk/{getline; printf $4}')
24748
24749         case "${blksz: -1}" in
24750                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24751                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24752                 *) ;;
24753         esac
24754
24755         echo $blksz
24756 }
24757
24758 test_312() { # LU-4856
24759         remote_ost_nodsh && skip "remote OST with nodsh"
24760         [ "$ost1_FSTYPE" = "zfs" ] ||
24761                 skip_env "the test only applies to zfs"
24762
24763         local max_blksz=$(do_facet ost1 \
24764                           $ZFS get -p recordsize $(facet_device ost1) |
24765                           awk '!/VALUE/{print $3}')
24766         local tf=$DIR/$tfile
24767
24768         $LFS setstripe -c1 $tf
24769         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
24770
24771         # Get ZFS object id
24772         local zfs_objid=$(zfs_get_objid $facet $tf)
24773         # block size change by sequential overwrite
24774         local bs
24775
24776         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24777                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24778
24779                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
24780                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
24781         done
24782         rm -f $tf
24783
24784         $LFS setstripe -c1 $tf
24785         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24786
24787         # block size change by sequential append write
24788         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24789         zfs_objid=$(zfs_get_objid $facet $tf)
24790         local count
24791
24792         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24793                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24794                         oflag=sync conv=notrunc
24795
24796                 blksz=$(zfs_object_blksz $facet $zfs_objid)
24797                 (( $blksz == 2 * count * PAGE_SIZE )) ||
24798                         error "blksz error, actual $blksz, " \
24799                                 "expected: 2 * $count * $PAGE_SIZE"
24800         done
24801         rm -f $tf
24802
24803         # random write
24804         $LFS setstripe -c1 $tf
24805         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24806         zfs_objid=$(zfs_get_objid $facet $tf)
24807
24808         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24809         blksz=$(zfs_object_blksz $facet $zfs_objid)
24810         (( blksz == PAGE_SIZE )) ||
24811                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24812
24813         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24814         blksz=$(zfs_object_blksz $facet $zfs_objid)
24815         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
24816
24817         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24818         blksz=$(zfs_object_blksz $facet $zfs_objid)
24819         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
24820 }
24821 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24822
24823 test_313() {
24824         remote_ost_nodsh && skip "remote OST with nodsh"
24825
24826         local file=$DIR/$tfile
24827
24828         rm -f $file
24829         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24830
24831         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24832         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24833         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24834                 error "write should failed"
24835         do_facet ost1 "$LCTL set_param fail_loc=0"
24836         rm -f $file
24837 }
24838 run_test 313 "io should fail after last_rcvd update fail"
24839
24840 test_314() {
24841         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24842
24843         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24844         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24845         rm -f $DIR/$tfile
24846         wait_delete_completed
24847         do_facet ost1 "$LCTL set_param fail_loc=0"
24848 }
24849 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24850
24851 test_315() { # LU-618
24852         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24853
24854         local file=$DIR/$tfile
24855         rm -f $file
24856
24857         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24858                 error "multiop file write failed"
24859         $MULTIOP $file oO_RDONLY:r4063232_c &
24860         PID=$!
24861
24862         sleep 2
24863
24864         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24865         kill -USR1 $PID
24866
24867         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24868         rm -f $file
24869 }
24870 run_test 315 "read should be accounted"
24871
24872 test_316() {
24873         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24874         large_xattr_enabled || skip "ea_inode feature disabled"
24875
24876         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24877         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24878         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24879         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24880
24881         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24882 }
24883 run_test 316 "lfs migrate of file with large_xattr enabled"
24884
24885 test_317() {
24886         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24887                 skip "Need MDS version at least 2.11.53"
24888         if [ "$ost1_FSTYPE" == "zfs" ]; then
24889                 skip "LU-10370: no implementation for ZFS"
24890         fi
24891
24892         local trunc_sz
24893         local grant_blk_size
24894
24895         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24896                         awk '/grant_block_size:/ { print $2; exit; }')
24897         #
24898         # Create File of size 5M. Truncate it to below size's and verify
24899         # blocks count.
24900         #
24901         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24902                 error "Create file $DIR/$tfile failed"
24903         stack_trap "rm -f $DIR/$tfile" EXIT
24904
24905         for trunc_sz in 2097152 4097 4000 509 0; do
24906                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24907                         error "truncate $tfile to $trunc_sz failed"
24908                 local sz=$(stat --format=%s $DIR/$tfile)
24909                 local blk=$(stat --format=%b $DIR/$tfile)
24910                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24911                                      grant_blk_size) * 8))
24912
24913                 if [[ $blk -ne $trunc_blk ]]; then
24914                         $(which stat) $DIR/$tfile
24915                         error "Expected Block $trunc_blk got $blk for $tfile"
24916                 fi
24917
24918                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24919                         error "Expected Size $trunc_sz got $sz for $tfile"
24920         done
24921
24922         #
24923         # sparse file test
24924         # Create file with a hole and write actual 65536 bytes which aligned
24925         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24926         #
24927         local bs=65536
24928         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24929                 error "Create file : $DIR/$tfile"
24930
24931         #
24932         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24933         # blocks. The block count must drop to 8.
24934         #
24935         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24936                 ((bs - grant_blk_size) + 1)))
24937         $TRUNCATE $DIR/$tfile $trunc_sz ||
24938                 error "truncate $tfile to $trunc_sz failed"
24939
24940         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24941         sz=$(stat --format=%s $DIR/$tfile)
24942         blk=$(stat --format=%b $DIR/$tfile)
24943
24944         if [[ $blk -ne $trunc_bsz ]]; then
24945                 $(which stat) $DIR/$tfile
24946                 error "Expected Block $trunc_bsz got $blk for $tfile"
24947         fi
24948
24949         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24950                 error "Expected Size $trunc_sz got $sz for $tfile"
24951 }
24952 run_test 317 "Verify blocks get correctly update after truncate"
24953
24954 test_318() {
24955         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24956         local old_max_active=$($LCTL get_param -n \
24957                             ${llite_name}.max_read_ahead_async_active \
24958                             2>/dev/null)
24959
24960         $LCTL set_param llite.*.max_read_ahead_async_active=256
24961         local max_active=$($LCTL get_param -n \
24962                            ${llite_name}.max_read_ahead_async_active \
24963                            2>/dev/null)
24964         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24965
24966         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24967                 error "set max_read_ahead_async_active should succeed"
24968
24969         $LCTL set_param llite.*.max_read_ahead_async_active=512
24970         max_active=$($LCTL get_param -n \
24971                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24972         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24973
24974         # restore @max_active
24975         [ $old_max_active -ne 0 ] && $LCTL set_param \
24976                 llite.*.max_read_ahead_async_active=$old_max_active
24977
24978         local old_threshold=$($LCTL get_param -n \
24979                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24980         local max_per_file_mb=$($LCTL get_param -n \
24981                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24982
24983         local invalid=$(($max_per_file_mb + 1))
24984         $LCTL set_param \
24985                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24986                         && error "set $invalid should fail"
24987
24988         local valid=$(($invalid - 1))
24989         $LCTL set_param \
24990                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24991                         error "set $valid should succeed"
24992         local threshold=$($LCTL get_param -n \
24993                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24994         [ $threshold -eq $valid ] || error \
24995                 "expect threshold $valid got $threshold"
24996         $LCTL set_param \
24997                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24998 }
24999 run_test 318 "Verify async readahead tunables"
25000
25001 test_319() {
25002         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25003
25004         local before=$(date +%s)
25005         local evict
25006         local mdir=$DIR/$tdir
25007         local file=$mdir/xxx
25008
25009         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25010         touch $file
25011
25012 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25013         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25014         $LFS migrate -m1 $mdir &
25015
25016         sleep 1
25017         dd if=$file of=/dev/null
25018         wait
25019         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25020           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25021
25022         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25023 }
25024 run_test 319 "lost lease lock on migrate error"
25025
25026 test_398a() { # LU-4198
25027         local ost1_imp=$(get_osc_import_name client ost1)
25028         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25029                          cut -d'.' -f2)
25030
25031         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25032         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25033
25034         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25035         # request a new lock on client
25036         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25037
25038         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25039         #local lock_count=$($LCTL get_param -n \
25040         #                  ldlm.namespaces.$imp_name.lru_size)
25041         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25042
25043         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25044
25045         # no lock cached, should use lockless DIO and not enqueue new lock
25046         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25047                 conv=notrunc ||
25048                 error "dio write failed"
25049         lock_count=$($LCTL get_param -n \
25050                      ldlm.namespaces.$imp_name.lru_size)
25051         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25052
25053         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25054
25055         # no lock cached, should use locked DIO append
25056         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25057                 conv=notrunc || error "DIO append failed"
25058         lock_count=$($LCTL get_param -n \
25059                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25060         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25061 }
25062 run_test 398a "direct IO should cancel lock otherwise lockless"
25063
25064 test_398b() { # LU-4198
25065         which fio || skip_env "no fio installed"
25066         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25067
25068         local size=48
25069         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25070
25071         local njobs=4
25072         # Single page, multiple pages, stripe size, 4*stripe size
25073         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25074                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25075                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25076                         --numjobs=$njobs --fallocate=none \
25077                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25078                         --filename=$DIR/$tfile &
25079                 bg_pid=$!
25080
25081                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25082                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25083                         --numjobs=$njobs --fallocate=none \
25084                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25085                         --filename=$DIR/$tfile || true
25086                 wait $bg_pid
25087         done
25088
25089         evict=$(do_facet client $LCTL get_param \
25090                 osc.$FSNAME-OST*-osc-*/state |
25091             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25092
25093         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25094                 (do_facet client $LCTL get_param \
25095                         osc.$FSNAME-OST*-osc-*/state;
25096                     error "eviction happened: $evict before:$before")
25097
25098         rm -f $DIR/$tfile
25099 }
25100 run_test 398b "DIO and buffer IO race"
25101
25102 test_398c() { # LU-4198
25103         local ost1_imp=$(get_osc_import_name client ost1)
25104         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25105                          cut -d'.' -f2)
25106
25107         which fio || skip_env "no fio installed"
25108
25109         saved_debug=$($LCTL get_param -n debug)
25110         $LCTL set_param debug=0
25111
25112         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25113         ((size /= 1024)) # by megabytes
25114         ((size /= 2)) # write half of the OST at most
25115         [ $size -gt 40 ] && size=40 #reduce test time anyway
25116
25117         $LFS setstripe -c 1 $DIR/$tfile
25118
25119         # it seems like ldiskfs reserves more space than necessary if the
25120         # writing blocks are not mapped, so it extends the file firstly
25121         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25122         cancel_lru_locks osc
25123
25124         # clear and verify rpc_stats later
25125         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25126
25127         local njobs=4
25128         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25129         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25130                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25131                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25132                 --filename=$DIR/$tfile
25133         [ $? -eq 0 ] || error "fio write error"
25134
25135         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25136                 error "Locks were requested while doing AIO"
25137
25138         # get the percentage of 1-page I/O
25139         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25140                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25141                 awk '{print $7}')
25142         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25143
25144         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25145         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25146                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25147                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25148                 --filename=$DIR/$tfile
25149         [ $? -eq 0 ] || error "fio mixed read write error"
25150
25151         echo "AIO with large block size ${size}M"
25152         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25153                 --numjobs=1 --fallocate=none --ioengine=libaio \
25154                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25155                 --filename=$DIR/$tfile
25156         [ $? -eq 0 ] || error "fio large block size failed"
25157
25158         rm -f $DIR/$tfile
25159         $LCTL set_param debug="$saved_debug"
25160 }
25161 run_test 398c "run fio to test AIO"
25162
25163 test_398d() { #  LU-13846
25164         which aiocp || skip_env "no aiocp installed"
25165         local aio_file=$DIR/$tfile.aio
25166
25167         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25168
25169         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25170         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25171         stack_trap "rm -f $DIR/$tfile $aio_file"
25172
25173         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25174
25175         # make sure we don't crash and fail properly
25176         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25177                 error "aio not aligned with PAGE SIZE should fail"
25178
25179         rm -f $DIR/$tfile $aio_file
25180 }
25181 run_test 398d "run aiocp to verify block size > stripe size"
25182
25183 test_398e() {
25184         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25185         touch $DIR/$tfile.new
25186         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25187 }
25188 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25189
25190 test_398f() { #  LU-14687
25191         which aiocp || skip_env "no aiocp installed"
25192         local aio_file=$DIR/$tfile.aio
25193
25194         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25195
25196         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25197         stack_trap "rm -f $DIR/$tfile $aio_file"
25198
25199         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25200         $LCTL set_param fail_loc=0x1418
25201         # make sure we don't crash and fail properly
25202         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25203                 error "aio with page allocation failure succeeded"
25204         $LCTL set_param fail_loc=0
25205         diff $DIR/$tfile $aio_file
25206         [[ $? != 0 ]] || error "no diff after failed aiocp"
25207 }
25208 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25209
25210 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25211 # stripe and i/o size must be > stripe size
25212 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25213 # single RPC in flight.  This test shows async DIO submission is working by
25214 # showing multiple RPCs in flight.
25215 test_398g() { #  LU-13798
25216         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25217
25218         # We need to do some i/o first to acquire enough grant to put our RPCs
25219         # in flight; otherwise a new connection may not have enough grant
25220         # available
25221         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25222                 error "parallel dio failed"
25223         stack_trap "rm -f $DIR/$tfile"
25224
25225         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25226         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25227         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25228         stack_trap "$LCTL set_param -n $pages_per_rpc"
25229
25230         # Recreate file so it's empty
25231         rm -f $DIR/$tfile
25232         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25233         #Pause rpc completion to guarantee we see multiple rpcs in flight
25234         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25235         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25236         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25237
25238         # Clear rpc stats
25239         $LCTL set_param osc.*.rpc_stats=c
25240
25241         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25242                 error "parallel dio failed"
25243         stack_trap "rm -f $DIR/$tfile"
25244
25245         $LCTL get_param osc.*-OST0000-*.rpc_stats
25246         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25247                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25248                 grep "8:" | awk '{print $8}')
25249         # We look at the "8 rpcs in flight" field, and verify A) it is present
25250         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25251         # as expected for an 8M DIO to a file with 1M stripes.
25252         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25253
25254         # Verify turning off parallel dio works as expected
25255         # Clear rpc stats
25256         $LCTL set_param osc.*.rpc_stats=c
25257         $LCTL set_param llite.*.parallel_dio=0
25258         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25259
25260         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25261                 error "dio with parallel dio disabled failed"
25262
25263         # Ideally, we would see only one RPC in flight here, but there is an
25264         # unavoidable race between i/o completion and RPC in flight counting,
25265         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25266         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25267         # So instead we just verify it's always < 8.
25268         $LCTL get_param osc.*-OST0000-*.rpc_stats
25269         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25270                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25271                 grep '^$' -B1 | grep . | awk '{print $1}')
25272         [ $ret != "8:" ] ||
25273                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25274 }
25275 run_test 398g "verify parallel dio async RPC submission"
25276
25277 test_398h() { #  LU-13798
25278         local dio_file=$DIR/$tfile.dio
25279
25280         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25281
25282         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25283         stack_trap "rm -f $DIR/$tfile $dio_file"
25284
25285         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25286                 error "parallel dio failed"
25287         diff $DIR/$tfile $dio_file
25288         [[ $? == 0 ]] || error "file diff after aiocp"
25289 }
25290 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25291
25292 test_398i() { #  LU-13798
25293         local dio_file=$DIR/$tfile.dio
25294
25295         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25296
25297         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25298         stack_trap "rm -f $DIR/$tfile $dio_file"
25299
25300         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25301         $LCTL set_param fail_loc=0x1418
25302         # make sure we don't crash and fail properly
25303         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25304                 error "parallel dio page allocation failure succeeded"
25305         diff $DIR/$tfile $dio_file
25306         [[ $? != 0 ]] || error "no diff after failed aiocp"
25307 }
25308 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25309
25310 test_398j() { #  LU-13798
25311         # Stripe size > RPC size but less than i/o size tests split across
25312         # stripes and RPCs for individual i/o op
25313         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25314
25315         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25316         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25317         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25318         stack_trap "$LCTL set_param -n $pages_per_rpc"
25319
25320         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25321                 error "parallel dio write failed"
25322         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25323
25324         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25325                 error "parallel dio read failed"
25326         diff $DIR/$tfile $DIR/$tfile.2
25327         [[ $? == 0 ]] || error "file diff after parallel dio read"
25328 }
25329 run_test 398j "test parallel dio where stripe size > rpc_size"
25330
25331 test_398k() { #  LU-13798
25332         wait_delete_completed
25333         wait_mds_ost_sync
25334
25335         # 4 stripe file; we will cause out of space on OST0
25336         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25337
25338         # Fill OST0 (if it's not too large)
25339         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25340                    head -n1)
25341         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25342                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25343         fi
25344         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25345         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25346                 error "dd should fill OST0"
25347         stack_trap "rm -f $DIR/$tfile.1"
25348
25349         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25350         err=$?
25351
25352         ls -la $DIR/$tfile
25353         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25354                 error "file is not 0 bytes in size"
25355
25356         # dd above should not succeed, but don't error until here so we can
25357         # get debug info above
25358         [[ $err != 0 ]] ||
25359                 error "parallel dio write with enospc succeeded"
25360         stack_trap "rm -f $DIR/$tfile"
25361 }
25362 run_test 398k "test enospc on first stripe"
25363
25364 test_398l() { #  LU-13798
25365         wait_delete_completed
25366         wait_mds_ost_sync
25367
25368         # 4 stripe file; we will cause out of space on OST0
25369         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25370         # happens on the second i/o chunk we issue
25371         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25372
25373         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25374         stack_trap "rm -f $DIR/$tfile"
25375
25376         # Fill OST0 (if it's not too large)
25377         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25378                    head -n1)
25379         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25380                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25381         fi
25382         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25383         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25384                 error "dd should fill OST0"
25385         stack_trap "rm -f $DIR/$tfile.1"
25386
25387         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25388         err=$?
25389         stack_trap "rm -f $DIR/$tfile.2"
25390
25391         # Check that short write completed as expected
25392         ls -la $DIR/$tfile.2
25393         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25394                 error "file is not 1M in size"
25395
25396         # dd above should not succeed, but don't error until here so we can
25397         # get debug info above
25398         [[ $err != 0 ]] ||
25399                 error "parallel dio write with enospc succeeded"
25400
25401         # Truncate source file to same length as output file and diff them
25402         $TRUNCATE $DIR/$tfile 1048576
25403         diff $DIR/$tfile $DIR/$tfile.2
25404         [[ $? == 0 ]] || error "data incorrect after short write"
25405 }
25406 run_test 398l "test enospc on intermediate stripe/RPC"
25407
25408 test_398m() { #  LU-13798
25409         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25410
25411         # Set up failure on OST0, the first stripe:
25412         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25413         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25414         # OST0 is on ost1, OST1 is on ost2.
25415         # So this fail_val specifies OST0
25416         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25417         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25418
25419         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25420                 error "parallel dio write with failure on first stripe succeeded"
25421         stack_trap "rm -f $DIR/$tfile"
25422         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25423
25424         # Place data in file for read
25425         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25426                 error "parallel dio write failed"
25427
25428         # Fail read on OST0, first stripe
25429         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25430         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25431         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25432                 error "parallel dio read with error on first stripe succeeded"
25433         rm -f $DIR/$tfile.2
25434         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25435
25436         # Switch to testing on OST1, second stripe
25437         # Clear file contents, maintain striping
25438         echo > $DIR/$tfile
25439         # Set up failure on OST1, second stripe:
25440         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25441         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25442
25443         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25444                 error "parallel dio write with failure on second stripe succeeded"
25445         stack_trap "rm -f $DIR/$tfile"
25446         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25447
25448         # Place data in file for read
25449         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25450                 error "parallel dio write failed"
25451
25452         # Fail read on OST1, second stripe
25453         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25454         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25455         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25456                 error "parallel dio read with error on second stripe succeeded"
25457         rm -f $DIR/$tfile.2
25458         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25459 }
25460 run_test 398m "test RPC failures with parallel dio"
25461
25462 # Parallel submission of DIO should not cause problems for append, but it's
25463 # important to verify.
25464 test_398n() { #  LU-13798
25465         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25466
25467         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25468                 error "dd to create source file failed"
25469         stack_trap "rm -f $DIR/$tfile"
25470
25471         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25472                 error "parallel dio write with failure on second stripe succeeded"
25473         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25474         diff $DIR/$tfile $DIR/$tfile.1
25475         [[ $? == 0 ]] || error "data incorrect after append"
25476
25477 }
25478 run_test 398n "test append with parallel DIO"
25479
25480 test_398o() {
25481         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25482 }
25483 run_test 398o "right kms with DIO"
25484
25485 test_fake_rw() {
25486         local read_write=$1
25487         if [ "$read_write" = "write" ]; then
25488                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25489         elif [ "$read_write" = "read" ]; then
25490                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25491         else
25492                 error "argument error"
25493         fi
25494
25495         # turn off debug for performance testing
25496         local saved_debug=$($LCTL get_param -n debug)
25497         $LCTL set_param debug=0
25498
25499         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25500
25501         # get ost1 size - $FSNAME-OST0000
25502         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25503         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25504         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25505
25506         if [ "$read_write" = "read" ]; then
25507                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25508         fi
25509
25510         local start_time=$(date +%s.%N)
25511         $dd_cmd bs=1M count=$blocks oflag=sync ||
25512                 error "real dd $read_write error"
25513         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25514
25515         if [ "$read_write" = "write" ]; then
25516                 rm -f $DIR/$tfile
25517         fi
25518
25519         # define OBD_FAIL_OST_FAKE_RW           0x238
25520         do_facet ost1 $LCTL set_param fail_loc=0x238
25521
25522         local start_time=$(date +%s.%N)
25523         $dd_cmd bs=1M count=$blocks oflag=sync ||
25524                 error "fake dd $read_write error"
25525         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25526
25527         if [ "$read_write" = "write" ]; then
25528                 # verify file size
25529                 cancel_lru_locks osc
25530                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25531                         error "$tfile size not $blocks MB"
25532         fi
25533         do_facet ost1 $LCTL set_param fail_loc=0
25534
25535         echo "fake $read_write $duration_fake vs. normal $read_write" \
25536                 "$duration in seconds"
25537         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25538                 error_not_in_vm "fake write is slower"
25539
25540         $LCTL set_param -n debug="$saved_debug"
25541         rm -f $DIR/$tfile
25542 }
25543 test_399a() { # LU-7655 for OST fake write
25544         remote_ost_nodsh && skip "remote OST with nodsh"
25545
25546         test_fake_rw write
25547 }
25548 run_test 399a "fake write should not be slower than normal write"
25549
25550 test_399b() { # LU-8726 for OST fake read
25551         remote_ost_nodsh && skip "remote OST with nodsh"
25552         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25553                 skip_env "ldiskfs only test"
25554         fi
25555
25556         test_fake_rw read
25557 }
25558 run_test 399b "fake read should not be slower than normal read"
25559
25560 test_400a() { # LU-1606, was conf-sanity test_74
25561         if ! which $CC > /dev/null 2>&1; then
25562                 skip_env "$CC is not installed"
25563         fi
25564
25565         local extra_flags=''
25566         local out=$TMP/$tfile
25567         local prefix=/usr/include/lustre
25568         local prog
25569
25570         # Oleg removes .c files in his test rig so test if any c files exist
25571         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25572                 skip_env "Needed .c test files are missing"
25573
25574         if ! [[ -d $prefix ]]; then
25575                 # Assume we're running in tree and fixup the include path.
25576                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25577                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25578                 extra_flags+=" -L$LUSTRE/utils/.libs"
25579         fi
25580
25581         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25582                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25583                         error "client api broken"
25584         done
25585         rm -f $out
25586 }
25587 run_test 400a "Lustre client api program can compile and link"
25588
25589 test_400b() { # LU-1606, LU-5011
25590         local header
25591         local out=$TMP/$tfile
25592         local prefix=/usr/include/linux/lustre
25593
25594         # We use a hard coded prefix so that this test will not fail
25595         # when run in tree. There are headers in lustre/include/lustre/
25596         # that are not packaged (like lustre_idl.h) and have more
25597         # complicated include dependencies (like config.h and lnet/types.h).
25598         # Since this test about correct packaging we just skip them when
25599         # they don't exist (see below) rather than try to fixup cppflags.
25600
25601         if ! which $CC > /dev/null 2>&1; then
25602                 skip_env "$CC is not installed"
25603         fi
25604
25605         for header in $prefix/*.h; do
25606                 if ! [[ -f "$header" ]]; then
25607                         continue
25608                 fi
25609
25610                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25611                         continue # lustre_ioctl.h is internal header
25612                 fi
25613
25614                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25615                         error "cannot compile '$header'"
25616         done
25617         rm -f $out
25618 }
25619 run_test 400b "packaged headers can be compiled"
25620
25621 test_401a() { #LU-7437
25622         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25623         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25624
25625         #count the number of parameters by "list_param -R"
25626         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25627         #count the number of parameters by listing proc files
25628         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25629         echo "proc_dirs='$proc_dirs'"
25630         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25631         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25632                       sort -u | wc -l)
25633
25634         [ $params -eq $procs ] ||
25635                 error "found $params parameters vs. $procs proc files"
25636
25637         # test the list_param -D option only returns directories
25638         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25639         #count the number of parameters by listing proc directories
25640         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25641                 sort -u | wc -l)
25642
25643         [ $params -eq $procs ] ||
25644                 error "found $params parameters vs. $procs proc files"
25645 }
25646 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25647
25648 test_401b() {
25649         # jobid_var may not allow arbitrary values, so use jobid_name
25650         # if available
25651         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25652                 local testname=jobid_name tmp='testing%p'
25653         else
25654                 local testname=jobid_var tmp=testing
25655         fi
25656
25657         local save=$($LCTL get_param -n $testname)
25658
25659         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25660                 error "no error returned when setting bad parameters"
25661
25662         local jobid_new=$($LCTL get_param -n foe $testname baz)
25663         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25664
25665         $LCTL set_param -n fog=bam $testname=$save bat=fog
25666         local jobid_old=$($LCTL get_param -n foe $testname bag)
25667         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25668 }
25669 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25670
25671 test_401c() {
25672         # jobid_var may not allow arbitrary values, so use jobid_name
25673         # if available
25674         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25675                 local testname=jobid_name
25676         else
25677                 local testname=jobid_var
25678         fi
25679
25680         local jobid_var_old=$($LCTL get_param -n $testname)
25681         local jobid_var_new
25682
25683         $LCTL set_param $testname= &&
25684                 error "no error returned for 'set_param a='"
25685
25686         jobid_var_new=$($LCTL get_param -n $testname)
25687         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25688                 error "$testname was changed by setting without value"
25689
25690         $LCTL set_param $testname &&
25691                 error "no error returned for 'set_param a'"
25692
25693         jobid_var_new=$($LCTL get_param -n $testname)
25694         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25695                 error "$testname was changed by setting without value"
25696 }
25697 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25698
25699 test_401d() {
25700         # jobid_var may not allow arbitrary values, so use jobid_name
25701         # if available
25702         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25703                 local testname=jobid_name new_value='foo=bar%p'
25704         else
25705                 local testname=jobid_var new_valuie=foo=bar
25706         fi
25707
25708         local jobid_var_old=$($LCTL get_param -n $testname)
25709         local jobid_var_new
25710
25711         $LCTL set_param $testname=$new_value ||
25712                 error "'set_param a=b' did not accept a value containing '='"
25713
25714         jobid_var_new=$($LCTL get_param -n $testname)
25715         [[ "$jobid_var_new" == "$new_value" ]] ||
25716                 error "'set_param a=b' failed on a value containing '='"
25717
25718         # Reset the $testname to test the other format
25719         $LCTL set_param $testname=$jobid_var_old
25720         jobid_var_new=$($LCTL get_param -n $testname)
25721         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25722                 error "failed to reset $testname"
25723
25724         $LCTL set_param $testname $new_value ||
25725                 error "'set_param a b' did not accept a value containing '='"
25726
25727         jobid_var_new=$($LCTL get_param -n $testname)
25728         [[ "$jobid_var_new" == "$new_value" ]] ||
25729                 error "'set_param a b' failed on a value containing '='"
25730
25731         $LCTL set_param $testname $jobid_var_old
25732         jobid_var_new=$($LCTL get_param -n $testname)
25733         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25734                 error "failed to reset $testname"
25735 }
25736 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25737
25738 test_401e() { # LU-14779
25739         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25740                 error "lctl list_param MGC* failed"
25741         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25742         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25743                 error "lctl get_param lru_size failed"
25744 }
25745 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25746
25747 test_402() {
25748         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25749         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25750                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25751         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25752                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25753                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25754         remote_mds_nodsh && skip "remote MDS with nodsh"
25755
25756         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25757 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25758         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25759         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25760                 echo "Touch failed - OK"
25761 }
25762 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25763
25764 test_403() {
25765         local file1=$DIR/$tfile.1
25766         local file2=$DIR/$tfile.2
25767         local tfile=$TMP/$tfile
25768
25769         rm -f $file1 $file2 $tfile
25770
25771         touch $file1
25772         ln $file1 $file2
25773
25774         # 30 sec OBD_TIMEOUT in ll_getattr()
25775         # right before populating st_nlink
25776         $LCTL set_param fail_loc=0x80001409
25777         stat -c %h $file1 > $tfile &
25778
25779         # create an alias, drop all locks and reclaim the dentry
25780         < $file2
25781         cancel_lru_locks mdc
25782         cancel_lru_locks osc
25783         sysctl -w vm.drop_caches=2
25784
25785         wait
25786
25787         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25788
25789         rm -f $tfile $file1 $file2
25790 }
25791 run_test 403 "i_nlink should not drop to zero due to aliasing"
25792
25793 test_404() { # LU-6601
25794         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25795                 skip "Need server version newer than 2.8.52"
25796         remote_mds_nodsh && skip "remote MDS with nodsh"
25797
25798         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25799                 awk '/osp .*-osc-MDT/ { print $4}')
25800
25801         local osp
25802         for osp in $mosps; do
25803                 echo "Deactivate: " $osp
25804                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25805                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25806                         awk -vp=$osp '$4 == p { print $2 }')
25807                 [ $stat = IN ] || {
25808                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25809                         error "deactivate error"
25810                 }
25811                 echo "Activate: " $osp
25812                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25813                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25814                         awk -vp=$osp '$4 == p { print $2 }')
25815                 [ $stat = UP ] || {
25816                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25817                         error "activate error"
25818                 }
25819         done
25820 }
25821 run_test 404 "validate manual {de}activated works properly for OSPs"
25822
25823 test_405() {
25824         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25825         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25826                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25827                         skip "Layout swap lock is not supported"
25828
25829         check_swap_layouts_support
25830         check_swap_layout_no_dom $DIR
25831
25832         test_mkdir $DIR/$tdir
25833         swap_lock_test -d $DIR/$tdir ||
25834                 error "One layout swap locked test failed"
25835 }
25836 run_test 405 "Various layout swap lock tests"
25837
25838 test_406() {
25839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25840         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25841         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25843         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25844                 skip "Need MDS version at least 2.8.50"
25845
25846         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25847         local test_pool=$TESTNAME
25848
25849         pool_add $test_pool || error "pool_add failed"
25850         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25851                 error "pool_add_targets failed"
25852
25853         save_layout_restore_at_exit $MOUNT
25854
25855         # parent set default stripe count only, child will stripe from both
25856         # parent and fs default
25857         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25858                 error "setstripe $MOUNT failed"
25859         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25860         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25861         for i in $(seq 10); do
25862                 local f=$DIR/$tdir/$tfile.$i
25863                 touch $f || error "touch failed"
25864                 local count=$($LFS getstripe -c $f)
25865                 [ $count -eq $OSTCOUNT ] ||
25866                         error "$f stripe count $count != $OSTCOUNT"
25867                 local offset=$($LFS getstripe -i $f)
25868                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25869                 local size=$($LFS getstripe -S $f)
25870                 [ $size -eq $((def_stripe_size * 2)) ] ||
25871                         error "$f stripe size $size != $((def_stripe_size * 2))"
25872                 local pool=$($LFS getstripe -p $f)
25873                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25874         done
25875
25876         # change fs default striping, delete parent default striping, now child
25877         # will stripe from new fs default striping only
25878         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25879                 error "change $MOUNT default stripe failed"
25880         $LFS setstripe -c 0 $DIR/$tdir ||
25881                 error "delete $tdir default stripe failed"
25882         for i in $(seq 11 20); do
25883                 local f=$DIR/$tdir/$tfile.$i
25884                 touch $f || error "touch $f failed"
25885                 local count=$($LFS getstripe -c $f)
25886                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25887                 local offset=$($LFS getstripe -i $f)
25888                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25889                 local size=$($LFS getstripe -S $f)
25890                 [ $size -eq $def_stripe_size ] ||
25891                         error "$f stripe size $size != $def_stripe_size"
25892                 local pool=$($LFS getstripe -p $f)
25893                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25894         done
25895
25896         unlinkmany $DIR/$tdir/$tfile. 1 20
25897
25898         local f=$DIR/$tdir/$tfile
25899         pool_remove_all_targets $test_pool $f
25900         pool_remove $test_pool $f
25901 }
25902 run_test 406 "DNE support fs default striping"
25903
25904 test_407() {
25905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25906         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25907                 skip "Need MDS version at least 2.8.55"
25908         remote_mds_nodsh && skip "remote MDS with nodsh"
25909
25910         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25911                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25912         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25913                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25914         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25915
25916         #define OBD_FAIL_DT_TXN_STOP    0x2019
25917         for idx in $(seq $MDSCOUNT); do
25918                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25919         done
25920         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25921         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25922                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25923         true
25924 }
25925 run_test 407 "transaction fail should cause operation fail"
25926
25927 test_408() {
25928         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25929
25930         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25931         lctl set_param fail_loc=0x8000040a
25932         # let ll_prepare_partial_page() fail
25933         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25934
25935         rm -f $DIR/$tfile
25936
25937         # create at least 100 unused inodes so that
25938         # shrink_icache_memory(0) should not return 0
25939         touch $DIR/$tfile-{0..100}
25940         rm -f $DIR/$tfile-{0..100}
25941         sync
25942
25943         echo 2 > /proc/sys/vm/drop_caches
25944 }
25945 run_test 408 "drop_caches should not hang due to page leaks"
25946
25947 test_409()
25948 {
25949         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25950
25951         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25952         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25953         touch $DIR/$tdir/guard || error "(2) Fail to create"
25954
25955         local PREFIX=$(str_repeat 'A' 128)
25956         echo "Create 1K hard links start at $(date)"
25957         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25958                 error "(3) Fail to hard link"
25959
25960         echo "Links count should be right although linkEA overflow"
25961         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25962         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25963         [ $linkcount -eq 1001 ] ||
25964                 error "(5) Unexpected hard links count: $linkcount"
25965
25966         echo "List all links start at $(date)"
25967         ls -l $DIR/$tdir/foo > /dev/null ||
25968                 error "(6) Fail to list $DIR/$tdir/foo"
25969
25970         echo "Unlink hard links start at $(date)"
25971         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25972                 error "(7) Fail to unlink"
25973         echo "Unlink hard links finished at $(date)"
25974 }
25975 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25976
25977 test_410()
25978 {
25979         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25980                 skip "Need client version at least 2.9.59"
25981         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25982                 skip "Need MODULES build"
25983
25984         # Create a file, and stat it from the kernel
25985         local testfile=$DIR/$tfile
25986         touch $testfile
25987
25988         local run_id=$RANDOM
25989         local my_ino=$(stat --format "%i" $testfile)
25990
25991         # Try to insert the module. This will always fail as the
25992         # module is designed to not be inserted.
25993         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25994             &> /dev/null
25995
25996         # Anything but success is a test failure
25997         dmesg | grep -q \
25998             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25999             error "no inode match"
26000 }
26001 run_test 410 "Test inode number returned from kernel thread"
26002
26003 cleanup_test411_cgroup() {
26004         trap 0
26005         rmdir "$1"
26006 }
26007
26008 test_411() {
26009         local cg_basedir=/sys/fs/cgroup/memory
26010         # LU-9966
26011         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26012                 skip "no setup for cgroup"
26013
26014         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26015                 error "test file creation failed"
26016         cancel_lru_locks osc
26017
26018         # Create a very small memory cgroup to force a slab allocation error
26019         local cgdir=$cg_basedir/osc_slab_alloc
26020         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26021         trap "cleanup_test411_cgroup $cgdir" EXIT
26022         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26023         echo 1M > $cgdir/memory.limit_in_bytes
26024
26025         # Should not LBUG, just be killed by oom-killer
26026         # dd will return 0 even allocation failure in some environment.
26027         # So don't check return value
26028         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26029         cleanup_test411_cgroup $cgdir
26030
26031         return 0
26032 }
26033 run_test 411 "Slab allocation error with cgroup does not LBUG"
26034
26035 test_412() {
26036         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26037         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26038                 skip "Need server version at least 2.10.55"
26039
26040         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26041                 error "mkdir failed"
26042         $LFS getdirstripe $DIR/$tdir
26043         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26044         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26045                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26046         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26047         [ $stripe_count -eq 2 ] ||
26048                 error "expect 2 get $stripe_count"
26049
26050         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26051
26052         local index
26053         local index2
26054
26055         # subdirs should be on the same MDT as parent
26056         for i in $(seq 0 $((MDSCOUNT - 1))); do
26057                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26058                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26059                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26060                 (( index == i )) || error "mdt$i/sub on MDT$index"
26061         done
26062
26063         # stripe offset -1, ditto
26064         for i in {1..10}; do
26065                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26066                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26067                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26068                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26069                 (( index == index2 )) ||
26070                         error "qos$i on MDT$index, sub on MDT$index2"
26071         done
26072
26073         local testdir=$DIR/$tdir/inherit
26074
26075         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26076         # inherit 2 levels
26077         for i in 1 2; do
26078                 testdir=$testdir/s$i
26079                 mkdir $testdir || error "mkdir $testdir failed"
26080                 index=$($LFS getstripe -m $testdir)
26081                 (( index == 1 )) ||
26082                         error "$testdir on MDT$index"
26083         done
26084
26085         # not inherit any more
26086         testdir=$testdir/s3
26087         mkdir $testdir || error "mkdir $testdir failed"
26088         getfattr -d -m dmv $testdir | grep dmv &&
26089                 error "default LMV set on $testdir" || true
26090 }
26091 run_test 412 "mkdir on specific MDTs"
26092
26093 TEST413_COUNT=${TEST413_COUNT:-200}
26094 generate_uneven_mdts() {
26095         local threshold=$1
26096         local lmv_qos_maxage
26097         local lod_qos_maxage
26098         local ffree
26099         local bavail
26100         local max
26101         local min
26102         local max_index
26103         local min_index
26104         local tmp
26105         local i
26106
26107         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26108         $LCTL set_param lmv.*.qos_maxage=1
26109         stack_trap "$LCTL set_param \
26110                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26111         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26112                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26113         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26114                 lod.*.mdt_qos_maxage=1
26115         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26116                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26117
26118         echo
26119         echo "Check for uneven MDTs: "
26120
26121         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26122         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26123         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26124
26125         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26126         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26127         max_index=0
26128         min_index=0
26129         for ((i = 1; i < ${#ffree[@]}; i++)); do
26130                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26131                 if [ $tmp -gt $max ]; then
26132                         max=$tmp
26133                         max_index=$i
26134                 fi
26135                 if [ $tmp -lt $min ]; then
26136                         min=$tmp
26137                         min_index=$i
26138                 fi
26139         done
26140
26141         (( ${ffree[min_index]} > 0 )) ||
26142                 skip "no free files in MDT$min_index"
26143         (( ${ffree[min_index]} < 10000000 )) ||
26144                 skip "too many free files in MDT$min_index"
26145
26146         # Check if we need to generate uneven MDTs
26147         local diff=$(((max - min) * 100 / min))
26148         local testdir=$DIR/$tdir-fillmdt
26149         local start
26150
26151         i=0
26152         while (( diff < threshold )); do
26153                 mkdir -p $testdir
26154                 # generate uneven MDTs, create till $threshold% diff
26155                 echo -n "weight diff=$diff% must be > $threshold% ..."
26156                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26157                 testdir=$DIR/$tdir-fillmdt/$i
26158                 [ -d $testdir ] && continue
26159                 $LFS mkdir -i $min_index $testdir ||
26160                         error "mkdir $testdir failed"
26161                 $LFS setstripe -E 1M -L mdt $testdir ||
26162                         error "setstripe $testdir failed"
26163                 start=$SECONDS
26164                 for ((F=0; F < TEST413_COUNT; F++)); do
26165                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26166                                 /dev/null 2>&1 || error "dd $F failed"
26167                 done
26168                 sync; sleep 1; sync
26169
26170                 # wait for QOS to update
26171                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26172
26173                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26174                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26175                 max=$(((${ffree[max_index]} >> 8) *
26176                         (${bavail[max_index]} * bsize >> 16)))
26177                 min=$(((${ffree[min_index]} >> 8) *
26178                         (${bavail[min_index]} * bsize >> 16)))
26179                 diff=$(((max - min) * 100 / min))
26180                 i=$((i + 1))
26181         done
26182
26183         echo "MDT filesfree available: ${ffree[*]}"
26184         echo "MDT blocks available: ${bavail[*]}"
26185         echo "weight diff=$diff%"
26186 }
26187
26188 test_qos_mkdir() {
26189         local mkdir_cmd=$1
26190         local stripe_count=$2
26191         local mdts=$(comma_list $(mdts_nodes))
26192
26193         local testdir
26194         local lmv_qos_prio_free
26195         local lmv_qos_threshold_rr
26196         local lmv_qos_maxage
26197         local lod_qos_prio_free
26198         local lod_qos_threshold_rr
26199         local lod_qos_maxage
26200         local count
26201         local i
26202
26203         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26204         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26205         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26206                 head -n1)
26207         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26208         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26209         stack_trap "$LCTL set_param \
26210                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26211         stack_trap "$LCTL set_param \
26212                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26213         stack_trap "$LCTL set_param \
26214                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26215
26216         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26217                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26218         lod_qos_prio_free=${lod_qos_prio_free%%%}
26219         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26220                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26221         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26222         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26223                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26224         stack_trap "do_nodes $mdts $LCTL set_param \
26225                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26226         stack_trap "do_nodes $mdts $LCTL set_param \
26227                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26228         stack_trap "do_nodes $mdts $LCTL set_param \
26229                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26230
26231         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26232         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26233
26234         testdir=$DIR/$tdir-s$stripe_count/rr
26235
26236         local stripe_index=$($LFS getstripe -m $testdir)
26237         local test_mkdir_rr=true
26238
26239         getfattr -d -m dmv -e hex $testdir | grep dmv
26240         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26241                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26242                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26243                         test_mkdir_rr=false
26244         fi
26245
26246         echo
26247         $test_mkdir_rr &&
26248                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26249                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26250
26251         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26252         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26253                 eval $mkdir_cmd $testdir/subdir$i ||
26254                         error "$mkdir_cmd subdir$i failed"
26255         done
26256
26257         for (( i = 0; i < $MDSCOUNT; i++ )); do
26258                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26259                 echo "$count directories created on MDT$i"
26260                 if $test_mkdir_rr; then
26261                         (( $count == 100 )) ||
26262                                 error "subdirs are not evenly distributed"
26263                 elif (( $i == $stripe_index )); then
26264                         (( $count == 100 * MDSCOUNT )) ||
26265                                 error "$count subdirs created on MDT$i"
26266                 else
26267                         (( $count == 0 )) ||
26268                                 error "$count subdirs created on MDT$i"
26269                 fi
26270
26271                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26272                         count=$($LFS getdirstripe $testdir/* |
26273                                 grep -c -P "^\s+$i\t")
26274                         echo "$count stripes created on MDT$i"
26275                         # deviation should < 5% of average
26276                         (( $count >= 95 * stripe_count &&
26277                            $count <= 105 * stripe_count)) ||
26278                                 error "stripes are not evenly distributed"
26279                 fi
26280         done
26281
26282         echo
26283         echo "Check for uneven MDTs: "
26284
26285         local ffree
26286         local bavail
26287         local max
26288         local min
26289         local max_index
26290         local min_index
26291         local tmp
26292
26293         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26294         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26295         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26296
26297         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26298         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26299         max_index=0
26300         min_index=0
26301         for ((i = 1; i < ${#ffree[@]}; i++)); do
26302                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26303                 if [ $tmp -gt $max ]; then
26304                         max=$tmp
26305                         max_index=$i
26306                 fi
26307                 if [ $tmp -lt $min ]; then
26308                         min=$tmp
26309                         min_index=$i
26310                 fi
26311         done
26312
26313         (( ${ffree[min_index]} > 0 )) ||
26314                 skip "no free files in MDT$min_index"
26315         (( ${ffree[min_index]} < 10000000 )) ||
26316                 skip "too many free files in MDT$min_index"
26317
26318         echo "MDT filesfree available: ${ffree[*]}"
26319         echo "MDT blocks available: ${bavail[*]}"
26320         echo "weight diff=$(((max - min) * 100 / min))%"
26321         echo
26322         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26323
26324         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26325         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26326         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26327         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26328         # decrease statfs age, so that it can be updated in time
26329         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26330         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26331
26332         sleep 1
26333
26334         testdir=$DIR/$tdir-s$stripe_count/qos
26335         local num=200
26336
26337         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26338         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26339                 eval $mkdir_cmd $testdir/subdir$i ||
26340                         error "$mkdir_cmd subdir$i failed"
26341         done
26342
26343         max=0
26344         for (( i = 0; i < $MDSCOUNT; i++ )); do
26345                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26346                 (( count > max )) && max=$count
26347                 echo "$count directories created on MDT$i"
26348         done
26349
26350         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26351
26352         # D-value should > 10% of averge
26353         (( max - min > num / 10 )) ||
26354                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26355
26356         # ditto for stripes
26357         if (( stripe_count > 1 )); then
26358                 max=0
26359                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26360                         count=$($LFS getdirstripe $testdir/* |
26361                                 grep -c -P "^\s+$i\t")
26362                         (( count > max )) && max=$count
26363                         echo "$count stripes created on MDT$i"
26364                 done
26365
26366                 min=$($LFS getdirstripe $testdir/* |
26367                         grep -c -P "^\s+$min_index\t")
26368                 (( max - min > num * stripe_count / 10 )) ||
26369                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26370         fi
26371 }
26372
26373 most_full_mdt() {
26374         local ffree
26375         local bavail
26376         local bsize
26377         local min
26378         local min_index
26379         local tmp
26380
26381         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26382         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26383         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26384
26385         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26386         min_index=0
26387         for ((i = 1; i < ${#ffree[@]}; i++)); do
26388                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26389                 (( tmp < min )) && min=$tmp && min_index=$i
26390         done
26391
26392         echo -n $min_index
26393 }
26394
26395 test_413a() {
26396         [ $MDSCOUNT -lt 2 ] &&
26397                 skip "We need at least 2 MDTs for this test"
26398
26399         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26400                 skip "Need server version at least 2.12.52"
26401
26402         local stripe_count
26403
26404         generate_uneven_mdts 100
26405         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26406                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26407                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26408                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26409                         error "mkdir failed"
26410                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26411         done
26412 }
26413 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26414
26415 test_413b() {
26416         [ $MDSCOUNT -lt 2 ] &&
26417                 skip "We need at least 2 MDTs for this test"
26418
26419         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26420                 skip "Need server version at least 2.12.52"
26421
26422         local testdir
26423         local stripe_count
26424
26425         generate_uneven_mdts 100
26426         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26427                 testdir=$DIR/$tdir-s$stripe_count
26428                 mkdir $testdir || error "mkdir $testdir failed"
26429                 mkdir $testdir/rr || error "mkdir rr failed"
26430                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26431                         error "mkdir qos failed"
26432                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26433                         $testdir/rr || error "setdirstripe rr failed"
26434                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26435                         error "setdirstripe failed"
26436                 test_qos_mkdir "mkdir" $stripe_count
26437         done
26438 }
26439 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26440
26441 test_413c() {
26442         (( $MDSCOUNT >= 2 )) ||
26443                 skip "We need at least 2 MDTs for this test"
26444
26445         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26446                 skip "Need server version at least 2.14.51"
26447
26448         local testdir
26449         local inherit
26450         local inherit_rr
26451
26452         testdir=$DIR/${tdir}-s1
26453         mkdir $testdir || error "mkdir $testdir failed"
26454         mkdir $testdir/rr || error "mkdir rr failed"
26455         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26456         # default max_inherit is -1, default max_inherit_rr is 0
26457         $LFS setdirstripe -D -c 1 $testdir/rr ||
26458                 error "setdirstripe rr failed"
26459         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26460                 error "setdirstripe qos failed"
26461         test_qos_mkdir "mkdir" 1
26462
26463         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26464         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26465         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26466         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26467         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26468
26469         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26470         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26471         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26472         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26473         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26474         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26475         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26476                 error "level2 shouldn't have default LMV" || true
26477 }
26478 run_test 413c "mkdir with default LMV max inherit rr"
26479
26480 test_413d() {
26481         (( MDSCOUNT >= 2 )) ||
26482                 skip "We need at least 2 MDTs for this test"
26483
26484         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26485                 skip "Need server version at least 2.14.51"
26486
26487         local lmv_qos_threshold_rr
26488
26489         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26490                 head -n1)
26491         stack_trap "$LCTL set_param \
26492                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26493
26494         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26495         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26496         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26497                 error "$tdir shouldn't have default LMV"
26498         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26499                 error "mkdir sub failed"
26500
26501         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26502
26503         (( count == 100 )) || error "$count subdirs on MDT0"
26504 }
26505 run_test 413d "inherit ROOT default LMV"
26506
26507 test_413e() {
26508         (( MDSCOUNT >= 2 )) ||
26509                 skip "We need at least 2 MDTs for this test"
26510         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26511                 skip "Need server version at least 2.14.55"
26512
26513         local testdir=$DIR/$tdir
26514         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26515         local max_inherit
26516         local sub_max_inherit
26517
26518         mkdir -p $testdir || error "failed to create $testdir"
26519
26520         # set default max-inherit to -1 if stripe count is 0 or 1
26521         $LFS setdirstripe -D -c 1 $testdir ||
26522                 error "failed to set default LMV"
26523         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26524         (( max_inherit == -1 )) ||
26525                 error "wrong max_inherit value $max_inherit"
26526
26527         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26528         $LFS setdirstripe -D -c -1 $testdir ||
26529                 error "failed to set default LMV"
26530         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26531         (( max_inherit > 0 )) ||
26532                 error "wrong max_inherit value $max_inherit"
26533
26534         # and the subdir will decrease the max_inherit by 1
26535         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26536         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26537         (( sub_max_inherit == max_inherit - 1)) ||
26538                 error "wrong max-inherit of subdir $sub_max_inherit"
26539
26540         # check specified --max-inherit and warning message
26541         stack_trap "rm -f $tmpfile"
26542         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26543                 error "failed to set default LMV"
26544         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26545         (( max_inherit == -1 )) ||
26546                 error "wrong max_inherit value $max_inherit"
26547
26548         # check the warning messages
26549         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26550                 error "failed to detect warning string"
26551         fi
26552 }
26553 run_test 413e "check default max-inherit value"
26554
26555 test_fs_dmv_inherit()
26556 {
26557         local testdir=$DIR/$tdir
26558
26559         local count
26560         local inherit
26561         local inherit_rr
26562
26563         for i in 1 2 3; do
26564                 mkdir $testdir || error "mkdir $testdir failed"
26565                 count=$($LFS getdirstripe -D -c $testdir)
26566                 (( count == 1 )) ||
26567                         error "$testdir default LMV count mismatch $count != 1"
26568                 inherit=$($LFS getdirstripe -D -X $testdir)
26569                 (( inherit == 3 - i )) ||
26570                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26571                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26572                 (( inherit_rr == 3 - i )) ||
26573                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26574                 testdir=$testdir/sub
26575         done
26576
26577         mkdir $testdir || error "mkdir $testdir failed"
26578         count=$($LFS getdirstripe -D -c $testdir)
26579         (( count == 0 )) ||
26580                 error "$testdir default LMV count not zero: $count"
26581 }
26582
26583 test_413f() {
26584         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26585
26586         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26587                 skip "Need server version at least 2.14.55"
26588
26589         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26590                 error "dump $DIR default LMV failed"
26591         stack_trap "setfattr --restore=$TMP/dmv.ea"
26592
26593         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26594                 error "set $DIR default LMV failed"
26595
26596         test_fs_dmv_inherit
26597 }
26598 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26599
26600 test_413g() {
26601         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26602
26603         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26604         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26605                 error "dump $DIR default LMV failed"
26606         stack_trap "setfattr --restore=$TMP/dmv.ea"
26607
26608         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26609                 error "set $DIR default LMV failed"
26610
26611         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26612                 error "mount $MOUNT2 failed"
26613         stack_trap "umount_client $MOUNT2"
26614
26615         local saved_DIR=$DIR
26616
26617         export DIR=$MOUNT2
26618
26619         stack_trap "export DIR=$saved_DIR"
26620
26621         # first check filesystem-wide default LMV inheritance
26622         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26623
26624         # then check subdirs are spread to all MDTs
26625         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26626
26627         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26628
26629         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26630 }
26631 run_test 413g "enforce ROOT default LMV on subdir mount"
26632
26633 test_413h() {
26634         (( MDSCOUNT >= 2 )) ||
26635                 skip "We need at least 2 MDTs for this test"
26636
26637         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26638                 skip "Need server version at least 2.15.50.6"
26639
26640         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26641
26642         stack_trap "$LCTL set_param \
26643                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26644         $LCTL set_param lmv.*.qos_maxage=1
26645
26646         local depth=5
26647         local rr_depth=4
26648         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26649         local count=$((MDSCOUNT * 20))
26650
26651         generate_uneven_mdts 50
26652
26653         mkdir -p $dir || error "mkdir $dir failed"
26654         stack_trap "rm -rf $dir"
26655         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26656                 --max-inherit-rr=$rr_depth $dir
26657
26658         for ((d=0; d < depth + 2; d++)); do
26659                 log "dir=$dir:"
26660                 for ((sub=0; sub < count; sub++)); do
26661                         mkdir $dir/d$sub
26662                 done
26663                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26664                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26665                 # subdirs within $rr_depth should be created round-robin
26666                 if (( d < rr_depth )); then
26667                         (( ${num[0]} != count )) ||
26668                                 error "all objects created on MDT ${num[1]}"
26669                 fi
26670
26671                 dir=$dir/d0
26672         done
26673 }
26674 run_test 413h "don't stick to parent for round-robin dirs"
26675
26676 test_413z() {
26677         local pids=""
26678         local subdir
26679         local pid
26680
26681         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26682                 unlinkmany $subdir/f. $TEST413_COUNT &
26683                 pids="$pids $!"
26684         done
26685
26686         for pid in $pids; do
26687                 wait $pid
26688         done
26689 }
26690 run_test 413z "413 test cleanup"
26691
26692 test_414() {
26693 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26694         $LCTL set_param fail_loc=0x80000521
26695         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26696         rm -f $DIR/$tfile
26697 }
26698 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26699
26700 test_415() {
26701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26702         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26703                 skip "Need server version at least 2.11.52"
26704
26705         # LU-11102
26706         local total
26707         local setattr_pid
26708         local start_time
26709         local end_time
26710         local duration
26711
26712         total=500
26713         # this test may be slow on ZFS
26714         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26715
26716         # though this test is designed for striped directory, let's test normal
26717         # directory too since lock is always saved as CoS lock.
26718         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26719         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26720
26721         (
26722                 while true; do
26723                         touch $DIR/$tdir
26724                 done
26725         ) &
26726         setattr_pid=$!
26727
26728         start_time=$(date +%s)
26729         for i in $(seq $total); do
26730                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26731                         > /dev/null
26732         done
26733         end_time=$(date +%s)
26734         duration=$((end_time - start_time))
26735
26736         kill -9 $setattr_pid
26737
26738         echo "rename $total files took $duration sec"
26739         [ $duration -lt 100 ] || error "rename took $duration sec"
26740 }
26741 run_test 415 "lock revoke is not missing"
26742
26743 test_416() {
26744         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26745                 skip "Need server version at least 2.11.55"
26746
26747         # define OBD_FAIL_OSD_TXN_START    0x19a
26748         do_facet mds1 lctl set_param fail_loc=0x19a
26749
26750         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26751
26752         true
26753 }
26754 run_test 416 "transaction start failure won't cause system hung"
26755
26756 cleanup_417() {
26757         trap 0
26758         do_nodes $(comma_list $(mdts_nodes)) \
26759                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26760         do_nodes $(comma_list $(mdts_nodes)) \
26761                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26762         do_nodes $(comma_list $(mdts_nodes)) \
26763                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26764 }
26765
26766 test_417() {
26767         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26768         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26769                 skip "Need MDS version at least 2.11.56"
26770
26771         trap cleanup_417 RETURN EXIT
26772
26773         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26774         do_nodes $(comma_list $(mdts_nodes)) \
26775                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26776         $LFS migrate -m 0 $DIR/$tdir.1 &&
26777                 error "migrate dir $tdir.1 should fail"
26778
26779         do_nodes $(comma_list $(mdts_nodes)) \
26780                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26781         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26782                 error "create remote dir $tdir.2 should fail"
26783
26784         do_nodes $(comma_list $(mdts_nodes)) \
26785                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26786         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26787                 error "create striped dir $tdir.3 should fail"
26788         true
26789 }
26790 run_test 417 "disable remote dir, striped dir and dir migration"
26791
26792 # Checks that the outputs of df [-i] and lfs df [-i] match
26793 #
26794 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26795 check_lfs_df() {
26796         local dir=$2
26797         local inodes
26798         local df_out
26799         local lfs_df_out
26800         local count
26801         local passed=false
26802
26803         # blocks or inodes
26804         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26805
26806         for count in {1..100}; do
26807                 do_nodes "$CLIENTS" \
26808                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26809                 sync; sleep 0.2
26810
26811                 # read the lines of interest
26812                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26813                         error "df $inodes $dir | tail -n +2 failed"
26814                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26815                         error "lfs df $inodes $dir | grep summary: failed"
26816
26817                 # skip first substrings of each output as they are different
26818                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26819                 # compare the two outputs
26820                 passed=true
26821                 #  skip "available" on MDT until LU-13997 is fixed.
26822                 #for i in {1..5}; do
26823                 for i in 1 2 4 5; do
26824                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26825                 done
26826                 $passed && break
26827         done
26828
26829         if ! $passed; then
26830                 df -P $inodes $dir
26831                 echo
26832                 lfs df $inodes $dir
26833                 error "df and lfs df $1 output mismatch: "      \
26834                       "df ${inodes}: ${df_out[*]}, "            \
26835                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26836         fi
26837 }
26838
26839 test_418() {
26840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26841
26842         local dir=$DIR/$tdir
26843         local numfiles=$((RANDOM % 4096 + 2))
26844         local numblocks=$((RANDOM % 256 + 1))
26845
26846         wait_delete_completed
26847         test_mkdir $dir
26848
26849         # check block output
26850         check_lfs_df blocks $dir
26851         # check inode output
26852         check_lfs_df inodes $dir
26853
26854         # create a single file and retest
26855         echo "Creating a single file and testing"
26856         createmany -o $dir/$tfile- 1 &>/dev/null ||
26857                 error "creating 1 file in $dir failed"
26858         check_lfs_df blocks $dir
26859         check_lfs_df inodes $dir
26860
26861         # create a random number of files
26862         echo "Creating $((numfiles - 1)) files and testing"
26863         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26864                 error "creating $((numfiles - 1)) files in $dir failed"
26865
26866         # write a random number of blocks to the first test file
26867         echo "Writing $numblocks 4K blocks and testing"
26868         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26869                 count=$numblocks &>/dev/null ||
26870                 error "dd to $dir/${tfile}-0 failed"
26871
26872         # retest
26873         check_lfs_df blocks $dir
26874         check_lfs_df inodes $dir
26875
26876         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26877                 error "unlinking $numfiles files in $dir failed"
26878 }
26879 run_test 418 "df and lfs df outputs match"
26880
26881 test_419()
26882 {
26883         local dir=$DIR/$tdir
26884
26885         mkdir -p $dir
26886         touch $dir/file
26887
26888         cancel_lru_locks mdc
26889
26890         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26891         $LCTL set_param fail_loc=0x1410
26892         cat $dir/file
26893         $LCTL set_param fail_loc=0
26894         rm -rf $dir
26895 }
26896 run_test 419 "Verify open file by name doesn't crash kernel"
26897
26898 test_420()
26899 {
26900         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26901                 skip "Need MDS version at least 2.12.53"
26902
26903         local SAVE_UMASK=$(umask)
26904         local dir=$DIR/$tdir
26905         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26906
26907         mkdir -p $dir
26908         umask 0000
26909         mkdir -m03777 $dir/testdir
26910         ls -dn $dir/testdir
26911         # Need to remove trailing '.' when SELinux is enabled
26912         local dirperms=$(ls -dn $dir/testdir |
26913                          awk '{ sub(/\.$/, "", $1); print $1}')
26914         [ $dirperms == "drwxrwsrwt" ] ||
26915                 error "incorrect perms on $dir/testdir"
26916
26917         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26918                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26919         ls -n $dir/testdir/testfile
26920         local fileperms=$(ls -n $dir/testdir/testfile |
26921                           awk '{ sub(/\.$/, "", $1); print $1}')
26922         [ $fileperms == "-rwxr-xr-x" ] ||
26923                 error "incorrect perms on $dir/testdir/testfile"
26924
26925         umask $SAVE_UMASK
26926 }
26927 run_test 420 "clear SGID bit on non-directories for non-members"
26928
26929 test_421a() {
26930         local cnt
26931         local fid1
26932         local fid2
26933
26934         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26935                 skip "Need MDS version at least 2.12.54"
26936
26937         test_mkdir $DIR/$tdir
26938         createmany -o $DIR/$tdir/f 3
26939         cnt=$(ls -1 $DIR/$tdir | wc -l)
26940         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26941
26942         fid1=$(lfs path2fid $DIR/$tdir/f1)
26943         fid2=$(lfs path2fid $DIR/$tdir/f2)
26944         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26945
26946         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26947         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26948
26949         cnt=$(ls -1 $DIR/$tdir | wc -l)
26950         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26951
26952         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26953         createmany -o $DIR/$tdir/f 3
26954         cnt=$(ls -1 $DIR/$tdir | wc -l)
26955         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26956
26957         fid1=$(lfs path2fid $DIR/$tdir/f1)
26958         fid2=$(lfs path2fid $DIR/$tdir/f2)
26959         echo "remove using fsname $FSNAME"
26960         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26961
26962         cnt=$(ls -1 $DIR/$tdir | wc -l)
26963         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26964 }
26965 run_test 421a "simple rm by fid"
26966
26967 test_421b() {
26968         local cnt
26969         local FID1
26970         local FID2
26971
26972         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26973                 skip "Need MDS version at least 2.12.54"
26974
26975         test_mkdir $DIR/$tdir
26976         createmany -o $DIR/$tdir/f 3
26977         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26978         MULTIPID=$!
26979
26980         FID1=$(lfs path2fid $DIR/$tdir/f1)
26981         FID2=$(lfs path2fid $DIR/$tdir/f2)
26982         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26983
26984         kill -USR1 $MULTIPID
26985         wait
26986
26987         cnt=$(ls $DIR/$tdir | wc -l)
26988         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26989 }
26990 run_test 421b "rm by fid on open file"
26991
26992 test_421c() {
26993         local cnt
26994         local FIDS
26995
26996         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26997                 skip "Need MDS version at least 2.12.54"
26998
26999         test_mkdir $DIR/$tdir
27000         createmany -o $DIR/$tdir/f 3
27001         touch $DIR/$tdir/$tfile
27002         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27003         cnt=$(ls -1 $DIR/$tdir | wc -l)
27004         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27005
27006         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27007         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27008
27009         cnt=$(ls $DIR/$tdir | wc -l)
27010         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27011 }
27012 run_test 421c "rm by fid against hardlinked files"
27013
27014 test_421d() {
27015         local cnt
27016         local FIDS
27017
27018         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27019                 skip "Need MDS version at least 2.12.54"
27020
27021         test_mkdir $DIR/$tdir
27022         createmany -o $DIR/$tdir/f 4097
27023         cnt=$(ls -1 $DIR/$tdir | wc -l)
27024         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27025
27026         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27027         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27028
27029         cnt=$(ls $DIR/$tdir | wc -l)
27030         rm -rf $DIR/$tdir
27031         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27032 }
27033 run_test 421d "rmfid en masse"
27034
27035 test_421e() {
27036         local cnt
27037         local FID
27038
27039         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27040         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27041                 skip "Need MDS version at least 2.12.54"
27042
27043         mkdir -p $DIR/$tdir
27044         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27045         createmany -o $DIR/$tdir/striped_dir/f 512
27046         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27047         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27048
27049         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27050                 sed "s/[/][^:]*://g")
27051         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27052
27053         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27054         rm -rf $DIR/$tdir
27055         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27056 }
27057 run_test 421e "rmfid in DNE"
27058
27059 test_421f() {
27060         local cnt
27061         local FID
27062
27063         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27064                 skip "Need MDS version at least 2.12.54"
27065
27066         test_mkdir $DIR/$tdir
27067         touch $DIR/$tdir/f
27068         cnt=$(ls -1 $DIR/$tdir | wc -l)
27069         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27070
27071         FID=$(lfs path2fid $DIR/$tdir/f)
27072         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27073         # rmfid should fail
27074         cnt=$(ls -1 $DIR/$tdir | wc -l)
27075         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27076
27077         chmod a+rw $DIR/$tdir
27078         ls -la $DIR/$tdir
27079         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27080         # rmfid should fail
27081         cnt=$(ls -1 $DIR/$tdir | wc -l)
27082         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27083
27084         rm -f $DIR/$tdir/f
27085         $RUNAS touch $DIR/$tdir/f
27086         FID=$(lfs path2fid $DIR/$tdir/f)
27087         echo "rmfid as root"
27088         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27089         cnt=$(ls -1 $DIR/$tdir | wc -l)
27090         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27091
27092         rm -f $DIR/$tdir/f
27093         $RUNAS touch $DIR/$tdir/f
27094         cnt=$(ls -1 $DIR/$tdir | wc -l)
27095         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27096         FID=$(lfs path2fid $DIR/$tdir/f)
27097         # rmfid w/o user_fid2path mount option should fail
27098         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27099         cnt=$(ls -1 $DIR/$tdir | wc -l)
27100         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27101
27102         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27103         stack_trap "rmdir $tmpdir"
27104         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27105                 error "failed to mount client'"
27106         stack_trap "umount_client $tmpdir"
27107
27108         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27109         # rmfid should succeed
27110         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27111         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27112
27113         # rmfid shouldn't allow to remove files due to dir's permission
27114         chmod a+rwx $tmpdir/$tdir
27115         touch $tmpdir/$tdir/f
27116         ls -la $tmpdir/$tdir
27117         FID=$(lfs path2fid $tmpdir/$tdir/f)
27118         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27119         return 0
27120 }
27121 run_test 421f "rmfid checks permissions"
27122
27123 test_421g() {
27124         local cnt
27125         local FIDS
27126
27127         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27128         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27129                 skip "Need MDS version at least 2.12.54"
27130
27131         mkdir -p $DIR/$tdir
27132         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27133         createmany -o $DIR/$tdir/striped_dir/f 512
27134         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27135         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27136
27137         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27138                 sed "s/[/][^:]*://g")
27139
27140         rm -f $DIR/$tdir/striped_dir/f1*
27141         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27142         removed=$((512 - cnt))
27143
27144         # few files have been just removed, so we expect
27145         # rmfid to fail on their fids
27146         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27147         [ $removed != $errors ] && error "$errors != $removed"
27148
27149         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27150         rm -rf $DIR/$tdir
27151         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27152 }
27153 run_test 421g "rmfid to return errors properly"
27154
27155 test_422() {
27156         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27157         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27158         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27159         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27160         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27161
27162         local amc=$(at_max_get client)
27163         local amo=$(at_max_get mds1)
27164         local timeout=`lctl get_param -n timeout`
27165
27166         at_max_set 0 client
27167         at_max_set 0 mds1
27168
27169 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27170         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27171                         fail_val=$(((2*timeout + 10)*1000))
27172         touch $DIR/$tdir/d3/file &
27173         sleep 2
27174 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27175         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27176                         fail_val=$((2*timeout + 5))
27177         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27178         local pid=$!
27179         sleep 1
27180         kill -9 $pid
27181         sleep $((2 * timeout))
27182         echo kill $pid
27183         kill -9 $pid
27184         lctl mark touch
27185         touch $DIR/$tdir/d2/file3
27186         touch $DIR/$tdir/d2/file4
27187         touch $DIR/$tdir/d2/file5
27188
27189         wait
27190         at_max_set $amc client
27191         at_max_set $amo mds1
27192
27193         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27194         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27195                 error "Watchdog is always throttled"
27196 }
27197 run_test 422 "kill a process with RPC in progress"
27198
27199 stat_test() {
27200     df -h $MOUNT &
27201     df -h $MOUNT &
27202     df -h $MOUNT &
27203     df -h $MOUNT &
27204     df -h $MOUNT &
27205     df -h $MOUNT &
27206 }
27207
27208 test_423() {
27209     local _stats
27210     # ensure statfs cache is expired
27211     sleep 2;
27212
27213     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27214     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27215
27216     return 0
27217 }
27218 run_test 423 "statfs should return a right data"
27219
27220 test_424() {
27221 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27222         $LCTL set_param fail_loc=0x80000522
27223         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27224         rm -f $DIR/$tfile
27225 }
27226 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27227
27228 test_425() {
27229         test_mkdir -c -1 $DIR/$tdir
27230         $LFS setstripe -c -1 $DIR/$tdir
27231
27232         lru_resize_disable "" 100
27233         stack_trap "lru_resize_enable" EXIT
27234
27235         sleep 5
27236
27237         for i in $(seq $((MDSCOUNT * 125))); do
27238                 local t=$DIR/$tdir/$tfile_$i
27239
27240                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27241                         error_noexit "Create file $t"
27242         done
27243         stack_trap "rm -rf $DIR/$tdir" EXIT
27244
27245         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27246                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27247                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27248
27249                 [ $lock_count -le $lru_size ] ||
27250                         error "osc lock count $lock_count > lru size $lru_size"
27251         done
27252
27253         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27254                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27255                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27256
27257                 [ $lock_count -le $lru_size ] ||
27258                         error "mdc lock count $lock_count > lru size $lru_size"
27259         done
27260 }
27261 run_test 425 "lock count should not exceed lru size"
27262
27263 test_426() {
27264         splice-test -r $DIR/$tfile
27265         splice-test -rd $DIR/$tfile
27266         splice-test $DIR/$tfile
27267         splice-test -d $DIR/$tfile
27268 }
27269 run_test 426 "splice test on Lustre"
27270
27271 test_427() {
27272         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27273         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27274                 skip "Need MDS version at least 2.12.4"
27275         local log
27276
27277         mkdir $DIR/$tdir
27278         mkdir $DIR/$tdir/1
27279         mkdir $DIR/$tdir/2
27280         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27281         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27282
27283         $LFS getdirstripe $DIR/$tdir/1/dir
27284
27285         #first setfattr for creating updatelog
27286         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27287
27288 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27289         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27290         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27291         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27292
27293         sleep 2
27294         fail mds2
27295         wait_recovery_complete mds2 $((2*TIMEOUT))
27296
27297         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27298         echo $log | grep "get update log failed" &&
27299                 error "update log corruption is detected" || true
27300 }
27301 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27302
27303 test_428() {
27304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27305         local cache_limit=$CACHE_MAX
27306
27307         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27308         $LCTL set_param -n llite.*.max_cached_mb=64
27309
27310         mkdir $DIR/$tdir
27311         $LFS setstripe -c 1 $DIR/$tdir
27312         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27313         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27314         #test write
27315         for f in $(seq 4); do
27316                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27317         done
27318         wait
27319
27320         cancel_lru_locks osc
27321         # Test read
27322         for f in $(seq 4); do
27323                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27324         done
27325         wait
27326 }
27327 run_test 428 "large block size IO should not hang"
27328
27329 test_429() { # LU-7915 / LU-10948
27330         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27331         local testfile=$DIR/$tfile
27332         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27333         local new_flag=1
27334         local first_rpc
27335         local second_rpc
27336         local third_rpc
27337
27338         $LCTL get_param $ll_opencache_threshold_count ||
27339                 skip "client does not have opencache parameter"
27340
27341         set_opencache $new_flag
27342         stack_trap "restore_opencache"
27343         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27344                 error "enable opencache failed"
27345         touch $testfile
27346         # drop MDC DLM locks
27347         cancel_lru_locks mdc
27348         # clear MDC RPC stats counters
27349         $LCTL set_param $mdc_rpcstats=clear
27350
27351         # According to the current implementation, we need to run 3 times
27352         # open & close file to verify if opencache is enabled correctly.
27353         # 1st, RPCs are sent for lookup/open and open handle is released on
27354         #      close finally.
27355         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27356         #      so open handle won't be released thereafter.
27357         # 3rd, No RPC is sent out.
27358         $MULTIOP $testfile oc || error "multiop failed"
27359         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27360         echo "1st: $first_rpc RPCs in flight"
27361
27362         $MULTIOP $testfile oc || error "multiop failed"
27363         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27364         echo "2nd: $second_rpc RPCs in flight"
27365
27366         $MULTIOP $testfile oc || error "multiop failed"
27367         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27368         echo "3rd: $third_rpc RPCs in flight"
27369
27370         #verify no MDC RPC is sent
27371         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27372 }
27373 run_test 429 "verify if opencache flag on client side does work"
27374
27375 lseek_test_430() {
27376         local offset
27377         local file=$1
27378
27379         # data at [200K, 400K)
27380         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27381                 error "256K->512K dd fails"
27382         # data at [2M, 3M)
27383         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27384                 error "2M->3M dd fails"
27385         # data at [4M, 5M)
27386         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27387                 error "4M->5M dd fails"
27388         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27389         # start at first component hole #1
27390         printf "Seeking hole from 1000 ... "
27391         offset=$(lseek_test -l 1000 $file)
27392         echo $offset
27393         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27394         printf "Seeking data from 1000 ... "
27395         offset=$(lseek_test -d 1000 $file)
27396         echo $offset
27397         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27398
27399         # start at first component data block
27400         printf "Seeking hole from 300000 ... "
27401         offset=$(lseek_test -l 300000 $file)
27402         echo $offset
27403         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27404         printf "Seeking data from 300000 ... "
27405         offset=$(lseek_test -d 300000 $file)
27406         echo $offset
27407         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27408
27409         # start at the first component but beyond end of object size
27410         printf "Seeking hole from 1000000 ... "
27411         offset=$(lseek_test -l 1000000 $file)
27412         echo $offset
27413         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27414         printf "Seeking data from 1000000 ... "
27415         offset=$(lseek_test -d 1000000 $file)
27416         echo $offset
27417         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27418
27419         # start at second component stripe 2 (empty file)
27420         printf "Seeking hole from 1500000 ... "
27421         offset=$(lseek_test -l 1500000 $file)
27422         echo $offset
27423         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27424         printf "Seeking data from 1500000 ... "
27425         offset=$(lseek_test -d 1500000 $file)
27426         echo $offset
27427         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27428
27429         # start at second component stripe 1 (all data)
27430         printf "Seeking hole from 3000000 ... "
27431         offset=$(lseek_test -l 3000000 $file)
27432         echo $offset
27433         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27434         printf "Seeking data from 3000000 ... "
27435         offset=$(lseek_test -d 3000000 $file)
27436         echo $offset
27437         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27438
27439         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27440                 error "2nd dd fails"
27441         echo "Add data block at 640K...1280K"
27442
27443         # start at before new data block, in hole
27444         printf "Seeking hole from 600000 ... "
27445         offset=$(lseek_test -l 600000 $file)
27446         echo $offset
27447         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27448         printf "Seeking data from 600000 ... "
27449         offset=$(lseek_test -d 600000 $file)
27450         echo $offset
27451         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27452
27453         # start at the first component new data block
27454         printf "Seeking hole from 1000000 ... "
27455         offset=$(lseek_test -l 1000000 $file)
27456         echo $offset
27457         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27458         printf "Seeking data from 1000000 ... "
27459         offset=$(lseek_test -d 1000000 $file)
27460         echo $offset
27461         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27462
27463         # start at second component stripe 2, new data
27464         printf "Seeking hole from 1200000 ... "
27465         offset=$(lseek_test -l 1200000 $file)
27466         echo $offset
27467         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27468         printf "Seeking data from 1200000 ... "
27469         offset=$(lseek_test -d 1200000 $file)
27470         echo $offset
27471         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27472
27473         # start beyond file end
27474         printf "Using offset > filesize ... "
27475         lseek_test -l 4000000 $file && error "lseek should fail"
27476         printf "Using offset > filesize ... "
27477         lseek_test -d 4000000 $file && error "lseek should fail"
27478
27479         printf "Done\n\n"
27480 }
27481
27482 test_430a() {
27483         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27484                 skip "MDT does not support SEEK_HOLE"
27485
27486         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27487                 skip "OST does not support SEEK_HOLE"
27488
27489         local file=$DIR/$tdir/$tfile
27490
27491         mkdir -p $DIR/$tdir
27492
27493         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27494         # OST stripe #1 will have continuous data at [1M, 3M)
27495         # OST stripe #2 is empty
27496         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27497         lseek_test_430 $file
27498         rm $file
27499         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27500         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27501         lseek_test_430 $file
27502         rm $file
27503         $LFS setstripe -c2 -S 512K $file
27504         echo "Two stripes, stripe size 512K"
27505         lseek_test_430 $file
27506         rm $file
27507         # FLR with stale mirror
27508         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27509                        -N -c2 -S 1M $file
27510         echo "Mirrored file:"
27511         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27512         echo "Plain 2 stripes 1M"
27513         lseek_test_430 $file
27514         rm $file
27515 }
27516 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27517
27518 test_430b() {
27519         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27520                 skip "OST does not support SEEK_HOLE"
27521
27522         local offset
27523         local file=$DIR/$tdir/$tfile
27524
27525         mkdir -p $DIR/$tdir
27526         # Empty layout lseek should fail
27527         $MCREATE $file
27528         # seek from 0
27529         printf "Seeking hole from 0 ... "
27530         lseek_test -l 0 $file && error "lseek should fail"
27531         printf "Seeking data from 0 ... "
27532         lseek_test -d 0 $file && error "lseek should fail"
27533         rm $file
27534
27535         # 1M-hole file
27536         $LFS setstripe -E 1M -c2 -E eof $file
27537         $TRUNCATE $file 1048576
27538         printf "Seeking hole from 1000000 ... "
27539         offset=$(lseek_test -l 1000000 $file)
27540         echo $offset
27541         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27542         printf "Seeking data from 1000000 ... "
27543         lseek_test -d 1000000 $file && error "lseek should fail"
27544         rm $file
27545
27546         # full component followed by non-inited one
27547         $LFS setstripe -E 1M -c2 -E eof $file
27548         dd if=/dev/urandom of=$file bs=1M count=1
27549         printf "Seeking hole from 1000000 ... "
27550         offset=$(lseek_test -l 1000000 $file)
27551         echo $offset
27552         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27553         printf "Seeking hole from 1048576 ... "
27554         lseek_test -l 1048576 $file && error "lseek should fail"
27555         # init second component and truncate back
27556         echo "123" >> $file
27557         $TRUNCATE $file 1048576
27558         printf "Seeking hole from 1000000 ... "
27559         offset=$(lseek_test -l 1000000 $file)
27560         echo $offset
27561         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27562         printf "Seeking hole from 1048576 ... "
27563         lseek_test -l 1048576 $file && error "lseek should fail"
27564         # boundary checks for big values
27565         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27566         offset=$(lseek_test -d 0 $file.10g)
27567         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27568         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27569         offset=$(lseek_test -d 0 $file.100g)
27570         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27571         return 0
27572 }
27573 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27574
27575 test_430c() {
27576         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27577                 skip "OST does not support SEEK_HOLE"
27578
27579         local file=$DIR/$tdir/$tfile
27580         local start
27581
27582         mkdir -p $DIR/$tdir
27583         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27584
27585         # cp version 8.33+ prefers lseek over fiemap
27586         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27587                 start=$SECONDS
27588                 time cp $file /dev/null
27589                 (( SECONDS - start < 5 )) ||
27590                         error "cp: too long runtime $((SECONDS - start))"
27591
27592         fi
27593         # tar version 1.29+ supports SEEK_HOLE/DATA
27594         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27595                 start=$SECONDS
27596                 time tar cS $file - | cat > /dev/null
27597                 (( SECONDS - start < 5 )) ||
27598                         error "tar: too long runtime $((SECONDS - start))"
27599         fi
27600 }
27601 run_test 430c "lseek: external tools check"
27602
27603 test_431() { # LU-14187
27604         local file=$DIR/$tdir/$tfile
27605
27606         mkdir -p $DIR/$tdir
27607         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27608         dd if=/dev/urandom of=$file bs=4k count=1
27609         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27610         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27611         #define OBD_FAIL_OST_RESTART_IO 0x251
27612         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27613         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27614         cp $file $file.0
27615         cancel_lru_locks
27616         sync_all_data
27617         echo 3 > /proc/sys/vm/drop_caches
27618         diff  $file $file.0 || error "data diff"
27619 }
27620 run_test 431 "Restart transaction for IO"
27621
27622 cleanup_test_432() {
27623         do_facet mgs $LCTL nodemap_activate 0
27624         wait_nm_sync active
27625 }
27626
27627 test_432() {
27628         local tmpdir=$TMP/dir432
27629
27630         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27631                 skip "Need MDS version at least 2.14.52"
27632
27633         stack_trap cleanup_test_432 EXIT
27634         mkdir $DIR/$tdir
27635         mkdir $tmpdir
27636
27637         do_facet mgs $LCTL nodemap_activate 1
27638         wait_nm_sync active
27639         do_facet mgs $LCTL nodemap_modify --name default \
27640                 --property admin --value 1
27641         do_facet mgs $LCTL nodemap_modify --name default \
27642                 --property trusted --value 1
27643         cancel_lru_locks mdc
27644         wait_nm_sync default admin_nodemap
27645         wait_nm_sync default trusted_nodemap
27646
27647         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27648                grep -ci "Operation not permitted") -ne 0 ]; then
27649                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27650         fi
27651 }
27652 run_test 432 "mv dir from outside Lustre"
27653
27654 test_433() {
27655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27656
27657         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27658                 skip "inode cache not supported"
27659
27660         $LCTL set_param llite.*.inode_cache=0
27661         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27662
27663         local count=256
27664         local before
27665         local after
27666
27667         cancel_lru_locks mdc
27668         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27669         createmany -m $DIR/$tdir/f $count
27670         createmany -d $DIR/$tdir/d $count
27671         ls -l $DIR/$tdir > /dev/null
27672         stack_trap "rm -rf $DIR/$tdir"
27673
27674         before=$(num_objects)
27675         cancel_lru_locks mdc
27676         after=$(num_objects)
27677
27678         # sometimes even @before is less than 2 * count
27679         while (( before - after < count )); do
27680                 sleep 1
27681                 after=$(num_objects)
27682                 wait=$((wait + 1))
27683                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27684                 if (( wait > 60 )); then
27685                         error "inode slab grew from $before to $after"
27686                 fi
27687         done
27688
27689         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27690 }
27691 run_test 433 "ldlm lock cancel releases dentries and inodes"
27692
27693 test_434() {
27694         local file
27695         local getxattr_count
27696         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27697         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27698
27699         [[ $(getenforce) == "Disabled" ]] ||
27700                 skip "lsm selinux module have to be disabled for this test"
27701
27702         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27703                 error "fail to create $DIR/$tdir/ on MDT0000"
27704
27705         touch $DIR/$tdir/$tfile-{001..100}
27706
27707         # disable the xattr cache
27708         save_lustre_params client "llite.*.xattr_cache" > $p
27709         lctl set_param llite.*.xattr_cache=0
27710         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27711
27712         # clear clients mdc stats
27713         clear_stats $mdc_stat_param ||
27714                 error "fail to clear stats on mdc MDT0000"
27715
27716         for file in $DIR/$tdir/$tfile-{001..100}; do
27717                 getfattr -n security.selinux $file |&
27718                         grep -q "Operation not supported" ||
27719                         error "getxattr on security.selinux should return EOPNOTSUPP"
27720         done
27721
27722         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27723         (( getxattr_count < 100 )) ||
27724                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27725 }
27726 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27727
27728 prep_801() {
27729         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27730         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27731                 skip "Need server version at least 2.9.55"
27732
27733         start_full_debug_logging
27734 }
27735
27736 post_801() {
27737         stop_full_debug_logging
27738 }
27739
27740 barrier_stat() {
27741         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27742                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27743                            awk '/The barrier for/ { print $7 }')
27744                 echo $st
27745         else
27746                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27747                 echo \'$st\'
27748         fi
27749 }
27750
27751 barrier_expired() {
27752         local expired
27753
27754         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27755                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27756                           awk '/will be expired/ { print $7 }')
27757         else
27758                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27759         fi
27760
27761         echo $expired
27762 }
27763
27764 test_801a() {
27765         prep_801
27766
27767         echo "Start barrier_freeze at: $(date)"
27768         #define OBD_FAIL_BARRIER_DELAY          0x2202
27769         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27770         # Do not reduce barrier time - See LU-11873
27771         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27772
27773         sleep 2
27774         local b_status=$(barrier_stat)
27775         echo "Got barrier status at: $(date)"
27776         [ "$b_status" = "'freezing_p1'" ] ||
27777                 error "(1) unexpected barrier status $b_status"
27778
27779         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27780         wait
27781         b_status=$(barrier_stat)
27782         [ "$b_status" = "'frozen'" ] ||
27783                 error "(2) unexpected barrier status $b_status"
27784
27785         local expired=$(barrier_expired)
27786         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27787         sleep $((expired + 3))
27788
27789         b_status=$(barrier_stat)
27790         [ "$b_status" = "'expired'" ] ||
27791                 error "(3) unexpected barrier status $b_status"
27792
27793         # Do not reduce barrier time - See LU-11873
27794         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27795                 error "(4) fail to freeze barrier"
27796
27797         b_status=$(barrier_stat)
27798         [ "$b_status" = "'frozen'" ] ||
27799                 error "(5) unexpected barrier status $b_status"
27800
27801         echo "Start barrier_thaw at: $(date)"
27802         #define OBD_FAIL_BARRIER_DELAY          0x2202
27803         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27804         do_facet mgs $LCTL barrier_thaw $FSNAME &
27805
27806         sleep 2
27807         b_status=$(barrier_stat)
27808         echo "Got barrier status at: $(date)"
27809         [ "$b_status" = "'thawing'" ] ||
27810                 error "(6) unexpected barrier status $b_status"
27811
27812         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27813         wait
27814         b_status=$(barrier_stat)
27815         [ "$b_status" = "'thawed'" ] ||
27816                 error "(7) unexpected barrier status $b_status"
27817
27818         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27819         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27820         do_facet mgs $LCTL barrier_freeze $FSNAME
27821
27822         b_status=$(barrier_stat)
27823         [ "$b_status" = "'failed'" ] ||
27824                 error "(8) unexpected barrier status $b_status"
27825
27826         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27827         do_facet mgs $LCTL barrier_thaw $FSNAME
27828
27829         post_801
27830 }
27831 run_test 801a "write barrier user interfaces and stat machine"
27832
27833 test_801b() {
27834         prep_801
27835
27836         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27837         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27838         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27839         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27840         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27841
27842         cancel_lru_locks mdc
27843
27844         # 180 seconds should be long enough
27845         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27846
27847         local b_status=$(barrier_stat)
27848         [ "$b_status" = "'frozen'" ] ||
27849                 error "(6) unexpected barrier status $b_status"
27850
27851         mkdir $DIR/$tdir/d0/d10 &
27852         mkdir_pid=$!
27853
27854         touch $DIR/$tdir/d1/f13 &
27855         touch_pid=$!
27856
27857         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27858         ln_pid=$!
27859
27860         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27861         mv_pid=$!
27862
27863         rm -f $DIR/$tdir/d4/f12 &
27864         rm_pid=$!
27865
27866         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27867
27868         # To guarantee taht the 'stat' is not blocked
27869         b_status=$(barrier_stat)
27870         [ "$b_status" = "'frozen'" ] ||
27871                 error "(8) unexpected barrier status $b_status"
27872
27873         # let above commands to run at background
27874         sleep 5
27875
27876         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27877         ps -p $touch_pid || error "(10) touch should be blocked"
27878         ps -p $ln_pid || error "(11) link should be blocked"
27879         ps -p $mv_pid || error "(12) rename should be blocked"
27880         ps -p $rm_pid || error "(13) unlink should be blocked"
27881
27882         b_status=$(barrier_stat)
27883         [ "$b_status" = "'frozen'" ] ||
27884                 error "(14) unexpected barrier status $b_status"
27885
27886         do_facet mgs $LCTL barrier_thaw $FSNAME
27887         b_status=$(barrier_stat)
27888         [ "$b_status" = "'thawed'" ] ||
27889                 error "(15) unexpected barrier status $b_status"
27890
27891         wait $mkdir_pid || error "(16) mkdir should succeed"
27892         wait $touch_pid || error "(17) touch should succeed"
27893         wait $ln_pid || error "(18) link should succeed"
27894         wait $mv_pid || error "(19) rename should succeed"
27895         wait $rm_pid || error "(20) unlink should succeed"
27896
27897         post_801
27898 }
27899 run_test 801b "modification will be blocked by write barrier"
27900
27901 test_801c() {
27902         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27903
27904         prep_801
27905
27906         stop mds2 || error "(1) Fail to stop mds2"
27907
27908         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27909
27910         local b_status=$(barrier_stat)
27911         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27912                 do_facet mgs $LCTL barrier_thaw $FSNAME
27913                 error "(2) unexpected barrier status $b_status"
27914         }
27915
27916         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27917                 error "(3) Fail to rescan barrier bitmap"
27918
27919         # Do not reduce barrier time - See LU-11873
27920         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27921
27922         b_status=$(barrier_stat)
27923         [ "$b_status" = "'frozen'" ] ||
27924                 error "(4) unexpected barrier status $b_status"
27925
27926         do_facet mgs $LCTL barrier_thaw $FSNAME
27927         b_status=$(barrier_stat)
27928         [ "$b_status" = "'thawed'" ] ||
27929                 error "(5) unexpected barrier status $b_status"
27930
27931         local devname=$(mdsdevname 2)
27932
27933         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27934
27935         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27936                 error "(7) Fail to rescan barrier bitmap"
27937
27938         post_801
27939 }
27940 run_test 801c "rescan barrier bitmap"
27941
27942 test_802b() {
27943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27944         remote_mds_nodsh && skip "remote MDS with nodsh"
27945
27946         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27947                 skip "readonly option not available"
27948
27949         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27950
27951         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27952                 error "(2) Fail to copy"
27953
27954         # write back all cached data before setting MDT to readonly
27955         cancel_lru_locks
27956         sync_all_data
27957
27958         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27959         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27960
27961         echo "Modify should be refused"
27962         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27963
27964         echo "Read should be allowed"
27965         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27966                 error "(7) Read should succeed under ro mode"
27967
27968         # disable readonly
27969         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27970 }
27971 run_test 802b "be able to set MDTs to readonly"
27972
27973 test_803a() {
27974         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27975         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27976                 skip "MDS needs to be newer than 2.10.54"
27977
27978         mkdir_on_mdt0 $DIR/$tdir
27979         # Create some objects on all MDTs to trigger related logs objects
27980         for idx in $(seq $MDSCOUNT); do
27981                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27982                         $DIR/$tdir/dir${idx} ||
27983                         error "Fail to create $DIR/$tdir/dir${idx}"
27984         done
27985
27986         wait_delete_completed # ensure old test cleanups are finished
27987         sleep 3
27988         echo "before create:"
27989         $LFS df -i $MOUNT
27990         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27991
27992         for i in {1..10}; do
27993                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27994                         error "Fail to create $DIR/$tdir/foo$i"
27995         done
27996
27997         # sync ZFS-on-MDS to refresh statfs data
27998         wait_zfs_commit mds1
27999         sleep 3
28000         echo "after create:"
28001         $LFS df -i $MOUNT
28002         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28003
28004         # allow for an llog to be cleaned up during the test
28005         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28006                 error "before ($before_used) + 10 > after ($after_used)"
28007
28008         for i in {1..10}; do
28009                 rm -rf $DIR/$tdir/foo$i ||
28010                         error "Fail to remove $DIR/$tdir/foo$i"
28011         done
28012
28013         # sync ZFS-on-MDS to refresh statfs data
28014         wait_zfs_commit mds1
28015         wait_delete_completed
28016         sleep 3 # avoid MDT return cached statfs
28017         echo "after unlink:"
28018         $LFS df -i $MOUNT
28019         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28020
28021         # allow for an llog to be created during the test
28022         [ $after_used -le $((before_used + 1)) ] ||
28023                 error "after ($after_used) > before ($before_used) + 1"
28024 }
28025 run_test 803a "verify agent object for remote object"
28026
28027 test_803b() {
28028         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28029         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28030                 skip "MDS needs to be newer than 2.13.56"
28031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28032
28033         for i in $(seq 0 $((MDSCOUNT - 1))); do
28034                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28035         done
28036
28037         local before=0
28038         local after=0
28039
28040         local tmp
28041
28042         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28043         for i in $(seq 0 $((MDSCOUNT - 1))); do
28044                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28045                         awk '/getattr/ { print $2 }')
28046                 before=$((before + tmp))
28047         done
28048         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28049         for i in $(seq 0 $((MDSCOUNT - 1))); do
28050                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28051                         awk '/getattr/ { print $2 }')
28052                 after=$((after + tmp))
28053         done
28054
28055         [ $before -eq $after ] || error "getattr count $before != $after"
28056 }
28057 run_test 803b "remote object can getattr from cache"
28058
28059 test_804() {
28060         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28061         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28062                 skip "MDS needs to be newer than 2.10.54"
28063         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28064
28065         mkdir -p $DIR/$tdir
28066         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28067                 error "Fail to create $DIR/$tdir/dir0"
28068
28069         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28070         local dev=$(mdsdevname 2)
28071
28072         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28073                 grep ${fid} || error "NOT found agent entry for dir0"
28074
28075         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28076                 error "Fail to create $DIR/$tdir/dir1"
28077
28078         touch $DIR/$tdir/dir1/foo0 ||
28079                 error "Fail to create $DIR/$tdir/dir1/foo0"
28080         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28081         local rc=0
28082
28083         for idx in $(seq $MDSCOUNT); do
28084                 dev=$(mdsdevname $idx)
28085                 do_facet mds${idx} \
28086                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28087                         grep ${fid} && rc=$idx
28088         done
28089
28090         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28091                 error "Fail to rename foo0 to foo1"
28092         if [ $rc -eq 0 ]; then
28093                 for idx in $(seq $MDSCOUNT); do
28094                         dev=$(mdsdevname $idx)
28095                         do_facet mds${idx} \
28096                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28097                         grep ${fid} && rc=$idx
28098                 done
28099         fi
28100
28101         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28102                 error "Fail to rename foo1 to foo2"
28103         if [ $rc -eq 0 ]; then
28104                 for idx in $(seq $MDSCOUNT); do
28105                         dev=$(mdsdevname $idx)
28106                         do_facet mds${idx} \
28107                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28108                         grep ${fid} && rc=$idx
28109                 done
28110         fi
28111
28112         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28113
28114         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28115                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28116         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28117                 error "Fail to rename foo2 to foo0"
28118         unlink $DIR/$tdir/dir1/foo0 ||
28119                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28120         rm -rf $DIR/$tdir/dir0 ||
28121                 error "Fail to rm $DIR/$tdir/dir0"
28122
28123         for idx in $(seq $MDSCOUNT); do
28124                 rc=0
28125
28126                 stop mds${idx}
28127                 dev=$(mdsdevname $idx)
28128                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28129                         rc=$?
28130                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28131                         error "mount mds$idx failed"
28132                 df $MOUNT > /dev/null 2>&1
28133
28134                 # e2fsck should not return error
28135                 [ $rc -eq 0 ] ||
28136                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28137         done
28138 }
28139 run_test 804 "verify agent entry for remote entry"
28140
28141 cleanup_805() {
28142         do_facet $SINGLEMDS zfs set quota=$old $fsset
28143         unlinkmany $DIR/$tdir/f- 1000000
28144         trap 0
28145 }
28146
28147 test_805() {
28148         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28149         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28150         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28151                 skip "netfree not implemented before 0.7"
28152         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28153                 skip "Need MDS version at least 2.10.57"
28154
28155         local fsset
28156         local freekb
28157         local usedkb
28158         local old
28159         local quota
28160         local pref="osd-zfs.$FSNAME-MDT0000."
28161
28162         # limit available space on MDS dataset to meet nospace issue
28163         # quickly. then ZFS 0.7.2 can use reserved space if asked
28164         # properly (using netfree flag in osd_declare_destroy()
28165         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28166         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28167                 gawk '{print $3}')
28168         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28169         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28170         let "usedkb=usedkb-freekb"
28171         let "freekb=freekb/2"
28172         if let "freekb > 5000"; then
28173                 let "freekb=5000"
28174         fi
28175         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28176         trap cleanup_805 EXIT
28177         mkdir_on_mdt0 $DIR/$tdir
28178         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28179                 error "Can't set PFL layout"
28180         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28181         rm -rf $DIR/$tdir || error "not able to remove"
28182         do_facet $SINGLEMDS zfs set quota=$old $fsset
28183         trap 0
28184 }
28185 run_test 805 "ZFS can remove from full fs"
28186
28187 # Size-on-MDS test
28188 check_lsom_data()
28189 {
28190         local file=$1
28191         local expect=$(stat -c %s $file)
28192
28193         check_lsom_size $1 $expect
28194
28195         local blocks=$($LFS getsom -b $file)
28196         expect=$(stat -c %b $file)
28197         [[ $blocks == $expect ]] ||
28198                 error "$file expected blocks: $expect, got: $blocks"
28199 }
28200
28201 check_lsom_size()
28202 {
28203         local size
28204         local expect=$2
28205
28206         cancel_lru_locks mdc
28207
28208         size=$($LFS getsom -s $1)
28209         [[ $size == $expect ]] ||
28210                 error "$file expected size: $expect, got: $size"
28211 }
28212
28213 test_806() {
28214         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28215                 skip "Need MDS version at least 2.11.52"
28216
28217         local bs=1048576
28218
28219         touch $DIR/$tfile || error "touch $tfile failed"
28220
28221         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28222         save_lustre_params client "llite.*.xattr_cache" > $save
28223         lctl set_param llite.*.xattr_cache=0
28224         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28225
28226         # single-threaded write
28227         echo "Test SOM for single-threaded write"
28228         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28229                 error "write $tfile failed"
28230         check_lsom_size $DIR/$tfile $bs
28231
28232         local num=32
28233         local size=$(($num * $bs))
28234         local offset=0
28235         local i
28236
28237         echo "Test SOM for single client multi-threaded($num) write"
28238         $TRUNCATE $DIR/$tfile 0
28239         for ((i = 0; i < $num; i++)); do
28240                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28241                 local pids[$i]=$!
28242                 offset=$((offset + $bs))
28243         done
28244         for (( i=0; i < $num; i++ )); do
28245                 wait ${pids[$i]}
28246         done
28247         check_lsom_size $DIR/$tfile $size
28248
28249         $TRUNCATE $DIR/$tfile 0
28250         for ((i = 0; i < $num; i++)); do
28251                 offset=$((offset - $bs))
28252                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28253                 local pids[$i]=$!
28254         done
28255         for (( i=0; i < $num; i++ )); do
28256                 wait ${pids[$i]}
28257         done
28258         check_lsom_size $DIR/$tfile $size
28259
28260         # multi-client writes
28261         num=$(get_node_count ${CLIENTS//,/ })
28262         size=$(($num * $bs))
28263         offset=0
28264         i=0
28265
28266         echo "Test SOM for multi-client ($num) writes"
28267         $TRUNCATE $DIR/$tfile 0
28268         for client in ${CLIENTS//,/ }; do
28269                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28270                 local pids[$i]=$!
28271                 i=$((i + 1))
28272                 offset=$((offset + $bs))
28273         done
28274         for (( i=0; i < $num; i++ )); do
28275                 wait ${pids[$i]}
28276         done
28277         check_lsom_size $DIR/$tfile $offset
28278
28279         i=0
28280         $TRUNCATE $DIR/$tfile 0
28281         for client in ${CLIENTS//,/ }; do
28282                 offset=$((offset - $bs))
28283                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28284                 local pids[$i]=$!
28285                 i=$((i + 1))
28286         done
28287         for (( i=0; i < $num; i++ )); do
28288                 wait ${pids[$i]}
28289         done
28290         check_lsom_size $DIR/$tfile $size
28291
28292         # verify truncate
28293         echo "Test SOM for truncate"
28294         $TRUNCATE $DIR/$tfile 1048576
28295         check_lsom_size $DIR/$tfile 1048576
28296         $TRUNCATE $DIR/$tfile 1234
28297         check_lsom_size $DIR/$tfile 1234
28298
28299         # verify SOM blocks count
28300         echo "Verify SOM block count"
28301         $TRUNCATE $DIR/$tfile 0
28302         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28303                 error "failed to write file $tfile"
28304         check_lsom_data $DIR/$tfile
28305 }
28306 run_test 806 "Verify Lazy Size on MDS"
28307
28308 test_807() {
28309         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28310         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28311                 skip "Need MDS version at least 2.11.52"
28312
28313         # Registration step
28314         changelog_register || error "changelog_register failed"
28315         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28316         changelog_users $SINGLEMDS | grep -q $cl_user ||
28317                 error "User $cl_user not found in changelog_users"
28318
28319         rm -rf $DIR/$tdir || error "rm $tdir failed"
28320         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28321         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28322         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28323         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28324                 error "truncate $tdir/trunc failed"
28325
28326         local bs=1048576
28327         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28328                 error "write $tfile failed"
28329
28330         # multi-client wirtes
28331         local num=$(get_node_count ${CLIENTS//,/ })
28332         local offset=0
28333         local i=0
28334
28335         echo "Test SOM for multi-client ($num) writes"
28336         touch $DIR/$tfile || error "touch $tfile failed"
28337         $TRUNCATE $DIR/$tfile 0
28338         for client in ${CLIENTS//,/ }; do
28339                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28340                 local pids[$i]=$!
28341                 i=$((i + 1))
28342                 offset=$((offset + $bs))
28343         done
28344         for (( i=0; i < $num; i++ )); do
28345                 wait ${pids[$i]}
28346         done
28347
28348         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28349         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28350         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28351         check_lsom_data $DIR/$tdir/trunc
28352         check_lsom_data $DIR/$tdir/single_dd
28353         check_lsom_data $DIR/$tfile
28354
28355         rm -rf $DIR/$tdir
28356         # Deregistration step
28357         changelog_deregister || error "changelog_deregister failed"
28358 }
28359 run_test 807 "verify LSOM syncing tool"
28360
28361 check_som_nologged()
28362 {
28363         local lines=$($LFS changelog $FSNAME-MDT0000 |
28364                 grep 'x=trusted.som' | wc -l)
28365         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28366 }
28367
28368 test_808() {
28369         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28370                 skip "Need MDS version at least 2.11.55"
28371
28372         # Registration step
28373         changelog_register || error "changelog_register failed"
28374
28375         touch $DIR/$tfile || error "touch $tfile failed"
28376         check_som_nologged
28377
28378         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28379                 error "write $tfile failed"
28380         check_som_nologged
28381
28382         $TRUNCATE $DIR/$tfile 1234
28383         check_som_nologged
28384
28385         $TRUNCATE $DIR/$tfile 1048576
28386         check_som_nologged
28387
28388         # Deregistration step
28389         changelog_deregister || error "changelog_deregister failed"
28390 }
28391 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28392
28393 check_som_nodata()
28394 {
28395         $LFS getsom $1
28396         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28397 }
28398
28399 test_809() {
28400         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28401                 skip "Need MDS version at least 2.11.56"
28402
28403         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28404                 error "failed to create DoM-only file $DIR/$tfile"
28405         touch $DIR/$tfile || error "touch $tfile failed"
28406         check_som_nodata $DIR/$tfile
28407
28408         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28409                 error "write $tfile failed"
28410         check_som_nodata $DIR/$tfile
28411
28412         $TRUNCATE $DIR/$tfile 1234
28413         check_som_nodata $DIR/$tfile
28414
28415         $TRUNCATE $DIR/$tfile 4097
28416         check_som_nodata $DIR/$file
28417 }
28418 run_test 809 "Verify no SOM xattr store for DoM-only files"
28419
28420 test_810() {
28421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28422         $GSS && skip_env "could not run with gss"
28423         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28424                 skip "OST < 2.12.58 doesn't align checksum"
28425
28426         set_checksums 1
28427         stack_trap "set_checksums $ORIG_CSUM" EXIT
28428         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28429
28430         local csum
28431         local before
28432         local after
28433         for csum in $CKSUM_TYPES; do
28434                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28435                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28436                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28437                         eval set -- $i
28438                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28439                         before=$(md5sum $DIR/$tfile)
28440                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28441                         after=$(md5sum $DIR/$tfile)
28442                         [ "$before" == "$after" ] ||
28443                                 error "$csum: $before != $after bs=$1 seek=$2"
28444                 done
28445         done
28446 }
28447 run_test 810 "partial page writes on ZFS (LU-11663)"
28448
28449 test_812a() {
28450         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28451                 skip "OST < 2.12.51 doesn't support this fail_loc"
28452
28453         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28454         # ensure ost1 is connected
28455         stat $DIR/$tfile >/dev/null || error "can't stat"
28456         wait_osc_import_state client ost1 FULL
28457         # no locks, no reqs to let the connection idle
28458         cancel_lru_locks osc
28459
28460         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28461 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28462         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28463         wait_osc_import_state client ost1 CONNECTING
28464         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28465
28466         stat $DIR/$tfile >/dev/null || error "can't stat file"
28467 }
28468 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28469
28470 test_812b() { # LU-12378
28471         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28472                 skip "OST < 2.12.51 doesn't support this fail_loc"
28473
28474         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28475         # ensure ost1 is connected
28476         stat $DIR/$tfile >/dev/null || error "can't stat"
28477         wait_osc_import_state client ost1 FULL
28478         # no locks, no reqs to let the connection idle
28479         cancel_lru_locks osc
28480
28481         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28482 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28483         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28484         wait_osc_import_state client ost1 CONNECTING
28485         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28486
28487         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28488         wait_osc_import_state client ost1 IDLE
28489 }
28490 run_test 812b "do not drop no resend request for idle connect"
28491
28492 test_812c() {
28493         local old
28494
28495         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28496
28497         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28498         $LFS getstripe $DIR/$tfile
28499         $LCTL set_param osc.*.idle_timeout=10
28500         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28501         # ensure ost1 is connected
28502         stat $DIR/$tfile >/dev/null || error "can't stat"
28503         wait_osc_import_state client ost1 FULL
28504         # no locks, no reqs to let the connection idle
28505         cancel_lru_locks osc
28506
28507 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28508         $LCTL set_param fail_loc=0x80000533
28509         sleep 15
28510         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28511 }
28512 run_test 812c "idle import vs lock enqueue race"
28513
28514 test_813() {
28515         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28516         [ -z "$file_heat_sav" ] && skip "no file heat support"
28517
28518         local readsample
28519         local writesample
28520         local readbyte
28521         local writebyte
28522         local readsample1
28523         local writesample1
28524         local readbyte1
28525         local writebyte1
28526
28527         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28528         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28529
28530         $LCTL set_param -n llite.*.file_heat=1
28531         echo "Turn on file heat"
28532         echo "Period second: $period_second, Decay percentage: $decay_pct"
28533
28534         echo "QQQQ" > $DIR/$tfile
28535         echo "QQQQ" > $DIR/$tfile
28536         echo "QQQQ" > $DIR/$tfile
28537         cat $DIR/$tfile > /dev/null
28538         cat $DIR/$tfile > /dev/null
28539         cat $DIR/$tfile > /dev/null
28540         cat $DIR/$tfile > /dev/null
28541
28542         local out=$($LFS heat_get $DIR/$tfile)
28543
28544         $LFS heat_get $DIR/$tfile
28545         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28546         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28547         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28548         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28549
28550         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28551         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28552         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28553         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28554
28555         sleep $((period_second + 3))
28556         echo "Sleep $((period_second + 3)) seconds..."
28557         # The recursion formula to calculate the heat of the file f is as
28558         # follow:
28559         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28560         # Where Hi is the heat value in the period between time points i*I and
28561         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28562         # to the weight of Ci.
28563         out=$($LFS heat_get $DIR/$tfile)
28564         $LFS heat_get $DIR/$tfile
28565         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28566         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28567         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28568         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28569
28570         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28571                 error "read sample ($readsample) is wrong"
28572         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28573                 error "write sample ($writesample) is wrong"
28574         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28575                 error "read bytes ($readbyte) is wrong"
28576         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28577                 error "write bytes ($writebyte) is wrong"
28578
28579         echo "QQQQ" > $DIR/$tfile
28580         echo "QQQQ" > $DIR/$tfile
28581         echo "QQQQ" > $DIR/$tfile
28582         cat $DIR/$tfile > /dev/null
28583         cat $DIR/$tfile > /dev/null
28584         cat $DIR/$tfile > /dev/null
28585         cat $DIR/$tfile > /dev/null
28586
28587         sleep $((period_second + 3))
28588         echo "Sleep $((period_second + 3)) seconds..."
28589
28590         out=$($LFS heat_get $DIR/$tfile)
28591         $LFS heat_get $DIR/$tfile
28592         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28593         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28594         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28595         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28596
28597         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28598                 4 * $decay_pct) / 100") -eq 1 ] ||
28599                 error "read sample ($readsample1) is wrong"
28600         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28601                 3 * $decay_pct) / 100") -eq 1 ] ||
28602                 error "write sample ($writesample1) is wrong"
28603         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28604                 20 * $decay_pct) / 100") -eq 1 ] ||
28605                 error "read bytes ($readbyte1) is wrong"
28606         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28607                 15 * $decay_pct) / 100") -eq 1 ] ||
28608                 error "write bytes ($writebyte1) is wrong"
28609
28610         echo "Turn off file heat for the file $DIR/$tfile"
28611         $LFS heat_set -o $DIR/$tfile
28612
28613         echo "QQQQ" > $DIR/$tfile
28614         echo "QQQQ" > $DIR/$tfile
28615         echo "QQQQ" > $DIR/$tfile
28616         cat $DIR/$tfile > /dev/null
28617         cat $DIR/$tfile > /dev/null
28618         cat $DIR/$tfile > /dev/null
28619         cat $DIR/$tfile > /dev/null
28620
28621         out=$($LFS heat_get $DIR/$tfile)
28622         $LFS heat_get $DIR/$tfile
28623         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28624         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28625         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28626         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28627
28628         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28629         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28630         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28631         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28632
28633         echo "Trun on file heat for the file $DIR/$tfile"
28634         $LFS heat_set -O $DIR/$tfile
28635
28636         echo "QQQQ" > $DIR/$tfile
28637         echo "QQQQ" > $DIR/$tfile
28638         echo "QQQQ" > $DIR/$tfile
28639         cat $DIR/$tfile > /dev/null
28640         cat $DIR/$tfile > /dev/null
28641         cat $DIR/$tfile > /dev/null
28642         cat $DIR/$tfile > /dev/null
28643
28644         out=$($LFS heat_get $DIR/$tfile)
28645         $LFS heat_get $DIR/$tfile
28646         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28647         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28648         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28649         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28650
28651         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28652         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28653         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28654         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28655
28656         $LFS heat_set -c $DIR/$tfile
28657         $LCTL set_param -n llite.*.file_heat=0
28658         echo "Turn off file heat support for the Lustre filesystem"
28659
28660         echo "QQQQ" > $DIR/$tfile
28661         echo "QQQQ" > $DIR/$tfile
28662         echo "QQQQ" > $DIR/$tfile
28663         cat $DIR/$tfile > /dev/null
28664         cat $DIR/$tfile > /dev/null
28665         cat $DIR/$tfile > /dev/null
28666         cat $DIR/$tfile > /dev/null
28667
28668         out=$($LFS heat_get $DIR/$tfile)
28669         $LFS heat_get $DIR/$tfile
28670         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28671         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28672         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28673         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28674
28675         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28676         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28677         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28678         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28679
28680         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28681         rm -f $DIR/$tfile
28682 }
28683 run_test 813 "File heat verfication"
28684
28685 test_814()
28686 {
28687         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28688         echo -n y >> $DIR/$tfile
28689         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28690         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28691 }
28692 run_test 814 "sparse cp works as expected (LU-12361)"
28693
28694 test_815()
28695 {
28696         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28697         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28698 }
28699 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28700
28701 test_816() {
28702         local ost1_imp=$(get_osc_import_name client ost1)
28703         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28704                          cut -d'.' -f2)
28705
28706         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28707         # ensure ost1 is connected
28708
28709         stat $DIR/$tfile >/dev/null || error "can't stat"
28710         wait_osc_import_state client ost1 FULL
28711         # no locks, no reqs to let the connection idle
28712         cancel_lru_locks osc
28713         lru_resize_disable osc
28714         local before
28715         local now
28716         before=$($LCTL get_param -n \
28717                  ldlm.namespaces.$imp_name.lru_size)
28718
28719         wait_osc_import_state client ost1 IDLE
28720         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28721         now=$($LCTL get_param -n \
28722               ldlm.namespaces.$imp_name.lru_size)
28723         [ $before == $now ] || error "lru_size changed $before != $now"
28724 }
28725 run_test 816 "do not reset lru_resize on idle reconnect"
28726
28727 cleanup_817() {
28728         umount $tmpdir
28729         exportfs -u localhost:$DIR/nfsexp
28730         rm -rf $DIR/nfsexp
28731 }
28732
28733 test_817() {
28734         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28735
28736         mkdir -p $DIR/nfsexp
28737         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28738                 error "failed to export nfs"
28739
28740         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28741         stack_trap cleanup_817 EXIT
28742
28743         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28744                 error "failed to mount nfs to $tmpdir"
28745
28746         cp /bin/true $tmpdir
28747         $DIR/nfsexp/true || error "failed to execute 'true' command"
28748 }
28749 run_test 817 "nfsd won't cache write lock for exec file"
28750
28751 test_818() {
28752         test_mkdir -i0 -c1 $DIR/$tdir
28753         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28754         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28755         stop $SINGLEMDS
28756
28757         # restore osp-syn threads
28758         stack_trap "fail $SINGLEMDS"
28759
28760         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28761         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28762         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28763                 error "start $SINGLEMDS failed"
28764         rm -rf $DIR/$tdir
28765
28766         local testid=$(echo $TESTNAME | tr '_' ' ')
28767
28768         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28769                 grep "run LFSCK" || error "run LFSCK is not suggested"
28770 }
28771 run_test 818 "unlink with failed llog"
28772
28773 test_819a() {
28774         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28775         cancel_lru_locks osc
28776         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28777         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28778         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28779         rm -f $TDIR/$tfile
28780 }
28781 run_test 819a "too big niobuf in read"
28782
28783 test_819b() {
28784         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28785         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28786         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28787         cancel_lru_locks osc
28788         sleep 1
28789         rm -f $TDIR/$tfile
28790 }
28791 run_test 819b "too big niobuf in write"
28792
28793
28794 function test_820_start_ost() {
28795         sleep 5
28796
28797         for num in $(seq $OSTCOUNT); do
28798                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28799         done
28800 }
28801
28802 test_820() {
28803         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28804
28805         mkdir $DIR/$tdir
28806         umount_client $MOUNT || error "umount failed"
28807         for num in $(seq $OSTCOUNT); do
28808                 stop ost$num
28809         done
28810
28811         # mount client with no active OSTs
28812         # so that the client can't initialize max LOV EA size
28813         # from OSC notifications
28814         mount_client $MOUNT || error "mount failed"
28815         # delay OST starting to keep this 0 max EA size for a while
28816         test_820_start_ost &
28817
28818         # create a directory on MDS2
28819         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28820                 error "Failed to create directory"
28821         # open intent should update default EA size
28822         # see mdc_update_max_ea_from_body()
28823         # notice this is the very first RPC to MDS2
28824         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28825         ret=$?
28826         echo $out
28827         # With SSK, this situation can lead to -EPERM being returned.
28828         # In that case, simply retry.
28829         if [ $ret -ne 0 ] && $SHARED_KEY; then
28830                 if echo "$out" | grep -q "not permitted"; then
28831                         cp /etc/services $DIR/$tdir/mds2
28832                         ret=$?
28833                 fi
28834         fi
28835         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28836 }
28837 run_test 820 "update max EA from open intent"
28838
28839 test_823() {
28840         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28841         local OST_MAX_PRECREATE=20000
28842
28843         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28844                 skip "Need MDS version at least 2.14.56"
28845
28846         save_lustre_params mds1 \
28847                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28848         do_facet $SINGLEMDS "$LCTL set_param -n \
28849                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28850         do_facet $SINGLEMDS "$LCTL set_param -n \
28851                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28852
28853         stack_trap "restore_lustre_params < $p; rm $p"
28854
28855         do_facet $SINGLEMDS "$LCTL set_param -n \
28856                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28857
28858         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28859                       osp.$FSNAME-OST0000*MDT0000.create_count")
28860         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28861                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28862         local expect_count=$(((($max/2)/256) * 256))
28863
28864         log "setting create_count to 100200:"
28865         log " -result- count: $count with max: $max, expecting: $expect_count"
28866
28867         [[ $count -eq expect_count ]] ||
28868                 error "Create count not set to max precreate."
28869 }
28870 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28871
28872 test_831() {
28873         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28874                 skip "Need MDS version 2.14.56"
28875
28876         local sync_changes=$(do_facet $SINGLEMDS \
28877                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28878
28879         [ "$sync_changes" -gt 100 ] &&
28880                 skip "Sync changes $sync_changes > 100 already"
28881
28882         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28883
28884         $LFS mkdir -i 0 $DIR/$tdir
28885         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28886
28887         save_lustre_params mds1 \
28888                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28889         save_lustre_params mds1 \
28890                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28891
28892         do_facet mds1 "$LCTL set_param -n \
28893                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28894                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28895         stack_trap "restore_lustre_params < $p" EXIT
28896
28897         createmany -o $DIR/$tdir/f- 1000
28898         unlinkmany $DIR/$tdir/f- 1000 &
28899         local UNLINK_PID=$!
28900
28901         while sleep 1; do
28902                 sync_changes=$(do_facet mds1 \
28903                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28904                 # the check in the code is racy, fail the test
28905                 # if the value above the limit by 10.
28906                 [ $sync_changes -gt 110 ] && {
28907                         kill -2 $UNLINK_PID
28908                         wait
28909                         error "osp changes throttling failed, $sync_changes>110"
28910                 }
28911                 kill -0 $UNLINK_PID 2> /dev/null || break
28912         done
28913         wait
28914 }
28915 run_test 831 "throttling unlink/setattr queuing on OSP"
28916
28917 test_832() {
28918         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
28919         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
28920                 skip "Need MDS version 2.15.52+"
28921         is_rmentry_supported || skip "rm_entry not supported"
28922
28923         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28924         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
28925         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
28926                 error "mkdir remote_dir failed"
28927         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
28928                 error "mkdir striped_dir failed"
28929         touch $DIR/$tdir/file || error "touch file failed"
28930         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
28931         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
28932 }
28933 run_test 832 "lfs rm_entry"
28934
28935 #
28936 # tests that do cleanup/setup should be run at the end
28937 #
28938
28939 test_900() {
28940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28941         local ls
28942
28943         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28944         $LCTL set_param fail_loc=0x903
28945
28946         cancel_lru_locks MGC
28947
28948         FAIL_ON_ERROR=true cleanup
28949         FAIL_ON_ERROR=true setup
28950 }
28951 run_test 900 "umount should not race with any mgc requeue thread"
28952
28953 # LUS-6253/LU-11185
28954 test_901() {
28955         local old
28956         local count
28957         local oldc
28958         local newc
28959         local olds
28960         local news
28961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28962
28963         # some get_param have a bug to handle dot in param name
28964         cancel_lru_locks MGC
28965         old=$(mount -t lustre | wc -l)
28966         # 1 config+sptlrpc
28967         # 2 params
28968         # 3 nodemap
28969         # 4 IR
28970         old=$((old * 4))
28971         oldc=0
28972         count=0
28973         while [ $old -ne $oldc ]; do
28974                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28975                 sleep 1
28976                 ((count++))
28977                 if [ $count -ge $TIMEOUT ]; then
28978                         error "too large timeout"
28979                 fi
28980         done
28981         umount_client $MOUNT || error "umount failed"
28982         mount_client $MOUNT || error "mount failed"
28983         cancel_lru_locks MGC
28984         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28985
28986         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28987
28988         return 0
28989 }
28990 run_test 901 "don't leak a mgc lock on client umount"
28991
28992 # LU-13377
28993 test_902() {
28994         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28995                 skip "client does not have LU-13377 fix"
28996         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28997         $LCTL set_param fail_loc=0x1415
28998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28999         cancel_lru_locks osc
29000         rm -f $DIR/$tfile
29001 }
29002 run_test 902 "test short write doesn't hang lustre"
29003
29004 # LU-14711
29005 test_903() {
29006         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29007         echo "blah" > $DIR/${tfile}-2
29008         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29009         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29010         $LCTL set_param fail_loc=0x417 fail_val=20
29011
29012         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29013         sleep 1 # To start the destroy
29014         wait_destroy_complete 150 || error "Destroy taking too long"
29015         cat $DIR/$tfile > /dev/null || error "Evicted"
29016 }
29017 run_test 903 "Test long page discard does not cause evictions"
29018
29019 test_904() {
29020         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29021         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29022                 grep -q project || skip "skip project quota not supported"
29023
29024         local testfile="$DIR/$tdir/$tfile"
29025         local xattr="trusted.projid"
29026         local projid
29027         local mdts=$(comma_list $(mdts_nodes))
29028         local saved=$(do_facet mds1 $LCTL get_param -n \
29029                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29030
29031         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29032         stack_trap "do_nodes $mdts $LCTL set_param \
29033                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29034
29035         mkdir -p $DIR/$tdir
29036         touch $testfile
29037         #hide projid xattr on server
29038         $LFS project -p 1 $testfile ||
29039                 error "set $testfile project id failed"
29040         getfattr -m - $testfile | grep $xattr &&
29041                 error "do not show trusted.projid when disabled on server"
29042         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29043         #should be hidden when projid is 0
29044         $LFS project -p 0 $testfile ||
29045                 error "set $testfile project id failed"
29046         getfattr -m - $testfile | grep $xattr &&
29047                 error "do not show trusted.projid with project ID 0"
29048
29049         #still can getxattr explicitly
29050         projid=$(getfattr -n $xattr $testfile |
29051                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29052         [ $projid == "0" ] ||
29053                 error "projid expected 0 not $projid"
29054
29055         #set the projid via setxattr
29056         setfattr -n $xattr -v "1000" $testfile ||
29057                 error "setattr failed with $?"
29058         projid=($($LFS project $testfile))
29059         [ ${projid[0]} == "1000" ] ||
29060                 error "projid expected 1000 not $projid"
29061
29062         #check the new projid via getxattr
29063         $LFS project -p 1001 $testfile ||
29064                 error "set $testfile project id failed"
29065         getfattr -m - $testfile | grep $xattr ||
29066                 error "should show trusted.projid when project ID != 0"
29067         projid=$(getfattr -n $xattr $testfile |
29068                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29069         [ $projid == "1001" ] ||
29070                 error "projid expected 1001 not $projid"
29071
29072         #try to set invalid projid
29073         setfattr -n $xattr -v "4294967295" $testfile &&
29074                 error "set invalid projid should fail"
29075
29076         #remove the xattr means setting projid to 0
29077         setfattr -x $xattr $testfile ||
29078                 error "setfattr failed with $?"
29079         projid=($($LFS project $testfile))
29080         [ ${projid[0]} == "0" ] ||
29081                 error "projid expected 0 not $projid"
29082
29083         #should be hidden when parent has inherit flag and same projid
29084         $LFS project -srp 1002 $DIR/$tdir ||
29085                 error "set $tdir project id failed"
29086         getfattr -m - $testfile | grep $xattr &&
29087                 error "do not show trusted.projid with inherit flag"
29088
29089         #still can getxattr explicitly
29090         projid=$(getfattr -n $xattr $testfile |
29091                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29092         [ $projid == "1002" ] ||
29093                 error "projid expected 1002 not $projid"
29094 }
29095 run_test 904 "virtual project ID xattr"
29096
29097 # LU-8582
29098 test_905() {
29099         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29100                 skip "lustre < 2.8.54 does not support ladvise"
29101
29102         remote_ost_nodsh && skip "remote OST with nodsh"
29103         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29104
29105         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29106
29107         #define OBD_FAIL_OST_OPCODE 0x253
29108         # OST_LADVISE = 21
29109         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29110         $LFS ladvise -a willread $DIR/$tfile &&
29111                 error "unexpected success of ladvise with fault injection"
29112         $LFS ladvise -a willread $DIR/$tfile |&
29113                 grep -q "Operation not supported"
29114         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29115 }
29116 run_test 905 "bad or new opcode should not stuck client"
29117
29118 test_906() {
29119         grep -q io_uring_setup /proc/kallsyms ||
29120                 skip "Client OS does not support io_uring I/O engine"
29121         io_uring_probe || skip "kernel does not support io_uring fully"
29122         which fio || skip_env "no fio installed"
29123         fio --enghelp | grep -q io_uring ||
29124                 skip_env "fio does not support io_uring I/O engine"
29125
29126         local file=$DIR/$tfile
29127         local ioengine="io_uring"
29128         local numjobs=2
29129         local size=50M
29130
29131         fio --name=seqwrite --ioengine=$ioengine        \
29132                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29133                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29134                 error "fio seqwrite $file failed"
29135
29136         fio --name=seqread --ioengine=$ioengine \
29137                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29138                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29139                 error "fio seqread $file failed"
29140
29141         rm -f $file || error "rm -f $file failed"
29142 }
29143 run_test 906 "Simple test for io_uring I/O engine via fio"
29144
29145
29146 complete $SECONDS
29147 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29148 check_and_cleanup_lustre
29149 if [ "$I_MOUNTED" != "yes" ]; then
29150         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29151 fi
29152 exit_status