Whamcloud - gitweb
LU-16412 llite: check truncated page in ->readpage()
[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 test_101k()
11156 {
11157         local file=$DIR/$tfile
11158
11159         check_set_fallocate_or_skip
11160
11161         $LCTL set_param -n llite.*.read_ahead_stats=0
11162         fallocate -l 16K $file || error "failed to fallocate $file"
11163         cancel_lru_locks osc
11164         $MULTIOP $file or1048576c
11165         $LCTL get_param llite.*.read_ahead_stats
11166 }
11167 run_test 101k "read ahead for small file"
11168
11169 setup_test102() {
11170         test_mkdir $DIR/$tdir
11171         chown $RUNAS_ID $DIR/$tdir
11172         STRIPE_SIZE=65536
11173         STRIPE_OFFSET=1
11174         STRIPE_COUNT=$OSTCOUNT
11175         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11176
11177         trap cleanup_test102 EXIT
11178         cd $DIR
11179         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11180         cd $DIR/$tdir
11181         for num in 1 2 3 4; do
11182                 for count in $(seq 1 $STRIPE_COUNT); do
11183                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11184                                 local size=`expr $STRIPE_SIZE \* $num`
11185                                 local file=file"$num-$idx-$count"
11186                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11187                         done
11188                 done
11189         done
11190
11191         cd $DIR
11192         $1 tar cf $TMP/f102.tar $tdir --xattrs
11193 }
11194
11195 cleanup_test102() {
11196         trap 0
11197         rm -f $TMP/f102.tar
11198         rm -rf $DIR/d0.sanity/d102
11199 }
11200
11201 test_102a() {
11202         [ "$UID" != 0 ] && skip "must run as root"
11203         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11204                 skip_env "must have user_xattr"
11205
11206         [ -z "$(which setfattr 2>/dev/null)" ] &&
11207                 skip_env "could not find setfattr"
11208
11209         local testfile=$DIR/$tfile
11210
11211         touch $testfile
11212         echo "set/get xattr..."
11213         setfattr -n trusted.name1 -v value1 $testfile ||
11214                 error "setfattr -n trusted.name1=value1 $testfile failed"
11215         getfattr -n trusted.name1 $testfile 2> /dev/null |
11216           grep "trusted.name1=.value1" ||
11217                 error "$testfile missing trusted.name1=value1"
11218
11219         setfattr -n user.author1 -v author1 $testfile ||
11220                 error "setfattr -n user.author1=author1 $testfile failed"
11221         getfattr -n user.author1 $testfile 2> /dev/null |
11222           grep "user.author1=.author1" ||
11223                 error "$testfile missing trusted.author1=author1"
11224
11225         echo "listxattr..."
11226         setfattr -n trusted.name2 -v value2 $testfile ||
11227                 error "$testfile unable to set trusted.name2"
11228         setfattr -n trusted.name3 -v value3 $testfile ||
11229                 error "$testfile unable to set trusted.name3"
11230         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11231             grep "trusted.name" | wc -l) -eq 3 ] ||
11232                 error "$testfile missing 3 trusted.name xattrs"
11233
11234         setfattr -n user.author2 -v author2 $testfile ||
11235                 error "$testfile unable to set user.author2"
11236         setfattr -n user.author3 -v author3 $testfile ||
11237                 error "$testfile unable to set user.author3"
11238         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11239             grep "user.author" | wc -l) -eq 3 ] ||
11240                 error "$testfile missing 3 user.author xattrs"
11241
11242         echo "remove xattr..."
11243         setfattr -x trusted.name1 $testfile ||
11244                 error "$testfile error deleting trusted.name1"
11245         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11246                 error "$testfile did not delete trusted.name1 xattr"
11247
11248         setfattr -x user.author1 $testfile ||
11249                 error "$testfile error deleting user.author1"
11250         echo "set lustre special xattr ..."
11251         $LFS setstripe -c1 $testfile
11252         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11253                 awk -F "=" '/trusted.lov/ { print $2 }' )
11254         setfattr -n "trusted.lov" -v $lovea $testfile ||
11255                 error "$testfile doesn't ignore setting trusted.lov again"
11256         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11257                 error "$testfile allow setting invalid trusted.lov"
11258         rm -f $testfile
11259 }
11260 run_test 102a "user xattr test =================================="
11261
11262 check_102b_layout() {
11263         local layout="$*"
11264         local testfile=$DIR/$tfile
11265
11266         echo "test layout '$layout'"
11267         $LFS setstripe $layout $testfile || error "setstripe failed"
11268         $LFS getstripe -y $testfile
11269
11270         echo "get/set/list trusted.lov xattr ..." # b=10930
11271         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11272         [[ "$value" =~ "trusted.lov" ]] ||
11273                 error "can't get trusted.lov from $testfile"
11274         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11275                 error "getstripe failed"
11276
11277         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11278
11279         value=$(cut -d= -f2 <<<$value)
11280         # LU-13168: truncated xattr should fail if short lov_user_md header
11281         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11282                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11283         for len in $lens; do
11284                 echo "setfattr $len $testfile.2"
11285                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11286                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11287         done
11288         local stripe_size=$($LFS getstripe -S $testfile.2)
11289         local stripe_count=$($LFS getstripe -c $testfile.2)
11290         [[ $stripe_size -eq 65536 ]] ||
11291                 error "stripe size $stripe_size != 65536"
11292         [[ $stripe_count -eq $stripe_count_orig ]] ||
11293                 error "stripe count $stripe_count != $stripe_count_orig"
11294         rm $testfile $testfile.2
11295 }
11296
11297 test_102b() {
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         # check plain layout
11303         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11304
11305         # and also check composite layout
11306         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11307
11308 }
11309 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11310
11311 test_102c() {
11312         [ -z "$(which setfattr 2>/dev/null)" ] &&
11313                 skip_env "could not find setfattr"
11314         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11315
11316         # b10930: get/set/list lustre.lov xattr
11317         echo "get/set/list lustre.lov xattr ..."
11318         test_mkdir $DIR/$tdir
11319         chown $RUNAS_ID $DIR/$tdir
11320         local testfile=$DIR/$tdir/$tfile
11321         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11322                 error "setstripe failed"
11323         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11324                 error "getstripe failed"
11325         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11326         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11327
11328         local testfile2=${testfile}2
11329         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11330                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11331
11332         $RUNAS $MCREATE $testfile2
11333         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11334         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11335         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11336         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11337         [ $stripe_count -eq $STRIPECOUNT ] ||
11338                 error "stripe count $stripe_count != $STRIPECOUNT"
11339 }
11340 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11341
11342 compare_stripe_info1() {
11343         local stripe_index_all_zero=true
11344
11345         for num in 1 2 3 4; do
11346                 for count in $(seq 1 $STRIPE_COUNT); do
11347                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11348                                 local size=$((STRIPE_SIZE * num))
11349                                 local file=file"$num-$offset-$count"
11350                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11351                                 [[ $stripe_size -ne $size ]] &&
11352                                     error "$file: size $stripe_size != $size"
11353                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11354                                 # allow fewer stripes to be created, ORI-601
11355                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11356                                     error "$file: count $stripe_count != $count"
11357                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11358                                 [[ $stripe_index -ne 0 ]] &&
11359                                         stripe_index_all_zero=false
11360                         done
11361                 done
11362         done
11363         $stripe_index_all_zero &&
11364                 error "all files are being extracted starting from OST index 0"
11365         return 0
11366 }
11367
11368 have_xattrs_include() {
11369         tar --help | grep -q xattrs-include &&
11370                 echo --xattrs-include="lustre.*"
11371 }
11372
11373 test_102d() {
11374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11375         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11376
11377         XINC=$(have_xattrs_include)
11378         setup_test102
11379         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11380         cd $DIR/$tdir/$tdir
11381         compare_stripe_info1
11382 }
11383 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11384
11385 test_102f() {
11386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11387         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11388
11389         XINC=$(have_xattrs_include)
11390         setup_test102
11391         test_mkdir $DIR/$tdir.restore
11392         cd $DIR
11393         tar cf - --xattrs $tdir | tar xf - \
11394                 -C $DIR/$tdir.restore --xattrs $XINC
11395         cd $DIR/$tdir.restore/$tdir
11396         compare_stripe_info1
11397 }
11398 run_test 102f "tar copy files, not keep osts"
11399
11400 grow_xattr() {
11401         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11402                 skip "must have user_xattr"
11403         [ -z "$(which setfattr 2>/dev/null)" ] &&
11404                 skip_env "could not find setfattr"
11405         [ -z "$(which getfattr 2>/dev/null)" ] &&
11406                 skip_env "could not find getfattr"
11407
11408         local xsize=${1:-1024}  # in bytes
11409         local file=$DIR/$tfile
11410         local value="$(generate_string $xsize)"
11411         local xbig=trusted.big
11412         local toobig=$2
11413
11414         touch $file
11415         log "save $xbig on $file"
11416         if [ -z "$toobig" ]
11417         then
11418                 setfattr -n $xbig -v $value $file ||
11419                         error "saving $xbig on $file failed"
11420         else
11421                 setfattr -n $xbig -v $value $file &&
11422                         error "saving $xbig on $file succeeded"
11423                 return 0
11424         fi
11425
11426         local orig=$(get_xattr_value $xbig $file)
11427         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11428
11429         local xsml=trusted.sml
11430         log "save $xsml on $file"
11431         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11432
11433         local new=$(get_xattr_value $xbig $file)
11434         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11435
11436         log "grow $xsml on $file"
11437         setfattr -n $xsml -v "$value" $file ||
11438                 error "growing $xsml on $file failed"
11439
11440         new=$(get_xattr_value $xbig $file)
11441         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11442         log "$xbig still valid after growing $xsml"
11443
11444         rm -f $file
11445 }
11446
11447 test_102h() { # bug 15777
11448         grow_xattr 1024
11449 }
11450 run_test 102h "grow xattr from inside inode to external block"
11451
11452 test_102ha() {
11453         large_xattr_enabled || skip_env "ea_inode feature disabled"
11454
11455         echo "setting xattr of max xattr size: $(max_xattr_size)"
11456         grow_xattr $(max_xattr_size)
11457
11458         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11459         echo "This should fail:"
11460         grow_xattr $(($(max_xattr_size) + 10)) 1
11461 }
11462 run_test 102ha "grow xattr from inside inode to external inode"
11463
11464 test_102i() { # bug 17038
11465         [ -z "$(which getfattr 2>/dev/null)" ] &&
11466                 skip "could not find getfattr"
11467
11468         touch $DIR/$tfile
11469         ln -s $DIR/$tfile $DIR/${tfile}link
11470         getfattr -n trusted.lov $DIR/$tfile ||
11471                 error "lgetxattr on $DIR/$tfile failed"
11472         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11473                 grep -i "no such attr" ||
11474                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11475         rm -f $DIR/$tfile $DIR/${tfile}link
11476 }
11477 run_test 102i "lgetxattr test on symbolic link ============"
11478
11479 test_102j() {
11480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11481         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11482
11483         XINC=$(have_xattrs_include)
11484         setup_test102 "$RUNAS"
11485         chown $RUNAS_ID $DIR/$tdir
11486         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11487         cd $DIR/$tdir/$tdir
11488         compare_stripe_info1 "$RUNAS"
11489 }
11490 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11491
11492 test_102k() {
11493         [ -z "$(which setfattr 2>/dev/null)" ] &&
11494                 skip "could not find setfattr"
11495
11496         touch $DIR/$tfile
11497         # b22187 just check that does not crash for regular file.
11498         setfattr -n trusted.lov $DIR/$tfile
11499         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11500         local test_kdir=$DIR/$tdir
11501         test_mkdir $test_kdir
11502         local default_size=$($LFS getstripe -S $test_kdir)
11503         local default_count=$($LFS getstripe -c $test_kdir)
11504         local default_offset=$($LFS getstripe -i $test_kdir)
11505         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11506                 error 'dir setstripe failed'
11507         setfattr -n trusted.lov $test_kdir
11508         local stripe_size=$($LFS getstripe -S $test_kdir)
11509         local stripe_count=$($LFS getstripe -c $test_kdir)
11510         local stripe_offset=$($LFS getstripe -i $test_kdir)
11511         [ $stripe_size -eq $default_size ] ||
11512                 error "stripe size $stripe_size != $default_size"
11513         [ $stripe_count -eq $default_count ] ||
11514                 error "stripe count $stripe_count != $default_count"
11515         [ $stripe_offset -eq $default_offset ] ||
11516                 error "stripe offset $stripe_offset != $default_offset"
11517         rm -rf $DIR/$tfile $test_kdir
11518 }
11519 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11520
11521 test_102l() {
11522         [ -z "$(which getfattr 2>/dev/null)" ] &&
11523                 skip "could not find getfattr"
11524
11525         # LU-532 trusted. xattr is invisible to non-root
11526         local testfile=$DIR/$tfile
11527
11528         touch $testfile
11529
11530         echo "listxattr as user..."
11531         chown $RUNAS_ID $testfile
11532         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11533             grep -q "trusted" &&
11534                 error "$testfile trusted xattrs are user visible"
11535
11536         return 0;
11537 }
11538 run_test 102l "listxattr size test =================================="
11539
11540 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11541         local path=$DIR/$tfile
11542         touch $path
11543
11544         listxattr_size_check $path || error "listattr_size_check $path failed"
11545 }
11546 run_test 102m "Ensure listxattr fails on small bufffer ========"
11547
11548 cleanup_test102
11549
11550 getxattr() { # getxattr path name
11551         # Return the base64 encoding of the value of xattr name on path.
11552         local path=$1
11553         local name=$2
11554
11555         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11556         # file: $path
11557         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11558         #
11559         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11560
11561         getfattr --absolute-names --encoding=base64 --name=$name $path |
11562                 awk -F= -v name=$name '$1 == name {
11563                         print substr($0, index($0, "=") + 1);
11564         }'
11565 }
11566
11567 test_102n() { # LU-4101 mdt: protect internal xattrs
11568         [ -z "$(which setfattr 2>/dev/null)" ] &&
11569                 skip "could not find setfattr"
11570         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11571         then
11572                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11573         fi
11574
11575         local file0=$DIR/$tfile.0
11576         local file1=$DIR/$tfile.1
11577         local xattr0=$TMP/$tfile.0
11578         local xattr1=$TMP/$tfile.1
11579         local namelist="lov lma lmv link fid version som hsm"
11580         local name
11581         local value
11582
11583         rm -rf $file0 $file1 $xattr0 $xattr1
11584         touch $file0 $file1
11585
11586         # Get 'before' xattrs of $file1.
11587         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11588
11589         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11590                 namelist+=" lfsck_namespace"
11591         for name in $namelist; do
11592                 # Try to copy xattr from $file0 to $file1.
11593                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11594
11595                 setfattr --name=trusted.$name --value="$value" $file1 ||
11596                         error "setxattr 'trusted.$name' failed"
11597
11598                 # Try to set a garbage xattr.
11599                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11600
11601                 if [[ x$name == "xlov" ]]; then
11602                         setfattr --name=trusted.lov --value="$value" $file1 &&
11603                         error "setxattr invalid 'trusted.lov' success"
11604                 else
11605                         setfattr --name=trusted.$name --value="$value" $file1 ||
11606                                 error "setxattr invalid 'trusted.$name' failed"
11607                 fi
11608
11609                 # Try to remove the xattr from $file1. We don't care if this
11610                 # appears to succeed or fail, we just don't want there to be
11611                 # any changes or crashes.
11612                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11613         done
11614
11615         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11616         then
11617                 name="lfsck_ns"
11618                 # Try to copy xattr from $file0 to $file1.
11619                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11620
11621                 setfattr --name=trusted.$name --value="$value" $file1 ||
11622                         error "setxattr 'trusted.$name' failed"
11623
11624                 # Try to set a garbage xattr.
11625                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11626
11627                 setfattr --name=trusted.$name --value="$value" $file1 ||
11628                         error "setxattr 'trusted.$name' failed"
11629
11630                 # Try to remove the xattr from $file1. We don't care if this
11631                 # appears to succeed or fail, we just don't want there to be
11632                 # any changes or crashes.
11633                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11634         fi
11635
11636         # Get 'after' xattrs of file1.
11637         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11638
11639         if ! diff $xattr0 $xattr1; then
11640                 error "before and after xattrs of '$file1' differ"
11641         fi
11642
11643         rm -rf $file0 $file1 $xattr0 $xattr1
11644
11645         return 0
11646 }
11647 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11648
11649 test_102p() { # LU-4703 setxattr did not check ownership
11650         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11651                 skip "MDS needs to be at least 2.5.56"
11652
11653         local testfile=$DIR/$tfile
11654
11655         touch $testfile
11656
11657         echo "setfacl as user..."
11658         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11659         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11660
11661         echo "setfattr as user..."
11662         setfacl -m "u:$RUNAS_ID:---" $testfile
11663         $RUNAS setfattr -x system.posix_acl_access $testfile
11664         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11665 }
11666 run_test 102p "check setxattr(2) correctly fails without permission"
11667
11668 test_102q() {
11669         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11670                 skip "MDS needs to be at least 2.6.92"
11671
11672         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11673 }
11674 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11675
11676 test_102r() {
11677         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11678                 skip "MDS needs to be at least 2.6.93"
11679
11680         touch $DIR/$tfile || error "touch"
11681         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11682         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11683         rm $DIR/$tfile || error "rm"
11684
11685         #normal directory
11686         mkdir -p $DIR/$tdir || error "mkdir"
11687         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11688         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11689         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11690                 error "$testfile error deleting user.author1"
11691         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11692                 grep "user.$(basename $tdir)" &&
11693                 error "$tdir did not delete user.$(basename $tdir)"
11694         rmdir $DIR/$tdir || error "rmdir"
11695
11696         #striped directory
11697         test_mkdir $DIR/$tdir
11698         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11699         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11700         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11701                 error "$testfile error deleting user.author1"
11702         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11703                 grep "user.$(basename $tdir)" &&
11704                 error "$tdir did not delete user.$(basename $tdir)"
11705         rmdir $DIR/$tdir || error "rm striped dir"
11706 }
11707 run_test 102r "set EAs with empty values"
11708
11709 test_102s() {
11710         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11711                 skip "MDS needs to be at least 2.11.52"
11712
11713         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11714
11715         save_lustre_params client "llite.*.xattr_cache" > $save
11716
11717         for cache in 0 1; do
11718                 lctl set_param llite.*.xattr_cache=$cache
11719
11720                 rm -f $DIR/$tfile
11721                 touch $DIR/$tfile || error "touch"
11722                 for prefix in lustre security system trusted user; do
11723                         # Note getxattr() may fail with 'Operation not
11724                         # supported' or 'No such attribute' depending
11725                         # on prefix and cache.
11726                         getfattr -n $prefix.n102s $DIR/$tfile &&
11727                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11728                 done
11729         done
11730
11731         restore_lustre_params < $save
11732 }
11733 run_test 102s "getting nonexistent xattrs should fail"
11734
11735 test_102t() {
11736         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11737                 skip "MDS needs to be at least 2.11.52"
11738
11739         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11740
11741         save_lustre_params client "llite.*.xattr_cache" > $save
11742
11743         for cache in 0 1; do
11744                 lctl set_param llite.*.xattr_cache=$cache
11745
11746                 for buf_size in 0 256; do
11747                         rm -f $DIR/$tfile
11748                         touch $DIR/$tfile || error "touch"
11749                         setfattr -n user.multiop $DIR/$tfile
11750                         $MULTIOP $DIR/$tfile oa$buf_size ||
11751                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11752                 done
11753         done
11754
11755         restore_lustre_params < $save
11756 }
11757 run_test 102t "zero length xattr values handled correctly"
11758
11759 run_acl_subtest()
11760 {
11761         local test=$LUSTRE/tests/acl/$1.test
11762         local tmp=$(mktemp -t $1-XXXXXX).test
11763         local bin=$2
11764         local dmn=$3
11765         local grp=$4
11766         local nbd=$5
11767         export LANG=C
11768
11769
11770         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11771         local sedgroups="-e s/:users/:$grp/g"
11772         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11773
11774         sed $sedusers $sedgroups < $test > $tmp
11775         stack_trap "rm -f $tmp"
11776         [[ -s $tmp ]] || error "sed failed to create test script"
11777
11778         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11779         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11780 }
11781
11782 test_103a() {
11783         [ "$UID" != 0 ] && skip "must run as root"
11784         $GSS && skip_env "could not run under gss"
11785         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11786                 skip_env "must have acl enabled"
11787         which setfacl || skip_env "could not find setfacl"
11788         remote_mds_nodsh && skip "remote MDS with nodsh"
11789
11790         ACLBIN=${ACLBIN:-"bin"}
11791         ACLDMN=${ACLDMN:-"daemon"}
11792         ACLGRP=${ACLGRP:-"users"}
11793         ACLNBD=${ACLNBD:-"nobody"}
11794
11795         if ! id $ACLBIN ||
11796            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11797                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11798                 ACLBIN=$USER0
11799                 if ! id $ACLBIN ; then
11800                         cat /etc/passwd
11801                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11802                 fi
11803         fi
11804         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11805            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11806                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11807                 ACLDMN=$USER1
11808                 if ! id $ACLDMN ; then
11809                         cat /etc/passwd
11810                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11811                 fi
11812         fi
11813         if ! getent group $ACLGRP; then
11814                 echo "missing 'users' group '$ACLGRP', using '$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         fi
11822
11823         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11824         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11825         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11826
11827         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11828                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11829                 ACLGRP="$TSTUSR"
11830                 if ! getent group $ACLGRP; then
11831                         echo "cannot find group '$ACLGRP', adding it"
11832                         cat /etc/group
11833                         add_group 60000 $ACLGRP
11834                 fi
11835                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11836                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11837                         cat /etc/group
11838                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11839                 fi
11840         fi
11841
11842         gpasswd -a $ACLDMN $ACLBIN ||
11843                 error "setting client group failed"             # LU-5641
11844         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11845                 error "setting MDS group failed"                # LU-5641
11846
11847         declare -a identity_old
11848
11849         for num in $(seq $MDSCOUNT); do
11850                 switch_identity $num true || identity_old[$num]=$?
11851         done
11852
11853         SAVE_UMASK=$(umask)
11854         umask 0022
11855         mkdir -p $DIR/$tdir
11856         cd $DIR/$tdir
11857
11858         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11859         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11860         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11861         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11862         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11863         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11864         if ! id -u $ACLNBD ||
11865            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11866                 ACLNBD="nfsnobody"
11867                 if ! id -u $ACLNBD; then
11868                         ACLNBD=""
11869                 fi
11870         fi
11871         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11872                 add_group $(id -u $ACLNBD) $ACLNBD
11873                 if ! getent group $ACLNBD; then
11874                         ACLNBD=""
11875                 fi
11876         fi
11877         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11878            [[ -n "$ACLNBD" ]] && which setfattr; then
11879                 run_acl_subtest permissions_xattr \
11880                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11881         elif [[ -z "$ACLNBD" ]]; then
11882                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11883         else
11884                 echo "skip 'permission_xattr' test - missing setfattr command"
11885         fi
11886         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11887
11888         # inheritance test got from HP
11889         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11890         chmod +x make-tree || error "chmod +x failed"
11891         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11892         rm -f make-tree
11893
11894         echo "LU-974 ignore umask when acl is enabled..."
11895         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11896         if [ $MDSCOUNT -ge 2 ]; then
11897                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11898         fi
11899
11900         echo "LU-2561 newly created file is same size as directory..."
11901         if [ "$mds1_FSTYPE" != "zfs" ]; then
11902                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11903         else
11904                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11905         fi
11906
11907         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11908
11909         cd $SAVE_PWD
11910         umask $SAVE_UMASK
11911
11912         for num in $(seq $MDSCOUNT); do
11913                 if [ "${identity_old[$num]}" = 1 ]; then
11914                         switch_identity $num false || identity_old[$num]=$?
11915                 fi
11916         done
11917 }
11918 run_test 103a "acl test"
11919
11920 test_103b() {
11921         declare -a pids
11922         local U
11923
11924         for U in {0..511}; do
11925                 {
11926                 local O=$(printf "%04o" $U)
11927
11928                 umask $(printf "%04o" $((511 ^ $O)))
11929                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11930                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11931
11932                 (( $S == ($O & 0666) )) ||
11933                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11934
11935                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11936                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11937                 (( $S == ($O & 0666) )) ||
11938                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11939
11940                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11941                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11942                 (( $S == ($O & 0666) )) ||
11943                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11944                 rm -f $DIR/$tfile.[smp]$0
11945                 } &
11946                 local pid=$!
11947
11948                 # limit the concurrently running threads to 64. LU-11878
11949                 local idx=$((U % 64))
11950                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11951                 pids[idx]=$pid
11952         done
11953         wait
11954 }
11955 run_test 103b "umask lfs setstripe"
11956
11957 test_103c() {
11958         mkdir -p $DIR/$tdir
11959         cp -rp $DIR/$tdir $DIR/$tdir.bak
11960
11961         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11962                 error "$DIR/$tdir shouldn't contain default ACL"
11963         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11964                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11965         true
11966 }
11967 run_test 103c "'cp -rp' won't set empty acl"
11968
11969 test_103e() {
11970         local numacl
11971         local fileacl
11972         local saved_debug=$($LCTL get_param -n debug)
11973
11974         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11975                 skip "MDS needs to be at least 2.14.52"
11976
11977         large_xattr_enabled || skip_env "ea_inode feature disabled"
11978
11979         mkdir -p $DIR/$tdir
11980         # add big LOV EA to cause reply buffer overflow earlier
11981         $LFS setstripe -C 1000 $DIR/$tdir
11982         lctl set_param mdc.*-mdc*.stats=clear
11983
11984         $LCTL set_param debug=0
11985         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11986         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11987
11988         # add a large number of default ACLs (expect 8000+ for 2.13+)
11989         for U in {2..7000}; do
11990                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11991                         error "Able to add just $U default ACLs"
11992         done
11993         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11994         echo "$numacl default ACLs created"
11995
11996         stat $DIR/$tdir || error "Cannot stat directory"
11997         # check file creation
11998         touch $DIR/$tdir/$tfile ||
11999                 error "failed to create $tfile with $numacl default ACLs"
12000         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12001         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12002         echo "$fileacl ACLs were inherited"
12003         (( $fileacl == $numacl )) ||
12004                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12005         # check that new ACLs creation adds new ACLs to inherited ACLs
12006         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12007                 error "Cannot set new ACL"
12008         numacl=$((numacl + 1))
12009         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12010         (( $fileacl == $numacl )) ||
12011                 error "failed to add new ACL: $fileacl != $numacl as expected"
12012         # adds more ACLs to a file to reach their maximum at 8000+
12013         numacl=0
12014         for U in {20000..25000}; do
12015                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12016                 numacl=$((numacl + 1))
12017         done
12018         echo "Added $numacl more ACLs to the file"
12019         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12020         echo "Total $fileacl ACLs in file"
12021         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12022         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12023         rmdir $DIR/$tdir || error "Cannot remove directory"
12024 }
12025 run_test 103e "inheritance of big amount of default ACLs"
12026
12027 test_103f() {
12028         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12029                 skip "MDS needs to be at least 2.14.51"
12030
12031         large_xattr_enabled || skip_env "ea_inode feature disabled"
12032
12033         # enable changelog to consume more internal MDD buffers
12034         changelog_register
12035
12036         mkdir -p $DIR/$tdir
12037         # add big LOV EA
12038         $LFS setstripe -C 1000 $DIR/$tdir
12039         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12040         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12041         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12042         rmdir $DIR/$tdir || error "Cannot remove directory"
12043 }
12044 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12045
12046 test_104a() {
12047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12048
12049         touch $DIR/$tfile
12050         lfs df || error "lfs df failed"
12051         lfs df -ih || error "lfs df -ih failed"
12052         lfs df -h $DIR || error "lfs df -h $DIR failed"
12053         lfs df -i $DIR || error "lfs df -i $DIR failed"
12054         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12055         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12056
12057         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12058         lctl --device %$OSC deactivate
12059         lfs df || error "lfs df with deactivated OSC failed"
12060         lctl --device %$OSC activate
12061         # wait the osc back to normal
12062         wait_osc_import_ready client ost
12063
12064         lfs df || error "lfs df with reactivated OSC failed"
12065         rm -f $DIR/$tfile
12066 }
12067 run_test 104a "lfs df [-ih] [path] test ========================="
12068
12069 test_104b() {
12070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12071         [ $RUNAS_ID -eq $UID ] &&
12072                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12073
12074         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12075                         grep "Permission denied" | wc -l)))
12076         if [ $denied_cnt -ne 0 ]; then
12077                 error "lfs check servers test failed"
12078         fi
12079 }
12080 run_test 104b "$RUNAS lfs check servers test ===================="
12081
12082 #
12083 # Verify $1 is within range of $2.
12084 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12085 # $1 is <= 2% of $2. Else Fail.
12086 #
12087 value_in_range() {
12088         # Strip all units (M, G, T)
12089         actual=$(echo $1 | tr -d A-Z)
12090         expect=$(echo $2 | tr -d A-Z)
12091
12092         expect_lo=$(($expect * 98 / 100)) # 2% below
12093         expect_hi=$(($expect * 102 / 100)) # 2% above
12094
12095         # permit 2% drift above and below
12096         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12097 }
12098
12099 test_104c() {
12100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12101         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12102
12103         local ost_param="osd-zfs.$FSNAME-OST0000."
12104         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12105         local ofacets=$(get_facets OST)
12106         local mfacets=$(get_facets MDS)
12107         local saved_ost_blocks=
12108         local saved_mdt_blocks=
12109
12110         echo "Before recordsize change"
12111         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12112         df=($(df -h | grep "$MOUNT"$))
12113
12114         # For checking.
12115         echo "lfs output : ${lfs_df[*]}"
12116         echo "df  output : ${df[*]}"
12117
12118         for facet in ${ofacets//,/ }; do
12119                 if [ -z $saved_ost_blocks ]; then
12120                         saved_ost_blocks=$(do_facet $facet \
12121                                 lctl get_param -n $ost_param.blocksize)
12122                         echo "OST Blocksize: $saved_ost_blocks"
12123                 fi
12124                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12125                 do_facet $facet zfs set recordsize=32768 $ost
12126         done
12127
12128         # BS too small. Sufficient for functional testing.
12129         for facet in ${mfacets//,/ }; do
12130                 if [ -z $saved_mdt_blocks ]; then
12131                         saved_mdt_blocks=$(do_facet $facet \
12132                                 lctl get_param -n $mdt_param.blocksize)
12133                         echo "MDT Blocksize: $saved_mdt_blocks"
12134                 fi
12135                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12136                 do_facet $facet zfs set recordsize=32768 $mdt
12137         done
12138
12139         # Give new values chance to reflect change
12140         sleep 2
12141
12142         echo "After recordsize change"
12143         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12144         df_after=($(df -h | grep "$MOUNT"$))
12145
12146         # For checking.
12147         echo "lfs output : ${lfs_df_after[*]}"
12148         echo "df  output : ${df_after[*]}"
12149
12150         # Verify lfs df
12151         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12152                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12153         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12154                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12155         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12156                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12157
12158         # Verify df
12159         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12160                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12161         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12162                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12163         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12164                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12165
12166         # Restore MDT recordize back to original
12167         for facet in ${mfacets//,/ }; do
12168                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12169                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12170         done
12171
12172         # Restore OST recordize back to original
12173         for facet in ${ofacets//,/ }; do
12174                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12175                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12176         done
12177
12178         return 0
12179 }
12180 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12181
12182 test_104d() {
12183         (( $RUNAS_ID != $UID )) ||
12184                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12185
12186         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12187                 skip "lustre version doesn't support lctl dl with non-root"
12188
12189         # debugfs only allows root users to access files, so the
12190         # previous move of the "devices" file to debugfs broke
12191         # "lctl dl" for non-root users. The LU-9680 Netlink
12192         # interface again allows non-root users to list devices.
12193         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12194                 error "lctl dl doesn't work for non root"
12195
12196         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12197         [ "$ost_count" -eq $OSTCOUNT ]  ||
12198                 error "lctl dl reports wrong number of OST devices"
12199
12200         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12201         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12202                 error "lctl dl reports wrong number of MDT devices"
12203 }
12204 run_test 104d "$RUNAS lctl dl test"
12205
12206 test_105a() {
12207         # doesn't work on 2.4 kernels
12208         touch $DIR/$tfile
12209         if $(flock_is_enabled); then
12210                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12211         else
12212                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12213         fi
12214         rm -f $DIR/$tfile
12215 }
12216 run_test 105a "flock when mounted without -o flock test ========"
12217
12218 test_105b() {
12219         touch $DIR/$tfile
12220         if $(flock_is_enabled); then
12221                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12222         else
12223                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12224         fi
12225         rm -f $DIR/$tfile
12226 }
12227 run_test 105b "fcntl when mounted without -o flock test ========"
12228
12229 test_105c() {
12230         touch $DIR/$tfile
12231         if $(flock_is_enabled); then
12232                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12233         else
12234                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12235         fi
12236         rm -f $DIR/$tfile
12237 }
12238 run_test 105c "lockf when mounted without -o flock test"
12239
12240 test_105d() { # bug 15924
12241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12242
12243         test_mkdir $DIR/$tdir
12244         flock_is_enabled || skip_env "mount w/o flock enabled"
12245         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12246         $LCTL set_param fail_loc=0x80000315
12247         flocks_test 2 $DIR/$tdir
12248 }
12249 run_test 105d "flock race (should not freeze) ========"
12250
12251 test_105e() { # bug 22660 && 22040
12252         flock_is_enabled || skip_env "mount w/o flock enabled"
12253
12254         touch $DIR/$tfile
12255         flocks_test 3 $DIR/$tfile
12256 }
12257 run_test 105e "Two conflicting flocks from same process"
12258
12259 test_106() { #bug 10921
12260         test_mkdir $DIR/$tdir
12261         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12262         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12263 }
12264 run_test 106 "attempt exec of dir followed by chown of that dir"
12265
12266 test_107() {
12267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12268
12269         CDIR=`pwd`
12270         local file=core
12271
12272         cd $DIR
12273         rm -f $file
12274
12275         local save_pattern=$(sysctl -n kernel.core_pattern)
12276         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12277         sysctl -w kernel.core_pattern=$file
12278         sysctl -w kernel.core_uses_pid=0
12279
12280         ulimit -c unlimited
12281         sleep 60 &
12282         SLEEPPID=$!
12283
12284         sleep 1
12285
12286         kill -s 11 $SLEEPPID
12287         wait $SLEEPPID
12288         if [ -e $file ]; then
12289                 size=`stat -c%s $file`
12290                 [ $size -eq 0 ] && error "Fail to create core file $file"
12291         else
12292                 error "Fail to create core file $file"
12293         fi
12294         rm -f $file
12295         sysctl -w kernel.core_pattern=$save_pattern
12296         sysctl -w kernel.core_uses_pid=$save_uses_pid
12297         cd $CDIR
12298 }
12299 run_test 107 "Coredump on SIG"
12300
12301 test_110() {
12302         test_mkdir $DIR/$tdir
12303         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12304         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12305                 error "mkdir with 256 char should fail, but did not"
12306         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12307                 error "create with 255 char failed"
12308         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12309                 error "create with 256 char should fail, but did not"
12310
12311         ls -l $DIR/$tdir
12312         rm -rf $DIR/$tdir
12313 }
12314 run_test 110 "filename length checking"
12315
12316 test_116a() { # was previously test_116()
12317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12318         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12319         remote_mds_nodsh && skip "remote MDS with nodsh"
12320
12321         echo -n "Free space priority "
12322         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12323                 head -n1
12324         declare -a AVAIL
12325         free_min_max
12326
12327         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12328         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12329         stack_trap simple_cleanup_common
12330
12331         # Check if we need to generate uneven OSTs
12332         test_mkdir -p $DIR/$tdir/OST${MINI}
12333         local FILL=$((MINV / 4))
12334         local DIFF=$((MAXV - MINV))
12335         local DIFF2=$((DIFF * 100 / MINV))
12336
12337         local threshold=$(do_facet $SINGLEMDS \
12338                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12339         threshold=${threshold%%%}
12340         echo -n "Check for uneven OSTs: "
12341         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12342
12343         if [[ $DIFF2 -gt $threshold ]]; then
12344                 echo "ok"
12345                 echo "Don't need to fill OST$MINI"
12346         else
12347                 # generate uneven OSTs. Write 2% over the QOS threshold value
12348                 echo "no"
12349                 DIFF=$((threshold - DIFF2 + 2))
12350                 DIFF2=$((MINV * DIFF / 100))
12351                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12352                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12353                         error "setstripe failed"
12354                 DIFF=$((DIFF2 / 2048))
12355                 i=0
12356                 while [ $i -lt $DIFF ]; do
12357                         i=$((i + 1))
12358                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12359                                 bs=2M count=1 2>/dev/null
12360                         echo -n .
12361                 done
12362                 echo .
12363                 sync
12364                 sleep_maxage
12365                 free_min_max
12366         fi
12367
12368         DIFF=$((MAXV - MINV))
12369         DIFF2=$((DIFF * 100 / MINV))
12370         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12371         if [ $DIFF2 -gt $threshold ]; then
12372                 echo "ok"
12373         else
12374                 skip "QOS imbalance criteria not met"
12375         fi
12376
12377         MINI1=$MINI
12378         MINV1=$MINV
12379         MAXI1=$MAXI
12380         MAXV1=$MAXV
12381
12382         # now fill using QOS
12383         $LFS setstripe -c 1 $DIR/$tdir
12384         FILL=$((FILL / 200))
12385         if [ $FILL -gt 600 ]; then
12386                 FILL=600
12387         fi
12388         echo "writing $FILL files to QOS-assigned OSTs"
12389         i=0
12390         while [ $i -lt $FILL ]; do
12391                 i=$((i + 1))
12392                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12393                         count=1 2>/dev/null
12394                 echo -n .
12395         done
12396         echo "wrote $i 200k files"
12397         sync
12398         sleep_maxage
12399
12400         echo "Note: free space may not be updated, so measurements might be off"
12401         free_min_max
12402         DIFF2=$((MAXV - MINV))
12403         echo "free space delta: orig $DIFF final $DIFF2"
12404         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12405         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12406         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12407         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12408         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12409         if [[ $DIFF -gt 0 ]]; then
12410                 FILL=$((DIFF2 * 100 / DIFF - 100))
12411                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12412         fi
12413
12414         # Figure out which files were written where
12415         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12416                awk '/'$MINI1': / {print $2; exit}')
12417         echo $UUID
12418         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12419         echo "$MINC files created on smaller OST $MINI1"
12420         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12421                awk '/'$MAXI1': / {print $2; exit}')
12422         echo $UUID
12423         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12424         echo "$MAXC files created on larger OST $MAXI1"
12425         if [[ $MINC -gt 0 ]]; then
12426                 FILL=$((MAXC * 100 / MINC - 100))
12427                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12428         fi
12429         [[ $MAXC -gt $MINC ]] ||
12430                 error_ignore LU-9 "stripe QOS didn't balance free space"
12431 }
12432 run_test 116a "stripe QOS: free space balance ==================="
12433
12434 test_116b() { # LU-2093
12435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12436         remote_mds_nodsh && skip "remote MDS with nodsh"
12437
12438 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12439         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12440                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12441         [ -z "$old_rr" ] && skip "no QOS"
12442         do_facet $SINGLEMDS lctl set_param \
12443                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12444         mkdir -p $DIR/$tdir
12445         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12446         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12447         do_facet $SINGLEMDS lctl set_param fail_loc=0
12448         rm -rf $DIR/$tdir
12449         do_facet $SINGLEMDS lctl set_param \
12450                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12451 }
12452 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12453
12454 test_117() # bug 10891
12455 {
12456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12457
12458         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12459         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12460         lctl set_param fail_loc=0x21e
12461         > $DIR/$tfile || error "truncate failed"
12462         lctl set_param fail_loc=0
12463         echo "Truncate succeeded."
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 117 "verify osd extend =========="
12467
12468 NO_SLOW_RESENDCOUNT=4
12469 export OLD_RESENDCOUNT=""
12470 set_resend_count () {
12471         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12472         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12473         lctl set_param -n $PROC_RESENDCOUNT $1
12474         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12475 }
12476
12477 # for reduce test_118* time (b=14842)
12478 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12479
12480 # Reset async IO behavior after error case
12481 reset_async() {
12482         FILE=$DIR/reset_async
12483
12484         # Ensure all OSCs are cleared
12485         $LFS setstripe -c -1 $FILE
12486         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12487         sync
12488         rm $FILE
12489 }
12490
12491 test_118a() #bug 11710
12492 {
12493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12494
12495         reset_async
12496
12497         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12498         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12499         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12500
12501         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12502                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12503                 return 1;
12504         fi
12505         rm -f $DIR/$tfile
12506 }
12507 run_test 118a "verify O_SYNC works =========="
12508
12509 test_118b()
12510 {
12511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12512         remote_ost_nodsh && skip "remote OST with nodsh"
12513
12514         reset_async
12515
12516         #define OBD_FAIL_SRV_ENOENT 0x217
12517         set_nodes_failloc "$(osts_nodes)" 0x217
12518         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12519         RC=$?
12520         set_nodes_failloc "$(osts_nodes)" 0
12521         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12522         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12523                     grep -c writeback)
12524
12525         if [[ $RC -eq 0 ]]; then
12526                 error "Must return error due to dropped pages, rc=$RC"
12527                 return 1;
12528         fi
12529
12530         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12531                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12532                 return 1;
12533         fi
12534
12535         echo "Dirty pages not leaked on ENOENT"
12536
12537         # Due to the above error the OSC will issue all RPCs syncronously
12538         # until a subsequent RPC completes successfully without error.
12539         $MULTIOP $DIR/$tfile Ow4096yc
12540         rm -f $DIR/$tfile
12541
12542         return 0
12543 }
12544 run_test 118b "Reclaim dirty pages on fatal error =========="
12545
12546 test_118c()
12547 {
12548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12549
12550         # for 118c, restore the original resend count, LU-1940
12551         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12552                                 set_resend_count $OLD_RESENDCOUNT
12553         remote_ost_nodsh && skip "remote OST with nodsh"
12554
12555         reset_async
12556
12557         #define OBD_FAIL_OST_EROFS               0x216
12558         set_nodes_failloc "$(osts_nodes)" 0x216
12559
12560         # multiop should block due to fsync until pages are written
12561         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12562         MULTIPID=$!
12563         sleep 1
12564
12565         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12566                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12567         fi
12568
12569         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12570                     grep -c writeback)
12571         if [[ $WRITEBACK -eq 0 ]]; then
12572                 error "No page in writeback, writeback=$WRITEBACK"
12573         fi
12574
12575         set_nodes_failloc "$(osts_nodes)" 0
12576         wait $MULTIPID
12577         RC=$?
12578         if [[ $RC -ne 0 ]]; then
12579                 error "Multiop fsync failed, rc=$RC"
12580         fi
12581
12582         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12583         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12584                     grep -c writeback)
12585         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12586                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12587         fi
12588
12589         rm -f $DIR/$tfile
12590         echo "Dirty pages flushed via fsync on EROFS"
12591         return 0
12592 }
12593 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12594
12595 # continue to use small resend count to reduce test_118* time (b=14842)
12596 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12597
12598 test_118d()
12599 {
12600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12601         remote_ost_nodsh && skip "remote OST with nodsh"
12602
12603         reset_async
12604
12605         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12606         set_nodes_failloc "$(osts_nodes)" 0x214
12607         # multiop should block due to fsync until pages are written
12608         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12609         MULTIPID=$!
12610         sleep 1
12611
12612         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12613                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12614         fi
12615
12616         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12617                     grep -c writeback)
12618         if [[ $WRITEBACK -eq 0 ]]; then
12619                 error "No page in writeback, writeback=$WRITEBACK"
12620         fi
12621
12622         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12623         set_nodes_failloc "$(osts_nodes)" 0
12624
12625         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12626         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12627                     grep -c writeback)
12628         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12629                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12630         fi
12631
12632         rm -f $DIR/$tfile
12633         echo "Dirty pages gaurenteed flushed via fsync"
12634         return 0
12635 }
12636 run_test 118d "Fsync validation inject a delay of the bulk =========="
12637
12638 test_118f() {
12639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12640
12641         reset_async
12642
12643         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12644         lctl set_param fail_loc=0x8000040a
12645
12646         # Should simulate EINVAL error which is fatal
12647         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12648         RC=$?
12649         if [[ $RC -eq 0 ]]; then
12650                 error "Must return error due to dropped pages, rc=$RC"
12651         fi
12652
12653         lctl set_param fail_loc=0x0
12654
12655         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12656         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12657         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12658                     grep -c writeback)
12659         if [[ $LOCKED -ne 0 ]]; then
12660                 error "Locked pages remain in cache, locked=$LOCKED"
12661         fi
12662
12663         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12664                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12665         fi
12666
12667         rm -f $DIR/$tfile
12668         echo "No pages locked after fsync"
12669
12670         reset_async
12671         return 0
12672 }
12673 run_test 118f "Simulate unrecoverable OSC side error =========="
12674
12675 test_118g() {
12676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12677
12678         reset_async
12679
12680         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12681         lctl set_param fail_loc=0x406
12682
12683         # simulate local -ENOMEM
12684         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12685         RC=$?
12686
12687         lctl set_param fail_loc=0
12688         if [[ $RC -eq 0 ]]; then
12689                 error "Must return error due to dropped pages, rc=$RC"
12690         fi
12691
12692         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12693         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12694         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12695                         grep -c writeback)
12696         if [[ $LOCKED -ne 0 ]]; then
12697                 error "Locked pages remain in cache, locked=$LOCKED"
12698         fi
12699
12700         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12701                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12702         fi
12703
12704         rm -f $DIR/$tfile
12705         echo "No pages locked after fsync"
12706
12707         reset_async
12708         return 0
12709 }
12710 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12711
12712 test_118h() {
12713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12714         remote_ost_nodsh && skip "remote OST with nodsh"
12715
12716         reset_async
12717
12718         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12719         set_nodes_failloc "$(osts_nodes)" 0x20e
12720         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12721         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12722         RC=$?
12723
12724         set_nodes_failloc "$(osts_nodes)" 0
12725         if [[ $RC -eq 0 ]]; then
12726                 error "Must return error due to dropped pages, rc=$RC"
12727         fi
12728
12729         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12730         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12731         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12732                     grep -c writeback)
12733         if [[ $LOCKED -ne 0 ]]; then
12734                 error "Locked pages remain in cache, locked=$LOCKED"
12735         fi
12736
12737         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12738                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12739         fi
12740
12741         rm -f $DIR/$tfile
12742         echo "No pages locked after fsync"
12743
12744         return 0
12745 }
12746 run_test 118h "Verify timeout in handling recoverables errors  =========="
12747
12748 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12749
12750 test_118i() {
12751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12752         remote_ost_nodsh && skip "remote OST with nodsh"
12753
12754         reset_async
12755
12756         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12757         set_nodes_failloc "$(osts_nodes)" 0x20e
12758
12759         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12760         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12761         PID=$!
12762         sleep 5
12763         set_nodes_failloc "$(osts_nodes)" 0
12764
12765         wait $PID
12766         RC=$?
12767         if [[ $RC -ne 0 ]]; then
12768                 error "got error, but should be not, rc=$RC"
12769         fi
12770
12771         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12772         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12773         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12774         if [[ $LOCKED -ne 0 ]]; then
12775                 error "Locked pages remain in cache, locked=$LOCKED"
12776         fi
12777
12778         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12779                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12780         fi
12781
12782         rm -f $DIR/$tfile
12783         echo "No pages locked after fsync"
12784
12785         return 0
12786 }
12787 run_test 118i "Fix error before timeout in recoverable error  =========="
12788
12789 [ "$SLOW" = "no" ] && set_resend_count 4
12790
12791 test_118j() {
12792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12793         remote_ost_nodsh && skip "remote OST with nodsh"
12794
12795         reset_async
12796
12797         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12798         set_nodes_failloc "$(osts_nodes)" 0x220
12799
12800         # return -EIO from OST
12801         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12802         RC=$?
12803         set_nodes_failloc "$(osts_nodes)" 0x0
12804         if [[ $RC -eq 0 ]]; then
12805                 error "Must return error due to dropped pages, rc=$RC"
12806         fi
12807
12808         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12809         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12810         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12811         if [[ $LOCKED -ne 0 ]]; then
12812                 error "Locked pages remain in cache, locked=$LOCKED"
12813         fi
12814
12815         # in recoverable error on OST we want resend and stay until it finished
12816         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12817                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12818         fi
12819
12820         rm -f $DIR/$tfile
12821         echo "No pages locked after fsync"
12822
12823         return 0
12824 }
12825 run_test 118j "Simulate unrecoverable OST side error =========="
12826
12827 test_118k()
12828 {
12829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12830         remote_ost_nodsh && skip "remote OSTs with nodsh"
12831
12832         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12833         set_nodes_failloc "$(osts_nodes)" 0x20e
12834         test_mkdir $DIR/$tdir
12835
12836         for ((i=0;i<10;i++)); do
12837                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12838                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12839                 SLEEPPID=$!
12840                 sleep 0.500s
12841                 kill $SLEEPPID
12842                 wait $SLEEPPID
12843         done
12844
12845         set_nodes_failloc "$(osts_nodes)" 0
12846         rm -rf $DIR/$tdir
12847 }
12848 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12849
12850 test_118l() # LU-646
12851 {
12852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12853
12854         test_mkdir $DIR/$tdir
12855         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12856         rm -rf $DIR/$tdir
12857 }
12858 run_test 118l "fsync dir"
12859
12860 test_118m() # LU-3066
12861 {
12862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12863
12864         test_mkdir $DIR/$tdir
12865         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12866         rm -rf $DIR/$tdir
12867 }
12868 run_test 118m "fdatasync dir ========="
12869
12870 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12871
12872 test_118n()
12873 {
12874         local begin
12875         local end
12876
12877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12878         remote_ost_nodsh && skip "remote OSTs with nodsh"
12879
12880         # Sleep to avoid a cached response.
12881         #define OBD_STATFS_CACHE_SECONDS 1
12882         sleep 2
12883
12884         # Inject a 10 second delay in the OST_STATFS handler.
12885         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12886         set_nodes_failloc "$(osts_nodes)" 0x242
12887
12888         begin=$SECONDS
12889         stat --file-system $MOUNT > /dev/null
12890         end=$SECONDS
12891
12892         set_nodes_failloc "$(osts_nodes)" 0
12893
12894         if ((end - begin > 20)); then
12895             error "statfs took $((end - begin)) seconds, expected 10"
12896         fi
12897 }
12898 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12899
12900 test_119a() # bug 11737
12901 {
12902         BSIZE=$((512 * 1024))
12903         directio write $DIR/$tfile 0 1 $BSIZE
12904         # We ask to read two blocks, which is more than a file size.
12905         # directio will indicate an error when requested and actual
12906         # sizes aren't equeal (a normal situation in this case) and
12907         # print actual read amount.
12908         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12909         if [ "$NOB" != "$BSIZE" ]; then
12910                 error "read $NOB bytes instead of $BSIZE"
12911         fi
12912         rm -f $DIR/$tfile
12913 }
12914 run_test 119a "Short directIO read must return actual read amount"
12915
12916 test_119b() # bug 11737
12917 {
12918         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12919
12920         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12921         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12922         sync
12923         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12924                 error "direct read failed"
12925         rm -f $DIR/$tfile
12926 }
12927 run_test 119b "Sparse directIO read must return actual read amount"
12928
12929 test_119c() # bug 13099
12930 {
12931         BSIZE=1048576
12932         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12933         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12934         rm -f $DIR/$tfile
12935 }
12936 run_test 119c "Testing for direct read hitting hole"
12937
12938 test_119d() # bug 15950
12939 {
12940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12941
12942         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12943         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12944         BSIZE=1048576
12945         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12946         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12947         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12948         lctl set_param fail_loc=0x40d
12949         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12950         pid_dio=$!
12951         sleep 1
12952         cat $DIR/$tfile > /dev/null &
12953         lctl set_param fail_loc=0
12954         pid_reads=$!
12955         wait $pid_dio
12956         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12957         sleep 2
12958         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12959         error "the read rpcs have not completed in 2s"
12960         rm -f $DIR/$tfile
12961         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12962 }
12963 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12964
12965 test_120a() {
12966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12967         remote_mds_nodsh && skip "remote MDS with nodsh"
12968         test_mkdir -i0 -c1 $DIR/$tdir
12969         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12970                 skip_env "no early lock cancel on server"
12971
12972         lru_resize_disable mdc
12973         lru_resize_disable osc
12974         cancel_lru_locks mdc
12975         # asynchronous object destroy at MDT could cause bl ast to client
12976         cancel_lru_locks osc
12977
12978         stat $DIR/$tdir > /dev/null
12979         can1=$(do_facet mds1 \
12980                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12981                awk '/ldlm_cancel/ {print $2}')
12982         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12983                awk '/ldlm_bl_callback/ {print $2}')
12984         test_mkdir -i0 -c1 $DIR/$tdir/d1
12985         can2=$(do_facet mds1 \
12986                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12987                awk '/ldlm_cancel/ {print $2}')
12988         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12989                awk '/ldlm_bl_callback/ {print $2}')
12990         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12991         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12992         lru_resize_enable mdc
12993         lru_resize_enable osc
12994 }
12995 run_test 120a "Early Lock Cancel: mkdir test"
12996
12997 test_120b() {
12998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12999         remote_mds_nodsh && skip "remote MDS with nodsh"
13000         test_mkdir $DIR/$tdir
13001         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13002                 skip_env "no early lock cancel on server"
13003
13004         lru_resize_disable mdc
13005         lru_resize_disable osc
13006         cancel_lru_locks mdc
13007         stat $DIR/$tdir > /dev/null
13008         can1=$(do_facet $SINGLEMDS \
13009                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13010                awk '/ldlm_cancel/ {print $2}')
13011         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13012                awk '/ldlm_bl_callback/ {print $2}')
13013         touch $DIR/$tdir/f1
13014         can2=$(do_facet $SINGLEMDS \
13015                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13016                awk '/ldlm_cancel/ {print $2}')
13017         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13018                awk '/ldlm_bl_callback/ {print $2}')
13019         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13020         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13021         lru_resize_enable mdc
13022         lru_resize_enable osc
13023 }
13024 run_test 120b "Early Lock Cancel: create test"
13025
13026 test_120c() {
13027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13028         remote_mds_nodsh && skip "remote MDS with nodsh"
13029         test_mkdir -i0 -c1 $DIR/$tdir
13030         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13031                 skip "no early lock cancel on server"
13032
13033         lru_resize_disable mdc
13034         lru_resize_disable osc
13035         test_mkdir -i0 -c1 $DIR/$tdir/d1
13036         test_mkdir -i0 -c1 $DIR/$tdir/d2
13037         touch $DIR/$tdir/d1/f1
13038         cancel_lru_locks mdc
13039         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13040         can1=$(do_facet mds1 \
13041                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13042                awk '/ldlm_cancel/ {print $2}')
13043         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13044                awk '/ldlm_bl_callback/ {print $2}')
13045         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13046         can2=$(do_facet mds1 \
13047                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13048                awk '/ldlm_cancel/ {print $2}')
13049         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13050                awk '/ldlm_bl_callback/ {print $2}')
13051         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13052         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13053         lru_resize_enable mdc
13054         lru_resize_enable osc
13055 }
13056 run_test 120c "Early Lock Cancel: link test"
13057
13058 test_120d() {
13059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13060         remote_mds_nodsh && skip "remote MDS with nodsh"
13061         test_mkdir -i0 -c1 $DIR/$tdir
13062         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13063                 skip_env "no early lock cancel on server"
13064
13065         lru_resize_disable mdc
13066         lru_resize_disable osc
13067         touch $DIR/$tdir
13068         cancel_lru_locks mdc
13069         stat $DIR/$tdir > /dev/null
13070         can1=$(do_facet mds1 \
13071                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13072                awk '/ldlm_cancel/ {print $2}')
13073         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13074                awk '/ldlm_bl_callback/ {print $2}')
13075         chmod a+x $DIR/$tdir
13076         can2=$(do_facet mds1 \
13077                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13078                awk '/ldlm_cancel/ {print $2}')
13079         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13080                awk '/ldlm_bl_callback/ {print $2}')
13081         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13082         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13083         lru_resize_enable mdc
13084         lru_resize_enable osc
13085 }
13086 run_test 120d "Early Lock Cancel: setattr test"
13087
13088 test_120e() {
13089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13090         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13091                 skip_env "no early lock cancel on server"
13092         remote_mds_nodsh && skip "remote MDS with nodsh"
13093
13094         local dlmtrace_set=false
13095
13096         test_mkdir -i0 -c1 $DIR/$tdir
13097         lru_resize_disable mdc
13098         lru_resize_disable osc
13099         ! $LCTL get_param debug | grep -q dlmtrace &&
13100                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13101         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13102         cancel_lru_locks mdc
13103         cancel_lru_locks osc
13104         dd if=$DIR/$tdir/f1 of=/dev/null
13105         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13106         # XXX client can not do early lock cancel of OST lock
13107         # during unlink (LU-4206), so cancel osc lock now.
13108         sleep 2
13109         cancel_lru_locks osc
13110         can1=$(do_facet mds1 \
13111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13112                awk '/ldlm_cancel/ {print $2}')
13113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13114                awk '/ldlm_bl_callback/ {print $2}')
13115         unlink $DIR/$tdir/f1
13116         sleep 5
13117         can2=$(do_facet mds1 \
13118                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13119                awk '/ldlm_cancel/ {print $2}')
13120         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13121                awk '/ldlm_bl_callback/ {print $2}')
13122         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13123                 $LCTL dk $TMP/cancel.debug.txt
13124         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13125                 $LCTL dk $TMP/blocking.debug.txt
13126         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13127         lru_resize_enable mdc
13128         lru_resize_enable osc
13129 }
13130 run_test 120e "Early Lock Cancel: unlink test"
13131
13132 test_120f() {
13133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13134         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13135                 skip_env "no early lock cancel on server"
13136         remote_mds_nodsh && skip "remote MDS with nodsh"
13137
13138         test_mkdir -i0 -c1 $DIR/$tdir
13139         lru_resize_disable mdc
13140         lru_resize_disable osc
13141         test_mkdir -i0 -c1 $DIR/$tdir/d1
13142         test_mkdir -i0 -c1 $DIR/$tdir/d2
13143         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13144         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13145         cancel_lru_locks mdc
13146         cancel_lru_locks osc
13147         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13148         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13149         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13150         # XXX client can not do early lock cancel of OST lock
13151         # during rename (LU-4206), so cancel osc lock now.
13152         sleep 2
13153         cancel_lru_locks osc
13154         can1=$(do_facet mds1 \
13155                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13156                awk '/ldlm_cancel/ {print $2}')
13157         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13158                awk '/ldlm_bl_callback/ {print $2}')
13159         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13160         sleep 5
13161         can2=$(do_facet mds1 \
13162                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13163                awk '/ldlm_cancel/ {print $2}')
13164         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13165                awk '/ldlm_bl_callback/ {print $2}')
13166         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13167         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13168         lru_resize_enable mdc
13169         lru_resize_enable osc
13170 }
13171 run_test 120f "Early Lock Cancel: rename test"
13172
13173 test_120g() {
13174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13175         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13176                 skip_env "no early lock cancel on server"
13177         remote_mds_nodsh && skip "remote MDS with nodsh"
13178
13179         lru_resize_disable mdc
13180         lru_resize_disable osc
13181         count=10000
13182         echo create $count files
13183         test_mkdir $DIR/$tdir
13184         cancel_lru_locks mdc
13185         cancel_lru_locks osc
13186         t0=$(date +%s)
13187
13188         can0=$(do_facet $SINGLEMDS \
13189                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13190                awk '/ldlm_cancel/ {print $2}')
13191         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13192                awk '/ldlm_bl_callback/ {print $2}')
13193         createmany -o $DIR/$tdir/f $count
13194         sync
13195         can1=$(do_facet $SINGLEMDS \
13196                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13197                awk '/ldlm_cancel/ {print $2}')
13198         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13199                awk '/ldlm_bl_callback/ {print $2}')
13200         t1=$(date +%s)
13201         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13202         echo rm $count files
13203         rm -r $DIR/$tdir
13204         sync
13205         can2=$(do_facet $SINGLEMDS \
13206                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13207                awk '/ldlm_cancel/ {print $2}')
13208         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13209                awk '/ldlm_bl_callback/ {print $2}')
13210         t2=$(date +%s)
13211         echo total: $count removes in $((t2-t1))
13212         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13213         sleep 2
13214         # wait for commitment of removal
13215         lru_resize_enable mdc
13216         lru_resize_enable osc
13217 }
13218 run_test 120g "Early Lock Cancel: performance test"
13219
13220 test_121() { #bug #10589
13221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13222
13223         rm -rf $DIR/$tfile
13224         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13225 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13226         lctl set_param fail_loc=0x310
13227         cancel_lru_locks osc > /dev/null
13228         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13229         lctl set_param fail_loc=0
13230         [[ $reads -eq $writes ]] ||
13231                 error "read $reads blocks, must be $writes blocks"
13232 }
13233 run_test 121 "read cancel race ========="
13234
13235 test_123a_base() { # was test 123, statahead(bug 11401)
13236         local lsx="$1"
13237
13238         SLOWOK=0
13239         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13240                 log "testing UP system. Performance may be lower than expected."
13241                 SLOWOK=1
13242         fi
13243         running_in_vm && SLOWOK=1
13244
13245         rm -rf $DIR/$tdir
13246         test_mkdir $DIR/$tdir
13247         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13248         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13249         MULT=10
13250         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13251                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13252
13253                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13254                 lctl set_param -n llite.*.statahead_max 0
13255                 lctl get_param llite.*.statahead_max
13256                 cancel_lru_locks mdc
13257                 cancel_lru_locks osc
13258                 stime=$(date +%s)
13259                 time $lsx $DIR/$tdir | wc -l
13260                 etime=$(date +%s)
13261                 delta=$((etime - stime))
13262                 log "$lsx $i files without statahead: $delta sec"
13263                 lctl set_param llite.*.statahead_max=$max
13264
13265                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13266                          awk '/statahead.wrong:/ { print $NF }')
13267                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13268                 cancel_lru_locks mdc
13269                 cancel_lru_locks osc
13270                 stime=$(date +%s)
13271                 time $lsx $DIR/$tdir | wc -l
13272                 etime=$(date +%s)
13273                 delta_sa=$((etime - stime))
13274                 log "$lsx $i files with statahead: $delta_sa sec"
13275                 lctl get_param -n llite.*.statahead_stats
13276                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13277                          awk '/statahead.wrong:/ { print $NF }')
13278
13279                 [[ $swrong -lt $ewrong ]] &&
13280                         log "statahead was stopped, maybe too many locks held!"
13281                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13282
13283                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13284                         max=$(lctl get_param -n llite.*.statahead_max |
13285                                 head -n 1)
13286                         lctl set_param -n llite.*.statahead_max 0
13287                         lctl get_param llite.*.statahead_max
13288                         cancel_lru_locks mdc
13289                         cancel_lru_locks osc
13290                         stime=$(date +%s)
13291                         time $lsx $DIR/$tdir | wc -l
13292                         etime=$(date +%s)
13293                         delta=$((etime - stime))
13294                         log "$lsx $i files again without statahead: $delta sec"
13295                         lctl set_param llite.*.statahead_max=$max
13296                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13297                                 if [ $SLOWOK -eq 0 ]; then
13298                                         error "$lsx $i files is slower with statahead!"
13299                                 else
13300                                         log "$lsx $i files is slower with statahead!"
13301                                 fi
13302                                 break
13303                         fi
13304                 fi
13305
13306                 [ $delta -gt 20 ] && break
13307                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13308                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13309         done
13310         log "$lsx done"
13311
13312         stime=$(date +%s)
13313         rm -r $DIR/$tdir
13314         sync
13315         etime=$(date +%s)
13316         delta=$((etime - stime))
13317         log "rm -r $DIR/$tdir/: $delta seconds"
13318         log "rm done"
13319         lctl get_param -n llite.*.statahead_stats
13320 }
13321
13322 test_123aa() {
13323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13324
13325         test_123a_base "ls -l"
13326 }
13327 run_test 123aa "verify statahead work"
13328
13329 test_123ab() {
13330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13331
13332         statx_supported || skip_env "Test must be statx() syscall supported"
13333
13334         test_123a_base "$STATX -l"
13335 }
13336 run_test 123ab "verify statahead work by using statx"
13337
13338 test_123ac() {
13339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13340
13341         statx_supported || skip_env "Test must be statx() syscall supported"
13342
13343         local rpcs_before
13344         local rpcs_after
13345         local agl_before
13346         local agl_after
13347
13348         cancel_lru_locks $OSC
13349         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13350         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13351                      awk '/agl.total:/ { print $NF }')
13352         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13353         test_123a_base "$STATX --cached=always -D"
13354         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13355                     awk '/agl.total:/ { print $NF }')
13356         [ $agl_before -eq $agl_after ] ||
13357                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13358         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13359         [ $rpcs_after -eq $rpcs_before ] ||
13360                 error "$STATX should not send glimpse RPCs to $OSC"
13361 }
13362 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13363
13364 test_123b () { # statahead(bug 15027)
13365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13366
13367         test_mkdir $DIR/$tdir
13368         createmany -o $DIR/$tdir/$tfile-%d 1000
13369
13370         cancel_lru_locks mdc
13371         cancel_lru_locks osc
13372
13373 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13374         lctl set_param fail_loc=0x80000803
13375         ls -lR $DIR/$tdir > /dev/null
13376         log "ls done"
13377         lctl set_param fail_loc=0x0
13378         lctl get_param -n llite.*.statahead_stats
13379         rm -r $DIR/$tdir
13380         sync
13381
13382 }
13383 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13384
13385 test_123c() {
13386         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13387
13388         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13389         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13390         touch $DIR/$tdir.1/{1..3}
13391         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13392
13393         remount_client $MOUNT
13394
13395         $MULTIOP $DIR/$tdir.0 Q
13396
13397         # let statahead to complete
13398         ls -l $DIR/$tdir.0 > /dev/null
13399
13400         testid=$(echo $TESTNAME | tr '_' ' ')
13401         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13402                 error "statahead warning" || true
13403 }
13404 run_test 123c "Can not initialize inode warning on DNE statahead"
13405
13406 test_123d() {
13407         local num=100
13408         local swrong
13409         local ewrong
13410
13411         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13412         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13413                 error "setdirstripe $DIR/$tdir failed"
13414         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13415         remount_client $MOUNT
13416         $LCTL get_param llite.*.statahead_max
13417         $LCTL set_param llite.*.statahead_stats=0 ||
13418                 error "clear statahead_stats failed"
13419         swrong=$(lctl get_param -n llite.*.statahead_stats |
13420                  awk '/statahead.wrong:/ { print $NF }')
13421         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13422         # wait for statahead thread finished to update hit/miss stats.
13423         sleep 1
13424         $LCTL get_param -n llite.*.statahead_stats
13425         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13426                  awk '/statahead.wrong:/ { print $NF }')
13427         (( $swrong == $ewrong )) ||
13428                 log "statahead was stopped, maybe too many locks held!"
13429 }
13430 run_test 123d "Statahead on striped directories works correctly"
13431
13432 test_124a() {
13433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13434         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13435                 skip_env "no lru resize on server"
13436
13437         local NR=2000
13438
13439         test_mkdir $DIR/$tdir
13440
13441         log "create $NR files at $DIR/$tdir"
13442         createmany -o $DIR/$tdir/f $NR ||
13443                 error "failed to create $NR files in $DIR/$tdir"
13444
13445         cancel_lru_locks mdc
13446         ls -l $DIR/$tdir > /dev/null
13447
13448         local NSDIR=""
13449         local LRU_SIZE=0
13450         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13451                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13452                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13453                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13454                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13455                         log "NSDIR=$NSDIR"
13456                         log "NS=$(basename $NSDIR)"
13457                         break
13458                 fi
13459         done
13460
13461         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13462                 skip "Not enough cached locks created!"
13463         fi
13464         log "LRU=$LRU_SIZE"
13465
13466         local SLEEP=30
13467
13468         # We know that lru resize allows one client to hold $LIMIT locks
13469         # for 10h. After that locks begin to be killed by client.
13470         local MAX_HRS=10
13471         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13472         log "LIMIT=$LIMIT"
13473         if [ $LIMIT -lt $LRU_SIZE ]; then
13474                 skip "Limit is too small $LIMIT"
13475         fi
13476
13477         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13478         # killing locks. Some time was spent for creating locks. This means
13479         # that up to the moment of sleep finish we must have killed some of
13480         # them (10-100 locks). This depends on how fast ther were created.
13481         # Many of them were touched in almost the same moment and thus will
13482         # be killed in groups.
13483         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13484
13485         # Use $LRU_SIZE_B here to take into account real number of locks
13486         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13487         local LRU_SIZE_B=$LRU_SIZE
13488         log "LVF=$LVF"
13489         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13490         log "OLD_LVF=$OLD_LVF"
13491         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13492
13493         # Let's make sure that we really have some margin. Client checks
13494         # cached locks every 10 sec.
13495         SLEEP=$((SLEEP+20))
13496         log "Sleep ${SLEEP} sec"
13497         local SEC=0
13498         while ((SEC<$SLEEP)); do
13499                 echo -n "..."
13500                 sleep 5
13501                 SEC=$((SEC+5))
13502                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13503                 echo -n "$LRU_SIZE"
13504         done
13505         echo ""
13506         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13507         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13508
13509         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13510                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13511                 unlinkmany $DIR/$tdir/f $NR
13512                 return
13513         }
13514
13515         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13516         log "unlink $NR files at $DIR/$tdir"
13517         unlinkmany $DIR/$tdir/f $NR
13518 }
13519 run_test 124a "lru resize ======================================="
13520
13521 get_max_pool_limit()
13522 {
13523         local limit=$($LCTL get_param \
13524                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13525         local max=0
13526         for l in $limit; do
13527                 if [[ $l -gt $max ]]; then
13528                         max=$l
13529                 fi
13530         done
13531         echo $max
13532 }
13533
13534 test_124b() {
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13537                 skip_env "no lru resize on server"
13538
13539         LIMIT=$(get_max_pool_limit)
13540
13541         NR=$(($(default_lru_size)*20))
13542         if [[ $NR -gt $LIMIT ]]; then
13543                 log "Limit lock number by $LIMIT locks"
13544                 NR=$LIMIT
13545         fi
13546
13547         IFree=$(mdsrate_inodes_available)
13548         if [ $IFree -lt $NR ]; then
13549                 log "Limit lock number by $IFree inodes"
13550                 NR=$IFree
13551         fi
13552
13553         lru_resize_disable mdc
13554         test_mkdir -p $DIR/$tdir/disable_lru_resize
13555
13556         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13557         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13558         cancel_lru_locks mdc
13559         stime=`date +%s`
13560         PID=""
13561         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13562         PID="$PID $!"
13563         sleep 2
13564         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13565         PID="$PID $!"
13566         sleep 2
13567         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13568         PID="$PID $!"
13569         wait $PID
13570         etime=`date +%s`
13571         nolruresize_delta=$((etime-stime))
13572         log "ls -la time: $nolruresize_delta seconds"
13573         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13574         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13575
13576         lru_resize_enable mdc
13577         test_mkdir -p $DIR/$tdir/enable_lru_resize
13578
13579         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13580         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13581         cancel_lru_locks mdc
13582         stime=`date +%s`
13583         PID=""
13584         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13585         PID="$PID $!"
13586         sleep 2
13587         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13588         PID="$PID $!"
13589         sleep 2
13590         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13591         PID="$PID $!"
13592         wait $PID
13593         etime=`date +%s`
13594         lruresize_delta=$((etime-stime))
13595         log "ls -la time: $lruresize_delta seconds"
13596         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13597
13598         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13599                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13600         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13601                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13602         else
13603                 log "lru resize performs the same with no lru resize"
13604         fi
13605         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13606 }
13607 run_test 124b "lru resize (performance test) ======================="
13608
13609 test_124c() {
13610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13611         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13612                 skip_env "no lru resize on server"
13613
13614         # cache ununsed locks on client
13615         local nr=100
13616         cancel_lru_locks mdc
13617         test_mkdir $DIR/$tdir
13618         createmany -o $DIR/$tdir/f $nr ||
13619                 error "failed to create $nr files in $DIR/$tdir"
13620         ls -l $DIR/$tdir > /dev/null
13621
13622         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13623         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13624         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13625         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13626         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13627
13628         # set lru_max_age to 1 sec
13629         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13630         echo "sleep $((recalc_p * 2)) seconds..."
13631         sleep $((recalc_p * 2))
13632
13633         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13634         # restore lru_max_age
13635         $LCTL set_param -n $nsdir.lru_max_age $max_age
13636         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13637         unlinkmany $DIR/$tdir/f $nr
13638 }
13639 run_test 124c "LRUR cancel very aged locks"
13640
13641 test_124d() {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13644                 skip_env "no lru resize on server"
13645
13646         # cache ununsed locks on client
13647         local nr=100
13648
13649         lru_resize_disable mdc
13650         stack_trap "lru_resize_enable mdc" EXIT
13651
13652         cancel_lru_locks mdc
13653
13654         # asynchronous object destroy at MDT could cause bl ast to client
13655         test_mkdir $DIR/$tdir
13656         createmany -o $DIR/$tdir/f $nr ||
13657                 error "failed to create $nr files in $DIR/$tdir"
13658         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13659
13660         ls -l $DIR/$tdir > /dev/null
13661
13662         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13663         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13664         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13665         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13666
13667         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13668
13669         # set lru_max_age to 1 sec
13670         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13671         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13672
13673         echo "sleep $((recalc_p * 2)) seconds..."
13674         sleep $((recalc_p * 2))
13675
13676         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13677
13678         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13679 }
13680 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13681
13682 test_125() { # 13358
13683         $LCTL get_param -n llite.*.client_type | grep -q local ||
13684                 skip "must run as local client"
13685         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13686                 skip_env "must have acl enabled"
13687         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13688
13689         test_mkdir $DIR/$tdir
13690         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13691         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13692                 error "setfacl $DIR/$tdir failed"
13693         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13694 }
13695 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13696
13697 test_126() { # bug 12829/13455
13698         $GSS && skip_env "must run as gss disabled"
13699         $LCTL get_param -n llite.*.client_type | grep -q local ||
13700                 skip "must run as local client"
13701         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13702
13703         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13704         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13705         rm -f $DIR/$tfile
13706         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13707 }
13708 run_test 126 "check that the fsgid provided by the client is taken into account"
13709
13710 test_127a() { # bug 15521
13711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13712         local name count samp unit min max sum sumsq
13713         local tmpfile=$TMP/$tfile.tmp
13714
13715         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13716         echo "stats before reset"
13717         stack_trap "rm -f $tmpfile"
13718         local now=$(date +%s)
13719
13720         $LCTL get_param osc.*.stats | tee $tmpfile
13721
13722         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13723         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13724         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13725         local uptime=$(awk '{ print $1 }' /proc/uptime)
13726
13727         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13728         (( ${snapshot_time%\.*} >= $now - 5 &&
13729            ${snapshot_time%\.*} <= $now + 5 )) ||
13730                 error "snapshot_time=$snapshot_time != now=$now"
13731         # elapsed _should_ be from mount, but at least less than uptime
13732         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13733                 error "elapsed=$elapsed > uptime=$uptime"
13734         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13735            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13736                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13737
13738         $LCTL set_param osc.*.stats=0
13739         local reset=$(date +%s)
13740         local fsize=$((2048 * 1024))
13741
13742         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13743         cancel_lru_locks osc
13744         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13745
13746         now=$(date +%s)
13747         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13748         while read name count samp unit min max sum sumsq; do
13749                 [[ "$samp" == "samples" ]] || continue
13750
13751                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13752                 [ ! $min ] && error "Missing min value for $name proc entry"
13753                 eval $name=$count || error "Wrong proc format"
13754
13755                 case $name in
13756                 read_bytes|write_bytes)
13757                         [[ "$unit" =~ "bytes" ]] ||
13758                                 error "unit is not 'bytes': $unit"
13759                         (( $min >= 4096 )) || error "min is too small: $min"
13760                         (( $min <= $fsize )) || error "min is too big: $min"
13761                         (( $max >= 4096 )) || error "max is too small: $max"
13762                         (( $max <= $fsize )) || error "max is too big: $max"
13763                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13764                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13765                                 error "sumsquare is too small: $sumsq"
13766                         (( $sumsq <= $fsize * $fsize )) ||
13767                                 error "sumsquare is too big: $sumsq"
13768                         ;;
13769                 ost_read|ost_write)
13770                         [[ "$unit" =~ "usec" ]] ||
13771                                 error "unit is not 'usec': $unit"
13772                         ;;
13773                 *)      ;;
13774                 esac
13775         done < $tmpfile
13776
13777         #check that we actually got some stats
13778         [ "$read_bytes" ] || error "Missing read_bytes stats"
13779         [ "$write_bytes" ] || error "Missing write_bytes stats"
13780         [ "$read_bytes" != 0 ] || error "no read done"
13781         [ "$write_bytes" != 0 ] || error "no write done"
13782
13783         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13784         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13785         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13786
13787         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13788         (( ${snapshot_time%\.*} >= $now - 5 &&
13789            ${snapshot_time%\.*} <= $now + 5 )) ||
13790                 error "reset snapshot_time=$snapshot_time != now=$now"
13791         # elapsed should be from time of stats reset
13792         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13793            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13794                 error "reset elapsed=$elapsed > $now - $reset"
13795         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13796            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13797                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13798 }
13799 run_test 127a "verify the client stats are sane"
13800
13801 test_127b() { # bug LU-333
13802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13803         local name count samp unit min max sum sumsq
13804
13805         echo "stats before reset"
13806         $LCTL get_param llite.*.stats
13807         $LCTL set_param llite.*.stats=0
13808
13809         # perform 2 reads and writes so MAX is different from SUM.
13810         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13811         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13812         cancel_lru_locks osc
13813         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13814         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13815
13816         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13817         stack_trap "rm -f $TMP/$tfile.tmp"
13818         while read name count samp unit min max sum sumsq; do
13819                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13820                 eval $name=$count || error "Wrong proc format"
13821
13822                 case $name in
13823                 read_bytes|write_bytes)
13824                         [[ "$unit" =~ "bytes" ]] ||
13825                                 error "unit is not 'bytes': $unit"
13826                         (( $count == 2 )) || error "count is not 2: $count"
13827                         (( $min == $PAGE_SIZE )) ||
13828                                 error "min is not $PAGE_SIZE: $min"
13829                         (( $max == $PAGE_SIZE )) ||
13830                                 error "max is not $PAGE_SIZE: $max"
13831                         (( $sum == $PAGE_SIZE * 2 )) ||
13832                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13833                         ;;
13834                 read|write)
13835                         [[ "$unit" =~ "usec" ]] ||
13836                                 error "unit is not 'usec': $unit"
13837                         ;;
13838                 *)      ;;
13839                 esac
13840         done < $TMP/$tfile.tmp
13841
13842         #check that we actually got some stats
13843         [ "$read_bytes" ] || error "Missing read_bytes stats"
13844         [ "$write_bytes" ] || error "Missing write_bytes stats"
13845         [ "$read_bytes" != 0 ] || error "no read done"
13846         [ "$write_bytes" != 0 ] || error "no write done"
13847 }
13848 run_test 127b "verify the llite client stats are sane"
13849
13850 test_127c() { # LU-12394
13851         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13852         local size
13853         local bsize
13854         local reads
13855         local writes
13856         local count
13857
13858         $LCTL set_param llite.*.extents_stats=1
13859         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13860
13861         # Use two stripes so there is enough space in default config
13862         $LFS setstripe -c 2 $DIR/$tfile
13863
13864         # Extent stats start at 0-4K and go in power of two buckets
13865         # LL_HIST_START = 12 --> 2^12 = 4K
13866         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13867         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13868         # small configs
13869         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13870                 do
13871                 # Write and read, 2x each, second time at a non-zero offset
13872                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13873                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13874                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13875                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13876                 rm -f $DIR/$tfile
13877         done
13878
13879         $LCTL get_param llite.*.extents_stats
13880
13881         count=2
13882         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13883                 do
13884                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13885                                 grep -m 1 $bsize)
13886                 reads=$(echo $bucket | awk '{print $5}')
13887                 writes=$(echo $bucket | awk '{print $9}')
13888                 [ "$reads" -eq $count ] ||
13889                         error "$reads reads in < $bsize bucket, expect $count"
13890                 [ "$writes" -eq $count ] ||
13891                         error "$writes writes in < $bsize bucket, expect $count"
13892         done
13893
13894         # Test mmap write and read
13895         $LCTL set_param llite.*.extents_stats=c
13896         size=512
13897         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13898         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13899         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13900
13901         $LCTL get_param llite.*.extents_stats
13902
13903         count=$(((size*1024) / PAGE_SIZE))
13904
13905         bsize=$((2 * PAGE_SIZE / 1024))K
13906
13907         bucket=$($LCTL get_param -n llite.*.extents_stats |
13908                         grep -m 1 $bsize)
13909         reads=$(echo $bucket | awk '{print $5}')
13910         writes=$(echo $bucket | awk '{print $9}')
13911         # mmap writes fault in the page first, creating an additonal read
13912         [ "$reads" -eq $((2 * count)) ] ||
13913                 error "$reads reads in < $bsize bucket, expect $count"
13914         [ "$writes" -eq $count ] ||
13915                 error "$writes writes in < $bsize bucket, expect $count"
13916 }
13917 run_test 127c "test llite extent stats with regular & mmap i/o"
13918
13919 test_128() { # bug 15212
13920         touch $DIR/$tfile
13921         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13922                 find $DIR/$tfile
13923                 find $DIR/$tfile
13924         EOF
13925
13926         result=$(grep error $TMP/$tfile.log)
13927         rm -f $DIR/$tfile $TMP/$tfile.log
13928         [ -z "$result" ] ||
13929                 error "consecutive find's under interactive lfs failed"
13930 }
13931 run_test 128 "interactive lfs for 2 consecutive find's"
13932
13933 set_dir_limits () {
13934         local mntdev
13935         local canondev
13936         local node
13937
13938         local ldproc=/proc/fs/ldiskfs
13939         local facets=$(get_facets MDS)
13940
13941         for facet in ${facets//,/ }; do
13942                 canondev=$(ldiskfs_canon \
13943                            *.$(convert_facet2label $facet).mntdev $facet)
13944                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13945                         ldproc=/sys/fs/ldiskfs
13946                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13947                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13948         done
13949 }
13950
13951 check_mds_dmesg() {
13952         local facets=$(get_facets MDS)
13953         for facet in ${facets//,/ }; do
13954                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13955         done
13956         return 1
13957 }
13958
13959 test_129() {
13960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13961         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13962                 skip "Need MDS version with at least 2.5.56"
13963         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13964                 skip_env "ldiskfs only test"
13965         fi
13966         remote_mds_nodsh && skip "remote MDS with nodsh"
13967
13968         local ENOSPC=28
13969         local has_warning=false
13970
13971         rm -rf $DIR/$tdir
13972         mkdir -p $DIR/$tdir
13973
13974         # block size of mds1
13975         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13976         set_dir_limits $maxsize $((maxsize * 6 / 8))
13977         stack_trap "set_dir_limits 0 0"
13978         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13979         local dirsize=$(stat -c%s "$DIR/$tdir")
13980         local nfiles=0
13981         while (( $dirsize <= $maxsize )); do
13982                 $MCREATE $DIR/$tdir/file_base_$nfiles
13983                 rc=$?
13984                 # check two errors:
13985                 # ENOSPC for ext4 max_dir_size, which has been used since
13986                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13987                 if (( rc == ENOSPC )); then
13988                         set_dir_limits 0 0
13989                         echo "rc=$rc returned as expected after $nfiles files"
13990
13991                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13992                                 error "create failed w/o dir size limit"
13993
13994                         # messages may be rate limited if test is run repeatedly
13995                         check_mds_dmesg '"is approaching max"' ||
13996                                 echo "warning message should be output"
13997                         check_mds_dmesg '"has reached max"' ||
13998                                 echo "reached message should be output"
13999
14000                         dirsize=$(stat -c%s "$DIR/$tdir")
14001
14002                         [[ $dirsize -ge $maxsize ]] && return 0
14003                         error "dirsize $dirsize < $maxsize after $nfiles files"
14004                 elif (( rc != 0 )); then
14005                         break
14006                 fi
14007                 nfiles=$((nfiles + 1))
14008                 dirsize=$(stat -c%s "$DIR/$tdir")
14009         done
14010
14011         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14012 }
14013 run_test 129 "test directory size limit ========================"
14014
14015 OLDIFS="$IFS"
14016 cleanup_130() {
14017         trap 0
14018         IFS="$OLDIFS"
14019 }
14020
14021 test_130a() {
14022         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14023         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14024
14025         trap cleanup_130 EXIT RETURN
14026
14027         local fm_file=$DIR/$tfile
14028         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14029         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14030                 error "dd failed for $fm_file"
14031
14032         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14033         filefrag -ves $fm_file
14034         local rc=$?
14035         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14036                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14037         (( $rc == 0 )) || error "filefrag $fm_file failed"
14038
14039         filefrag_op=$(filefrag -ve -k $fm_file |
14040                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14041         local lun=$($LFS getstripe -i $fm_file)
14042
14043         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14044         IFS=$'\n'
14045         local tot_len=0
14046         for line in $filefrag_op; do
14047                 local frag_lun=$(echo $line | cut -d: -f5)
14048                 local ext_len=$(echo $line | cut -d: -f4)
14049
14050                 if (( $frag_lun != $lun )); then
14051                         error "FIEMAP on 1-stripe file($fm_file) failed"
14052                         return
14053                 fi
14054                 (( tot_len += ext_len ))
14055         done
14056
14057         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14058                 error "FIEMAP on 1-stripe file($fm_file) failed"
14059                 return
14060         fi
14061
14062         echo "FIEMAP on single striped file succeeded"
14063 }
14064 run_test 130a "FIEMAP (1-stripe file)"
14065
14066 test_130b() {
14067         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14068
14069         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14070         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14071         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14072                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14073
14074         trap cleanup_130 EXIT RETURN
14075
14076         local fm_file=$DIR/$tfile
14077         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14078                 error "setstripe on $fm_file"
14079
14080         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14081                 error "dd failed on $fm_file"
14082
14083         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14084         filefrag_op=$(filefrag -ve -k $fm_file |
14085                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14086
14087         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14088                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14089
14090         IFS=$'\n'
14091         local tot_len=0
14092         local num_luns=1
14093
14094         for line in $filefrag_op; do
14095                 local frag_lun=$(echo $line | cut -d: -f5 |
14096                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14097                 local ext_len=$(echo $line | cut -d: -f4)
14098                 if (( $frag_lun != $last_lun )); then
14099                         if (( tot_len != 1024 )); then
14100                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14101                                 return
14102                         else
14103                                 (( num_luns += 1 ))
14104                                 tot_len=0
14105                         fi
14106                 fi
14107                 (( tot_len += ext_len ))
14108                 last_lun=$frag_lun
14109         done
14110         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14111                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14112                 return
14113         fi
14114
14115         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14116 }
14117 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14118
14119 test_130c() {
14120         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14121
14122         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14123         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14124         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14125                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14126
14127         trap cleanup_130 EXIT RETURN
14128
14129         local fm_file=$DIR/$tfile
14130         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14131
14132         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14133                 error "dd failed on $fm_file"
14134
14135         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14136         filefrag_op=$(filefrag -ve -k $fm_file |
14137                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14138
14139         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14140                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14141
14142         IFS=$'\n'
14143         local tot_len=0
14144         local num_luns=1
14145         for line in $filefrag_op; do
14146                 local frag_lun=$(echo $line | cut -d: -f5 |
14147                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14148                 local ext_len=$(echo $line | cut -d: -f4)
14149                 if (( $frag_lun != $last_lun )); then
14150                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14151                         if (( logical != 512 )); then
14152                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14153                                 return
14154                         fi
14155                         if (( tot_len != 512 )); then
14156                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14157                                 return
14158                         else
14159                                 (( num_luns += 1 ))
14160                                 tot_len=0
14161                         fi
14162                 fi
14163                 (( tot_len += ext_len ))
14164                 last_lun=$frag_lun
14165         done
14166         if (( num_luns != 2 || tot_len != 512 )); then
14167                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14168                 return
14169         fi
14170
14171         echo "FIEMAP on 2-stripe file with hole succeeded"
14172 }
14173 run_test 130c "FIEMAP (2-stripe file with hole)"
14174
14175 test_130d() {
14176         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14177
14178         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14179         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14180         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14181                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14182
14183         trap cleanup_130 EXIT RETURN
14184
14185         local fm_file=$DIR/$tfile
14186         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14187                         error "setstripe on $fm_file"
14188
14189         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14190         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14191                 error "dd failed on $fm_file"
14192
14193         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14194         filefrag_op=$(filefrag -ve -k $fm_file |
14195                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14196
14197         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14198                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14199
14200         IFS=$'\n'
14201         local tot_len=0
14202         local num_luns=1
14203         for line in $filefrag_op; do
14204                 local frag_lun=$(echo $line | cut -d: -f5 |
14205                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14206                 local ext_len=$(echo $line | cut -d: -f4)
14207                 if (( $frag_lun != $last_lun )); then
14208                         if (( tot_len != 1024 )); then
14209                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14210                                 return
14211                         else
14212                                 (( num_luns += 1 ))
14213                                 local tot_len=0
14214                         fi
14215                 fi
14216                 (( tot_len += ext_len ))
14217                 last_lun=$frag_lun
14218         done
14219         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14220                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14221                 return
14222         fi
14223
14224         echo "FIEMAP on N-stripe file succeeded"
14225 }
14226 run_test 130d "FIEMAP (N-stripe file)"
14227
14228 test_130e() {
14229         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14230
14231         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14232         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14233         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14234                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14235
14236         trap cleanup_130 EXIT RETURN
14237
14238         local fm_file=$DIR/$tfile
14239         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14240
14241         local num_blks=512
14242         local expected_len=$(( (num_blks / 2) * 64 ))
14243         for ((i = 0; i < $num_blks; i++)); do
14244                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14245                         conv=notrunc > /dev/null 2>&1
14246         done
14247
14248         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14249         filefrag_op=$(filefrag -ve -k $fm_file |
14250                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14251
14252         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14253
14254         IFS=$'\n'
14255         local tot_len=0
14256         local num_luns=1
14257         for line in $filefrag_op; do
14258                 local frag_lun=$(echo $line | cut -d: -f5)
14259                 local ext_len=$(echo $line | cut -d: -f4)
14260                 if (( $frag_lun != $last_lun )); then
14261                         if (( tot_len != $expected_len )); then
14262                                 error "OST$last_lun $tot_len != $expected_len"
14263                         else
14264                                 (( num_luns += 1 ))
14265                                 tot_len=0
14266                         fi
14267                 fi
14268                 (( tot_len += ext_len ))
14269                 last_lun=$frag_lun
14270         done
14271         if (( num_luns != 2 || tot_len != $expected_len )); then
14272                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14273         fi
14274
14275         echo "FIEMAP with continuation calls succeeded"
14276 }
14277 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14278
14279 test_130f() {
14280         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14281         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14282         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14283                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14284
14285         local fm_file=$DIR/$tfile
14286         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14287                 error "multiop create with lov_delay_create on $fm_file"
14288
14289         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14290         filefrag_extents=$(filefrag -vek $fm_file |
14291                            awk '/extents? found/ { print $2 }')
14292         if (( $filefrag_extents != 0 )); then
14293                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14294         fi
14295
14296         rm -f $fm_file
14297 }
14298 run_test 130f "FIEMAP (unstriped file)"
14299
14300 test_130g() {
14301         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14302                 skip "Need MDS version with at least 2.12.53 for overstriping"
14303         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14304         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14305         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14306                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14307
14308         local file=$DIR/$tfile
14309         local nr=$((OSTCOUNT * 100))
14310
14311         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14312
14313         stack_trap "rm -f $file"
14314         dd if=/dev/zero of=$file count=$nr bs=1M
14315         sync
14316         nr=$($LFS getstripe -c $file)
14317
14318         local extents=$(filefrag -v $file |
14319                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14320
14321         echo "filefrag list $extents extents in file with stripecount $nr"
14322         if (( extents < nr )); then
14323                 $LFS getstripe $file
14324                 filefrag -v $file
14325                 error "filefrag printed $extents < $nr extents"
14326         fi
14327 }
14328 run_test 130g "FIEMAP (overstripe file)"
14329
14330 # Test for writev/readv
14331 test_131a() {
14332         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14333                 error "writev test failed"
14334         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14335                 error "readv failed"
14336         rm -f $DIR/$tfile
14337 }
14338 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14339
14340 test_131b() {
14341         local fsize=$((524288 + 1048576 + 1572864))
14342         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14343                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14344                         error "append writev test failed"
14345
14346         ((fsize += 1572864 + 1048576))
14347         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14348                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14349                         error "append writev test failed"
14350         rm -f $DIR/$tfile
14351 }
14352 run_test 131b "test append writev"
14353
14354 test_131c() {
14355         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14356         error "NOT PASS"
14357 }
14358 run_test 131c "test read/write on file w/o objects"
14359
14360 test_131d() {
14361         rwv -f $DIR/$tfile -w -n 1 1572864
14362         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14363         if [ "$NOB" != 1572864 ]; then
14364                 error "Short read filed: read $NOB bytes instead of 1572864"
14365         fi
14366         rm -f $DIR/$tfile
14367 }
14368 run_test 131d "test short read"
14369
14370 test_131e() {
14371         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14372         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14373         error "read hitting hole failed"
14374         rm -f $DIR/$tfile
14375 }
14376 run_test 131e "test read hitting hole"
14377
14378 check_stats() {
14379         local facet=$1
14380         local op=$2
14381         local want=${3:-0}
14382         local res
14383
14384         # open             11 samples [usecs] 468 4793 13658 35791898
14385         case $facet in
14386         mds*) res=($(do_facet $facet \
14387                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14388                  ;;
14389         ost*) res=($(do_facet $facet \
14390                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14391                  ;;
14392         *) error "Wrong facet '$facet'" ;;
14393         esac
14394         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14395         # if $want is zero, it means any stat increment is ok.
14396         if (( $want > 0 )); then
14397                 local count=${res[1]}
14398
14399                 if (( $count != $want )); then
14400                         if [[ $facet =~ "mds" ]]; then
14401                                 do_nodes $(comma_list $(mdts_nodes)) \
14402                                         $LCTL get_param mdt.*.md_stats
14403                         else
14404                                 do_nodes $(comma_list $(osts-nodes)) \
14405                                         $LCTL get_param obdfilter.*.stats
14406                         fi
14407                         error "The $op counter on $facet is $count, not $want"
14408                 fi
14409         fi
14410 }
14411
14412 test_133a() {
14413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14414         remote_ost_nodsh && skip "remote OST with nodsh"
14415         remote_mds_nodsh && skip "remote MDS with nodsh"
14416         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14417                 skip_env "MDS doesn't support rename stats"
14418
14419         local testdir=$DIR/${tdir}/stats_testdir
14420
14421         mkdir -p $DIR/${tdir}
14422
14423         # clear stats.
14424         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14425         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14426
14427         # verify mdt stats first.
14428         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14429         check_stats $SINGLEMDS "mkdir" 1
14430
14431         # clear "open" from "lfs mkdir" above
14432         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14433         touch ${testdir}/${tfile} || error "touch failed"
14434         check_stats $SINGLEMDS "open" 1
14435         check_stats $SINGLEMDS "close" 1
14436         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14437                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14438                 check_stats $SINGLEMDS "mknod" 2
14439         }
14440         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14441         check_stats $SINGLEMDS "unlink" 1
14442         rm -f ${testdir}/${tfile} || error "file remove failed"
14443         check_stats $SINGLEMDS "unlink" 2
14444
14445         # remove working dir and check mdt stats again.
14446         rmdir ${testdir} || error "rmdir failed"
14447         check_stats $SINGLEMDS "rmdir" 1
14448
14449         local testdir1=$DIR/${tdir}/stats_testdir1
14450         mkdir_on_mdt0 -p ${testdir}
14451         mkdir_on_mdt0 -p ${testdir1}
14452         touch ${testdir1}/test1
14453         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14454         check_stats $SINGLEMDS "crossdir_rename" 1
14455
14456         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14457         check_stats $SINGLEMDS "samedir_rename" 1
14458
14459         rm -rf $DIR/${tdir}
14460 }
14461 run_test 133a "Verifying MDT stats ========================================"
14462
14463 test_133b() {
14464         local res
14465
14466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14467         remote_ost_nodsh && skip "remote OST with nodsh"
14468         remote_mds_nodsh && skip "remote MDS with nodsh"
14469
14470         local testdir=$DIR/${tdir}/stats_testdir
14471
14472         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14473         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14474         touch ${testdir}/${tfile} || error "touch failed"
14475         cancel_lru_locks mdc
14476
14477         # clear stats.
14478         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14479         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14480
14481         # extra mdt stats verification.
14482         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14483         check_stats $SINGLEMDS "setattr" 1
14484         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14485         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14486         then            # LU-1740
14487                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14488                 check_stats $SINGLEMDS "getattr" 1
14489         fi
14490         rm -rf $DIR/${tdir}
14491
14492         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14493         # so the check below is not reliable
14494         [ $MDSCOUNT -eq 1 ] || return 0
14495
14496         # Sleep to avoid a cached response.
14497         #define OBD_STATFS_CACHE_SECONDS 1
14498         sleep 2
14499         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14500         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14501         $LFS df || error "lfs failed"
14502         check_stats $SINGLEMDS "statfs" 1
14503
14504         # check aggregated statfs (LU-10018)
14505         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14506                 return 0
14507         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14508                 return 0
14509         sleep 2
14510         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14511         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14512         df $DIR
14513         check_stats $SINGLEMDS "statfs" 1
14514
14515         # We want to check that the client didn't send OST_STATFS to
14516         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14517         # extra care is needed here.
14518         if remote_mds; then
14519                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14520                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14521
14522                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14523                 [ "$res" ] && error "OST got STATFS"
14524         fi
14525
14526         return 0
14527 }
14528 run_test 133b "Verifying extra MDT stats =================================="
14529
14530 test_133c() {
14531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14532         remote_ost_nodsh && skip "remote OST with nodsh"
14533         remote_mds_nodsh && skip "remote MDS with nodsh"
14534
14535         local testdir=$DIR/$tdir/stats_testdir
14536
14537         test_mkdir -p $testdir
14538
14539         # verify obdfilter stats.
14540         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14541         sync
14542         cancel_lru_locks osc
14543         wait_delete_completed
14544
14545         # clear stats.
14546         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14547         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14548
14549         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14550                 error "dd failed"
14551         sync
14552         cancel_lru_locks osc
14553         check_stats ost1 "write" 1
14554
14555         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14556         check_stats ost1 "read" 1
14557
14558         > $testdir/$tfile || error "truncate failed"
14559         check_stats ost1 "punch" 1
14560
14561         rm -f $testdir/$tfile || error "file remove failed"
14562         wait_delete_completed
14563         check_stats ost1 "destroy" 1
14564
14565         rm -rf $DIR/$tdir
14566 }
14567 run_test 133c "Verifying OST stats ========================================"
14568
14569 order_2() {
14570         local value=$1
14571         local orig=$value
14572         local order=1
14573
14574         while [ $value -ge 2 ]; do
14575                 order=$((order*2))
14576                 value=$((value/2))
14577         done
14578
14579         if [ $orig -gt $order ]; then
14580                 order=$((order*2))
14581         fi
14582         echo $order
14583 }
14584
14585 size_in_KMGT() {
14586     local value=$1
14587     local size=('K' 'M' 'G' 'T');
14588     local i=0
14589     local size_string=$value
14590
14591     while [ $value -ge 1024 ]; do
14592         if [ $i -gt 3 ]; then
14593             #T is the biggest unit we get here, if that is bigger,
14594             #just return XXXT
14595             size_string=${value}T
14596             break
14597         fi
14598         value=$((value >> 10))
14599         if [ $value -lt 1024 ]; then
14600             size_string=${value}${size[$i]}
14601             break
14602         fi
14603         i=$((i + 1))
14604     done
14605
14606     echo $size_string
14607 }
14608
14609 get_rename_size() {
14610         local size=$1
14611         local context=${2:-.}
14612         local sample=$(do_facet $SINGLEMDS $LCTL \
14613                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14614                 grep -A1 $context |
14615                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14616         echo $sample
14617 }
14618
14619 test_133d() {
14620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14621         remote_ost_nodsh && skip "remote OST with nodsh"
14622         remote_mds_nodsh && skip "remote MDS with nodsh"
14623         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14624                 skip_env "MDS doesn't support rename stats"
14625
14626         local testdir1=$DIR/${tdir}/stats_testdir1
14627         local testdir2=$DIR/${tdir}/stats_testdir2
14628         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14629
14630         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14631
14632         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14633         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14634
14635         createmany -o $testdir1/test 512 || error "createmany failed"
14636
14637         # check samedir rename size
14638         mv ${testdir1}/test0 ${testdir1}/test_0
14639
14640         local testdir1_size=$(ls -l $DIR/${tdir} |
14641                 awk '/stats_testdir1/ {print $5}')
14642         local testdir2_size=$(ls -l $DIR/${tdir} |
14643                 awk '/stats_testdir2/ {print $5}')
14644
14645         testdir1_size=$(order_2 $testdir1_size)
14646         testdir2_size=$(order_2 $testdir2_size)
14647
14648         testdir1_size=$(size_in_KMGT $testdir1_size)
14649         testdir2_size=$(size_in_KMGT $testdir2_size)
14650
14651         echo "source rename dir size: ${testdir1_size}"
14652         echo "target rename dir size: ${testdir2_size}"
14653
14654         local cmd="do_facet $SINGLEMDS $LCTL "
14655         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14656
14657         eval $cmd || error "$cmd failed"
14658         local samedir=$($cmd | grep 'same_dir')
14659         local same_sample=$(get_rename_size $testdir1_size)
14660         [ -z "$samedir" ] && error "samedir_rename_size count error"
14661         [[ $same_sample -eq 1 ]] ||
14662                 error "samedir_rename_size error $same_sample"
14663         echo "Check same dir rename stats success"
14664
14665         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14666
14667         # check crossdir rename size
14668         mv ${testdir1}/test_0 ${testdir2}/test_0
14669
14670         testdir1_size=$(ls -l $DIR/${tdir} |
14671                 awk '/stats_testdir1/ {print $5}')
14672         testdir2_size=$(ls -l $DIR/${tdir} |
14673                 awk '/stats_testdir2/ {print $5}')
14674
14675         testdir1_size=$(order_2 $testdir1_size)
14676         testdir2_size=$(order_2 $testdir2_size)
14677
14678         testdir1_size=$(size_in_KMGT $testdir1_size)
14679         testdir2_size=$(size_in_KMGT $testdir2_size)
14680
14681         echo "source rename dir size: ${testdir1_size}"
14682         echo "target rename dir size: ${testdir2_size}"
14683
14684         eval $cmd || error "$cmd failed"
14685         local crossdir=$($cmd | grep 'crossdir')
14686         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14687         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14688         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14689         [[ $src_sample -eq 1 ]] ||
14690                 error "crossdir_rename_size error $src_sample"
14691         [[ $tgt_sample -eq 1 ]] ||
14692                 error "crossdir_rename_size error $tgt_sample"
14693         echo "Check cross dir rename stats success"
14694         rm -rf $DIR/${tdir}
14695 }
14696 run_test 133d "Verifying rename_stats ========================================"
14697
14698 test_133e() {
14699         remote_mds_nodsh && skip "remote MDS with nodsh"
14700         remote_ost_nodsh && skip "remote OST with nodsh"
14701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14702
14703         local testdir=$DIR/${tdir}/stats_testdir
14704         local ctr f0 f1 bs=32768 count=42 sum
14705
14706         mkdir -p ${testdir} || error "mkdir failed"
14707
14708         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14709
14710         for ctr in {write,read}_bytes; do
14711                 sync
14712                 cancel_lru_locks osc
14713
14714                 do_facet ost1 $LCTL set_param -n \
14715                         "obdfilter.*.exports.clear=clear"
14716
14717                 if [ $ctr = write_bytes ]; then
14718                         f0=/dev/zero
14719                         f1=${testdir}/${tfile}
14720                 else
14721                         f0=${testdir}/${tfile}
14722                         f1=/dev/null
14723                 fi
14724
14725                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14726                         error "dd failed"
14727                 sync
14728                 cancel_lru_locks osc
14729
14730                 sum=$(do_facet ost1 $LCTL get_param \
14731                         "obdfilter.*.exports.*.stats" |
14732                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14733                                 $1 == ctr { sum += $7 }
14734                                 END { printf("%0.0f", sum) }')
14735
14736                 if ((sum != bs * count)); then
14737                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14738                 fi
14739         done
14740
14741         rm -rf $DIR/${tdir}
14742 }
14743 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14744
14745 test_133f() {
14746         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14747                 skip "too old lustre for get_param -R ($facet_ver)"
14748
14749         # verifying readability.
14750         $LCTL get_param -R '*' &> /dev/null
14751
14752         # Verifing writability with badarea_io.
14753         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14754         local skipped_params='force_lbug|changelog_mask|daemon_file'
14755         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14756                 egrep -v "$skipped_params" |
14757                 xargs -n 1 find $proc_dirs -name |
14758                 xargs -n 1 badarea_io ||
14759                 error "client badarea_io failed"
14760
14761         # remount the FS in case writes/reads /proc break the FS
14762         cleanup || error "failed to unmount"
14763         setup || error "failed to setup"
14764 }
14765 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14766
14767 test_133g() {
14768         remote_mds_nodsh && skip "remote MDS with nodsh"
14769         remote_ost_nodsh && skip "remote OST with nodsh"
14770
14771         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14772         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14773         local facet
14774         for facet in mds1 ost1; do
14775                 local facet_ver=$(lustre_version_code $facet)
14776                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14777                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14778                 else
14779                         log "$facet: too old lustre for get_param -R"
14780                 fi
14781                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14782                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14783                                 tr -d = | egrep -v $skipped_params |
14784                                 xargs -n 1 find $proc_dirs -name |
14785                                 xargs -n 1 badarea_io" ||
14786                                         error "$facet badarea_io failed"
14787                 else
14788                         skip_noexit "$facet: too old lustre for get_param -R"
14789                 fi
14790         done
14791
14792         # remount the FS in case writes/reads /proc break the FS
14793         cleanup || error "failed to unmount"
14794         setup || error "failed to setup"
14795 }
14796 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14797
14798 test_133h() {
14799         remote_mds_nodsh && skip "remote MDS with nodsh"
14800         remote_ost_nodsh && skip "remote OST with nodsh"
14801         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14802                 skip "Need MDS version at least 2.9.54"
14803
14804         local facet
14805         for facet in client mds1 ost1; do
14806                 # Get the list of files that are missing the terminating newline
14807                 local plist=$(do_facet $facet
14808                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14809                 local ent
14810                 for ent in $plist; do
14811                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14812                                 awk -v FS='\v' -v RS='\v\v' \
14813                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14814                                         print FILENAME}'" 2>/dev/null)
14815                         [ -z $missing ] || {
14816                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14817                                 error "file does not end with newline: $facet-$ent"
14818                         }
14819                 done
14820         done
14821 }
14822 run_test 133h "Proc files should end with newlines"
14823
14824 test_134a() {
14825         remote_mds_nodsh && skip "remote MDS with nodsh"
14826         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14827                 skip "Need MDS version at least 2.7.54"
14828
14829         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14830         cancel_lru_locks mdc
14831
14832         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14833         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14834         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14835
14836         local nr=1000
14837         createmany -o $DIR/$tdir/f $nr ||
14838                 error "failed to create $nr files in $DIR/$tdir"
14839         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14840
14841         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14842         do_facet mds1 $LCTL set_param fail_loc=0x327
14843         do_facet mds1 $LCTL set_param fail_val=500
14844         touch $DIR/$tdir/m
14845
14846         echo "sleep 10 seconds ..."
14847         sleep 10
14848         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14849
14850         do_facet mds1 $LCTL set_param fail_loc=0
14851         do_facet mds1 $LCTL set_param fail_val=0
14852         [ $lck_cnt -lt $unused ] ||
14853                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14854
14855         rm $DIR/$tdir/m
14856         unlinkmany $DIR/$tdir/f $nr
14857 }
14858 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14859
14860 test_134b() {
14861         remote_mds_nodsh && skip "remote MDS with nodsh"
14862         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14863                 skip "Need MDS version at least 2.7.54"
14864
14865         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14866         cancel_lru_locks mdc
14867
14868         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14869                         ldlm.lock_reclaim_threshold_mb)
14870         # disable reclaim temporarily
14871         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14872
14873         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14874         do_facet mds1 $LCTL set_param fail_loc=0x328
14875         do_facet mds1 $LCTL set_param fail_val=500
14876
14877         $LCTL set_param debug=+trace
14878
14879         local nr=600
14880         createmany -o $DIR/$tdir/f $nr &
14881         local create_pid=$!
14882
14883         echo "Sleep $TIMEOUT seconds ..."
14884         sleep $TIMEOUT
14885         if ! ps -p $create_pid  > /dev/null 2>&1; then
14886                 do_facet mds1 $LCTL set_param fail_loc=0
14887                 do_facet mds1 $LCTL set_param fail_val=0
14888                 do_facet mds1 $LCTL set_param \
14889                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14890                 error "createmany finished incorrectly!"
14891         fi
14892         do_facet mds1 $LCTL set_param fail_loc=0
14893         do_facet mds1 $LCTL set_param fail_val=0
14894         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14895         wait $create_pid || return 1
14896
14897         unlinkmany $DIR/$tdir/f $nr
14898 }
14899 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14900
14901 test_135() {
14902         remote_mds_nodsh && skip "remote MDS with nodsh"
14903         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14904                 skip "Need MDS version at least 2.13.50"
14905         local fname
14906
14907         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14908
14909 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14910         #set only one record at plain llog
14911         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14912
14913         #fill already existed plain llog each 64767
14914         #wrapping whole catalog
14915         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14916
14917         createmany -o $DIR/$tdir/$tfile_ 64700
14918         for (( i = 0; i < 64700; i = i + 2 ))
14919         do
14920                 rm $DIR/$tdir/$tfile_$i &
14921                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14922                 local pid=$!
14923                 wait $pid
14924         done
14925
14926         #waiting osp synchronization
14927         wait_delete_completed
14928 }
14929 run_test 135 "Race catalog processing"
14930
14931 test_136() {
14932         remote_mds_nodsh && skip "remote MDS with nodsh"
14933         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14934                 skip "Need MDS version at least 2.13.50"
14935         local fname
14936
14937         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14938         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14939         #set only one record at plain llog
14940 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14941         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14942
14943         #fill already existed 2 plain llogs each 64767
14944         #wrapping whole catalog
14945         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14946         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14947         wait_delete_completed
14948
14949         createmany -o $DIR/$tdir/$tfile_ 10
14950         sleep 25
14951
14952         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14953         for (( i = 0; i < 10; i = i + 3 ))
14954         do
14955                 rm $DIR/$tdir/$tfile_$i &
14956                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14957                 local pid=$!
14958                 wait $pid
14959                 sleep 7
14960                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14961         done
14962
14963         #waiting osp synchronization
14964         wait_delete_completed
14965 }
14966 run_test 136 "Race catalog processing 2"
14967
14968 test_140() { #bug-17379
14969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14970
14971         test_mkdir $DIR/$tdir
14972         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14973         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14974
14975         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14976         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14977         local i=0
14978         while i=$((i + 1)); do
14979                 test_mkdir $i
14980                 cd $i || error "Changing to $i"
14981                 ln -s ../stat stat || error "Creating stat symlink"
14982                 # Read the symlink until ELOOP present,
14983                 # not LBUGing the system is considered success,
14984                 # we didn't overrun the stack.
14985                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14986                 if [ $ret -ne 0 ]; then
14987                         if [ $ret -eq 40 ]; then
14988                                 break  # -ELOOP
14989                         else
14990                                 error "Open stat symlink"
14991                                         return
14992                         fi
14993                 fi
14994         done
14995         i=$((i - 1))
14996         echo "The symlink depth = $i"
14997         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14998                 error "Invalid symlink depth"
14999
15000         # Test recursive symlink
15001         ln -s symlink_self symlink_self
15002         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15003         echo "open symlink_self returns $ret"
15004         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15005 }
15006 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15007
15008 test_150a() {
15009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15010
15011         local TF="$TMP/$tfile"
15012
15013         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15014         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15015         cp $TF $DIR/$tfile
15016         cancel_lru_locks $OSC
15017         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15018         remount_client $MOUNT
15019         df -P $MOUNT
15020         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15021
15022         $TRUNCATE $TF 6000
15023         $TRUNCATE $DIR/$tfile 6000
15024         cancel_lru_locks $OSC
15025         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15026
15027         echo "12345" >>$TF
15028         echo "12345" >>$DIR/$tfile
15029         cancel_lru_locks $OSC
15030         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15031
15032         echo "12345" >>$TF
15033         echo "12345" >>$DIR/$tfile
15034         cancel_lru_locks $OSC
15035         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15036 }
15037 run_test 150a "truncate/append tests"
15038
15039 test_150b() {
15040         check_set_fallocate_or_skip
15041         local out
15042
15043         touch $DIR/$tfile
15044         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15045         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15046                 skip_eopnotsupp "$out|check_fallocate failed"
15047 }
15048 run_test 150b "Verify fallocate (prealloc) functionality"
15049
15050 test_150bb() {
15051         check_set_fallocate_or_skip
15052
15053         touch $DIR/$tfile
15054         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15055         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15056         > $DIR/$tfile
15057         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15058         # precomputed md5sum for 20MB of zeroes
15059         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15060         local sum=($(md5sum $DIR/$tfile))
15061
15062         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15063
15064         check_set_fallocate 1
15065
15066         > $DIR/$tfile
15067         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15068         sum=($(md5sum $DIR/$tfile))
15069
15070         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15071 }
15072 run_test 150bb "Verify fallocate modes both zero space"
15073
15074 test_150c() {
15075         check_set_fallocate_or_skip
15076         local striping="-c2"
15077
15078         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15079         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15080         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15081         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15082         local want=$((OSTCOUNT * 1048576))
15083
15084         # Must allocate all requested space, not more than 5% extra
15085         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15086                 error "bytes $bytes is not $want"
15087
15088         rm -f $DIR/$tfile
15089
15090         echo "verify fallocate on PFL file"
15091
15092         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15093
15094         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15095                 error "Create $DIR/$tfile failed"
15096         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15097         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15098         want=$((512 * 1048576))
15099
15100         # Must allocate all requested space, not more than 5% extra
15101         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15102                 error "bytes $bytes is not $want"
15103 }
15104 run_test 150c "Verify fallocate Size and Blocks"
15105
15106 test_150d() {
15107         check_set_fallocate_or_skip
15108         local striping="-c2"
15109
15110         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15111
15112         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15113         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15114                 error "setstripe failed"
15115         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15116         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15117         local want=$((OSTCOUNT * 1048576))
15118
15119         # Must allocate all requested space, not more than 5% extra
15120         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15121                 error "bytes $bytes is not $want"
15122 }
15123 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15124
15125 test_150e() {
15126         check_set_fallocate_or_skip
15127
15128         echo "df before:"
15129         $LFS df
15130         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15131         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15132                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15133
15134         # Find OST with Minimum Size
15135         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15136                        sort -un | head -1)
15137
15138         # Get 100MB per OST of the available space to reduce run time
15139         # else 60% of the available space if we are running SLOW tests
15140         if [ $SLOW == "no" ]; then
15141                 local space=$((1024 * 100 * OSTCOUNT))
15142         else
15143                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15144         fi
15145
15146         fallocate -l${space}k $DIR/$tfile ||
15147                 error "fallocate ${space}k $DIR/$tfile failed"
15148         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15149
15150         # get size immediately after fallocate. This should be correctly
15151         # updated
15152         local size=$(stat -c '%s' $DIR/$tfile)
15153         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15154
15155         # Sleep for a while for statfs to get updated. And not pull from cache.
15156         sleep 2
15157
15158         echo "df after fallocate:"
15159         $LFS df
15160
15161         (( size / 1024 == space )) || error "size $size != requested $space"
15162         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15163                 error "used $used < space $space"
15164
15165         rm $DIR/$tfile || error "rm failed"
15166         sync
15167         wait_delete_completed
15168
15169         echo "df after unlink:"
15170         $LFS df
15171 }
15172 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15173
15174 test_150f() {
15175         local size
15176         local blocks
15177         local want_size_before=20480 # in bytes
15178         local want_blocks_before=40 # 512 sized blocks
15179         local want_blocks_after=24  # 512 sized blocks
15180         local length=$(((want_blocks_before - want_blocks_after) * 512))
15181
15182         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15183                 skip "need at least 2.14.0 for fallocate punch"
15184
15185         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15186                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15187         fi
15188
15189         check_set_fallocate_or_skip
15190         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15191
15192         [[ "x$DOM" == "xyes" ]] &&
15193                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15194
15195         echo "Verify fallocate punch: Range within the file range"
15196         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15197                 error "dd failed for bs 4096 and count 5"
15198
15199         # Call fallocate with punch range which is within the file range
15200         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15201                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15202         # client must see changes immediately after fallocate
15203         size=$(stat -c '%s' $DIR/$tfile)
15204         blocks=$(stat -c '%b' $DIR/$tfile)
15205
15206         # Verify punch worked.
15207         (( blocks == want_blocks_after )) ||
15208                 error "punch failed: blocks $blocks != $want_blocks_after"
15209
15210         (( size == want_size_before )) ||
15211                 error "punch failed: size $size != $want_size_before"
15212
15213         # Verify there is hole in file
15214         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15215         # precomputed md5sum
15216         local expect="4a9a834a2db02452929c0a348273b4aa"
15217
15218         cksum=($(md5sum $DIR/$tfile))
15219         [[ "${cksum[0]}" == "$expect" ]] ||
15220                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15221
15222         # Start second sub-case for fallocate punch.
15223         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15224         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15225                 error "dd failed for bs 4096 and count 5"
15226
15227         # Punch range less than block size will have no change in block count
15228         want_blocks_after=40  # 512 sized blocks
15229
15230         # Punch overlaps two blocks and less than blocksize
15231         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15232                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15233         size=$(stat -c '%s' $DIR/$tfile)
15234         blocks=$(stat -c '%b' $DIR/$tfile)
15235
15236         # Verify punch worked.
15237         (( blocks == want_blocks_after )) ||
15238                 error "punch failed: blocks $blocks != $want_blocks_after"
15239
15240         (( size == want_size_before )) ||
15241                 error "punch failed: size $size != $want_size_before"
15242
15243         # Verify if range is really zero'ed out. We expect Zeros.
15244         # precomputed md5sum
15245         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15246         cksum=($(md5sum $DIR/$tfile))
15247         [[ "${cksum[0]}" == "$expect" ]] ||
15248                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15249 }
15250 run_test 150f "Verify fallocate punch functionality"
15251
15252 test_150g() {
15253         local space
15254         local size
15255         local blocks
15256         local blocks_after
15257         local size_after
15258         local BS=4096 # Block size in bytes
15259
15260         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15261                 skip "need at least 2.14.0 for fallocate punch"
15262
15263         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15264                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15265         fi
15266
15267         check_set_fallocate_or_skip
15268         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15269
15270         if [[ "x$DOM" == "xyes" ]]; then
15271                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15272                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15273         else
15274                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15275                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15276         fi
15277
15278         # Get 100MB per OST of the available space to reduce run time
15279         # else 60% of the available space if we are running SLOW tests
15280         if [ $SLOW == "no" ]; then
15281                 space=$((1024 * 100 * OSTCOUNT))
15282         else
15283                 # Find OST with Minimum Size
15284                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15285                         sort -un | head -1)
15286                 echo "min size OST: $space"
15287                 space=$(((space * 60)/100 * OSTCOUNT))
15288         fi
15289         # space in 1k units, round to 4k blocks
15290         local blkcount=$((space * 1024 / $BS))
15291
15292         echo "Verify fallocate punch: Very large Range"
15293         fallocate -l${space}k $DIR/$tfile ||
15294                 error "fallocate ${space}k $DIR/$tfile failed"
15295         # write 1M at the end, start and in the middle
15296         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15297                 error "dd failed: bs $BS count 256"
15298         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15299                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15300         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15301                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15302
15303         # Gather stats.
15304         size=$(stat -c '%s' $DIR/$tfile)
15305
15306         # gather punch length.
15307         local punch_size=$((size - (BS * 2)))
15308
15309         echo "punch_size = $punch_size"
15310         echo "size - punch_size: $((size - punch_size))"
15311         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15312
15313         # Call fallocate to punch all except 2 blocks. We leave the
15314         # first and the last block
15315         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15316         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15317                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15318
15319         size_after=$(stat -c '%s' $DIR/$tfile)
15320         blocks_after=$(stat -c '%b' $DIR/$tfile)
15321
15322         # Verify punch worked.
15323         # Size should be kept
15324         (( size == size_after )) ||
15325                 error "punch failed: size $size != $size_after"
15326
15327         # two 4k data blocks to remain plus possible 1 extra extent block
15328         (( blocks_after <= ((BS / 512) * 3) )) ||
15329                 error "too many blocks remains: $blocks_after"
15330
15331         # Verify that file has hole between the first and the last blocks
15332         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15333         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15334
15335         echo "Hole at [$hole_start, $hole_end)"
15336         (( hole_start == BS )) ||
15337                 error "no hole at offset $BS after punch"
15338
15339         (( hole_end == BS + punch_size )) ||
15340                 error "data at offset $hole_end < $((BS + punch_size))"
15341 }
15342 run_test 150g "Verify fallocate punch on large range"
15343
15344 test_150h() {
15345         local file=$DIR/$tfile
15346         local size
15347
15348         check_set_fallocate_or_skip
15349         statx_supported || skip_env "Test must be statx() syscall supported"
15350
15351         # fallocate() does not update the size information on the MDT
15352         fallocate -l 16K $file || error "failed to fallocate $file"
15353         cancel_lru_locks $OSC
15354         # STATX with cached-always mode will not send glimpse RPCs to OST,
15355         # it uses the caching attrs on the client side as much as possible.
15356         size=$($STATX --cached=always -c %s $file)
15357         [ $size == 16384 ] ||
15358                 error "size after fallocate() is $size, expected 16384"
15359 }
15360 run_test 150h "Verify extend fallocate updates the file size"
15361
15362 #LU-2902 roc_hit was not able to read all values from lproc
15363 function roc_hit_init() {
15364         local list=$(comma_list $(osts_nodes))
15365         local dir=$DIR/$tdir-check
15366         local file=$dir/$tfile
15367         local BEFORE
15368         local AFTER
15369         local idx
15370
15371         test_mkdir $dir
15372         #use setstripe to do a write to every ost
15373         for i in $(seq 0 $((OSTCOUNT-1))); do
15374                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15375                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15376                 idx=$(printf %04x $i)
15377                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15378                         awk '$1 == "cache_access" {sum += $7}
15379                                 END { printf("%0.0f", sum) }')
15380
15381                 cancel_lru_locks osc
15382                 cat $file >/dev/null
15383
15384                 AFTER=$(get_osd_param $list *OST*$idx stats |
15385                         awk '$1 == "cache_access" {sum += $7}
15386                                 END { printf("%0.0f", sum) }')
15387
15388                 echo BEFORE:$BEFORE AFTER:$AFTER
15389                 if ! let "AFTER - BEFORE == 4"; then
15390                         rm -rf $dir
15391                         error "roc_hit is not safe to use"
15392                 fi
15393                 rm $file
15394         done
15395
15396         rm -rf $dir
15397 }
15398
15399 function roc_hit() {
15400         local list=$(comma_list $(osts_nodes))
15401         echo $(get_osd_param $list '' stats |
15402                 awk '$1 == "cache_hit" {sum += $7}
15403                         END { printf("%0.0f", sum) }')
15404 }
15405
15406 function set_cache() {
15407         local on=1
15408
15409         if [ "$2" == "off" ]; then
15410                 on=0;
15411         fi
15412         local list=$(comma_list $(osts_nodes))
15413         set_osd_param $list '' $1_cache_enable $on
15414
15415         cancel_lru_locks osc
15416 }
15417
15418 test_151() {
15419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15420         remote_ost_nodsh && skip "remote OST with nodsh"
15421
15422         local CPAGES=3
15423         local list=$(comma_list $(osts_nodes))
15424
15425         # check whether obdfilter is cache capable at all
15426         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15427                 skip "not cache-capable obdfilter"
15428         fi
15429
15430         # check cache is enabled on all obdfilters
15431         if get_osd_param $list '' read_cache_enable | grep 0; then
15432                 skip "oss cache is disabled"
15433         fi
15434
15435         set_osd_param $list '' writethrough_cache_enable 1
15436
15437         # check write cache is enabled on all obdfilters
15438         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15439                 skip "oss write cache is NOT enabled"
15440         fi
15441
15442         roc_hit_init
15443
15444         #define OBD_FAIL_OBD_NO_LRU  0x609
15445         do_nodes $list $LCTL set_param fail_loc=0x609
15446
15447         # pages should be in the case right after write
15448         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15449                 error "dd failed"
15450
15451         local BEFORE=$(roc_hit)
15452         cancel_lru_locks osc
15453         cat $DIR/$tfile >/dev/null
15454         local AFTER=$(roc_hit)
15455
15456         do_nodes $list $LCTL set_param fail_loc=0
15457
15458         if ! let "AFTER - BEFORE == CPAGES"; then
15459                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15460         fi
15461
15462         cancel_lru_locks osc
15463         # invalidates OST cache
15464         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15465         set_osd_param $list '' read_cache_enable 0
15466         cat $DIR/$tfile >/dev/null
15467
15468         # now data shouldn't be found in the cache
15469         BEFORE=$(roc_hit)
15470         cancel_lru_locks osc
15471         cat $DIR/$tfile >/dev/null
15472         AFTER=$(roc_hit)
15473         if let "AFTER - BEFORE != 0"; then
15474                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15475         fi
15476
15477         set_osd_param $list '' read_cache_enable 1
15478         rm -f $DIR/$tfile
15479 }
15480 run_test 151 "test cache on oss and controls ==============================="
15481
15482 test_152() {
15483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15484
15485         local TF="$TMP/$tfile"
15486
15487         # simulate ENOMEM during write
15488 #define OBD_FAIL_OST_NOMEM      0x226
15489         lctl set_param fail_loc=0x80000226
15490         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15491         cp $TF $DIR/$tfile
15492         sync || error "sync failed"
15493         lctl set_param fail_loc=0
15494
15495         # discard client's cache
15496         cancel_lru_locks osc
15497
15498         # simulate ENOMEM during read
15499         lctl set_param fail_loc=0x80000226
15500         cmp $TF $DIR/$tfile || error "cmp failed"
15501         lctl set_param fail_loc=0
15502
15503         rm -f $TF
15504 }
15505 run_test 152 "test read/write with enomem ============================"
15506
15507 test_153() {
15508         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15509 }
15510 run_test 153 "test if fdatasync does not crash ======================="
15511
15512 dot_lustre_fid_permission_check() {
15513         local fid=$1
15514         local ffid=$MOUNT/.lustre/fid/$fid
15515         local test_dir=$2
15516
15517         echo "stat fid $fid"
15518         stat $ffid || error "stat $ffid failed."
15519         echo "touch fid $fid"
15520         touch $ffid || error "touch $ffid failed."
15521         echo "write to fid $fid"
15522         cat /etc/hosts > $ffid || error "write $ffid failed."
15523         echo "read fid $fid"
15524         diff /etc/hosts $ffid || error "read $ffid failed."
15525         echo "append write to fid $fid"
15526         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15527         echo "rename fid $fid"
15528         mv $ffid $test_dir/$tfile.1 &&
15529                 error "rename $ffid to $tfile.1 should fail."
15530         touch $test_dir/$tfile.1
15531         mv $test_dir/$tfile.1 $ffid &&
15532                 error "rename $tfile.1 to $ffid should fail."
15533         rm -f $test_dir/$tfile.1
15534         echo "truncate fid $fid"
15535         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15536         echo "link fid $fid"
15537         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15538         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15539                 echo "setfacl fid $fid"
15540                 setfacl -R -m u:$USER0:rwx $ffid ||
15541                         error "setfacl $ffid failed"
15542                 echo "getfacl fid $fid"
15543                 getfacl $ffid || error "getfacl $ffid failed."
15544         fi
15545         echo "unlink fid $fid"
15546         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15547         echo "mknod fid $fid"
15548         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15549
15550         fid=[0xf00000400:0x1:0x0]
15551         ffid=$MOUNT/.lustre/fid/$fid
15552
15553         echo "stat non-exist fid $fid"
15554         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15555         echo "write to non-exist fid $fid"
15556         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15557         echo "link new fid $fid"
15558         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15559
15560         mkdir -p $test_dir/$tdir
15561         touch $test_dir/$tdir/$tfile
15562         fid=$($LFS path2fid $test_dir/$tdir)
15563         rc=$?
15564         [ $rc -ne 0 ] &&
15565                 error "error: could not get fid for $test_dir/$dir/$tfile."
15566
15567         ffid=$MOUNT/.lustre/fid/$fid
15568
15569         echo "ls $fid"
15570         ls $ffid || error "ls $ffid failed."
15571         echo "touch $fid/$tfile.1"
15572         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15573
15574         echo "touch $MOUNT/.lustre/fid/$tfile"
15575         touch $MOUNT/.lustre/fid/$tfile && \
15576                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15577
15578         echo "setxattr to $MOUNT/.lustre/fid"
15579         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15580
15581         echo "listxattr for $MOUNT/.lustre/fid"
15582         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15583
15584         echo "delxattr from $MOUNT/.lustre/fid"
15585         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15586
15587         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15588         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15589                 error "touch invalid fid should fail."
15590
15591         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15592         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15593                 error "touch non-normal fid should fail."
15594
15595         echo "rename $tdir to $MOUNT/.lustre/fid"
15596         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15597                 error "rename to $MOUNT/.lustre/fid should fail."
15598
15599         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15600         then            # LU-3547
15601                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15602                 local new_obf_mode=777
15603
15604                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15605                 chmod $new_obf_mode $DIR/.lustre/fid ||
15606                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15607
15608                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15609                 [ $obf_mode -eq $new_obf_mode ] ||
15610                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15611
15612                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15613                 chmod $old_obf_mode $DIR/.lustre/fid ||
15614                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15615         fi
15616
15617         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15618         fid=$($LFS path2fid $test_dir/$tfile-2)
15619
15620         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15621         then # LU-5424
15622                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15623                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15624                         error "create lov data thru .lustre failed"
15625         fi
15626         echo "cp /etc/passwd $test_dir/$tfile-2"
15627         cp /etc/passwd $test_dir/$tfile-2 ||
15628                 error "copy to $test_dir/$tfile-2 failed."
15629         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15630         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15631                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15632
15633         rm -rf $test_dir/tfile.lnk
15634         rm -rf $test_dir/$tfile-2
15635 }
15636
15637 test_154A() {
15638         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15639                 skip "Need MDS version at least 2.4.1"
15640
15641         local tf=$DIR/$tfile
15642         touch $tf
15643
15644         local fid=$($LFS path2fid $tf)
15645         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15646
15647         # check that we get the same pathname back
15648         local rootpath
15649         local found
15650         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15651                 echo "$rootpath $fid"
15652                 found=$($LFS fid2path $rootpath "$fid")
15653                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15654                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15655         done
15656
15657         # check wrong root path format
15658         rootpath=$MOUNT"_wrong"
15659         found=$($LFS fid2path $rootpath "$fid")
15660         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15661 }
15662 run_test 154A "lfs path2fid and fid2path basic checks"
15663
15664 test_154B() {
15665         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15666                 skip "Need MDS version at least 2.4.1"
15667
15668         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15669         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15670         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15671         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15672
15673         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15674         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15675
15676         # check that we get the same pathname
15677         echo "PFID: $PFID, name: $name"
15678         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15679         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15680         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15681                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15682
15683         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15684 }
15685 run_test 154B "verify the ll_decode_linkea tool"
15686
15687 test_154a() {
15688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15689         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15690         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15691                 skip "Need MDS version at least 2.2.51"
15692         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15693
15694         cp /etc/hosts $DIR/$tfile
15695
15696         fid=$($LFS path2fid $DIR/$tfile)
15697         rc=$?
15698         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15699
15700         dot_lustre_fid_permission_check "$fid" $DIR ||
15701                 error "dot lustre permission check $fid failed"
15702
15703         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15704
15705         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15706
15707         touch $MOUNT/.lustre/file &&
15708                 error "creation is not allowed under .lustre"
15709
15710         mkdir $MOUNT/.lustre/dir &&
15711                 error "mkdir is not allowed under .lustre"
15712
15713         rm -rf $DIR/$tfile
15714 }
15715 run_test 154a "Open-by-FID"
15716
15717 test_154b() {
15718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15719         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15721         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15722                 skip "Need MDS version at least 2.2.51"
15723
15724         local remote_dir=$DIR/$tdir/remote_dir
15725         local MDTIDX=1
15726         local rc=0
15727
15728         mkdir -p $DIR/$tdir
15729         $LFS mkdir -i $MDTIDX $remote_dir ||
15730                 error "create remote directory failed"
15731
15732         cp /etc/hosts $remote_dir/$tfile
15733
15734         fid=$($LFS path2fid $remote_dir/$tfile)
15735         rc=$?
15736         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15737
15738         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15739                 error "dot lustre permission check $fid failed"
15740         rm -rf $DIR/$tdir
15741 }
15742 run_test 154b "Open-by-FID for remote directory"
15743
15744 test_154c() {
15745         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15746                 skip "Need MDS version at least 2.4.1"
15747
15748         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15749         local FID1=$($LFS path2fid $DIR/$tfile.1)
15750         local FID2=$($LFS path2fid $DIR/$tfile.2)
15751         local FID3=$($LFS path2fid $DIR/$tfile.3)
15752
15753         local N=1
15754         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15755                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15756                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15757                 local want=FID$N
15758                 [ "$FID" = "${!want}" ] ||
15759                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15760                 N=$((N + 1))
15761         done
15762
15763         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15764         do
15765                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15766                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15767                 N=$((N + 1))
15768         done
15769 }
15770 run_test 154c "lfs path2fid and fid2path multiple arguments"
15771
15772 test_154d() {
15773         remote_mds_nodsh && skip "remote MDS with nodsh"
15774         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15775                 skip "Need MDS version at least 2.5.53"
15776
15777         if remote_mds; then
15778                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15779         else
15780                 nid="0@lo"
15781         fi
15782         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15783         local fd
15784         local cmd
15785
15786         rm -f $DIR/$tfile
15787         touch $DIR/$tfile
15788
15789         local fid=$($LFS path2fid $DIR/$tfile)
15790         # Open the file
15791         fd=$(free_fd)
15792         cmd="exec $fd<$DIR/$tfile"
15793         eval $cmd
15794         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15795         echo "$fid_list" | grep "$fid"
15796         rc=$?
15797
15798         cmd="exec $fd>/dev/null"
15799         eval $cmd
15800         if [ $rc -ne 0 ]; then
15801                 error "FID $fid not found in open files list $fid_list"
15802         fi
15803 }
15804 run_test 154d "Verify open file fid"
15805
15806 test_154e()
15807 {
15808         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15809                 skip "Need MDS version at least 2.6.50"
15810
15811         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15812                 error ".lustre returned by readdir"
15813         fi
15814 }
15815 run_test 154e ".lustre is not returned by readdir"
15816
15817 test_154f() {
15818         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15819
15820         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15821         mkdir_on_mdt0 $DIR/$tdir
15822         # test dirs inherit from its stripe
15823         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15824         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15825         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15826         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15827         touch $DIR/f
15828
15829         # get fid of parents
15830         local FID0=$($LFS path2fid $DIR/$tdir)
15831         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15832         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15833         local FID3=$($LFS path2fid $DIR)
15834
15835         # check that path2fid --parents returns expected <parent_fid>/name
15836         # 1) test for a directory (single parent)
15837         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15838         [ "$parent" == "$FID0/foo1" ] ||
15839                 error "expected parent: $FID0/foo1, got: $parent"
15840
15841         # 2) test for a file with nlink > 1 (multiple parents)
15842         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15843         echo "$parent" | grep -F "$FID1/$tfile" ||
15844                 error "$FID1/$tfile not returned in parent list"
15845         echo "$parent" | grep -F "$FID2/link" ||
15846                 error "$FID2/link not returned in parent list"
15847
15848         # 3) get parent by fid
15849         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15850         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15851         echo "$parent" | grep -F "$FID1/$tfile" ||
15852                 error "$FID1/$tfile not returned in parent list (by fid)"
15853         echo "$parent" | grep -F "$FID2/link" ||
15854                 error "$FID2/link not returned in parent list (by fid)"
15855
15856         # 4) test for entry in root directory
15857         parent=$($LFS path2fid --parents $DIR/f)
15858         echo "$parent" | grep -F "$FID3/f" ||
15859                 error "$FID3/f not returned in parent list"
15860
15861         # 5) test it on root directory
15862         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15863                 error "$MOUNT should not have parents"
15864
15865         # enable xattr caching and check that linkea is correctly updated
15866         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15867         save_lustre_params client "llite.*.xattr_cache" > $save
15868         lctl set_param llite.*.xattr_cache 1
15869
15870         # 6.1) linkea update on rename
15871         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15872
15873         # get parents by fid
15874         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15875         # foo1 should no longer be returned in parent list
15876         echo "$parent" | grep -F "$FID1" &&
15877                 error "$FID1 should no longer be in parent list"
15878         # the new path should appear
15879         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15880                 error "$FID2/$tfile.moved is not in parent list"
15881
15882         # 6.2) linkea update on unlink
15883         rm -f $DIR/$tdir/foo2/link
15884         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15885         # foo2/link should no longer be returned in parent list
15886         echo "$parent" | grep -F "$FID2/link" &&
15887                 error "$FID2/link should no longer be in parent list"
15888         true
15889
15890         rm -f $DIR/f
15891         restore_lustre_params < $save
15892         rm -f $save
15893 }
15894 run_test 154f "get parent fids by reading link ea"
15895
15896 test_154g()
15897 {
15898         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15899            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15900                 skip "Need MDS version at least 2.6.92"
15901
15902         mkdir_on_mdt0 $DIR/$tdir
15903         llapi_fid_test -d $DIR/$tdir
15904 }
15905 run_test 154g "various llapi FID tests"
15906
15907 test_155_small_load() {
15908     local temp=$TMP/$tfile
15909     local file=$DIR/$tfile
15910
15911     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15912         error "dd of=$temp bs=6096 count=1 failed"
15913     cp $temp $file
15914     cancel_lru_locks $OSC
15915     cmp $temp $file || error "$temp $file differ"
15916
15917     $TRUNCATE $temp 6000
15918     $TRUNCATE $file 6000
15919     cmp $temp $file || error "$temp $file differ (truncate1)"
15920
15921     echo "12345" >>$temp
15922     echo "12345" >>$file
15923     cmp $temp $file || error "$temp $file differ (append1)"
15924
15925     echo "12345" >>$temp
15926     echo "12345" >>$file
15927     cmp $temp $file || error "$temp $file differ (append2)"
15928
15929     rm -f $temp $file
15930     true
15931 }
15932
15933 test_155_big_load() {
15934         remote_ost_nodsh && skip "remote OST with nodsh"
15935
15936         local temp=$TMP/$tfile
15937         local file=$DIR/$tfile
15938
15939         free_min_max
15940         local cache_size=$(do_facet ost$((MAXI+1)) \
15941                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15942
15943         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15944         # pre-set value
15945         if [ -z "$cache_size" ]; then
15946                 cache_size=256
15947         fi
15948         local large_file_size=$((cache_size * 2))
15949
15950         echo "OSS cache size: $cache_size KB"
15951         echo "Large file size: $large_file_size KB"
15952
15953         [ $MAXV -le $large_file_size ] &&
15954                 skip_env "max available OST size needs > $large_file_size KB"
15955
15956         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15957
15958         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15959                 error "dd of=$temp bs=$large_file_size count=1k failed"
15960         cp $temp $file
15961         ls -lh $temp $file
15962         cancel_lru_locks osc
15963         cmp $temp $file || error "$temp $file differ"
15964
15965         rm -f $temp $file
15966         true
15967 }
15968
15969 save_writethrough() {
15970         local facets=$(get_facets OST)
15971
15972         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15973 }
15974
15975 test_155a() {
15976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15977
15978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15979
15980         save_writethrough $p
15981
15982         set_cache read on
15983         set_cache writethrough on
15984         test_155_small_load
15985         restore_lustre_params < $p
15986         rm -f $p
15987 }
15988 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15989
15990 test_155b() {
15991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15992
15993         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15994
15995         save_writethrough $p
15996
15997         set_cache read on
15998         set_cache writethrough off
15999         test_155_small_load
16000         restore_lustre_params < $p
16001         rm -f $p
16002 }
16003 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16004
16005 test_155c() {
16006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16007
16008         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16009
16010         save_writethrough $p
16011
16012         set_cache read off
16013         set_cache writethrough on
16014         test_155_small_load
16015         restore_lustre_params < $p
16016         rm -f $p
16017 }
16018 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16019
16020 test_155d() {
16021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16022
16023         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16024
16025         save_writethrough $p
16026
16027         set_cache read off
16028         set_cache writethrough off
16029         test_155_small_load
16030         restore_lustre_params < $p
16031         rm -f $p
16032 }
16033 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16034
16035 test_155e() {
16036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16037
16038         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16039
16040         save_writethrough $p
16041
16042         set_cache read on
16043         set_cache writethrough on
16044         test_155_big_load
16045         restore_lustre_params < $p
16046         rm -f $p
16047 }
16048 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16049
16050 test_155f() {
16051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16052
16053         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16054
16055         save_writethrough $p
16056
16057         set_cache read on
16058         set_cache writethrough off
16059         test_155_big_load
16060         restore_lustre_params < $p
16061         rm -f $p
16062 }
16063 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16064
16065 test_155g() {
16066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16067
16068         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16069
16070         save_writethrough $p
16071
16072         set_cache read off
16073         set_cache writethrough on
16074         test_155_big_load
16075         restore_lustre_params < $p
16076         rm -f $p
16077 }
16078 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16079
16080 test_155h() {
16081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16082
16083         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16084
16085         save_writethrough $p
16086
16087         set_cache read off
16088         set_cache writethrough off
16089         test_155_big_load
16090         restore_lustre_params < $p
16091         rm -f $p
16092 }
16093 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16094
16095 test_156() {
16096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16097         remote_ost_nodsh && skip "remote OST with nodsh"
16098         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16099                 skip "stats not implemented on old servers"
16100         [ "$ost1_FSTYPE" = "zfs" ] &&
16101                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16102
16103         local CPAGES=3
16104         local BEFORE
16105         local AFTER
16106         local file="$DIR/$tfile"
16107         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16108
16109         save_writethrough $p
16110         roc_hit_init
16111
16112         log "Turn on read and write cache"
16113         set_cache read on
16114         set_cache writethrough on
16115
16116         log "Write data and read it back."
16117         log "Read should be satisfied from the cache."
16118         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16119         BEFORE=$(roc_hit)
16120         cancel_lru_locks osc
16121         cat $file >/dev/null
16122         AFTER=$(roc_hit)
16123         if ! let "AFTER - BEFORE == CPAGES"; then
16124                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16125         else
16126                 log "cache hits: before: $BEFORE, after: $AFTER"
16127         fi
16128
16129         log "Read again; it should be satisfied from the cache."
16130         BEFORE=$AFTER
16131         cancel_lru_locks osc
16132         cat $file >/dev/null
16133         AFTER=$(roc_hit)
16134         if ! let "AFTER - BEFORE == CPAGES"; then
16135                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16136         else
16137                 log "cache hits:: before: $BEFORE, after: $AFTER"
16138         fi
16139
16140         log "Turn off the read cache and turn on the write cache"
16141         set_cache read off
16142         set_cache writethrough on
16143
16144         log "Read again; it should be satisfied from the cache."
16145         BEFORE=$(roc_hit)
16146         cancel_lru_locks osc
16147         cat $file >/dev/null
16148         AFTER=$(roc_hit)
16149         if ! let "AFTER - BEFORE == CPAGES"; then
16150                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16151         else
16152                 log "cache hits:: before: $BEFORE, after: $AFTER"
16153         fi
16154
16155         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16156                 # > 2.12.56 uses pagecache if cached
16157                 log "Read again; it should not be satisfied from the cache."
16158                 BEFORE=$AFTER
16159                 cancel_lru_locks osc
16160                 cat $file >/dev/null
16161                 AFTER=$(roc_hit)
16162                 if ! let "AFTER - BEFORE == 0"; then
16163                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16164                 else
16165                         log "cache hits:: before: $BEFORE, after: $AFTER"
16166                 fi
16167         fi
16168
16169         log "Write data and read it back."
16170         log "Read should be satisfied from the cache."
16171         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16172         BEFORE=$(roc_hit)
16173         cancel_lru_locks osc
16174         cat $file >/dev/null
16175         AFTER=$(roc_hit)
16176         if ! let "AFTER - BEFORE == CPAGES"; then
16177                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16178         else
16179                 log "cache hits:: before: $BEFORE, after: $AFTER"
16180         fi
16181
16182         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16183                 # > 2.12.56 uses pagecache if cached
16184                 log "Read again; it should not be satisfied from the cache."
16185                 BEFORE=$AFTER
16186                 cancel_lru_locks osc
16187                 cat $file >/dev/null
16188                 AFTER=$(roc_hit)
16189                 if ! let "AFTER - BEFORE == 0"; then
16190                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16191                 else
16192                         log "cache hits:: before: $BEFORE, after: $AFTER"
16193                 fi
16194         fi
16195
16196         log "Turn off read and write cache"
16197         set_cache read off
16198         set_cache writethrough off
16199
16200         log "Write data and read it back"
16201         log "It should not be satisfied from the cache."
16202         rm -f $file
16203         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16204         cancel_lru_locks osc
16205         BEFORE=$(roc_hit)
16206         cat $file >/dev/null
16207         AFTER=$(roc_hit)
16208         if ! let "AFTER - BEFORE == 0"; then
16209                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16210         else
16211                 log "cache hits:: before: $BEFORE, after: $AFTER"
16212         fi
16213
16214         log "Turn on the read cache and turn off the write cache"
16215         set_cache read on
16216         set_cache writethrough off
16217
16218         log "Write data and read it back"
16219         log "It should not be satisfied from the cache."
16220         rm -f $file
16221         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16222         BEFORE=$(roc_hit)
16223         cancel_lru_locks osc
16224         cat $file >/dev/null
16225         AFTER=$(roc_hit)
16226         if ! let "AFTER - BEFORE == 0"; then
16227                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16228         else
16229                 log "cache hits:: before: $BEFORE, after: $AFTER"
16230         fi
16231
16232         log "Read again; it should be satisfied from the cache."
16233         BEFORE=$(roc_hit)
16234         cancel_lru_locks osc
16235         cat $file >/dev/null
16236         AFTER=$(roc_hit)
16237         if ! let "AFTER - BEFORE == CPAGES"; then
16238                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16239         else
16240                 log "cache hits:: before: $BEFORE, after: $AFTER"
16241         fi
16242
16243         restore_lustre_params < $p
16244         rm -f $p $file
16245 }
16246 run_test 156 "Verification of tunables"
16247
16248 test_160a() {
16249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16250         remote_mds_nodsh && skip "remote MDS with nodsh"
16251         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16252                 skip "Need MDS version at least 2.2.0"
16253
16254         changelog_register || error "changelog_register failed"
16255         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16256         changelog_users $SINGLEMDS | grep -q $cl_user ||
16257                 error "User $cl_user not found in changelog_users"
16258
16259         mkdir_on_mdt0 $DIR/$tdir
16260
16261         # change something
16262         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16263         changelog_clear 0 || error "changelog_clear failed"
16264         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16265         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16266         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16267         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16268         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16269         rm $DIR/$tdir/pics/desktop.jpg
16270
16271         echo "verifying changelog mask"
16272         changelog_chmask "-MKDIR"
16273         changelog_chmask "-CLOSE"
16274
16275         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16276         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16277
16278         changelog_chmask "+MKDIR"
16279         changelog_chmask "+CLOSE"
16280
16281         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16282         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16283
16284         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16285         CLOSES=$(changelog_dump | grep -c "CLOSE")
16286         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16287         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16288
16289         # verify contents
16290         echo "verifying target fid"
16291         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16292         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16293         [ "$fidc" == "$fidf" ] ||
16294                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16295         echo "verifying parent fid"
16296         # The FID returned from the Changelog may be the directory shard on
16297         # a different MDT, and not the FID returned by path2fid on the parent.
16298         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16299         # since this is what will matter when recreating this file in the tree.
16300         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16301         local pathp=$($LFS fid2path $MOUNT "$fidp")
16302         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16303                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16304
16305         echo "getting records for $cl_user"
16306         changelog_users $SINGLEMDS
16307         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16308         local nclr=3
16309         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16310                 error "changelog_clear failed"
16311         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16312         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16313         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16314                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16315
16316         local min0_rec=$(changelog_users $SINGLEMDS |
16317                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16318         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16319                           awk '{ print $1; exit; }')
16320
16321         changelog_dump | tail -n 5
16322         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16323         [ $first_rec == $((min0_rec + 1)) ] ||
16324                 error "first index should be $min0_rec + 1 not $first_rec"
16325
16326         # LU-3446 changelog index reset on MDT restart
16327         local cur_rec1=$(changelog_users $SINGLEMDS |
16328                          awk '/^current.index:/ { print $NF }')
16329         changelog_clear 0 ||
16330                 error "clear all changelog records for $cl_user failed"
16331         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16332         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16333                 error "Fail to start $SINGLEMDS"
16334         local cur_rec2=$(changelog_users $SINGLEMDS |
16335                          awk '/^current.index:/ { print $NF }')
16336         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16337         [ $cur_rec1 == $cur_rec2 ] ||
16338                 error "current index should be $cur_rec1 not $cur_rec2"
16339
16340         echo "verifying users from this test are deregistered"
16341         changelog_deregister || error "changelog_deregister failed"
16342         changelog_users $SINGLEMDS | grep -q $cl_user &&
16343                 error "User '$cl_user' still in changelog_users"
16344
16345         # lctl get_param -n mdd.*.changelog_users
16346         # current_index: 144
16347         # ID    index (idle seconds)
16348         # cl3   144   (2) mask=<list>
16349         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16350                 # this is the normal case where all users were deregistered
16351                 # make sure no new records are added when no users are present
16352                 local last_rec1=$(changelog_users $SINGLEMDS |
16353                                   awk '/^current.index:/ { print $NF }')
16354                 touch $DIR/$tdir/chloe
16355                 local last_rec2=$(changelog_users $SINGLEMDS |
16356                                   awk '/^current.index:/ { print $NF }')
16357                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16358                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16359         else
16360                 # any changelog users must be leftovers from a previous test
16361                 changelog_users $SINGLEMDS
16362                 echo "other changelog users; can't verify off"
16363         fi
16364 }
16365 run_test 160a "changelog sanity"
16366
16367 test_160b() { # LU-3587
16368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16369         remote_mds_nodsh && skip "remote MDS with nodsh"
16370         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16371                 skip "Need MDS version at least 2.2.0"
16372
16373         changelog_register || error "changelog_register failed"
16374         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16375         changelog_users $SINGLEMDS | grep -q $cl_user ||
16376                 error "User '$cl_user' not found in changelog_users"
16377
16378         local longname1=$(str_repeat a 255)
16379         local longname2=$(str_repeat b 255)
16380
16381         cd $DIR
16382         echo "creating very long named file"
16383         touch $longname1 || error "create of '$longname1' failed"
16384         echo "renaming very long named file"
16385         mv $longname1 $longname2
16386
16387         changelog_dump | grep RENME | tail -n 5
16388         rm -f $longname2
16389 }
16390 run_test 160b "Verify that very long rename doesn't crash in changelog"
16391
16392 test_160c() {
16393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16394         remote_mds_nodsh && skip "remote MDS with nodsh"
16395
16396         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16397                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16398                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16399                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16400
16401         local rc=0
16402
16403         # Registration step
16404         changelog_register || error "changelog_register failed"
16405
16406         rm -rf $DIR/$tdir
16407         mkdir -p $DIR/$tdir
16408         $MCREATE $DIR/$tdir/foo_160c
16409         changelog_chmask "-TRUNC"
16410         $TRUNCATE $DIR/$tdir/foo_160c 200
16411         changelog_chmask "+TRUNC"
16412         $TRUNCATE $DIR/$tdir/foo_160c 199
16413         changelog_dump | tail -n 5
16414         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16415         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16416 }
16417 run_test 160c "verify that changelog log catch the truncate event"
16418
16419 test_160d() {
16420         remote_mds_nodsh && skip "remote MDS with nodsh"
16421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16423         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16424                 skip "Need MDS version at least 2.7.60"
16425
16426         # Registration step
16427         changelog_register || error "changelog_register failed"
16428
16429         mkdir -p $DIR/$tdir/migrate_dir
16430         changelog_clear 0 || error "changelog_clear failed"
16431
16432         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16433         changelog_dump | tail -n 5
16434         local migrates=$(changelog_dump | grep -c "MIGRT")
16435         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16436 }
16437 run_test 160d "verify that changelog log catch the migrate event"
16438
16439 test_160e() {
16440         remote_mds_nodsh && skip "remote MDS with nodsh"
16441
16442         # Create a user
16443         changelog_register || error "changelog_register failed"
16444
16445         local MDT0=$(facet_svc $SINGLEMDS)
16446         local rc
16447
16448         # No user (expect fail)
16449         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16450         rc=$?
16451         if [ $rc -eq 0 ]; then
16452                 error "Should fail without user"
16453         elif [ $rc -ne 4 ]; then
16454                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16455         fi
16456
16457         # Delete a future user (expect fail)
16458         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16459         rc=$?
16460         if [ $rc -eq 0 ]; then
16461                 error "Deleted non-existant user cl77"
16462         elif [ $rc -ne 2 ]; then
16463                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16464         fi
16465
16466         # Clear to a bad index (1 billion should be safe)
16467         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16468         rc=$?
16469
16470         if [ $rc -eq 0 ]; then
16471                 error "Successfully cleared to invalid CL index"
16472         elif [ $rc -ne 22 ]; then
16473                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16474         fi
16475 }
16476 run_test 160e "changelog negative testing (should return errors)"
16477
16478 test_160f() {
16479         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16480         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16481                 skip "Need MDS version at least 2.10.56"
16482
16483         local mdts=$(comma_list $(mdts_nodes))
16484
16485         # Create a user
16486         changelog_register || error "first changelog_register failed"
16487         changelog_register || error "second changelog_register failed"
16488         local cl_users
16489         declare -A cl_user1
16490         declare -A cl_user2
16491         local user_rec1
16492         local user_rec2
16493         local i
16494
16495         # generate some changelog records to accumulate on each MDT
16496         # use all_char because created files should be evenly distributed
16497         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16498                 error "test_mkdir $tdir failed"
16499         log "$(date +%s): creating first files"
16500         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16501                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16502                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16503         done
16504
16505         # check changelogs have been generated
16506         local start=$SECONDS
16507         local idle_time=$((MDSCOUNT * 5 + 5))
16508         local nbcl=$(changelog_dump | wc -l)
16509         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16510
16511         for param in "changelog_max_idle_time=$idle_time" \
16512                      "changelog_gc=1" \
16513                      "changelog_min_gc_interval=2" \
16514                      "changelog_min_free_cat_entries=3"; do
16515                 local MDT0=$(facet_svc $SINGLEMDS)
16516                 local var="${param%=*}"
16517                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16518
16519                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16520                 do_nodes $mdts $LCTL set_param mdd.*.$param
16521         done
16522
16523         # force cl_user2 to be idle (1st part), but also cancel the
16524         # cl_user1 records so that it is not evicted later in the test.
16525         local sleep1=$((idle_time / 2))
16526         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16527         sleep $sleep1
16528
16529         # simulate changelog catalog almost full
16530         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16531         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16532
16533         for i in $(seq $MDSCOUNT); do
16534                 cl_users=(${CL_USERS[mds$i]})
16535                 cl_user1[mds$i]="${cl_users[0]}"
16536                 cl_user2[mds$i]="${cl_users[1]}"
16537
16538                 [ -n "${cl_user1[mds$i]}" ] ||
16539                         error "mds$i: no user registered"
16540                 [ -n "${cl_user2[mds$i]}" ] ||
16541                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16542
16543                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16544                 [ -n "$user_rec1" ] ||
16545                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16546                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16547                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16548                 [ -n "$user_rec2" ] ||
16549                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16550                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16551                      "$user_rec1 + 2 == $user_rec2"
16552                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16553                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16554                               "$user_rec1 + 2, but is $user_rec2"
16555                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16556                 [ -n "$user_rec2" ] ||
16557                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16558                 [ $user_rec1 == $user_rec2 ] ||
16559                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16560                               "$user_rec1, but is $user_rec2"
16561         done
16562
16563         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16564         local sleep2=$((idle_time - (SECONDS - start) + 1))
16565         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16566         sleep $sleep2
16567
16568         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16569         # cl_user1 should be OK because it recently processed records.
16570         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16571         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16572                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16573                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16574         done
16575
16576         # ensure gc thread is done
16577         for i in $(mdts_nodes); do
16578                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16579                         error "$i: GC-thread not done"
16580         done
16581
16582         local first_rec
16583         for (( i = 1; i <= MDSCOUNT; i++ )); do
16584                 # check cl_user1 still registered
16585                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16586                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16587                 # check cl_user2 unregistered
16588                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16589                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16590
16591                 # check changelogs are present and starting at $user_rec1 + 1
16592                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16593                 [ -n "$user_rec1" ] ||
16594                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16595                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16596                             awk '{ print $1; exit; }')
16597
16598                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16599                 [ $((user_rec1 + 1)) == $first_rec ] ||
16600                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16601         done
16602 }
16603 run_test 160f "changelog garbage collect (timestamped users)"
16604
16605 test_160g() {
16606         remote_mds_nodsh && skip "remote MDS with nodsh"
16607         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16608                 skip "Need MDS version at least 2.14.55"
16609
16610         local mdts=$(comma_list $(mdts_nodes))
16611
16612         # Create a user
16613         changelog_register || error "first changelog_register failed"
16614         changelog_register || error "second changelog_register failed"
16615         local cl_users
16616         declare -A cl_user1
16617         declare -A cl_user2
16618         local user_rec1
16619         local user_rec2
16620         local i
16621
16622         # generate some changelog records to accumulate on each MDT
16623         # use all_char because created files should be evenly distributed
16624         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16625                 error "test_mkdir $tdir failed"
16626         for ((i = 0; i < MDSCOUNT; i++)); do
16627                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16628                         error "create $DIR/$tdir/d$i.1 failed"
16629         done
16630
16631         # check changelogs have been generated
16632         local nbcl=$(changelog_dump | wc -l)
16633         (( $nbcl > 0 )) || error "no changelogs found"
16634
16635         # reduce the max_idle_indexes value to make sure we exceed it
16636         for param in "changelog_max_idle_indexes=2" \
16637                      "changelog_gc=1" \
16638                      "changelog_min_gc_interval=2"; do
16639                 local MDT0=$(facet_svc $SINGLEMDS)
16640                 local var="${param%=*}"
16641                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16642
16643                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16644                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16645                         error "unable to set mdd.*.$param"
16646         done
16647
16648         local start=$SECONDS
16649         for i in $(seq $MDSCOUNT); do
16650                 cl_users=(${CL_USERS[mds$i]})
16651                 cl_user1[mds$i]="${cl_users[0]}"
16652                 cl_user2[mds$i]="${cl_users[1]}"
16653
16654                 [ -n "${cl_user1[mds$i]}" ] ||
16655                         error "mds$i: user1 is not registered"
16656                 [ -n "${cl_user2[mds$i]}" ] ||
16657                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16658
16659                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16660                 [ -n "$user_rec1" ] ||
16661                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16662                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16663                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16664                 [ -n "$user_rec2" ] ||
16665                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16666                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16667                      "$user_rec1 + 2 == $user_rec2"
16668                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16669                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16670                               "expected $user_rec1 + 2, but is $user_rec2"
16671                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16672                 [ -n "$user_rec2" ] ||
16673                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16674                 [ $user_rec1 == $user_rec2 ] ||
16675                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16676                               "expected $user_rec1, but is $user_rec2"
16677         done
16678
16679         # ensure we are past the previous changelog_min_gc_interval set above
16680         local sleep2=$((start + 2 - SECONDS))
16681         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16682         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16683         # cl_user1 should be OK because it recently processed records.
16684         for ((i = 0; i < MDSCOUNT; i++)); do
16685                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16686                         error "create $DIR/$tdir/d$i.3 failed"
16687         done
16688
16689         # ensure gc thread is done
16690         for i in $(mdts_nodes); do
16691                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16692                         error "$i: GC-thread not done"
16693         done
16694
16695         local first_rec
16696         for (( i = 1; i <= MDSCOUNT; i++ )); do
16697                 # check cl_user1 still registered
16698                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16699                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16700                 # check cl_user2 unregistered
16701                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16702                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16703
16704                 # check changelogs are present and starting at $user_rec1 + 1
16705                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16706                 [ -n "$user_rec1" ] ||
16707                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16708                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16709                             awk '{ print $1; exit; }')
16710
16711                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16712                 [ $((user_rec1 + 1)) == $first_rec ] ||
16713                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16714         done
16715 }
16716 run_test 160g "changelog garbage collect on idle records"
16717
16718 test_160h() {
16719         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16720         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16721                 skip "Need MDS version at least 2.10.56"
16722
16723         local mdts=$(comma_list $(mdts_nodes))
16724
16725         # Create a user
16726         changelog_register || error "first changelog_register failed"
16727         changelog_register || error "second changelog_register failed"
16728         local cl_users
16729         declare -A cl_user1
16730         declare -A cl_user2
16731         local user_rec1
16732         local user_rec2
16733         local i
16734
16735         # generate some changelog records to accumulate on each MDT
16736         # use all_char because created files should be evenly distributed
16737         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16738                 error "test_mkdir $tdir failed"
16739         for ((i = 0; i < MDSCOUNT; i++)); do
16740                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16741                         error "create $DIR/$tdir/d$i.1 failed"
16742         done
16743
16744         # check changelogs have been generated
16745         local nbcl=$(changelog_dump | wc -l)
16746         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16747
16748         for param in "changelog_max_idle_time=10" \
16749                      "changelog_gc=1" \
16750                      "changelog_min_gc_interval=2"; do
16751                 local MDT0=$(facet_svc $SINGLEMDS)
16752                 local var="${param%=*}"
16753                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16754
16755                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16756                 do_nodes $mdts $LCTL set_param mdd.*.$param
16757         done
16758
16759         # force cl_user2 to be idle (1st part)
16760         sleep 9
16761
16762         for i in $(seq $MDSCOUNT); do
16763                 cl_users=(${CL_USERS[mds$i]})
16764                 cl_user1[mds$i]="${cl_users[0]}"
16765                 cl_user2[mds$i]="${cl_users[1]}"
16766
16767                 [ -n "${cl_user1[mds$i]}" ] ||
16768                         error "mds$i: no user registered"
16769                 [ -n "${cl_user2[mds$i]}" ] ||
16770                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16771
16772                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16773                 [ -n "$user_rec1" ] ||
16774                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16775                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16776                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16777                 [ -n "$user_rec2" ] ||
16778                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16779                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16780                      "$user_rec1 + 2 == $user_rec2"
16781                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16782                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16783                               "$user_rec1 + 2, but is $user_rec2"
16784                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16785                 [ -n "$user_rec2" ] ||
16786                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16787                 [ $user_rec1 == $user_rec2 ] ||
16788                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16789                               "$user_rec1, but is $user_rec2"
16790         done
16791
16792         # force cl_user2 to be idle (2nd part) and to reach
16793         # changelog_max_idle_time
16794         sleep 2
16795
16796         # force each GC-thread start and block then
16797         # one per MDT/MDD, set fail_val accordingly
16798         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16799         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16800
16801         # generate more changelogs to trigger fail_loc
16802         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16803                 error "create $DIR/$tdir/${tfile}bis failed"
16804
16805         # stop MDT to stop GC-thread, should be done in back-ground as it will
16806         # block waiting for the thread to be released and exit
16807         declare -A stop_pids
16808         for i in $(seq $MDSCOUNT); do
16809                 stop mds$i &
16810                 stop_pids[mds$i]=$!
16811         done
16812
16813         for i in $(mdts_nodes); do
16814                 local facet
16815                 local nb=0
16816                 local facets=$(facets_up_on_host $i)
16817
16818                 for facet in ${facets//,/ }; do
16819                         if [[ $facet == mds* ]]; then
16820                                 nb=$((nb + 1))
16821                         fi
16822                 done
16823                 # ensure each MDS's gc threads are still present and all in "R"
16824                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16825                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16826                         error "$i: expected $nb GC-thread"
16827                 wait_update $i \
16828                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16829                         "R" 20 ||
16830                         error "$i: GC-thread not found in R-state"
16831                 # check umounts of each MDT on MDS have reached kthread_stop()
16832                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16833                         error "$i: expected $nb umount"
16834                 wait_update $i \
16835                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16836                         error "$i: umount not found in D-state"
16837         done
16838
16839         # release all GC-threads
16840         do_nodes $mdts $LCTL set_param fail_loc=0
16841
16842         # wait for MDT stop to complete
16843         for i in $(seq $MDSCOUNT); do
16844                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16845         done
16846
16847         # XXX
16848         # may try to check if any orphan changelog records are present
16849         # via ldiskfs/zfs and llog_reader...
16850
16851         # re-start/mount MDTs
16852         for i in $(seq $MDSCOUNT); do
16853                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16854                         error "Fail to start mds$i"
16855         done
16856
16857         local first_rec
16858         for i in $(seq $MDSCOUNT); do
16859                 # check cl_user1 still registered
16860                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16861                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16862                 # check cl_user2 unregistered
16863                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16864                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16865
16866                 # check changelogs are present and starting at $user_rec1 + 1
16867                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16868                 [ -n "$user_rec1" ] ||
16869                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16870                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16871                             awk '{ print $1; exit; }')
16872
16873                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16874                 [ $((user_rec1 + 1)) == $first_rec ] ||
16875                         error "mds$i: first index should be $user_rec1 + 1, " \
16876                               "but is $first_rec"
16877         done
16878 }
16879 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16880               "during mount"
16881
16882 test_160i() {
16883
16884         local mdts=$(comma_list $(mdts_nodes))
16885
16886         changelog_register || error "first changelog_register failed"
16887
16888         # generate some changelog records to accumulate on each MDT
16889         # use all_char because created files should be evenly distributed
16890         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16891                 error "test_mkdir $tdir failed"
16892         for ((i = 0; i < MDSCOUNT; i++)); do
16893                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16894                         error "create $DIR/$tdir/d$i.1 failed"
16895         done
16896
16897         # check changelogs have been generated
16898         local nbcl=$(changelog_dump | wc -l)
16899         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16900
16901         # simulate race between register and unregister
16902         # XXX as fail_loc is set per-MDS, with DNE configs the race
16903         # simulation will only occur for one MDT per MDS and for the
16904         # others the normal race scenario will take place
16905         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16906         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16907         do_nodes $mdts $LCTL set_param fail_val=1
16908
16909         # unregister 1st user
16910         changelog_deregister &
16911         local pid1=$!
16912         # wait some time for deregister work to reach race rdv
16913         sleep 2
16914         # register 2nd user
16915         changelog_register || error "2nd user register failed"
16916
16917         wait $pid1 || error "1st user deregister failed"
16918
16919         local i
16920         local last_rec
16921         declare -A LAST_REC
16922         for i in $(seq $MDSCOUNT); do
16923                 if changelog_users mds$i | grep "^cl"; then
16924                         # make sure new records are added with one user present
16925                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16926                                           awk '/^current.index:/ { print $NF }')
16927                 else
16928                         error "mds$i has no user registered"
16929                 fi
16930         done
16931
16932         # generate more changelog records to accumulate on each MDT
16933         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16934                 error "create $DIR/$tdir/${tfile}bis failed"
16935
16936         for i in $(seq $MDSCOUNT); do
16937                 last_rec=$(changelog_users $SINGLEMDS |
16938                            awk '/^current.index:/ { print $NF }')
16939                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16940                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16941                         error "changelogs are off on mds$i"
16942         done
16943 }
16944 run_test 160i "changelog user register/unregister race"
16945
16946 test_160j() {
16947         remote_mds_nodsh && skip "remote MDS with nodsh"
16948         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16949                 skip "Need MDS version at least 2.12.56"
16950
16951         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16952         stack_trap "umount $MOUNT2" EXIT
16953
16954         changelog_register || error "first changelog_register failed"
16955         stack_trap "changelog_deregister" EXIT
16956
16957         # generate some changelog
16958         # use all_char because created files should be evenly distributed
16959         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16960                 error "mkdir $tdir failed"
16961         for ((i = 0; i < MDSCOUNT; i++)); do
16962                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16963                         error "create $DIR/$tdir/d$i.1 failed"
16964         done
16965
16966         # open the changelog device
16967         exec 3>/dev/changelog-$FSNAME-MDT0000
16968         stack_trap "exec 3>&-" EXIT
16969         exec 4</dev/changelog-$FSNAME-MDT0000
16970         stack_trap "exec 4<&-" EXIT
16971
16972         # umount the first lustre mount
16973         umount $MOUNT
16974         stack_trap "mount_client $MOUNT" EXIT
16975
16976         # read changelog, which may or may not fail, but should not crash
16977         cat <&4 >/dev/null
16978
16979         # clear changelog
16980         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16981         changelog_users $SINGLEMDS | grep -q $cl_user ||
16982                 error "User $cl_user not found in changelog_users"
16983
16984         printf 'clear:'$cl_user':0' >&3
16985 }
16986 run_test 160j "client can be umounted while its chanangelog is being used"
16987
16988 test_160k() {
16989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16990         remote_mds_nodsh && skip "remote MDS with nodsh"
16991
16992         mkdir -p $DIR/$tdir/1/1
16993
16994         changelog_register || error "changelog_register failed"
16995         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16996
16997         changelog_users $SINGLEMDS | grep -q $cl_user ||
16998                 error "User '$cl_user' not found in changelog_users"
16999 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17000         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17001         rmdir $DIR/$tdir/1/1 & sleep 1
17002         mkdir $DIR/$tdir/2
17003         touch $DIR/$tdir/2/2
17004         rm -rf $DIR/$tdir/2
17005
17006         wait
17007         sleep 4
17008
17009         changelog_dump | grep rmdir || error "rmdir not recorded"
17010 }
17011 run_test 160k "Verify that changelog records are not lost"
17012
17013 # Verifies that a file passed as a parameter has recently had an operation
17014 # performed on it that has generated an MTIME changelog which contains the
17015 # correct parent FID. As files might reside on a different MDT from the
17016 # parent directory in DNE configurations, the FIDs are translated to paths
17017 # before being compared, which should be identical
17018 compare_mtime_changelog() {
17019         local file="${1}"
17020         local mdtidx
17021         local mtime
17022         local cl_fid
17023         local pdir
17024         local dir
17025
17026         mdtidx=$($LFS getstripe --mdt-index $file)
17027         mdtidx=$(printf "%04x" $mdtidx)
17028
17029         # Obtain the parent FID from the MTIME changelog
17030         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17031         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17032
17033         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17034         [ -z "$cl_fid" ] && error "parent FID not present"
17035
17036         # Verify that the path for the parent FID is the same as the path for
17037         # the test directory
17038         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17039
17040         dir=$(dirname $1)
17041
17042         [[ "${pdir%/}" == "$dir" ]] ||
17043                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17044 }
17045
17046 test_160l() {
17047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17048
17049         remote_mds_nodsh && skip "remote MDS with nodsh"
17050         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17051                 skip "Need MDS version at least 2.13.55"
17052
17053         local cl_user
17054
17055         changelog_register || error "changelog_register failed"
17056         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17057
17058         changelog_users $SINGLEMDS | grep -q $cl_user ||
17059                 error "User '$cl_user' not found in changelog_users"
17060
17061         # Clear some types so that MTIME changelogs are generated
17062         changelog_chmask "-CREAT"
17063         changelog_chmask "-CLOSE"
17064
17065         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17066
17067         # Test CL_MTIME during setattr
17068         touch $DIR/$tdir/$tfile
17069         compare_mtime_changelog $DIR/$tdir/$tfile
17070
17071         # Test CL_MTIME during close
17072         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17073         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17074 }
17075 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17076
17077 test_160m() {
17078         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17079         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17080                 skip "Need MDS version at least 2.14.51"
17081         local cl_users
17082         local cl_user1
17083         local cl_user2
17084         local pid1
17085
17086         # Create a user
17087         changelog_register || error "first changelog_register failed"
17088         changelog_register || error "second changelog_register failed"
17089
17090         cl_users=(${CL_USERS[mds1]})
17091         cl_user1="${cl_users[0]}"
17092         cl_user2="${cl_users[1]}"
17093         # generate some changelog records to accumulate on MDT0
17094         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17095         createmany -m $DIR/$tdir/$tfile 50 ||
17096                 error "create $DIR/$tdir/$tfile failed"
17097         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17098         rm -f $DIR/$tdir
17099
17100         # check changelogs have been generated
17101         local nbcl=$(changelog_dump | wc -l)
17102         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17103
17104 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17105         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17106
17107         __changelog_clear mds1 $cl_user1 +10
17108         __changelog_clear mds1 $cl_user2 0 &
17109         pid1=$!
17110         sleep 2
17111         __changelog_clear mds1 $cl_user1 0 ||
17112                 error "fail to cancel record for $cl_user1"
17113         wait $pid1
17114         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17115 }
17116 run_test 160m "Changelog clear race"
17117
17118 test_160n() {
17119         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17120         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17121                 skip "Need MDS version at least 2.14.51"
17122         local cl_users
17123         local cl_user1
17124         local cl_user2
17125         local pid1
17126         local first_rec
17127         local last_rec=0
17128
17129         # Create a user
17130         changelog_register || error "first changelog_register failed"
17131
17132         cl_users=(${CL_USERS[mds1]})
17133         cl_user1="${cl_users[0]}"
17134
17135         # generate some changelog records to accumulate on MDT0
17136         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17137         first_rec=$(changelog_users $SINGLEMDS |
17138                         awk '/^current.index:/ { print $NF }')
17139         while (( last_rec < (( first_rec + 65000)) )); do
17140                 createmany -m $DIR/$tdir/$tfile 10000 ||
17141                         error "create $DIR/$tdir/$tfile failed"
17142
17143                 for i in $(seq 0 10000); do
17144                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17145                                 > /dev/null
17146                 done
17147
17148                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17149                         error "unlinkmany failed unlink"
17150                 last_rec=$(changelog_users $SINGLEMDS |
17151                         awk '/^current.index:/ { print $NF }')
17152                 echo last record $last_rec
17153                 (( last_rec == 0 )) && error "no changelog found"
17154         done
17155
17156 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17157         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17158
17159         __changelog_clear mds1 $cl_user1 0 &
17160         pid1=$!
17161         sleep 2
17162         __changelog_clear mds1 $cl_user1 0 ||
17163                 error "fail to cancel record for $cl_user1"
17164         wait $pid1
17165         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17166 }
17167 run_test 160n "Changelog destroy race"
17168
17169 test_160o() {
17170         local mdt="$(facet_svc $SINGLEMDS)"
17171
17172         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17173         remote_mds_nodsh && skip "remote MDS with nodsh"
17174         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17175                 skip "Need MDS version at least 2.14.52"
17176
17177         changelog_register --user test_160o -m unlnk+close+open ||
17178                 error "changelog_register failed"
17179
17180         do_facet $SINGLEMDS $LCTL --device $mdt \
17181                                 changelog_register -u "Tt3_-#" &&
17182                 error "bad symbols in name should fail"
17183
17184         do_facet $SINGLEMDS $LCTL --device $mdt \
17185                                 changelog_register -u test_160o &&
17186                 error "the same name registration should fail"
17187
17188         do_facet $SINGLEMDS $LCTL --device $mdt \
17189                         changelog_register -u test_160toolongname &&
17190                 error "too long name registration should fail"
17191
17192         changelog_chmask "MARK+HSM"
17193         lctl get_param mdd.*.changelog*mask
17194         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17195         changelog_users $SINGLEMDS | grep -q $cl_user ||
17196                 error "User $cl_user not found in changelog_users"
17197         #verify username
17198         echo $cl_user | grep -q test_160o ||
17199                 error "User $cl_user has no specific name 'test160o'"
17200
17201         # change something
17202         changelog_clear 0 || error "changelog_clear failed"
17203         # generate some changelog records to accumulate on MDT0
17204         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17205         touch $DIR/$tdir/$tfile                 # open 1
17206
17207         OPENS=$(changelog_dump | grep -c "OPEN")
17208         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17209
17210         # must be no MKDIR it wasn't set as user mask
17211         MKDIR=$(changelog_dump | grep -c "MKDIR")
17212         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17213
17214         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17215                                 mdd.$mdt.changelog_current_mask -n)
17216         # register maskless user
17217         changelog_register || error "changelog_register failed"
17218         # effective mask should be not changed because it is not minimal
17219         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17220                                 mdd.$mdt.changelog_current_mask -n)
17221         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17222         # set server mask to minimal value
17223         changelog_chmask "MARK"
17224         # check effective mask again, should be treated as DEFMASK now
17225         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17226                                 mdd.$mdt.changelog_current_mask -n)
17227         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17228
17229         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17230                 # set server mask back to some value
17231                 changelog_chmask "CLOSE,UNLNK"
17232                 # check effective mask again, should not remain as DEFMASK
17233                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17234                                 mdd.$mdt.changelog_current_mask -n)
17235                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17236         fi
17237
17238         do_facet $SINGLEMDS $LCTL --device $mdt \
17239                                 changelog_deregister -u test_160o ||
17240                 error "cannot deregister by name"
17241 }
17242 run_test 160o "changelog user name and mask"
17243
17244 test_160p() {
17245         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17246         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17247                 skip "Need MDS version at least 2.14.51"
17248         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17249         local cl_users
17250         local cl_user1
17251         local entry_count
17252
17253         # Create a user
17254         changelog_register || error "first changelog_register failed"
17255
17256         cl_users=(${CL_USERS[mds1]})
17257         cl_user1="${cl_users[0]}"
17258
17259         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17260         createmany -m $DIR/$tdir/$tfile 50 ||
17261                 error "create $DIR/$tdir/$tfile failed"
17262         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17263         rm -rf $DIR/$tdir
17264
17265         # check changelogs have been generated
17266         entry_count=$(changelog_dump | wc -l)
17267         ((entry_count != 0)) || error "no changelog entries found"
17268
17269         # remove changelog_users and check that orphan entries are removed
17270         stop mds1
17271         local dev=$(mdsdevname 1)
17272         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17273         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17274         entry_count=$(changelog_dump | wc -l)
17275         ((entry_count == 0)) ||
17276                 error "found $entry_count changelog entries, expected none"
17277 }
17278 run_test 160p "Changelog orphan cleanup with no users"
17279
17280 test_160q() {
17281         local mdt="$(facet_svc $SINGLEMDS)"
17282         local clu
17283
17284         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17285         remote_mds_nodsh && skip "remote MDS with nodsh"
17286         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17287                 skip "Need MDS version at least 2.14.54"
17288
17289         # set server mask to minimal value like server init does
17290         changelog_chmask "MARK"
17291         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17292                 error "changelog_register failed"
17293         # check effective mask again, should be treated as DEFMASK now
17294         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17295                                 mdd.$mdt.changelog_current_mask -n)
17296         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17297                 error "changelog_deregister failed"
17298         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17299 }
17300 run_test 160q "changelog effective mask is DEFMASK if not set"
17301
17302 test_160s() {
17303         remote_mds_nodsh && skip "remote MDS with nodsh"
17304         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17305                 skip "Need MDS version at least 2.14.55"
17306
17307         local mdts=$(comma_list $(mdts_nodes))
17308
17309         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17310         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17311                                        fail_val=$((24 * 3600 * 10))
17312
17313         # Create a user which is 10 days old
17314         changelog_register || error "first changelog_register failed"
17315         local cl_users
17316         declare -A cl_user1
17317         local i
17318
17319         # generate some changelog records to accumulate on each MDT
17320         # use all_char because created files should be evenly distributed
17321         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17322                 error "test_mkdir $tdir failed"
17323         for ((i = 0; i < MDSCOUNT; i++)); do
17324                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17325                         error "create $DIR/$tdir/d$i.1 failed"
17326         done
17327
17328         # check changelogs have been generated
17329         local nbcl=$(changelog_dump | wc -l)
17330         (( nbcl > 0 )) || error "no changelogs found"
17331
17332         # reduce the max_idle_indexes value to make sure we exceed it
17333         for param in "changelog_max_idle_indexes=2097446912" \
17334                      "changelog_max_idle_time=2592000" \
17335                      "changelog_gc=1" \
17336                      "changelog_min_gc_interval=2"; do
17337                 local MDT0=$(facet_svc $SINGLEMDS)
17338                 local var="${param%=*}"
17339                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17340
17341                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17342                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17343                         error "unable to set mdd.*.$param"
17344         done
17345
17346         local start=$SECONDS
17347         for i in $(seq $MDSCOUNT); do
17348                 cl_users=(${CL_USERS[mds$i]})
17349                 cl_user1[mds$i]="${cl_users[0]}"
17350
17351                 [[ -n "${cl_user1[mds$i]}" ]] ||
17352                         error "mds$i: no user registered"
17353         done
17354
17355         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17356         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17357
17358         # ensure we are past the previous changelog_min_gc_interval set above
17359         local sleep2=$((start + 2 - SECONDS))
17360         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17361
17362         # Generate one more changelog to trigger GC
17363         for ((i = 0; i < MDSCOUNT; i++)); do
17364                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17365                         error "create $DIR/$tdir/d$i.3 failed"
17366         done
17367
17368         # ensure gc thread is done
17369         for node in $(mdts_nodes); do
17370                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17371                         error "$node: GC-thread not done"
17372         done
17373
17374         do_nodes $mdts $LCTL set_param fail_loc=0
17375
17376         for (( i = 1; i <= MDSCOUNT; i++ )); do
17377                 # check cl_user1 is purged
17378                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17379                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17380         done
17381         return 0
17382 }
17383 run_test 160s "changelog garbage collect on idle records * time"
17384
17385 test_160t() {
17386         remote_mds_nodsh && skip "remote MDS with nodsh"
17387         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17388                 skip "Need MDS version at least 2.15.50"
17389
17390         local MDT0=$(facet_svc $SINGLEMDS)
17391         local cl_users
17392         local cl_user1
17393         local cl_user2
17394         local start
17395
17396         changelog_register --user user1 -m all ||
17397                 error "user1 failed to register"
17398
17399         mkdir_on_mdt0 $DIR/$tdir
17400         # create default overstripe to maximize changelog size
17401         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17402         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17403         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17404
17405         # user2 consumes less records so less space
17406         changelog_register --user user2 || error "user2 failed to register"
17407         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17408         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17409
17410         # check changelogs have been generated
17411         local nbcl=$(changelog_dump | wc -l)
17412         (( nbcl > 0 )) || error "no changelogs found"
17413
17414         # reduce the changelog_min_gc_interval to force check
17415         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17416                 local var="${param%=*}"
17417                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17418
17419                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17420                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17421                         error "unable to set mdd.*.$param"
17422         done
17423
17424         start=$SECONDS
17425         cl_users=(${CL_USERS[mds1]})
17426         cl_user1="${cl_users[0]}"
17427         cl_user2="${cl_users[1]}"
17428
17429         [[ -n $cl_user1 ]] ||
17430                 error "mds1: user #1 isn't registered"
17431         [[ -n $cl_user2 ]] ||
17432                 error "mds1: user #2 isn't registered"
17433
17434         # ensure we are past the previous changelog_min_gc_interval set above
17435         local sleep2=$((start + 2 - SECONDS))
17436         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17437
17438         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17439         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17440                         fail_val=$(((llog_size1 + llog_size2) / 2))
17441
17442         # Generate more changelog to trigger GC
17443         createmany -o $DIR/$tdir/u3_ 4 ||
17444                 error "create failed for more files"
17445
17446         # ensure gc thread is done
17447         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17448                 error "mds1: GC-thread not done"
17449
17450         do_facet mds1 $LCTL set_param fail_loc=0
17451
17452         # check cl_user1 is purged
17453         changelog_users mds1 | grep -q "$cl_user1" &&
17454                 error "User $cl_user1 is registered"
17455         # check cl_user2 is not purged
17456         changelog_users mds1 | grep -q "$cl_user2" ||
17457                 error "User $cl_user2 is not registered"
17458 }
17459 run_test 160t "changelog garbage collect on lack of space"
17460
17461 test_161a() {
17462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17463
17464         test_mkdir -c1 $DIR/$tdir
17465         cp /etc/hosts $DIR/$tdir/$tfile
17466         test_mkdir -c1 $DIR/$tdir/foo1
17467         test_mkdir -c1 $DIR/$tdir/foo2
17468         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17469         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17470         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17471         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17472         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17473         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17474                 $LFS fid2path $DIR $FID
17475                 error "bad link ea"
17476         fi
17477         # middle
17478         rm $DIR/$tdir/foo2/zachary
17479         # last
17480         rm $DIR/$tdir/foo2/thor
17481         # first
17482         rm $DIR/$tdir/$tfile
17483         # rename
17484         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17485         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17486                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17487         rm $DIR/$tdir/foo2/maggie
17488
17489         # overflow the EA
17490         local longname=$tfile.avg_len_is_thirty_two_
17491         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17492                 error_noexit 'failed to unlink many hardlinks'" EXIT
17493         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17494                 error "failed to hardlink many files"
17495         links=$($LFS fid2path $DIR $FID | wc -l)
17496         echo -n "${links}/1000 links in link EA"
17497         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17498 }
17499 run_test 161a "link ea sanity"
17500
17501 test_161b() {
17502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17503         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17504
17505         local MDTIDX=1
17506         local remote_dir=$DIR/$tdir/remote_dir
17507
17508         mkdir -p $DIR/$tdir
17509         $LFS mkdir -i $MDTIDX $remote_dir ||
17510                 error "create remote directory failed"
17511
17512         cp /etc/hosts $remote_dir/$tfile
17513         mkdir -p $remote_dir/foo1
17514         mkdir -p $remote_dir/foo2
17515         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17516         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17517         ln $remote_dir/$tfile $remote_dir/foo1/luna
17518         ln $remote_dir/$tfile $remote_dir/foo2/thor
17519
17520         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17521                      tr -d ']')
17522         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17523                 $LFS fid2path $DIR $FID
17524                 error "bad link ea"
17525         fi
17526         # middle
17527         rm $remote_dir/foo2/zachary
17528         # last
17529         rm $remote_dir/foo2/thor
17530         # first
17531         rm $remote_dir/$tfile
17532         # rename
17533         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17534         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17535         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17536                 $LFS fid2path $DIR $FID
17537                 error "bad link rename"
17538         fi
17539         rm $remote_dir/foo2/maggie
17540
17541         # overflow the EA
17542         local longname=filename_avg_len_is_thirty_two_
17543         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17544                 error "failed to hardlink many files"
17545         links=$($LFS fid2path $DIR $FID | wc -l)
17546         echo -n "${links}/1000 links in link EA"
17547         [[ ${links} -gt 60 ]] ||
17548                 error "expected at least 60 links in link EA"
17549         unlinkmany $remote_dir/foo2/$longname 1000 ||
17550         error "failed to unlink many hardlinks"
17551 }
17552 run_test 161b "link ea sanity under remote directory"
17553
17554 test_161c() {
17555         remote_mds_nodsh && skip "remote MDS with nodsh"
17556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17557         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17558                 skip "Need MDS version at least 2.1.5"
17559
17560         # define CLF_RENAME_LAST 0x0001
17561         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17562         changelog_register || error "changelog_register failed"
17563
17564         rm -rf $DIR/$tdir
17565         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17566         touch $DIR/$tdir/foo_161c
17567         touch $DIR/$tdir/bar_161c
17568         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17569         changelog_dump | grep RENME | tail -n 5
17570         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17571         changelog_clear 0 || error "changelog_clear failed"
17572         if [ x$flags != "x0x1" ]; then
17573                 error "flag $flags is not 0x1"
17574         fi
17575
17576         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17577         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17578         touch $DIR/$tdir/foo_161c
17579         touch $DIR/$tdir/bar_161c
17580         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17581         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17582         changelog_dump | grep RENME | tail -n 5
17583         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17584         changelog_clear 0 || error "changelog_clear failed"
17585         if [ x$flags != "x0x0" ]; then
17586                 error "flag $flags is not 0x0"
17587         fi
17588         echo "rename overwrite a target having nlink > 1," \
17589                 "changelog record has flags of $flags"
17590
17591         # rename doesn't overwrite a target (changelog flag 0x0)
17592         touch $DIR/$tdir/foo_161c
17593         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17594         changelog_dump | grep RENME | tail -n 5
17595         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17596         changelog_clear 0 || error "changelog_clear failed"
17597         if [ x$flags != "x0x0" ]; then
17598                 error "flag $flags is not 0x0"
17599         fi
17600         echo "rename doesn't overwrite a target," \
17601                 "changelog record has flags of $flags"
17602
17603         # define CLF_UNLINK_LAST 0x0001
17604         # unlink a file having nlink = 1 (changelog flag 0x1)
17605         rm -f $DIR/$tdir/foo2_161c
17606         changelog_dump | grep UNLNK | tail -n 5
17607         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17608         changelog_clear 0 || error "changelog_clear failed"
17609         if [ x$flags != "x0x1" ]; then
17610                 error "flag $flags is not 0x1"
17611         fi
17612         echo "unlink a file having nlink = 1," \
17613                 "changelog record has flags of $flags"
17614
17615         # unlink a file having nlink > 1 (changelog flag 0x0)
17616         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17617         rm -f $DIR/$tdir/foobar_161c
17618         changelog_dump | grep UNLNK | tail -n 5
17619         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17620         changelog_clear 0 || error "changelog_clear failed"
17621         if [ x$flags != "x0x0" ]; then
17622                 error "flag $flags is not 0x0"
17623         fi
17624         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17625 }
17626 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17627
17628 test_161d() {
17629         remote_mds_nodsh && skip "remote MDS with nodsh"
17630         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17631
17632         local pid
17633         local fid
17634
17635         changelog_register || error "changelog_register failed"
17636
17637         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17638         # interfer with $MOUNT/.lustre/fid/ access
17639         mkdir $DIR/$tdir
17640         [[ $? -eq 0 ]] || error "mkdir failed"
17641
17642         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17643         $LCTL set_param fail_loc=0x8000140c
17644         # 5s pause
17645         $LCTL set_param fail_val=5
17646
17647         # create file
17648         echo foofoo > $DIR/$tdir/$tfile &
17649         pid=$!
17650
17651         # wait for create to be delayed
17652         sleep 2
17653
17654         ps -p $pid
17655         [[ $? -eq 0 ]] || error "create should be blocked"
17656
17657         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17658         stack_trap "rm -f $tempfile"
17659         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17660         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17661         # some delay may occur during ChangeLog publishing and file read just
17662         # above, that could allow file write to happen finally
17663         [[ -s $tempfile ]] && echo "file should be empty"
17664
17665         $LCTL set_param fail_loc=0
17666
17667         wait $pid
17668         [[ $? -eq 0 ]] || error "create failed"
17669 }
17670 run_test 161d "create with concurrent .lustre/fid access"
17671
17672 check_path() {
17673         local expected="$1"
17674         shift
17675         local fid="$2"
17676
17677         local path
17678         path=$($LFS fid2path "$@")
17679         local rc=$?
17680
17681         if [ $rc -ne 0 ]; then
17682                 error "path looked up of '$expected' failed: rc=$rc"
17683         elif [ "$path" != "$expected" ]; then
17684                 error "path looked up '$path' instead of '$expected'"
17685         else
17686                 echo "FID '$fid' resolves to path '$path' as expected"
17687         fi
17688 }
17689
17690 test_162a() { # was test_162
17691         test_mkdir -p -c1 $DIR/$tdir/d2
17692         touch $DIR/$tdir/d2/$tfile
17693         touch $DIR/$tdir/d2/x1
17694         touch $DIR/$tdir/d2/x2
17695         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17696         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17697         # regular file
17698         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17699         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17700
17701         # softlink
17702         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17703         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17704         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17705
17706         # softlink to wrong file
17707         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17708         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17709         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17710
17711         # hardlink
17712         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17713         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17714         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17715         # fid2path dir/fsname should both work
17716         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17717         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17718
17719         # hardlink count: check that there are 2 links
17720         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17721         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17722
17723         # hardlink indexing: remove the first link
17724         rm $DIR/$tdir/d2/p/q/r/hlink
17725         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17726 }
17727 run_test 162a "path lookup sanity"
17728
17729 test_162b() {
17730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17731         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17732
17733         mkdir $DIR/$tdir
17734         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17735                                 error "create striped dir failed"
17736
17737         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17738                                         tail -n 1 | awk '{print $2}')
17739         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17740
17741         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17742         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17743
17744         # regular file
17745         for ((i=0;i<5;i++)); do
17746                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17747                         error "get fid for f$i failed"
17748                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17749
17750                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17751                         error "get fid for d$i failed"
17752                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17753         done
17754
17755         return 0
17756 }
17757 run_test 162b "striped directory path lookup sanity"
17758
17759 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17760 test_162c() {
17761         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17762                 skip "Need MDS version at least 2.7.51"
17763
17764         local lpath=$tdir.local
17765         local rpath=$tdir.remote
17766
17767         test_mkdir $DIR/$lpath
17768         test_mkdir $DIR/$rpath
17769
17770         for ((i = 0; i <= 101; i++)); do
17771                 lpath="$lpath/$i"
17772                 mkdir $DIR/$lpath
17773                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17774                         error "get fid for local directory $DIR/$lpath failed"
17775                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17776
17777                 rpath="$rpath/$i"
17778                 test_mkdir $DIR/$rpath
17779                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17780                         error "get fid for remote directory $DIR/$rpath failed"
17781                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17782         done
17783
17784         return 0
17785 }
17786 run_test 162c "fid2path works with paths 100 or more directories deep"
17787
17788 oalr_event_count() {
17789         local event="${1}"
17790         local trace="${2}"
17791
17792         awk -v name="${FSNAME}-OST0000" \
17793             -v event="${event}" \
17794             '$1 == "TRACE" && $2 == event && $3 == name' \
17795             "${trace}" |
17796         wc -l
17797 }
17798
17799 oalr_expect_event_count() {
17800         local event="${1}"
17801         local trace="${2}"
17802         local expect="${3}"
17803         local count
17804
17805         count=$(oalr_event_count "${event}" "${trace}")
17806         if ((count == expect)); then
17807                 return 0
17808         fi
17809
17810         error_noexit "${event} event count was '${count}', expected ${expect}"
17811         cat "${trace}" >&2
17812         exit 1
17813 }
17814
17815 cleanup_165() {
17816         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17817         stop ost1
17818         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17819 }
17820
17821 setup_165() {
17822         sync # Flush previous IOs so we can count log entries.
17823         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17824         stack_trap cleanup_165 EXIT
17825 }
17826
17827 test_165a() {
17828         local trace="/tmp/${tfile}.trace"
17829         local rc
17830         local count
17831
17832         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17833                 skip "OFD access log unsupported"
17834
17835         setup_165
17836         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17837         sleep 5
17838
17839         do_facet ost1 ofd_access_log_reader --list
17840         stop ost1
17841
17842         do_facet ost1 killall -TERM ofd_access_log_reader
17843         wait
17844         rc=$?
17845
17846         if ((rc != 0)); then
17847                 error "ofd_access_log_reader exited with rc = '${rc}'"
17848         fi
17849
17850         # Parse trace file for discovery events:
17851         oalr_expect_event_count alr_log_add "${trace}" 1
17852         oalr_expect_event_count alr_log_eof "${trace}" 1
17853         oalr_expect_event_count alr_log_free "${trace}" 1
17854 }
17855 run_test 165a "ofd access log discovery"
17856
17857 test_165b() {
17858         local trace="/tmp/${tfile}.trace"
17859         local file="${DIR}/${tfile}"
17860         local pfid1
17861         local pfid2
17862         local -a entry
17863         local rc
17864         local count
17865         local size
17866         local flags
17867
17868         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17869                 skip "OFD access log unsupported"
17870
17871         setup_165
17872         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17873         sleep 5
17874
17875         do_facet ost1 ofd_access_log_reader --list
17876
17877         lfs setstripe -c 1 -i 0 "${file}"
17878         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17879                 error "cannot create '${file}'"
17880
17881         sleep 5
17882         do_facet ost1 killall -TERM ofd_access_log_reader
17883         wait
17884         rc=$?
17885
17886         if ((rc != 0)); then
17887                 error "ofd_access_log_reader exited with rc = '${rc}'"
17888         fi
17889
17890         oalr_expect_event_count alr_log_entry "${trace}" 1
17891
17892         pfid1=$($LFS path2fid "${file}")
17893
17894         # 1     2             3   4    5     6   7    8    9     10
17895         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17896         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17897
17898         echo "entry = '${entry[*]}'" >&2
17899
17900         pfid2=${entry[4]}
17901         if [[ "${pfid1}" != "${pfid2}" ]]; then
17902                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17903         fi
17904
17905         size=${entry[8]}
17906         if ((size != 1048576)); then
17907                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17908         fi
17909
17910         flags=${entry[10]}
17911         if [[ "${flags}" != "w" ]]; then
17912                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17913         fi
17914
17915         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17916         sleep 5
17917
17918         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17919                 error "cannot read '${file}'"
17920         sleep 5
17921
17922         do_facet ost1 killall -TERM ofd_access_log_reader
17923         wait
17924         rc=$?
17925
17926         if ((rc != 0)); then
17927                 error "ofd_access_log_reader exited with rc = '${rc}'"
17928         fi
17929
17930         oalr_expect_event_count alr_log_entry "${trace}" 1
17931
17932         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17933         echo "entry = '${entry[*]}'" >&2
17934
17935         pfid2=${entry[4]}
17936         if [[ "${pfid1}" != "${pfid2}" ]]; then
17937                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17938         fi
17939
17940         size=${entry[8]}
17941         if ((size != 524288)); then
17942                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17943         fi
17944
17945         flags=${entry[10]}
17946         if [[ "${flags}" != "r" ]]; then
17947                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17948         fi
17949 }
17950 run_test 165b "ofd access log entries are produced and consumed"
17951
17952 test_165c() {
17953         local trace="/tmp/${tfile}.trace"
17954         local file="${DIR}/${tdir}/${tfile}"
17955
17956         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17957                 skip "OFD access log unsupported"
17958
17959         test_mkdir "${DIR}/${tdir}"
17960
17961         setup_165
17962         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17963         sleep 5
17964
17965         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17966
17967         # 4096 / 64 = 64. Create twice as many entries.
17968         for ((i = 0; i < 128; i++)); do
17969                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17970                         error "cannot create file"
17971         done
17972
17973         sync
17974
17975         do_facet ost1 killall -TERM ofd_access_log_reader
17976         wait
17977         rc=$?
17978         if ((rc != 0)); then
17979                 error "ofd_access_log_reader exited with rc = '${rc}'"
17980         fi
17981
17982         unlinkmany  "${file}-%d" 128
17983 }
17984 run_test 165c "full ofd access logs do not block IOs"
17985
17986 oal_get_read_count() {
17987         local stats="$1"
17988
17989         # STATS lustre-OST0001 alr_read_count 1
17990
17991         do_facet ost1 cat "${stats}" |
17992         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17993              END { print count; }'
17994 }
17995
17996 oal_expect_read_count() {
17997         local stats="$1"
17998         local count
17999         local expect="$2"
18000
18001         # Ask ofd_access_log_reader to write stats.
18002         do_facet ost1 killall -USR1 ofd_access_log_reader
18003
18004         # Allow some time for things to happen.
18005         sleep 1
18006
18007         count=$(oal_get_read_count "${stats}")
18008         if ((count == expect)); then
18009                 return 0
18010         fi
18011
18012         error_noexit "bad read count, got ${count}, expected ${expect}"
18013         do_facet ost1 cat "${stats}" >&2
18014         exit 1
18015 }
18016
18017 test_165d() {
18018         local stats="/tmp/${tfile}.stats"
18019         local file="${DIR}/${tdir}/${tfile}"
18020         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18021
18022         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18023                 skip "OFD access log unsupported"
18024
18025         test_mkdir "${DIR}/${tdir}"
18026
18027         setup_165
18028         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18029         sleep 5
18030
18031         lfs setstripe -c 1 -i 0 "${file}"
18032
18033         do_facet ost1 lctl set_param "${param}=rw"
18034         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18035                 error "cannot create '${file}'"
18036         oal_expect_read_count "${stats}" 1
18037
18038         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18039                 error "cannot read '${file}'"
18040         oal_expect_read_count "${stats}" 2
18041
18042         do_facet ost1 lctl set_param "${param}=r"
18043         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18044                 error "cannot create '${file}'"
18045         oal_expect_read_count "${stats}" 2
18046
18047         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18048                 error "cannot read '${file}'"
18049         oal_expect_read_count "${stats}" 3
18050
18051         do_facet ost1 lctl set_param "${param}=w"
18052         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18053                 error "cannot create '${file}'"
18054         oal_expect_read_count "${stats}" 4
18055
18056         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18057                 error "cannot read '${file}'"
18058         oal_expect_read_count "${stats}" 4
18059
18060         do_facet ost1 lctl set_param "${param}=0"
18061         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18062                 error "cannot create '${file}'"
18063         oal_expect_read_count "${stats}" 4
18064
18065         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18066                 error "cannot read '${file}'"
18067         oal_expect_read_count "${stats}" 4
18068
18069         do_facet ost1 killall -TERM ofd_access_log_reader
18070         wait
18071         rc=$?
18072         if ((rc != 0)); then
18073                 error "ofd_access_log_reader exited with rc = '${rc}'"
18074         fi
18075 }
18076 run_test 165d "ofd_access_log mask works"
18077
18078 test_165e() {
18079         local stats="/tmp/${tfile}.stats"
18080         local file0="${DIR}/${tdir}-0/${tfile}"
18081         local file1="${DIR}/${tdir}-1/${tfile}"
18082
18083         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18084                 skip "OFD access log unsupported"
18085
18086         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18087
18088         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18089         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18090
18091         lfs setstripe -c 1 -i 0 "${file0}"
18092         lfs setstripe -c 1 -i 0 "${file1}"
18093
18094         setup_165
18095         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18096         sleep 5
18097
18098         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18099                 error "cannot create '${file0}'"
18100         sync
18101         oal_expect_read_count "${stats}" 0
18102
18103         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18104                 error "cannot create '${file1}'"
18105         sync
18106         oal_expect_read_count "${stats}" 1
18107
18108         do_facet ost1 killall -TERM ofd_access_log_reader
18109         wait
18110         rc=$?
18111         if ((rc != 0)); then
18112                 error "ofd_access_log_reader exited with rc = '${rc}'"
18113         fi
18114 }
18115 run_test 165e "ofd_access_log MDT index filter works"
18116
18117 test_165f() {
18118         local trace="/tmp/${tfile}.trace"
18119         local rc
18120         local count
18121
18122         setup_165
18123         do_facet ost1 timeout 60 ofd_access_log_reader \
18124                 --exit-on-close --debug=- --trace=- > "${trace}" &
18125         sleep 5
18126         stop ost1
18127
18128         wait
18129         rc=$?
18130
18131         if ((rc != 0)); then
18132                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18133                 cat "${trace}"
18134                 exit 1
18135         fi
18136 }
18137 run_test 165f "ofd_access_log_reader --exit-on-close works"
18138
18139 test_169() {
18140         # do directio so as not to populate the page cache
18141         log "creating a 10 Mb file"
18142         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18143                 error "multiop failed while creating a file"
18144         log "starting reads"
18145         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18146         log "truncating the file"
18147         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18148                 error "multiop failed while truncating the file"
18149         log "killing dd"
18150         kill %+ || true # reads might have finished
18151         echo "wait until dd is finished"
18152         wait
18153         log "removing the temporary file"
18154         rm -rf $DIR/$tfile || error "tmp file removal failed"
18155 }
18156 run_test 169 "parallel read and truncate should not deadlock"
18157
18158 test_170() {
18159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18160
18161         $LCTL clear     # bug 18514
18162         $LCTL debug_daemon start $TMP/${tfile}_log_good
18163         touch $DIR/$tfile
18164         $LCTL debug_daemon stop
18165         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18166                 error "sed failed to read log_good"
18167
18168         $LCTL debug_daemon start $TMP/${tfile}_log_good
18169         rm -rf $DIR/$tfile
18170         $LCTL debug_daemon stop
18171
18172         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18173                error "lctl df log_bad failed"
18174
18175         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18176         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18177
18178         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18179         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18180
18181         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18182                 error "bad_line good_line1 good_line2 are empty"
18183
18184         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18185         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18186         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18187
18188         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18189         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18190         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18191
18192         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18193                 error "bad_line_new good_line_new are empty"
18194
18195         local expected_good=$((good_line1 + good_line2*2))
18196
18197         rm -f $TMP/${tfile}*
18198         # LU-231, short malformed line may not be counted into bad lines
18199         if [ $bad_line -ne $bad_line_new ] &&
18200                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18201                 error "expected $bad_line bad lines, but got $bad_line_new"
18202                 return 1
18203         fi
18204
18205         if [ $expected_good -ne $good_line_new ]; then
18206                 error "expected $expected_good good lines, but got $good_line_new"
18207                 return 2
18208         fi
18209         true
18210 }
18211 run_test 170 "test lctl df to handle corrupted log ====================="
18212
18213 test_171() { # bug20592
18214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18215
18216         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18217         $LCTL set_param fail_loc=0x50e
18218         $LCTL set_param fail_val=3000
18219         multiop_bg_pause $DIR/$tfile O_s || true
18220         local MULTIPID=$!
18221         kill -USR1 $MULTIPID
18222         # cause log dump
18223         sleep 3
18224         wait $MULTIPID
18225         if dmesg | grep "recursive fault"; then
18226                 error "caught a recursive fault"
18227         fi
18228         $LCTL set_param fail_loc=0
18229         true
18230 }
18231 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18232
18233 test_172() {
18234
18235         #define OBD_FAIL_OBD_CLEANUP  0x60e
18236         $LCTL set_param fail_loc=0x60e
18237         umount $MOUNT || error "umount $MOUNT failed"
18238         stack_trap "mount_client $MOUNT"
18239
18240         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18241                 error "no client OBDs are remained"
18242
18243         $LCTL dl | while read devno state type name foo; do
18244                 case $type in
18245                 lov|osc|lmv|mdc)
18246                         $LCTL --device $name cleanup
18247                         $LCTL --device $name detach
18248                         ;;
18249                 *)
18250                         # skip server devices
18251                         ;;
18252                 esac
18253         done
18254
18255         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18256                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18257                 error "some client OBDs are still remained"
18258         fi
18259
18260 }
18261 run_test 172 "manual device removal with lctl cleanup/detach ======"
18262
18263 # it would be good to share it with obdfilter-survey/iokit-libecho code
18264 setup_obdecho_osc () {
18265         local rc=0
18266         local ost_nid=$1
18267         local obdfilter_name=$2
18268         echo "Creating new osc for $obdfilter_name on $ost_nid"
18269         # make sure we can find loopback nid
18270         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18271
18272         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18273                            ${obdfilter_name}_osc_UUID || rc=2; }
18274         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18275                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18276         return $rc
18277 }
18278
18279 cleanup_obdecho_osc () {
18280         local obdfilter_name=$1
18281         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18282         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18283         return 0
18284 }
18285
18286 obdecho_test() {
18287         local OBD=$1
18288         local node=$2
18289         local pages=${3:-64}
18290         local rc=0
18291         local id
18292
18293         local count=10
18294         local obd_size=$(get_obd_size $node $OBD)
18295         local page_size=$(get_page_size $node)
18296         if [[ -n "$obd_size" ]]; then
18297                 local new_count=$((obd_size / (pages * page_size / 1024)))
18298                 [[ $new_count -ge $count ]] || count=$new_count
18299         fi
18300
18301         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18302         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18303                            rc=2; }
18304         if [ $rc -eq 0 ]; then
18305             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18306             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18307         fi
18308         echo "New object id is $id"
18309         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18310                            rc=4; }
18311         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18312                            "test_brw $count w v $pages $id" || rc=4; }
18313         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18314                            rc=4; }
18315         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18316                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18317         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18318                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18319         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18320         return $rc
18321 }
18322
18323 test_180a() {
18324         skip "obdecho on osc is no longer supported"
18325 }
18326 run_test 180a "test obdecho on osc"
18327
18328 test_180b() {
18329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18330         remote_ost_nodsh && skip "remote OST with nodsh"
18331
18332         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18333                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18334                 error "failed to load module obdecho"
18335
18336         local target=$(do_facet ost1 $LCTL dl |
18337                        awk '/obdfilter/ { print $4; exit; }')
18338
18339         if [ -n "$target" ]; then
18340                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18341         else
18342                 do_facet ost1 $LCTL dl
18343                 error "there is no obdfilter target on ost1"
18344         fi
18345 }
18346 run_test 180b "test obdecho directly on obdfilter"
18347
18348 test_180c() { # LU-2598
18349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18350         remote_ost_nodsh && skip "remote OST with nodsh"
18351         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18352                 skip "Need MDS version at least 2.4.0"
18353
18354         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18355                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18356                 error "failed to load module obdecho"
18357
18358         local target=$(do_facet ost1 $LCTL dl |
18359                        awk '/obdfilter/ { print $4; exit; }')
18360
18361         if [ -n "$target" ]; then
18362                 local pages=16384 # 64MB bulk I/O RPC size
18363
18364                 obdecho_test "$target" ost1 "$pages" ||
18365                         error "obdecho_test with pages=$pages failed with $?"
18366         else
18367                 do_facet ost1 $LCTL dl
18368                 error "there is no obdfilter target on ost1"
18369         fi
18370 }
18371 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18372
18373 test_181() { # bug 22177
18374         test_mkdir $DIR/$tdir
18375         # create enough files to index the directory
18376         createmany -o $DIR/$tdir/foobar 4000
18377         # print attributes for debug purpose
18378         lsattr -d .
18379         # open dir
18380         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18381         MULTIPID=$!
18382         # remove the files & current working dir
18383         unlinkmany $DIR/$tdir/foobar 4000
18384         rmdir $DIR/$tdir
18385         kill -USR1 $MULTIPID
18386         wait $MULTIPID
18387         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18388         return 0
18389 }
18390 run_test 181 "Test open-unlinked dir ========================"
18391
18392 test_182a() {
18393         local fcount=1000
18394         local tcount=10
18395
18396         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18397
18398         $LCTL set_param mdc.*.rpc_stats=clear
18399
18400         for (( i = 0; i < $tcount; i++ )) ; do
18401                 mkdir $DIR/$tdir/$i
18402         done
18403
18404         for (( i = 0; i < $tcount; i++ )) ; do
18405                 createmany -o $DIR/$tdir/$i/f- $fcount &
18406         done
18407         wait
18408
18409         for (( i = 0; i < $tcount; i++ )) ; do
18410                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18411         done
18412         wait
18413
18414         $LCTL get_param mdc.*.rpc_stats
18415
18416         rm -rf $DIR/$tdir
18417 }
18418 run_test 182a "Test parallel modify metadata operations from mdc"
18419
18420 test_182b() {
18421         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18422         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18423         local dcount=1000
18424         local tcount=10
18425         local stime
18426         local etime
18427         local delta
18428
18429         do_facet mds1 $LCTL list_param \
18430                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18431                 skip "MDS lacks parallel RPC handling"
18432
18433         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18434
18435         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18436                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18437
18438         stime=$(date +%s)
18439         createmany -i 0 -d $DIR/$tdir/t- $tcount
18440
18441         for (( i = 0; i < $tcount; i++ )) ; do
18442                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18443         done
18444         wait
18445         etime=$(date +%s)
18446         delta=$((etime - stime))
18447         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18448
18449         stime=$(date +%s)
18450         for (( i = 0; i < $tcount; i++ )) ; do
18451                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18452         done
18453         wait
18454         etime=$(date +%s)
18455         delta=$((etime - stime))
18456         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18457
18458         rm -rf $DIR/$tdir
18459
18460         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18461
18462         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18463
18464         stime=$(date +%s)
18465         createmany -i 0 -d $DIR/$tdir/t- $tcount
18466
18467         for (( i = 0; i < $tcount; i++ )) ; do
18468                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18469         done
18470         wait
18471         etime=$(date +%s)
18472         delta=$((etime - stime))
18473         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18474
18475         stime=$(date +%s)
18476         for (( i = 0; i < $tcount; i++ )) ; do
18477                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18478         done
18479         wait
18480         etime=$(date +%s)
18481         delta=$((etime - stime))
18482         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18483
18484         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18485 }
18486 run_test 182b "Test parallel modify metadata operations from osp"
18487
18488 test_183() { # LU-2275
18489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18490         remote_mds_nodsh && skip "remote MDS with nodsh"
18491         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18492                 skip "Need MDS version at least 2.3.56"
18493
18494         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18495         echo aaa > $DIR/$tdir/$tfile
18496
18497 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18498         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18499
18500         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18501         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18502
18503         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18504
18505         # Flush negative dentry cache
18506         touch $DIR/$tdir/$tfile
18507
18508         # We are not checking for any leaked references here, they'll
18509         # become evident next time we do cleanup with module unload.
18510         rm -rf $DIR/$tdir
18511 }
18512 run_test 183 "No crash or request leak in case of strange dispositions ========"
18513
18514 # test suite 184 is for LU-2016, LU-2017
18515 test_184a() {
18516         check_swap_layouts_support
18517
18518         dir0=$DIR/$tdir/$testnum
18519         test_mkdir -p -c1 $dir0
18520         ref1=/etc/passwd
18521         ref2=/etc/group
18522         file1=$dir0/f1
18523         file2=$dir0/f2
18524         $LFS setstripe -c1 $file1
18525         cp $ref1 $file1
18526         $LFS setstripe -c2 $file2
18527         cp $ref2 $file2
18528         gen1=$($LFS getstripe -g $file1)
18529         gen2=$($LFS getstripe -g $file2)
18530
18531         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18532         gen=$($LFS getstripe -g $file1)
18533         [[ $gen1 != $gen ]] ||
18534                 error "Layout generation on $file1 does not change"
18535         gen=$($LFS getstripe -g $file2)
18536         [[ $gen2 != $gen ]] ||
18537                 error "Layout generation on $file2 does not change"
18538
18539         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18540         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18541
18542         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18543 }
18544 run_test 184a "Basic layout swap"
18545
18546 test_184b() {
18547         check_swap_layouts_support
18548
18549         dir0=$DIR/$tdir/$testnum
18550         mkdir -p $dir0 || error "creating dir $dir0"
18551         file1=$dir0/f1
18552         file2=$dir0/f2
18553         file3=$dir0/f3
18554         dir1=$dir0/d1
18555         dir2=$dir0/d2
18556         mkdir $dir1 $dir2
18557         $LFS setstripe -c1 $file1
18558         $LFS setstripe -c2 $file2
18559         $LFS setstripe -c1 $file3
18560         chown $RUNAS_ID $file3
18561         gen1=$($LFS getstripe -g $file1)
18562         gen2=$($LFS getstripe -g $file2)
18563
18564         $LFS swap_layouts $dir1 $dir2 &&
18565                 error "swap of directories layouts should fail"
18566         $LFS swap_layouts $dir1 $file1 &&
18567                 error "swap of directory and file layouts should fail"
18568         $RUNAS $LFS swap_layouts $file1 $file2 &&
18569                 error "swap of file we cannot write should fail"
18570         $LFS swap_layouts $file1 $file3 &&
18571                 error "swap of file with different owner should fail"
18572         /bin/true # to clear error code
18573 }
18574 run_test 184b "Forbidden layout swap (will generate errors)"
18575
18576 test_184c() {
18577         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18578         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18579         check_swap_layouts_support
18580         check_swap_layout_no_dom $DIR
18581
18582         local dir0=$DIR/$tdir/$testnum
18583         mkdir -p $dir0 || error "creating dir $dir0"
18584
18585         local ref1=$dir0/ref1
18586         local ref2=$dir0/ref2
18587         local file1=$dir0/file1
18588         local file2=$dir0/file2
18589         # create a file large enough for the concurrent test
18590         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18591         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18592         echo "ref file size: ref1($(stat -c %s $ref1))," \
18593              "ref2($(stat -c %s $ref2))"
18594
18595         cp $ref2 $file2
18596         dd if=$ref1 of=$file1 bs=16k &
18597         local DD_PID=$!
18598
18599         # Make sure dd starts to copy file, but wait at most 5 seconds
18600         local loops=0
18601         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18602
18603         $LFS swap_layouts $file1 $file2
18604         local rc=$?
18605         wait $DD_PID
18606         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18607         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18608
18609         # how many bytes copied before swapping layout
18610         local copied=$(stat -c %s $file2)
18611         local remaining=$(stat -c %s $ref1)
18612         remaining=$((remaining - copied))
18613         echo "Copied $copied bytes before swapping layout..."
18614
18615         cmp -n $copied $file1 $ref2 | grep differ &&
18616                 error "Content mismatch [0, $copied) of ref2 and file1"
18617         cmp -n $copied $file2 $ref1 ||
18618                 error "Content mismatch [0, $copied) of ref1 and file2"
18619         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18620                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18621
18622         # clean up
18623         rm -f $ref1 $ref2 $file1 $file2
18624 }
18625 run_test 184c "Concurrent write and layout swap"
18626
18627 test_184d() {
18628         check_swap_layouts_support
18629         check_swap_layout_no_dom $DIR
18630         [ -z "$(which getfattr 2>/dev/null)" ] &&
18631                 skip_env "no getfattr command"
18632
18633         local file1=$DIR/$tdir/$tfile-1
18634         local file2=$DIR/$tdir/$tfile-2
18635         local file3=$DIR/$tdir/$tfile-3
18636         local lovea1
18637         local lovea2
18638
18639         mkdir -p $DIR/$tdir
18640         touch $file1 || error "create $file1 failed"
18641         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18642                 error "create $file2 failed"
18643         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18644                 error "create $file3 failed"
18645         lovea1=$(get_layout_param $file1)
18646
18647         $LFS swap_layouts $file2 $file3 ||
18648                 error "swap $file2 $file3 layouts failed"
18649         $LFS swap_layouts $file1 $file2 ||
18650                 error "swap $file1 $file2 layouts failed"
18651
18652         lovea2=$(get_layout_param $file2)
18653         echo "$lovea1"
18654         echo "$lovea2"
18655         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18656
18657         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18658         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18659 }
18660 run_test 184d "allow stripeless layouts swap"
18661
18662 test_184e() {
18663         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18664                 skip "Need MDS version at least 2.6.94"
18665         check_swap_layouts_support
18666         check_swap_layout_no_dom $DIR
18667         [ -z "$(which getfattr 2>/dev/null)" ] &&
18668                 skip_env "no getfattr command"
18669
18670         local file1=$DIR/$tdir/$tfile-1
18671         local file2=$DIR/$tdir/$tfile-2
18672         local file3=$DIR/$tdir/$tfile-3
18673         local lovea
18674
18675         mkdir -p $DIR/$tdir
18676         touch $file1 || error "create $file1 failed"
18677         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18678                 error "create $file2 failed"
18679         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18680                 error "create $file3 failed"
18681
18682         $LFS swap_layouts $file1 $file2 ||
18683                 error "swap $file1 $file2 layouts failed"
18684
18685         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18686         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18687
18688         echo 123 > $file1 || error "Should be able to write into $file1"
18689
18690         $LFS swap_layouts $file1 $file3 ||
18691                 error "swap $file1 $file3 layouts failed"
18692
18693         echo 123 > $file1 || error "Should be able to write into $file1"
18694
18695         rm -rf $file1 $file2 $file3
18696 }
18697 run_test 184e "Recreate layout after stripeless layout swaps"
18698
18699 test_184f() {
18700         # Create a file with name longer than sizeof(struct stat) ==
18701         # 144 to see if we can get chars from the file name to appear
18702         # in the returned striping. Note that 'f' == 0x66.
18703         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18704
18705         mkdir -p $DIR/$tdir
18706         mcreate $DIR/$tdir/$file
18707         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18708                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18709         fi
18710 }
18711 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18712
18713 test_185() { # LU-2441
18714         # LU-3553 - no volatile file support in old servers
18715         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18716                 skip "Need MDS version at least 2.3.60"
18717
18718         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18719         touch $DIR/$tdir/spoo
18720         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18721         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18722                 error "cannot create/write a volatile file"
18723         [ "$FILESET" == "" ] &&
18724         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18725                 error "FID is still valid after close"
18726
18727         multiop_bg_pause $DIR/$tdir vVw4096_c
18728         local multi_pid=$!
18729
18730         local OLD_IFS=$IFS
18731         IFS=":"
18732         local fidv=($fid)
18733         IFS=$OLD_IFS
18734         # assume that the next FID for this client is sequential, since stdout
18735         # is unfortunately eaten by multiop_bg_pause
18736         local n=$((${fidv[1]} + 1))
18737         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18738         if [ "$FILESET" == "" ]; then
18739                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18740                         error "FID is missing before close"
18741         fi
18742         kill -USR1 $multi_pid
18743         # 1 second delay, so if mtime change we will see it
18744         sleep 1
18745         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18746         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18747 }
18748 run_test 185 "Volatile file support"
18749
18750 function create_check_volatile() {
18751         local idx=$1
18752         local tgt
18753
18754         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18755         local PID=$!
18756         sleep 1
18757         local FID=$(cat /tmp/${tfile}.fid)
18758         [ "$FID" == "" ] && error "can't get FID for volatile"
18759         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18760         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18761         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18762         kill -USR1 $PID
18763         wait
18764         sleep 1
18765         cancel_lru_locks mdc # flush opencache
18766         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18767         return 0
18768 }
18769
18770 test_185a(){
18771         # LU-12516 - volatile creation via .lustre
18772         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18773                 skip "Need MDS version at least 2.3.55"
18774
18775         create_check_volatile 0
18776         [ $MDSCOUNT -lt 2 ] && return 0
18777
18778         # DNE case
18779         create_check_volatile 1
18780
18781         return 0
18782 }
18783 run_test 185a "Volatile file creation in .lustre/fid/"
18784
18785 test_187a() {
18786         remote_mds_nodsh && skip "remote MDS with nodsh"
18787         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18788                 skip "Need MDS version at least 2.3.0"
18789
18790         local dir0=$DIR/$tdir/$testnum
18791         mkdir -p $dir0 || error "creating dir $dir0"
18792
18793         local file=$dir0/file1
18794         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18795         local dv1=$($LFS data_version $file)
18796         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18797         local dv2=$($LFS data_version $file)
18798         [[ $dv1 != $dv2 ]] ||
18799                 error "data version did not change on write $dv1 == $dv2"
18800
18801         # clean up
18802         rm -f $file1
18803 }
18804 run_test 187a "Test data version change"
18805
18806 test_187b() {
18807         remote_mds_nodsh && skip "remote MDS with nodsh"
18808         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18809                 skip "Need MDS version at least 2.3.0"
18810
18811         local dir0=$DIR/$tdir/$testnum
18812         mkdir -p $dir0 || error "creating dir $dir0"
18813
18814         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18815         [[ ${DV[0]} != ${DV[1]} ]] ||
18816                 error "data version did not change on write"\
18817                       " ${DV[0]} == ${DV[1]}"
18818
18819         # clean up
18820         rm -f $file1
18821 }
18822 run_test 187b "Test data version change on volatile file"
18823
18824 test_200() {
18825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18826         remote_mgs_nodsh && skip "remote MGS with nodsh"
18827         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18828
18829         local POOL=${POOL:-cea1}
18830         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18831         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18832         # Pool OST targets
18833         local first_ost=0
18834         local last_ost=$(($OSTCOUNT - 1))
18835         local ost_step=2
18836         local ost_list=$(seq $first_ost $ost_step $last_ost)
18837         local ost_range="$first_ost $last_ost $ost_step"
18838         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18839         local file_dir=$POOL_ROOT/file_tst
18840         local subdir=$test_path/subdir
18841         local rc=0
18842
18843         while : ; do
18844                 # former test_200a test_200b
18845                 pool_add $POOL                          || { rc=$? ; break; }
18846                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18847                 # former test_200c test_200d
18848                 mkdir -p $test_path
18849                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18850                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18851                 mkdir -p $subdir
18852                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18853                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18854                                                         || { rc=$? ; break; }
18855                 # former test_200e test_200f
18856                 local files=$((OSTCOUNT*3))
18857                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18858                                                         || { rc=$? ; break; }
18859                 pool_create_files $POOL $file_dir $files "$ost_list" \
18860                                                         || { rc=$? ; break; }
18861                 # former test_200g test_200h
18862                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18863                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18864
18865                 # former test_201a test_201b test_201c
18866                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18867
18868                 local f=$test_path/$tfile
18869                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18870                 pool_remove $POOL $f                    || { rc=$? ; break; }
18871                 break
18872         done
18873
18874         destroy_test_pools
18875
18876         return $rc
18877 }
18878 run_test 200 "OST pools"
18879
18880 # usage: default_attr <count | size | offset>
18881 default_attr() {
18882         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18883 }
18884
18885 # usage: check_default_stripe_attr
18886 check_default_stripe_attr() {
18887         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18888         case $1 in
18889         --stripe-count|-c)
18890                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18891         --stripe-size|-S)
18892                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18893         --stripe-index|-i)
18894                 EXPECTED=-1;;
18895         *)
18896                 error "unknown getstripe attr '$1'"
18897         esac
18898
18899         [ $ACTUAL == $EXPECTED ] ||
18900                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18901 }
18902
18903 test_204a() {
18904         test_mkdir $DIR/$tdir
18905         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18906
18907         check_default_stripe_attr --stripe-count
18908         check_default_stripe_attr --stripe-size
18909         check_default_stripe_attr --stripe-index
18910 }
18911 run_test 204a "Print default stripe attributes"
18912
18913 test_204b() {
18914         test_mkdir $DIR/$tdir
18915         $LFS setstripe --stripe-count 1 $DIR/$tdir
18916
18917         check_default_stripe_attr --stripe-size
18918         check_default_stripe_attr --stripe-index
18919 }
18920 run_test 204b "Print default stripe size and offset"
18921
18922 test_204c() {
18923         test_mkdir $DIR/$tdir
18924         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18925
18926         check_default_stripe_attr --stripe-count
18927         check_default_stripe_attr --stripe-index
18928 }
18929 run_test 204c "Print default stripe count and offset"
18930
18931 test_204d() {
18932         test_mkdir $DIR/$tdir
18933         $LFS setstripe --stripe-index 0 $DIR/$tdir
18934
18935         check_default_stripe_attr --stripe-count
18936         check_default_stripe_attr --stripe-size
18937 }
18938 run_test 204d "Print default stripe count and size"
18939
18940 test_204e() {
18941         test_mkdir $DIR/$tdir
18942         $LFS setstripe -d $DIR/$tdir
18943
18944         check_default_stripe_attr --stripe-count --raw
18945         check_default_stripe_attr --stripe-size --raw
18946         check_default_stripe_attr --stripe-index --raw
18947 }
18948 run_test 204e "Print raw stripe attributes"
18949
18950 test_204f() {
18951         test_mkdir $DIR/$tdir
18952         $LFS setstripe --stripe-count 1 $DIR/$tdir
18953
18954         check_default_stripe_attr --stripe-size --raw
18955         check_default_stripe_attr --stripe-index --raw
18956 }
18957 run_test 204f "Print raw stripe size and offset"
18958
18959 test_204g() {
18960         test_mkdir $DIR/$tdir
18961         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18962
18963         check_default_stripe_attr --stripe-count --raw
18964         check_default_stripe_attr --stripe-index --raw
18965 }
18966 run_test 204g "Print raw stripe count and offset"
18967
18968 test_204h() {
18969         test_mkdir $DIR/$tdir
18970         $LFS setstripe --stripe-index 0 $DIR/$tdir
18971
18972         check_default_stripe_attr --stripe-count --raw
18973         check_default_stripe_attr --stripe-size --raw
18974 }
18975 run_test 204h "Print raw stripe count and size"
18976
18977 # Figure out which job scheduler is being used, if any,
18978 # or use a fake one
18979 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18980         JOBENV=SLURM_JOB_ID
18981 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18982         JOBENV=LSB_JOBID
18983 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18984         JOBENV=PBS_JOBID
18985 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18986         JOBENV=LOADL_STEP_ID
18987 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18988         JOBENV=JOB_ID
18989 else
18990         $LCTL list_param jobid_name > /dev/null 2>&1
18991         if [ $? -eq 0 ]; then
18992                 JOBENV=nodelocal
18993         else
18994                 JOBENV=FAKE_JOBID
18995         fi
18996 fi
18997 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18998
18999 verify_jobstats() {
19000         local cmd=($1)
19001         shift
19002         local facets="$@"
19003
19004 # we don't really need to clear the stats for this test to work, since each
19005 # command has a unique jobid, but it makes debugging easier if needed.
19006 #       for facet in $facets; do
19007 #               local dev=$(convert_facet2label $facet)
19008 #               # clear old jobstats
19009 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19010 #       done
19011
19012         # use a new JobID for each test, or we might see an old one
19013         [ "$JOBENV" = "FAKE_JOBID" ] &&
19014                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19015
19016         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19017
19018         [ "$JOBENV" = "nodelocal" ] && {
19019                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19020                 $LCTL set_param jobid_name=$FAKE_JOBID
19021                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19022         }
19023
19024         log "Test: ${cmd[*]}"
19025         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19026
19027         if [ $JOBENV = "FAKE_JOBID" ]; then
19028                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19029         else
19030                 ${cmd[*]}
19031         fi
19032
19033         # all files are created on OST0000
19034         for facet in $facets; do
19035                 local stats="*.$(convert_facet2label $facet).job_stats"
19036
19037                 # strip out libtool wrappers for in-tree executables
19038                 if (( $(do_facet $facet lctl get_param $stats |
19039                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19040                         do_facet $facet lctl get_param $stats
19041                         error "No jobstats for $JOBVAL found on $facet::$stats"
19042                 fi
19043         done
19044 }
19045
19046 jobstats_set() {
19047         local new_jobenv=$1
19048
19049         set_persistent_param_and_check client "jobid_var" \
19050                 "$FSNAME.sys.jobid_var" $new_jobenv
19051 }
19052
19053 test_205a() { # Job stats
19054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19055         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19056                 skip "Need MDS version with at least 2.7.1"
19057         remote_mgs_nodsh && skip "remote MGS with nodsh"
19058         remote_mds_nodsh && skip "remote MDS with nodsh"
19059         remote_ost_nodsh && skip "remote OST with nodsh"
19060         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19061                 skip "Server doesn't support jobstats"
19062         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19063
19064         local old_jobenv=$($LCTL get_param -n jobid_var)
19065         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19066
19067         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19068                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19069         else
19070                 stack_trap "do_facet mgs $PERM_CMD \
19071                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19072         fi
19073         changelog_register
19074
19075         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19076                                 mdt.*.job_cleanup_interval | head -n 1)
19077         local new_interval=5
19078         do_facet $SINGLEMDS \
19079                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19080         stack_trap "do_facet $SINGLEMDS \
19081                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19082         local start=$SECONDS
19083
19084         local cmd
19085         # mkdir
19086         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19087         verify_jobstats "$cmd" "$SINGLEMDS"
19088         # rmdir
19089         cmd="rmdir $DIR/$tdir"
19090         verify_jobstats "$cmd" "$SINGLEMDS"
19091         # mkdir on secondary MDT
19092         if [ $MDSCOUNT -gt 1 ]; then
19093                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19094                 verify_jobstats "$cmd" "mds2"
19095         fi
19096         # mknod
19097         cmd="mknod $DIR/$tfile c 1 3"
19098         verify_jobstats "$cmd" "$SINGLEMDS"
19099         # unlink
19100         cmd="rm -f $DIR/$tfile"
19101         verify_jobstats "$cmd" "$SINGLEMDS"
19102         # create all files on OST0000 so verify_jobstats can find OST stats
19103         # open & close
19104         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19105         verify_jobstats "$cmd" "$SINGLEMDS"
19106         # setattr
19107         cmd="touch $DIR/$tfile"
19108         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19109         # write
19110         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19111         verify_jobstats "$cmd" "ost1"
19112         # read
19113         cancel_lru_locks osc
19114         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19115         verify_jobstats "$cmd" "ost1"
19116         # truncate
19117         cmd="$TRUNCATE $DIR/$tfile 0"
19118         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19119         # rename
19120         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19121         verify_jobstats "$cmd" "$SINGLEMDS"
19122         # jobstats expiry - sleep until old stats should be expired
19123         local left=$((new_interval + 5 - (SECONDS - start)))
19124         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19125                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19126                         "0" $left
19127         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19128         verify_jobstats "$cmd" "$SINGLEMDS"
19129         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19130             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19131
19132         # Ensure that jobid are present in changelog (if supported by MDS)
19133         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19134                 changelog_dump | tail -10
19135                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19136                 [ $jobids -eq 9 ] ||
19137                         error "Wrong changelog jobid count $jobids != 9"
19138
19139                 # LU-5862
19140                 JOBENV="disable"
19141                 jobstats_set $JOBENV
19142                 touch $DIR/$tfile
19143                 changelog_dump | grep $tfile
19144                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19145                 [ $jobids -eq 0 ] ||
19146                         error "Unexpected jobids when jobid_var=$JOBENV"
19147         fi
19148
19149         # test '%j' access to environment variable - if supported
19150         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19151                 JOBENV="JOBCOMPLEX"
19152                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19153
19154                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19155         fi
19156
19157         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19158                 JOBENV="JOBCOMPLEX"
19159                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19160
19161                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19162         fi
19163
19164         # test '%j' access to per-session jobid - if supported
19165         if lctl list_param jobid_this_session > /dev/null 2>&1
19166         then
19167                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19168                 lctl set_param jobid_this_session=$USER
19169
19170                 JOBENV="JOBCOMPLEX"
19171                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19172
19173                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19174         fi
19175 }
19176 run_test 205a "Verify job stats"
19177
19178 # LU-13117, LU-13597
19179 test_205b() {
19180         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19181                 skip "Need MDS version at least 2.13.54.91"
19182
19183         local job_stats="mdt.*.job_stats"
19184         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19185
19186         do_facet mds1 $LCTL set_param $job_stats=clear
19187
19188         # Setting jobid_var to USER might not be supported
19189         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19190         $LCTL set_param jobid_var=USER || true
19191         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19192         $LCTL set_param jobid_name="%j.%e.%u"
19193
19194         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19195         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19196                 { do_facet mds1 $LCTL get_param $job_stats;
19197                   error "Unexpected jobid found"; }
19198         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19199                 { do_facet mds1 $LCTL get_param $job_stats;
19200                   error "wrong job_stats format found"; }
19201
19202         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19203                 echo "MDS does not yet escape jobid" && return 0
19204         $LCTL set_param jobid_var=TEST205b
19205         env -i TEST205b="has sp" touch $DIR/$tfile.2
19206         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19207                 { do_facet mds1 $LCTL get_param $job_stats;
19208                   error "jobid not escaped"; }
19209 }
19210 run_test 205b "Verify job stats jobid and output format"
19211
19212 # LU-13733
19213 test_205c() {
19214         $LCTL set_param llite.*.stats=0
19215         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19216         $LCTL get_param llite.*.stats
19217         $LCTL get_param llite.*.stats | grep \
19218                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19219                         error "wrong client stats format found"
19220 }
19221 run_test 205c "Verify client stats format"
19222
19223 test_205d() {
19224         local file=$DIR/$tdir/$tfile
19225
19226         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19227                 skip "need lustre >= 2.15.53 for lljobstat"
19228         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19229                 skip "need lustre >= 2.15.53 for lljobstat"
19230         verify_yaml_available || skip_env "YAML verification not installed"
19231
19232         test_mkdir -i 0 $DIR/$tdir
19233         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19234
19235         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19236                 error "failed to write data to $file"
19237         mv $file $file.2
19238
19239         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19240         echo -n 'verify rename_stats...'
19241         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19242                 verify_yaml || error "rename_stats is not valid YAML"
19243         echo " OK"
19244
19245         echo -n 'verify mdt job_stats...'
19246         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19247                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19248         echo " OK"
19249
19250         echo -n 'verify ost job_stats...'
19251         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19252                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19253         echo " OK"
19254 }
19255 run_test 205d "verify the format of some stats files"
19256
19257 test_205e() {
19258         local ops_comma
19259         local file=$DIR/$tdir/$tfile
19260
19261         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19262                 skip "need lustre >= 2.15.53 for lljobstat"
19263         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19264                 skip "need lustre >= 2.15.53 for lljobstat"
19265         verify_yaml_available || skip_env "YAML verification not installed"
19266
19267         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19268
19269         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19270                 error "failed to create $file on ost1"
19271         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19272                 error "failed to write data to $file"
19273
19274         do_facet mds1 "$LCTL get_param *.*.job_stats"
19275         do_facet ost1 "$LCTL get_param *.*.job_stats"
19276
19277         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19278         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19279                 error "The output of lljobstat is not an valid YAML"
19280
19281         # verify that job dd.0 does exist and has some ops on ost1
19282         # typically this line is like:
19283         # - dd.0:            {ops: 20, ...}
19284         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19285                     awk '$2=="dd.0:" {print $4}')
19286
19287         (( ${ops_comma%,} >= 10 )) ||
19288                 error "cannot find job dd.0 with ops >= 10"
19289 }
19290 run_test 205e "verify the output of lljobstat"
19291
19292 # LU-1480, LU-1773 and LU-1657
19293 test_206() {
19294         mkdir -p $DIR/$tdir
19295         $LFS setstripe -c -1 $DIR/$tdir
19296 #define OBD_FAIL_LOV_INIT 0x1403
19297         $LCTL set_param fail_loc=0xa0001403
19298         $LCTL set_param fail_val=1
19299         touch $DIR/$tdir/$tfile || true
19300 }
19301 run_test 206 "fail lov_init_raid0() doesn't lbug"
19302
19303 test_207a() {
19304         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19305         local fsz=`stat -c %s $DIR/$tfile`
19306         cancel_lru_locks mdc
19307
19308         # do not return layout in getattr intent
19309 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19310         $LCTL set_param fail_loc=0x170
19311         local sz=`stat -c %s $DIR/$tfile`
19312
19313         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19314
19315         rm -rf $DIR/$tfile
19316 }
19317 run_test 207a "can refresh layout at glimpse"
19318
19319 test_207b() {
19320         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19321         local cksum=`md5sum $DIR/$tfile`
19322         local fsz=`stat -c %s $DIR/$tfile`
19323         cancel_lru_locks mdc
19324         cancel_lru_locks osc
19325
19326         # do not return layout in getattr intent
19327 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19328         $LCTL set_param fail_loc=0x171
19329
19330         # it will refresh layout after the file is opened but before read issues
19331         echo checksum is "$cksum"
19332         echo "$cksum" |md5sum -c --quiet || error "file differs"
19333
19334         rm -rf $DIR/$tfile
19335 }
19336 run_test 207b "can refresh layout at open"
19337
19338 test_208() {
19339         # FIXME: in this test suite, only RD lease is used. This is okay
19340         # for now as only exclusive open is supported. After generic lease
19341         # is done, this test suite should be revised. - Jinshan
19342
19343         remote_mds_nodsh && skip "remote MDS with nodsh"
19344         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19345                 skip "Need MDS version at least 2.4.52"
19346
19347         echo "==== test 1: verify get lease work"
19348         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19349
19350         echo "==== test 2: verify lease can be broken by upcoming open"
19351         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19352         local PID=$!
19353         sleep 2
19354
19355         $MULTIOP $DIR/$tfile oO_RDWR:c
19356         kill -USR1 $PID && wait $PID || error "break lease error"
19357
19358         echo "==== test 3: verify lease can't be granted if an open already exists"
19359         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19360         local PID=$!
19361         sleep 2
19362
19363         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19364         kill -USR1 $PID && wait $PID || error "open file error"
19365
19366         echo "==== test 4: lease can sustain over recovery"
19367         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19368         PID=$!
19369         sleep 2
19370
19371         fail mds1
19372
19373         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19374
19375         echo "==== test 5: lease broken can't be regained by replay"
19376         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19377         PID=$!
19378         sleep 2
19379
19380         # open file to break lease and then recovery
19381         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19382         fail mds1
19383
19384         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19385
19386         rm -f $DIR/$tfile
19387 }
19388 run_test 208 "Exclusive open"
19389
19390 test_209() {
19391         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19392                 skip_env "must have disp_stripe"
19393
19394         touch $DIR/$tfile
19395         sync; sleep 5; sync;
19396
19397         echo 3 > /proc/sys/vm/drop_caches
19398         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19399                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19400         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19401
19402         # open/close 500 times
19403         for i in $(seq 500); do
19404                 cat $DIR/$tfile
19405         done
19406
19407         echo 3 > /proc/sys/vm/drop_caches
19408         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19409                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19410         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19411
19412         echo "before: $req_before, after: $req_after"
19413         [ $((req_after - req_before)) -ge 300 ] &&
19414                 error "open/close requests are not freed"
19415         return 0
19416 }
19417 run_test 209 "read-only open/close requests should be freed promptly"
19418
19419 test_210() {
19420         local pid
19421
19422         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19423         pid=$!
19424         sleep 1
19425
19426         $LFS getstripe $DIR/$tfile
19427         kill -USR1 $pid
19428         wait $pid || error "multiop failed"
19429
19430         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19431         pid=$!
19432         sleep 1
19433
19434         $LFS getstripe $DIR/$tfile
19435         kill -USR1 $pid
19436         wait $pid || error "multiop failed"
19437 }
19438 run_test 210 "lfs getstripe does not break leases"
19439
19440 test_212() {
19441         size=`date +%s`
19442         size=$((size % 8192 + 1))
19443         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19444         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19445         rm -f $DIR/f212 $DIR/f212.xyz
19446 }
19447 run_test 212 "Sendfile test ============================================"
19448
19449 test_213() {
19450         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19451         cancel_lru_locks osc
19452         lctl set_param fail_loc=0x8000040f
19453         # generate a read lock
19454         cat $DIR/$tfile > /dev/null
19455         # write to the file, it will try to cancel the above read lock.
19456         cat /etc/hosts >> $DIR/$tfile
19457 }
19458 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19459
19460 test_214() { # for bug 20133
19461         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19462         for (( i=0; i < 340; i++ )) ; do
19463                 touch $DIR/$tdir/d214c/a$i
19464         done
19465
19466         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19467         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19468         ls $DIR/d214c || error "ls $DIR/d214c failed"
19469         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19470         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19471 }
19472 run_test 214 "hash-indexed directory test - bug 20133"
19473
19474 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19475 create_lnet_proc_files() {
19476         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19477 }
19478
19479 # counterpart of create_lnet_proc_files
19480 remove_lnet_proc_files() {
19481         rm -f $TMP/lnet_$1.sys
19482 }
19483
19484 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19485 # 3rd arg as regexp for body
19486 check_lnet_proc_stats() {
19487         local l=$(cat "$TMP/lnet_$1" |wc -l)
19488         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19489
19490         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19491 }
19492
19493 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19494 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19495 # optional and can be regexp for 2nd line (lnet.routes case)
19496 check_lnet_proc_entry() {
19497         local blp=2          # blp stands for 'position of 1st line of body'
19498         [ -z "$5" ] || blp=3 # lnet.routes case
19499
19500         local l=$(cat "$TMP/lnet_$1" |wc -l)
19501         # subtracting one from $blp because the body can be empty
19502         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19503
19504         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19505                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19506
19507         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19508                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19509
19510         # bail out if any unexpected line happened
19511         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19512         [ "$?" != 0 ] || error "$2 misformatted"
19513 }
19514
19515 test_215() { # for bugs 18102, 21079, 21517
19516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19517
19518         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19519         local P='[1-9][0-9]*'           # positive numeric
19520         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19521         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19522         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19523         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19524
19525         local L1 # regexp for 1st line
19526         local L2 # regexp for 2nd line (optional)
19527         local BR # regexp for the rest (body)
19528
19529         # lnet.stats should look as 11 space-separated non-negative numerics
19530         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19531         create_lnet_proc_files "stats"
19532         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19533         remove_lnet_proc_files "stats"
19534
19535         # lnet.routes should look like this:
19536         # Routing disabled/enabled
19537         # net hops priority state router
19538         # where net is a string like tcp0, hops > 0, priority >= 0,
19539         # state is up/down,
19540         # router is a string like 192.168.1.1@tcp2
19541         L1="^Routing (disabled|enabled)$"
19542         L2="^net +hops +priority +state +router$"
19543         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19544         create_lnet_proc_files "routes"
19545         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19546         remove_lnet_proc_files "routes"
19547
19548         # lnet.routers should look like this:
19549         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19550         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19551         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19552         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19553         L1="^ref +rtr_ref +alive +router$"
19554         BR="^$P +$P +(up|down) +$NID$"
19555         create_lnet_proc_files "routers"
19556         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19557         remove_lnet_proc_files "routers"
19558
19559         # lnet.peers should look like this:
19560         # nid refs state last max rtr min tx min queue
19561         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19562         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19563         # numeric (0 or >0 or <0), queue >= 0.
19564         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19565         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19566         create_lnet_proc_files "peers"
19567         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19568         remove_lnet_proc_files "peers"
19569
19570         # lnet.buffers  should look like this:
19571         # pages count credits min
19572         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19573         L1="^pages +count +credits +min$"
19574         BR="^ +$N +$N +$I +$I$"
19575         create_lnet_proc_files "buffers"
19576         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19577         remove_lnet_proc_files "buffers"
19578
19579         # lnet.nis should look like this:
19580         # nid status alive refs peer rtr max tx min
19581         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19582         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19583         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19584         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19585         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19586         create_lnet_proc_files "nis"
19587         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19588         remove_lnet_proc_files "nis"
19589
19590         # can we successfully write to lnet.stats?
19591         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19592 }
19593 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19594
19595 test_216() { # bug 20317
19596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19597         remote_ost_nodsh && skip "remote OST with nodsh"
19598
19599         local node
19600         local facets=$(get_facets OST)
19601         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19602
19603         save_lustre_params client "osc.*.contention_seconds" > $p
19604         save_lustre_params $facets \
19605                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19606         save_lustre_params $facets \
19607                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19608         save_lustre_params $facets \
19609                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19610         clear_stats osc.*.osc_stats
19611
19612         # agressive lockless i/o settings
19613         do_nodes $(comma_list $(osts_nodes)) \
19614                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19615                         ldlm.namespaces.filter-*.contended_locks=0 \
19616                         ldlm.namespaces.filter-*.contention_seconds=60"
19617         lctl set_param -n osc.*.contention_seconds=60
19618
19619         $DIRECTIO write $DIR/$tfile 0 10 4096
19620         $CHECKSTAT -s 40960 $DIR/$tfile
19621
19622         # disable lockless i/o
19623         do_nodes $(comma_list $(osts_nodes)) \
19624                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19625                         ldlm.namespaces.filter-*.contended_locks=32 \
19626                         ldlm.namespaces.filter-*.contention_seconds=0"
19627         lctl set_param -n osc.*.contention_seconds=0
19628         clear_stats osc.*.osc_stats
19629
19630         dd if=/dev/zero of=$DIR/$tfile count=0
19631         $CHECKSTAT -s 0 $DIR/$tfile
19632
19633         restore_lustre_params <$p
19634         rm -f $p
19635         rm $DIR/$tfile
19636 }
19637 run_test 216 "check lockless direct write updates file size and kms correctly"
19638
19639 test_217() { # bug 22430
19640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19641
19642         local node
19643         local nid
19644
19645         for node in $(nodes_list); do
19646                 nid=$(host_nids_address $node $NETTYPE)
19647                 if [[ $nid = *-* ]] ; then
19648                         echo "lctl ping $(h2nettype $nid)"
19649                         lctl ping $(h2nettype $nid)
19650                 else
19651                         echo "skipping $node (no hyphen detected)"
19652                 fi
19653         done
19654 }
19655 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19656
19657 test_218() {
19658        # do directio so as not to populate the page cache
19659        log "creating a 10 Mb file"
19660        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19661        log "starting reads"
19662        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19663        log "truncating the file"
19664        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19665        log "killing dd"
19666        kill %+ || true # reads might have finished
19667        echo "wait until dd is finished"
19668        wait
19669        log "removing the temporary file"
19670        rm -rf $DIR/$tfile || error "tmp file removal failed"
19671 }
19672 run_test 218 "parallel read and truncate should not deadlock"
19673
19674 test_219() {
19675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19676
19677         # write one partial page
19678         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19679         # set no grant so vvp_io_commit_write will do sync write
19680         $LCTL set_param fail_loc=0x411
19681         # write a full page at the end of file
19682         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19683
19684         $LCTL set_param fail_loc=0
19685         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19686         $LCTL set_param fail_loc=0x411
19687         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19688
19689         # LU-4201
19690         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19691         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19692 }
19693 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19694
19695 test_220() { #LU-325
19696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19697         remote_ost_nodsh && skip "remote OST with nodsh"
19698         remote_mds_nodsh && skip "remote MDS with nodsh"
19699         remote_mgs_nodsh && skip "remote MGS with nodsh"
19700
19701         local OSTIDX=0
19702
19703         # create on MDT0000 so the last_id and next_id are correct
19704         mkdir_on_mdt0 $DIR/$tdir
19705         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19706         OST=${OST%_UUID}
19707
19708         # on the mdt's osc
19709         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19710         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19711                         osp.$mdtosc_proc1.prealloc_last_id)
19712         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19713                         osp.$mdtosc_proc1.prealloc_next_id)
19714
19715         $LFS df -i
19716
19717         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19718         #define OBD_FAIL_OST_ENOINO              0x229
19719         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19720         create_pool $FSNAME.$TESTNAME || return 1
19721         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19722
19723         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19724
19725         MDSOBJS=$((last_id - next_id))
19726         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19727
19728         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19729         echo "OST still has $count kbytes free"
19730
19731         echo "create $MDSOBJS files @next_id..."
19732         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19733
19734         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19735                         osp.$mdtosc_proc1.prealloc_last_id)
19736         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19737                         osp.$mdtosc_proc1.prealloc_next_id)
19738
19739         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19740         $LFS df -i
19741
19742         echo "cleanup..."
19743
19744         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19745         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19746
19747         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19748                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19749         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19750                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19751         echo "unlink $MDSOBJS files @$next_id..."
19752         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19753 }
19754 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19755
19756 test_221() {
19757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19758
19759         dd if=`which date` of=$MOUNT/date oflag=sync
19760         chmod +x $MOUNT/date
19761
19762         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19763         $LCTL set_param fail_loc=0x80001401
19764
19765         $MOUNT/date > /dev/null
19766         rm -f $MOUNT/date
19767 }
19768 run_test 221 "make sure fault and truncate race to not cause OOM"
19769
19770 test_222a () {
19771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19772
19773         rm -rf $DIR/$tdir
19774         test_mkdir $DIR/$tdir
19775         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19776         createmany -o $DIR/$tdir/$tfile 10
19777         cancel_lru_locks mdc
19778         cancel_lru_locks osc
19779         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19780         $LCTL set_param fail_loc=0x31a
19781         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19782         $LCTL set_param fail_loc=0
19783         rm -r $DIR/$tdir
19784 }
19785 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19786
19787 test_222b () {
19788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19789
19790         rm -rf $DIR/$tdir
19791         test_mkdir $DIR/$tdir
19792         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19793         createmany -o $DIR/$tdir/$tfile 10
19794         cancel_lru_locks mdc
19795         cancel_lru_locks osc
19796         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19797         $LCTL set_param fail_loc=0x31a
19798         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19799         $LCTL set_param fail_loc=0
19800 }
19801 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19802
19803 test_223 () {
19804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19805
19806         rm -rf $DIR/$tdir
19807         test_mkdir $DIR/$tdir
19808         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19809         createmany -o $DIR/$tdir/$tfile 10
19810         cancel_lru_locks mdc
19811         cancel_lru_locks osc
19812         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19813         $LCTL set_param fail_loc=0x31b
19814         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19815         $LCTL set_param fail_loc=0
19816         rm -r $DIR/$tdir
19817 }
19818 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19819
19820 test_224a() { # LU-1039, MRP-303
19821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19822         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19823         $LCTL set_param fail_loc=0x508
19824         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19825         $LCTL set_param fail_loc=0
19826         df $DIR
19827 }
19828 run_test 224a "Don't panic on bulk IO failure"
19829
19830 test_224bd_sub() { # LU-1039, MRP-303
19831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19832         local timeout=$1
19833
19834         shift
19835         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19836
19837         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19838
19839         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19840         cancel_lru_locks osc
19841         set_checksums 0
19842         stack_trap "set_checksums $ORIG_CSUM" EXIT
19843         local at_max_saved=0
19844
19845         # adaptive timeouts may prevent seeing the issue
19846         if at_is_enabled; then
19847                 at_max_saved=$(at_max_get mds)
19848                 at_max_set 0 mds client
19849                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19850         fi
19851
19852         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19853         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19854         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19855
19856         do_facet ost1 $LCTL set_param fail_loc=0
19857         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19858         df $DIR
19859 }
19860
19861 test_224b() {
19862         test_224bd_sub 3 error "dd failed"
19863 }
19864 run_test 224b "Don't panic on bulk IO failure"
19865
19866 test_224c() { # LU-6441
19867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19868         remote_mds_nodsh && skip "remote MDS with nodsh"
19869
19870         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19871         save_writethrough $p
19872         set_cache writethrough on
19873
19874         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19875         local at_max=$($LCTL get_param -n at_max)
19876         local timeout=$($LCTL get_param -n timeout)
19877         local test_at="at_max"
19878         local param_at="$FSNAME.sys.at_max"
19879         local test_timeout="timeout"
19880         local param_timeout="$FSNAME.sys.timeout"
19881
19882         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19883
19884         set_persistent_param_and_check client "$test_at" "$param_at" 0
19885         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19886
19887         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19888         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19889         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19890         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19891         sync
19892         do_facet ost1 "$LCTL set_param fail_loc=0"
19893
19894         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19895         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19896                 $timeout
19897
19898         $LCTL set_param -n $pages_per_rpc
19899         restore_lustre_params < $p
19900         rm -f $p
19901 }
19902 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19903
19904 test_224d() { # LU-11169
19905         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19906 }
19907 run_test 224d "Don't corrupt data on bulk IO timeout"
19908
19909 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19910 test_225a () {
19911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19912         if [ -z ${MDSSURVEY} ]; then
19913                 skip_env "mds-survey not found"
19914         fi
19915         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19916                 skip "Need MDS version at least 2.2.51"
19917
19918         local mds=$(facet_host $SINGLEMDS)
19919         local target=$(do_nodes $mds 'lctl dl' |
19920                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19921
19922         local cmd1="file_count=1000 thrhi=4"
19923         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19924         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19925         local cmd="$cmd1 $cmd2 $cmd3"
19926
19927         rm -f ${TMP}/mds_survey*
19928         echo + $cmd
19929         eval $cmd || error "mds-survey with zero-stripe failed"
19930         cat ${TMP}/mds_survey*
19931         rm -f ${TMP}/mds_survey*
19932 }
19933 run_test 225a "Metadata survey sanity with zero-stripe"
19934
19935 test_225b () {
19936         if [ -z ${MDSSURVEY} ]; then
19937                 skip_env "mds-survey not found"
19938         fi
19939         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19940                 skip "Need MDS version at least 2.2.51"
19941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19942         remote_mds_nodsh && skip "remote MDS with nodsh"
19943         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19944                 skip_env "Need to mount OST to test"
19945         fi
19946
19947         local mds=$(facet_host $SINGLEMDS)
19948         local target=$(do_nodes $mds 'lctl dl' |
19949                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19950
19951         local cmd1="file_count=1000 thrhi=4"
19952         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19953         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19954         local cmd="$cmd1 $cmd2 $cmd3"
19955
19956         rm -f ${TMP}/mds_survey*
19957         echo + $cmd
19958         eval $cmd || error "mds-survey with stripe_count failed"
19959         cat ${TMP}/mds_survey*
19960         rm -f ${TMP}/mds_survey*
19961 }
19962 run_test 225b "Metadata survey sanity with stripe_count = 1"
19963
19964 mcreate_path2fid () {
19965         local mode=$1
19966         local major=$2
19967         local minor=$3
19968         local name=$4
19969         local desc=$5
19970         local path=$DIR/$tdir/$name
19971         local fid
19972         local rc
19973         local fid_path
19974
19975         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19976                 error "cannot create $desc"
19977
19978         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19979         rc=$?
19980         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19981
19982         fid_path=$($LFS fid2path $MOUNT $fid)
19983         rc=$?
19984         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19985
19986         [ "$path" == "$fid_path" ] ||
19987                 error "fid2path returned $fid_path, expected $path"
19988
19989         echo "pass with $path and $fid"
19990 }
19991
19992 test_226a () {
19993         rm -rf $DIR/$tdir
19994         mkdir -p $DIR/$tdir
19995
19996         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19997         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19998         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19999         mcreate_path2fid 0040666 0 0 dir "directory"
20000         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20001         mcreate_path2fid 0100666 0 0 file "regular file"
20002         mcreate_path2fid 0120666 0 0 link "symbolic link"
20003         mcreate_path2fid 0140666 0 0 sock "socket"
20004 }
20005 run_test 226a "call path2fid and fid2path on files of all type"
20006
20007 test_226b () {
20008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20009
20010         local MDTIDX=1
20011
20012         rm -rf $DIR/$tdir
20013         mkdir -p $DIR/$tdir
20014         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20015                 error "create remote directory failed"
20016         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20017         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20018                                 "character special file (null)"
20019         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20020                                 "character special file (no device)"
20021         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20022         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20023                                 "block special file (loop)"
20024         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20025         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20026         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20027 }
20028 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20029
20030 test_226c () {
20031         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20032         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20033                 skip "Need MDS version at least 2.13.55"
20034
20035         local submnt=/mnt/submnt
20036         local srcfile=/etc/passwd
20037         local dstfile=$submnt/passwd
20038         local path
20039         local fid
20040
20041         rm -rf $DIR/$tdir
20042         rm -rf $submnt
20043         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20044                 error "create remote directory failed"
20045         mkdir -p $submnt || error "create $submnt failed"
20046         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20047                 error "mount $submnt failed"
20048         stack_trap "umount $submnt" EXIT
20049
20050         cp $srcfile $dstfile
20051         fid=$($LFS path2fid $dstfile)
20052         path=$($LFS fid2path $submnt "$fid")
20053         [ "$path" = "$dstfile" ] ||
20054                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20055 }
20056 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20057
20058 # LU-1299 Executing or running ldd on a truncated executable does not
20059 # cause an out-of-memory condition.
20060 test_227() {
20061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20062         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20063
20064         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20065         chmod +x $MOUNT/date
20066
20067         $MOUNT/date > /dev/null
20068         ldd $MOUNT/date > /dev/null
20069         rm -f $MOUNT/date
20070 }
20071 run_test 227 "running truncated executable does not cause OOM"
20072
20073 # LU-1512 try to reuse idle OI blocks
20074 test_228a() {
20075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20076         remote_mds_nodsh && skip "remote MDS with nodsh"
20077         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20078
20079         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20080         local myDIR=$DIR/$tdir
20081
20082         mkdir -p $myDIR
20083         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20084         $LCTL set_param fail_loc=0x80001002
20085         createmany -o $myDIR/t- 10000
20086         $LCTL set_param fail_loc=0
20087         # The guard is current the largest FID holder
20088         touch $myDIR/guard
20089         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20090                     tr -d '[')
20091         local IDX=$(($SEQ % 64))
20092
20093         do_facet $SINGLEMDS sync
20094         # Make sure journal flushed.
20095         sleep 6
20096         local blk1=$(do_facet $SINGLEMDS \
20097                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20098                      grep Blockcount | awk '{print $4}')
20099
20100         # Remove old files, some OI blocks will become idle.
20101         unlinkmany $myDIR/t- 10000
20102         # Create new files, idle OI blocks should be reused.
20103         createmany -o $myDIR/t- 2000
20104         do_facet $SINGLEMDS sync
20105         # Make sure journal flushed.
20106         sleep 6
20107         local blk2=$(do_facet $SINGLEMDS \
20108                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20109                      grep Blockcount | awk '{print $4}')
20110
20111         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20112 }
20113 run_test 228a "try to reuse idle OI blocks"
20114
20115 test_228b() {
20116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20117         remote_mds_nodsh && skip "remote MDS with nodsh"
20118         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20119
20120         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20121         local myDIR=$DIR/$tdir
20122
20123         mkdir -p $myDIR
20124         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20125         $LCTL set_param fail_loc=0x80001002
20126         createmany -o $myDIR/t- 10000
20127         $LCTL set_param fail_loc=0
20128         # The guard is current the largest FID holder
20129         touch $myDIR/guard
20130         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20131                     tr -d '[')
20132         local IDX=$(($SEQ % 64))
20133
20134         do_facet $SINGLEMDS sync
20135         # Make sure journal flushed.
20136         sleep 6
20137         local blk1=$(do_facet $SINGLEMDS \
20138                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20139                      grep Blockcount | awk '{print $4}')
20140
20141         # Remove old files, some OI blocks will become idle.
20142         unlinkmany $myDIR/t- 10000
20143
20144         # stop the MDT
20145         stop $SINGLEMDS || error "Fail to stop MDT."
20146         # remount the MDT
20147         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20148                 error "Fail to start MDT."
20149
20150         client_up || error "Fail to df."
20151         # Create new files, idle OI blocks should be reused.
20152         createmany -o $myDIR/t- 2000
20153         do_facet $SINGLEMDS sync
20154         # Make sure journal flushed.
20155         sleep 6
20156         local blk2=$(do_facet $SINGLEMDS \
20157                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20158                      grep Blockcount | awk '{print $4}')
20159
20160         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20161 }
20162 run_test 228b "idle OI blocks can be reused after MDT restart"
20163
20164 #LU-1881
20165 test_228c() {
20166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20167         remote_mds_nodsh && skip "remote MDS with nodsh"
20168         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20169
20170         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20171         local myDIR=$DIR/$tdir
20172
20173         mkdir -p $myDIR
20174         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20175         $LCTL set_param fail_loc=0x80001002
20176         # 20000 files can guarantee there are index nodes in the OI file
20177         createmany -o $myDIR/t- 20000
20178         $LCTL set_param fail_loc=0
20179         # The guard is current the largest FID holder
20180         touch $myDIR/guard
20181         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20182                     tr -d '[')
20183         local IDX=$(($SEQ % 64))
20184
20185         do_facet $SINGLEMDS sync
20186         # Make sure journal flushed.
20187         sleep 6
20188         local blk1=$(do_facet $SINGLEMDS \
20189                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20190                      grep Blockcount | awk '{print $4}')
20191
20192         # Remove old files, some OI blocks will become idle.
20193         unlinkmany $myDIR/t- 20000
20194         rm -f $myDIR/guard
20195         # The OI file should become empty now
20196
20197         # Create new files, idle OI blocks should be reused.
20198         createmany -o $myDIR/t- 2000
20199         do_facet $SINGLEMDS sync
20200         # Make sure journal flushed.
20201         sleep 6
20202         local blk2=$(do_facet $SINGLEMDS \
20203                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20204                      grep Blockcount | awk '{print $4}')
20205
20206         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20207 }
20208 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20209
20210 test_229() { # LU-2482, LU-3448
20211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20212         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20213         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20214                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20215
20216         rm -f $DIR/$tfile
20217
20218         # Create a file with a released layout and stripe count 2.
20219         $MULTIOP $DIR/$tfile H2c ||
20220                 error "failed to create file with released layout"
20221
20222         $LFS getstripe -v $DIR/$tfile
20223
20224         local pattern=$($LFS getstripe -L $DIR/$tfile)
20225         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20226
20227         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20228                 error "getstripe"
20229         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20230         stat $DIR/$tfile || error "failed to stat released file"
20231
20232         chown $RUNAS_ID $DIR/$tfile ||
20233                 error "chown $RUNAS_ID $DIR/$tfile failed"
20234
20235         chgrp $RUNAS_ID $DIR/$tfile ||
20236                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20237
20238         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20239         rm $DIR/$tfile || error "failed to remove released file"
20240 }
20241 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20242
20243 test_230a() {
20244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20245         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20246         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20247                 skip "Need MDS version at least 2.11.52"
20248
20249         local MDTIDX=1
20250
20251         test_mkdir $DIR/$tdir
20252         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20253         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20254         [ $mdt_idx -ne 0 ] &&
20255                 error "create local directory on wrong MDT $mdt_idx"
20256
20257         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20258                         error "create remote directory failed"
20259         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20260         [ $mdt_idx -ne $MDTIDX ] &&
20261                 error "create remote directory on wrong MDT $mdt_idx"
20262
20263         createmany -o $DIR/$tdir/test_230/t- 10 ||
20264                 error "create files on remote directory failed"
20265         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20266         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20267         rm -r $DIR/$tdir || error "unlink remote directory failed"
20268 }
20269 run_test 230a "Create remote directory and files under the remote directory"
20270
20271 test_230b() {
20272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20274         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20275                 skip "Need MDS version at least 2.11.52"
20276
20277         local MDTIDX=1
20278         local mdt_index
20279         local i
20280         local file
20281         local pid
20282         local stripe_count
20283         local migrate_dir=$DIR/$tdir/migrate_dir
20284         local other_dir=$DIR/$tdir/other_dir
20285
20286         test_mkdir $DIR/$tdir
20287         test_mkdir -i0 -c1 $migrate_dir
20288         test_mkdir -i0 -c1 $other_dir
20289         for ((i=0; i<10; i++)); do
20290                 mkdir -p $migrate_dir/dir_${i}
20291                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20292                         error "create files under remote dir failed $i"
20293         done
20294
20295         cp /etc/passwd $migrate_dir/$tfile
20296         cp /etc/passwd $other_dir/$tfile
20297         chattr +SAD $migrate_dir
20298         chattr +SAD $migrate_dir/$tfile
20299
20300         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20301         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20302         local old_dir_mode=$(stat -c%f $migrate_dir)
20303         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20304
20305         mkdir -p $migrate_dir/dir_default_stripe2
20306         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20307         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20308
20309         mkdir -p $other_dir
20310         ln $migrate_dir/$tfile $other_dir/luna
20311         ln $migrate_dir/$tfile $migrate_dir/sofia
20312         ln $other_dir/$tfile $migrate_dir/david
20313         ln -s $migrate_dir/$tfile $other_dir/zachary
20314         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20315         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20316
20317         local len
20318         local lnktgt
20319
20320         # inline symlink
20321         for len in 58 59 60; do
20322                 lnktgt=$(str_repeat 'l' $len)
20323                 touch $migrate_dir/$lnktgt
20324                 ln -s $lnktgt $migrate_dir/${len}char_ln
20325         done
20326
20327         # PATH_MAX
20328         for len in 4094 4095; do
20329                 lnktgt=$(str_repeat 'l' $len)
20330                 ln -s $lnktgt $migrate_dir/${len}char_ln
20331         done
20332
20333         # NAME_MAX
20334         for len in 254 255; do
20335                 touch $migrate_dir/$(str_repeat 'l' $len)
20336         done
20337
20338         $LFS migrate -m $MDTIDX $migrate_dir ||
20339                 error "fails on migrating remote dir to MDT1"
20340
20341         echo "migratate to MDT1, then checking.."
20342         for ((i = 0; i < 10; i++)); do
20343                 for file in $(find $migrate_dir/dir_${i}); do
20344                         mdt_index=$($LFS getstripe -m $file)
20345                         # broken symlink getstripe will fail
20346                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20347                                 error "$file is not on MDT${MDTIDX}"
20348                 done
20349         done
20350
20351         # the multiple link file should still in MDT0
20352         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20353         [ $mdt_index == 0 ] ||
20354                 error "$file is not on MDT${MDTIDX}"
20355
20356         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20357         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20358                 error " expect $old_dir_flag get $new_dir_flag"
20359
20360         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20361         [ "$old_file_flag" = "$new_file_flag" ] ||
20362                 error " expect $old_file_flag get $new_file_flag"
20363
20364         local new_dir_mode=$(stat -c%f $migrate_dir)
20365         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20366                 error "expect mode $old_dir_mode get $new_dir_mode"
20367
20368         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20369         [ "$old_file_mode" = "$new_file_mode" ] ||
20370                 error "expect mode $old_file_mode get $new_file_mode"
20371
20372         diff /etc/passwd $migrate_dir/$tfile ||
20373                 error "$tfile different after migration"
20374
20375         diff /etc/passwd $other_dir/luna ||
20376                 error "luna different after migration"
20377
20378         diff /etc/passwd $migrate_dir/sofia ||
20379                 error "sofia different after migration"
20380
20381         diff /etc/passwd $migrate_dir/david ||
20382                 error "david different after migration"
20383
20384         diff /etc/passwd $other_dir/zachary ||
20385                 error "zachary different after migration"
20386
20387         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20388                 error "${tfile}_ln different after migration"
20389
20390         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20391                 error "${tfile}_ln_other different after migration"
20392
20393         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20394         [ $stripe_count = 2 ] ||
20395                 error "dir strpe_count $d != 2 after migration."
20396
20397         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20398         [ $stripe_count = 2 ] ||
20399                 error "file strpe_count $d != 2 after migration."
20400
20401         #migrate back to MDT0
20402         MDTIDX=0
20403
20404         $LFS migrate -m $MDTIDX $migrate_dir ||
20405                 error "fails on migrating remote dir to MDT0"
20406
20407         echo "migrate back to MDT0, checking.."
20408         for file in $(find $migrate_dir); do
20409                 mdt_index=$($LFS getstripe -m $file)
20410                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20411                         error "$file is not on MDT${MDTIDX}"
20412         done
20413
20414         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20415         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20416                 error " expect $old_dir_flag get $new_dir_flag"
20417
20418         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20419         [ "$old_file_flag" = "$new_file_flag" ] ||
20420                 error " expect $old_file_flag get $new_file_flag"
20421
20422         local new_dir_mode=$(stat -c%f $migrate_dir)
20423         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20424                 error "expect mode $old_dir_mode get $new_dir_mode"
20425
20426         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20427         [ "$old_file_mode" = "$new_file_mode" ] ||
20428                 error "expect mode $old_file_mode get $new_file_mode"
20429
20430         diff /etc/passwd ${migrate_dir}/$tfile ||
20431                 error "$tfile different after migration"
20432
20433         diff /etc/passwd ${other_dir}/luna ||
20434                 error "luna different after migration"
20435
20436         diff /etc/passwd ${migrate_dir}/sofia ||
20437                 error "sofia different after migration"
20438
20439         diff /etc/passwd ${other_dir}/zachary ||
20440                 error "zachary different after migration"
20441
20442         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20443                 error "${tfile}_ln different after migration"
20444
20445         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20446                 error "${tfile}_ln_other different after migration"
20447
20448         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20449         [ $stripe_count = 2 ] ||
20450                 error "dir strpe_count $d != 2 after migration."
20451
20452         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20453         [ $stripe_count = 2 ] ||
20454                 error "file strpe_count $d != 2 after migration."
20455
20456         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20457 }
20458 run_test 230b "migrate directory"
20459
20460 test_230c() {
20461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20462         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20463         remote_mds_nodsh && skip "remote MDS with nodsh"
20464         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20465                 skip "Need MDS version at least 2.11.52"
20466
20467         local MDTIDX=1
20468         local total=3
20469         local mdt_index
20470         local file
20471         local migrate_dir=$DIR/$tdir/migrate_dir
20472
20473         #If migrating directory fails in the middle, all entries of
20474         #the directory is still accessiable.
20475         test_mkdir $DIR/$tdir
20476         test_mkdir -i0 -c1 $migrate_dir
20477         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20478         stat $migrate_dir
20479         createmany -o $migrate_dir/f $total ||
20480                 error "create files under ${migrate_dir} failed"
20481
20482         # fail after migrating top dir, and this will fail only once, so the
20483         # first sub file migration will fail (currently f3), others succeed.
20484         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20485         do_facet mds1 lctl set_param fail_loc=0x1801
20486         local t=$(ls $migrate_dir | wc -l)
20487         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20488                 error "migrate should fail"
20489         local u=$(ls $migrate_dir | wc -l)
20490         [ "$u" == "$t" ] || error "$u != $t during migration"
20491
20492         # add new dir/file should succeed
20493         mkdir $migrate_dir/dir ||
20494                 error "mkdir failed under migrating directory"
20495         touch $migrate_dir/file ||
20496                 error "create file failed under migrating directory"
20497
20498         # add file with existing name should fail
20499         for file in $migrate_dir/f*; do
20500                 stat $file > /dev/null || error "stat $file failed"
20501                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20502                         error "open(O_CREAT|O_EXCL) $file should fail"
20503                 $MULTIOP $file m && error "create $file should fail"
20504                 touch $DIR/$tdir/remote_dir/$tfile ||
20505                         error "touch $tfile failed"
20506                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20507                         error "link $file should fail"
20508                 mdt_index=$($LFS getstripe -m $file)
20509                 if [ $mdt_index == 0 ]; then
20510                         # file failed to migrate is not allowed to rename to
20511                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20512                                 error "rename to $file should fail"
20513                 else
20514                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20515                                 error "rename to $file failed"
20516                 fi
20517                 echo hello >> $file || error "write $file failed"
20518         done
20519
20520         # resume migration with different options should fail
20521         $LFS migrate -m 0 $migrate_dir &&
20522                 error "migrate -m 0 $migrate_dir should fail"
20523
20524         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20525                 error "migrate -c 2 $migrate_dir should fail"
20526
20527         # resume migration should succeed
20528         $LFS migrate -m $MDTIDX $migrate_dir ||
20529                 error "migrate $migrate_dir failed"
20530
20531         echo "Finish migration, then checking.."
20532         for file in $(find $migrate_dir); do
20533                 mdt_index=$($LFS getstripe -m $file)
20534                 [ $mdt_index == $MDTIDX ] ||
20535                         error "$file is not on MDT${MDTIDX}"
20536         done
20537
20538         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20539 }
20540 run_test 230c "check directory accessiblity if migration failed"
20541
20542 test_230d() {
20543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20545         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20546                 skip "Need MDS version at least 2.11.52"
20547         # LU-11235
20548         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20549
20550         local migrate_dir=$DIR/$tdir/migrate_dir
20551         local old_index
20552         local new_index
20553         local old_count
20554         local new_count
20555         local new_hash
20556         local mdt_index
20557         local i
20558         local j
20559
20560         old_index=$((RANDOM % MDSCOUNT))
20561         old_count=$((MDSCOUNT - old_index))
20562         new_index=$((RANDOM % MDSCOUNT))
20563         new_count=$((MDSCOUNT - new_index))
20564         new_hash=1 # for all_char
20565
20566         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20567         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20568
20569         test_mkdir $DIR/$tdir
20570         test_mkdir -i $old_index -c $old_count $migrate_dir
20571
20572         for ((i=0; i<100; i++)); do
20573                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20574                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20575                         error "create files under remote dir failed $i"
20576         done
20577
20578         echo -n "Migrate from MDT$old_index "
20579         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20580         echo -n "to MDT$new_index"
20581         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20582         echo
20583
20584         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20585         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20586                 error "migrate remote dir error"
20587
20588         echo "Finish migration, then checking.."
20589         for file in $(find $migrate_dir -maxdepth 1); do
20590                 mdt_index=$($LFS getstripe -m $file)
20591                 if [ $mdt_index -lt $new_index ] ||
20592                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20593                         error "$file is on MDT$mdt_index"
20594                 fi
20595         done
20596
20597         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20598 }
20599 run_test 230d "check migrate big directory"
20600
20601 test_230e() {
20602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20603         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20604         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20605                 skip "Need MDS version at least 2.11.52"
20606
20607         local i
20608         local j
20609         local a_fid
20610         local b_fid
20611
20612         mkdir_on_mdt0 $DIR/$tdir
20613         mkdir $DIR/$tdir/migrate_dir
20614         mkdir $DIR/$tdir/other_dir
20615         touch $DIR/$tdir/migrate_dir/a
20616         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20617         ls $DIR/$tdir/other_dir
20618
20619         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20620                 error "migrate dir fails"
20621
20622         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20623         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20624
20625         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20626         [ $mdt_index == 0 ] || error "a is not on MDT0"
20627
20628         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20629                 error "migrate dir fails"
20630
20631         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20632         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20633
20634         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20635         [ $mdt_index == 1 ] || error "a is not on MDT1"
20636
20637         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20638         [ $mdt_index == 1 ] || error "b is not on MDT1"
20639
20640         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20641         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20642
20643         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20644
20645         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20646 }
20647 run_test 230e "migrate mulitple local link files"
20648
20649 test_230f() {
20650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20652         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20653                 skip "Need MDS version at least 2.11.52"
20654
20655         local a_fid
20656         local ln_fid
20657
20658         mkdir -p $DIR/$tdir
20659         mkdir $DIR/$tdir/migrate_dir
20660         $LFS mkdir -i1 $DIR/$tdir/other_dir
20661         touch $DIR/$tdir/migrate_dir/a
20662         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20663         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20664         ls $DIR/$tdir/other_dir
20665
20666         # a should be migrated to MDT1, since no other links on MDT0
20667         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20668                 error "#1 migrate dir fails"
20669         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20670         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20671         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20672         [ $mdt_index == 1 ] || error "a is not on MDT1"
20673
20674         # a should stay on MDT1, because it is a mulitple link file
20675         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20676                 error "#2 migrate dir fails"
20677         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20678         [ $mdt_index == 1 ] || error "a is not on MDT1"
20679
20680         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20681                 error "#3 migrate dir fails"
20682
20683         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20684         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20685         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20686
20687         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20688         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20689
20690         # a should be migrated to MDT0, since no other links on MDT1
20691         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20692                 error "#4 migrate dir fails"
20693         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20694         [ $mdt_index == 0 ] || error "a is not on MDT0"
20695
20696         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20697 }
20698 run_test 230f "migrate mulitple remote link files"
20699
20700 test_230g() {
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         mkdir -p $DIR/$tdir/migrate_dir
20707
20708         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20709                 error "migrating dir to non-exist MDT succeeds"
20710         true
20711 }
20712 run_test 230g "migrate dir to non-exist MDT"
20713
20714 test_230h() {
20715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20716         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20717         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20718                 skip "Need MDS version at least 2.11.52"
20719
20720         local mdt_index
20721
20722         mkdir -p $DIR/$tdir/migrate_dir
20723
20724         $LFS migrate -m1 $DIR &&
20725                 error "migrating mountpoint1 should fail"
20726
20727         $LFS migrate -m1 $DIR/$tdir/.. &&
20728                 error "migrating mountpoint2 should fail"
20729
20730         # same as mv
20731         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20732                 error "migrating $tdir/migrate_dir/.. should fail"
20733
20734         true
20735 }
20736 run_test 230h "migrate .. and root"
20737
20738 test_230i() {
20739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20741         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20742                 skip "Need MDS version at least 2.11.52"
20743
20744         mkdir -p $DIR/$tdir/migrate_dir
20745
20746         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20747                 error "migration fails with a tailing slash"
20748
20749         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20750                 error "migration fails with two tailing slashes"
20751 }
20752 run_test 230i "lfs migrate -m tolerates trailing slashes"
20753
20754 test_230j() {
20755         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20756         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20757                 skip "Need MDS version at least 2.11.52"
20758
20759         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20760         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20761                 error "create $tfile failed"
20762         cat /etc/passwd > $DIR/$tdir/$tfile
20763
20764         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20765
20766         cmp /etc/passwd $DIR/$tdir/$tfile ||
20767                 error "DoM file mismatch after migration"
20768 }
20769 run_test 230j "DoM file data not changed after dir migration"
20770
20771 test_230k() {
20772         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20773         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20774                 skip "Need MDS version at least 2.11.56"
20775
20776         local total=20
20777         local files_on_starting_mdt=0
20778
20779         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20780         $LFS getdirstripe $DIR/$tdir
20781         for i in $(seq $total); do
20782                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20783                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20784                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20785         done
20786
20787         echo "$files_on_starting_mdt files on MDT0"
20788
20789         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 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 migration"
20796                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20797                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20798         done
20799
20800         echo "$files_on_starting_mdt files on MDT1 after migration"
20801         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20802
20803         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20804         $LFS getdirstripe $DIR/$tdir
20805
20806         files_on_starting_mdt=0
20807         for i in $(seq $total); do
20808                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20809                         error "file $tfile.$i mismatch after 2nd migration"
20810                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20811                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20812         done
20813
20814         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20815         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20816
20817         true
20818 }
20819 run_test 230k "file data not changed after dir migration"
20820
20821 test_230l() {
20822         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20823         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20824                 skip "Need MDS version at least 2.11.56"
20825
20826         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20827         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20828                 error "create files under remote dir failed $i"
20829         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20830 }
20831 run_test 230l "readdir between MDTs won't crash"
20832
20833 test_230m() {
20834         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20835         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20836                 skip "Need MDS version at least 2.11.56"
20837
20838         local MDTIDX=1
20839         local mig_dir=$DIR/$tdir/migrate_dir
20840         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20841         local shortstr="b"
20842         local val
20843
20844         echo "Creating files and dirs with xattrs"
20845         test_mkdir $DIR/$tdir
20846         test_mkdir -i0 -c1 $mig_dir
20847         mkdir $mig_dir/dir
20848         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20849                 error "cannot set xattr attr1 on dir"
20850         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20851                 error "cannot set xattr attr2 on dir"
20852         touch $mig_dir/dir/f0
20853         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20854                 error "cannot set xattr attr1 on file"
20855         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20856                 error "cannot set xattr attr2 on file"
20857         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20858         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20859         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20860         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20861         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20862         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20863         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20864         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20865         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20866
20867         echo "Migrating to MDT1"
20868         $LFS migrate -m $MDTIDX $mig_dir ||
20869                 error "fails on migrating dir to MDT1"
20870
20871         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20872         echo "Checking xattrs"
20873         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20874         [ "$val" = $longstr ] ||
20875                 error "expecting xattr1 $longstr on dir, found $val"
20876         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20877         [ "$val" = $shortstr ] ||
20878                 error "expecting xattr2 $shortstr on dir, found $val"
20879         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20880         [ "$val" = $longstr ] ||
20881                 error "expecting xattr1 $longstr on file, found $val"
20882         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20883         [ "$val" = $shortstr ] ||
20884                 error "expecting xattr2 $shortstr on file, found $val"
20885 }
20886 run_test 230m "xattrs not changed after dir migration"
20887
20888 test_230n() {
20889         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20890         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20891                 skip "Need MDS version at least 2.13.53"
20892
20893         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20894         cat /etc/hosts > $DIR/$tdir/$tfile
20895         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20896         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20897
20898         cmp /etc/hosts $DIR/$tdir/$tfile ||
20899                 error "File data mismatch after migration"
20900 }
20901 run_test 230n "Dir migration with mirrored file"
20902
20903 test_230o() {
20904         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20905         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20906                 skip "Need MDS version at least 2.13.52"
20907
20908         local mdts=$(comma_list $(mdts_nodes))
20909         local timeout=100
20910         local restripe_status
20911         local delta
20912         local i
20913
20914         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20915
20916         # in case "crush" hash type is not set
20917         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20918
20919         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20920                            mdt.*MDT0000.enable_dir_restripe)
20921         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20922         stack_trap "do_nodes $mdts $LCTL set_param \
20923                     mdt.*.enable_dir_restripe=$restripe_status"
20924
20925         mkdir $DIR/$tdir
20926         createmany -m $DIR/$tdir/f 100 ||
20927                 error "create files under remote dir failed $i"
20928         createmany -d $DIR/$tdir/d 100 ||
20929                 error "create dirs under remote dir failed $i"
20930
20931         for i in $(seq 2 $MDSCOUNT); do
20932                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20933                 $LFS setdirstripe -c $i $DIR/$tdir ||
20934                         error "split -c $i $tdir failed"
20935                 wait_update $HOSTNAME \
20936                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20937                         error "dir split not finished"
20938                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20939                         awk '/migrate/ {sum += $2} END { print sum }')
20940                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20941                 # delta is around total_files/stripe_count
20942                 (( $delta < 200 / (i - 1) + 4 )) ||
20943                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20944         done
20945 }
20946 run_test 230o "dir split"
20947
20948 test_230p() {
20949         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20950         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20951                 skip "Need MDS version at least 2.13.52"
20952
20953         local mdts=$(comma_list $(mdts_nodes))
20954         local timeout=100
20955         local restripe_status
20956         local delta
20957         local c
20958
20959         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20960
20961         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20962
20963         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20964                            mdt.*MDT0000.enable_dir_restripe)
20965         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20966         stack_trap "do_nodes $mdts $LCTL set_param \
20967                     mdt.*.enable_dir_restripe=$restripe_status"
20968
20969         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20970         createmany -m $DIR/$tdir/f 100 ||
20971                 error "create files under remote dir failed"
20972         createmany -d $DIR/$tdir/d 100 ||
20973                 error "create dirs under remote dir failed"
20974
20975         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20976                 local mdt_hash="crush"
20977
20978                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20979                 $LFS setdirstripe -c $c $DIR/$tdir ||
20980                         error "split -c $c $tdir failed"
20981                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20982                         mdt_hash="$mdt_hash,fixed"
20983                 elif [ $c -eq 1 ]; then
20984                         mdt_hash="none"
20985                 fi
20986                 wait_update $HOSTNAME \
20987                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20988                         error "dir merge not finished"
20989                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20990                         awk '/migrate/ {sum += $2} END { print sum }')
20991                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20992                 # delta is around total_files/stripe_count
20993                 (( delta < 200 / c + 4 )) ||
20994                         error "$delta files migrated >= $((200 / c + 4))"
20995         done
20996 }
20997 run_test 230p "dir merge"
20998
20999 test_230q() {
21000         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21001         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21002                 skip "Need MDS version at least 2.13.52"
21003
21004         local mdts=$(comma_list $(mdts_nodes))
21005         local saved_threshold=$(do_facet mds1 \
21006                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21007         local saved_delta=$(do_facet mds1 \
21008                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21009         local threshold=100
21010         local delta=2
21011         local total=0
21012         local stripe_count=0
21013         local stripe_index
21014         local nr_files
21015         local create
21016
21017         # test with fewer files on ZFS
21018         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21019
21020         stack_trap "do_nodes $mdts $LCTL set_param \
21021                     mdt.*.dir_split_count=$saved_threshold"
21022         stack_trap "do_nodes $mdts $LCTL set_param \
21023                     mdt.*.dir_split_delta=$saved_delta"
21024         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21025         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21026         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21027         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21028         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21029         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21030
21031         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21032         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21033
21034         create=$((threshold * 3 / 2))
21035         while [ $stripe_count -lt $MDSCOUNT ]; do
21036                 createmany -m $DIR/$tdir/f $total $create ||
21037                         error "create sub files failed"
21038                 stat $DIR/$tdir > /dev/null
21039                 total=$((total + create))
21040                 stripe_count=$((stripe_count + delta))
21041                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21042
21043                 wait_update $HOSTNAME \
21044                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21045                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21046
21047                 wait_update $HOSTNAME \
21048                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21049                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21050
21051                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21052                 echo "$nr_files/$total files on MDT$stripe_index after split"
21053                 # allow 10% margin of imbalance with crush hash
21054                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21055                         error "$nr_files files on MDT$stripe_index after split"
21056
21057                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21058                 [ $nr_files -eq $total ] ||
21059                         error "total sub files $nr_files != $total"
21060         done
21061
21062         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21063
21064         echo "fixed layout directory won't auto split"
21065         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21066         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21067                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21068         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21069                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21070 }
21071 run_test 230q "dir auto split"
21072
21073 test_230r() {
21074         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21075         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21076         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21077                 skip "Need MDS version at least 2.13.54"
21078
21079         # maximum amount of local locks:
21080         # parent striped dir - 2 locks
21081         # new stripe in parent to migrate to - 1 lock
21082         # source and target - 2 locks
21083         # Total 5 locks for regular file
21084         mkdir -p $DIR/$tdir
21085         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21086         touch $DIR/$tdir/dir1/eee
21087
21088         # create 4 hardlink for 4 more locks
21089         # Total: 9 locks > RS_MAX_LOCKS (8)
21090         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21091         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21092         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21093         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21094         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21095         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21096         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21097         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21098
21099         cancel_lru_locks mdc
21100
21101         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21102                 error "migrate dir fails"
21103
21104         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21105 }
21106 run_test 230r "migrate with too many local locks"
21107
21108 test_230s() {
21109         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21110                 skip "Need MDS version at least 2.14.52"
21111
21112         local mdts=$(comma_list $(mdts_nodes))
21113         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21114                                 mdt.*MDT0000.enable_dir_restripe)
21115
21116         stack_trap "do_nodes $mdts $LCTL set_param \
21117                     mdt.*.enable_dir_restripe=$restripe_status"
21118
21119         local st
21120         for st in 0 1; do
21121                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21122                 test_mkdir $DIR/$tdir
21123                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21124                         error "$LFS mkdir should return EEXIST if target exists"
21125                 rmdir $DIR/$tdir
21126         done
21127 }
21128 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21129
21130 test_230t()
21131 {
21132         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21133         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21134                 skip "Need MDS version at least 2.14.50"
21135
21136         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21137         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21138         $LFS project -p 1 -s $DIR/$tdir ||
21139                 error "set $tdir project id failed"
21140         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21141                 error "set subdir project id failed"
21142         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21143 }
21144 run_test 230t "migrate directory with project ID set"
21145
21146 test_230u()
21147 {
21148         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21149         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21150                 skip "Need MDS version at least 2.14.53"
21151
21152         local count
21153
21154         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21155         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21156         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21157         for i in $(seq 0 $((MDSCOUNT - 1))); do
21158                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21159                 echo "$count dirs migrated to MDT$i"
21160         done
21161         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21162         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21163 }
21164 run_test 230u "migrate directory by QOS"
21165
21166 test_230v()
21167 {
21168         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21169         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21170                 skip "Need MDS version at least 2.14.53"
21171
21172         local count
21173
21174         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21175         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21176         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21177         for i in $(seq 0 $((MDSCOUNT - 1))); do
21178                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21179                 echo "$count subdirs migrated to MDT$i"
21180                 (( i == 3 )) && (( count > 0 )) &&
21181                         error "subdir shouldn't be migrated to MDT3"
21182         done
21183         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21184         (( count == 3 )) || error "dirs migrated to $count MDTs"
21185 }
21186 run_test 230v "subdir migrated to the MDT where its parent is located"
21187
21188 test_230w() {
21189         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21190         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21191                 skip "Need MDS version at least 2.15.0"
21192
21193         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21194         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21195         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21196
21197         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21198                 error "migrate failed"
21199
21200         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21201                 error "$tdir stripe count mismatch"
21202
21203         for i in $(seq 0 9); do
21204                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21205                         error "d$i is striped"
21206         done
21207 }
21208 run_test 230w "non-recursive mode dir migration"
21209
21210 test_230x() {
21211         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21212         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21213                 skip "Need MDS version at least 2.15.0"
21214
21215         mkdir -p $DIR/$tdir || error "mkdir failed"
21216         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21217
21218         local mdt_name=$(mdtname_from_index 0)
21219         local low=$(do_facet mds2 $LCTL get_param -n \
21220                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21221         local high=$(do_facet mds2 $LCTL get_param -n \
21222                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21223         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21224         local maxage=$(do_facet mds2 $LCTL get_param -n \
21225                 osp.*$mdt_name-osp-MDT0001.maxage)
21226
21227         stack_trap "do_facet mds2 $LCTL set_param -n \
21228                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21229                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21230         stack_trap "do_facet mds2 $LCTL set_param -n \
21231                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21232
21233         do_facet mds2 $LCTL set_param -n \
21234                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21235         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21236         sleep 4
21237         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21238                 error "migrate $tdir should fail"
21239
21240         do_facet mds2 $LCTL set_param -n \
21241                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21242         do_facet mds2 $LCTL set_param -n \
21243                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21244         sleep 4
21245         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21246                 error "migrate failed"
21247         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21248                 error "$tdir stripe count mismatch"
21249 }
21250 run_test 230x "dir migration check space"
21251
21252 test_231a()
21253 {
21254         # For simplicity this test assumes that max_pages_per_rpc
21255         # is the same across all OSCs
21256         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21257         local bulk_size=$((max_pages * PAGE_SIZE))
21258         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21259                                        head -n 1)
21260
21261         mkdir -p $DIR/$tdir
21262         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21263                 error "failed to set stripe with -S ${brw_size}M option"
21264
21265         # clear the OSC stats
21266         $LCTL set_param osc.*.stats=0 &>/dev/null
21267         stop_writeback
21268
21269         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21270         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21271                 oflag=direct &>/dev/null || error "dd failed"
21272
21273         sync; sleep 1; sync # just to be safe
21274         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21275         if [ x$nrpcs != "x1" ]; then
21276                 $LCTL get_param osc.*.stats
21277                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21278         fi
21279
21280         start_writeback
21281         # Drop the OSC cache, otherwise we will read from it
21282         cancel_lru_locks osc
21283
21284         # clear the OSC stats
21285         $LCTL set_param osc.*.stats=0 &>/dev/null
21286
21287         # Client reads $bulk_size.
21288         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21289                 iflag=direct &>/dev/null || error "dd failed"
21290
21291         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21292         if [ x$nrpcs != "x1" ]; then
21293                 $LCTL get_param osc.*.stats
21294                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21295         fi
21296 }
21297 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21298
21299 test_231b() {
21300         mkdir -p $DIR/$tdir
21301         local i
21302         for i in {0..1023}; do
21303                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21304                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21305                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21306         done
21307         sync
21308 }
21309 run_test 231b "must not assert on fully utilized OST request buffer"
21310
21311 test_232a() {
21312         mkdir -p $DIR/$tdir
21313         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21314
21315         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21316         do_facet ost1 $LCTL set_param fail_loc=0x31c
21317
21318         # ignore dd failure
21319         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21320
21321         do_facet ost1 $LCTL set_param fail_loc=0
21322         umount_client $MOUNT || error "umount failed"
21323         mount_client $MOUNT || error "mount failed"
21324         stop ost1 || error "cannot stop ost1"
21325         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21326 }
21327 run_test 232a "failed lock should not block umount"
21328
21329 test_232b() {
21330         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21331                 skip "Need MDS version at least 2.10.58"
21332
21333         mkdir -p $DIR/$tdir
21334         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21335         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21336         sync
21337         cancel_lru_locks osc
21338
21339         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21340         do_facet ost1 $LCTL set_param fail_loc=0x31c
21341
21342         # ignore failure
21343         $LFS data_version $DIR/$tdir/$tfile || true
21344
21345         do_facet ost1 $LCTL set_param fail_loc=0
21346         umount_client $MOUNT || error "umount failed"
21347         mount_client $MOUNT || error "mount failed"
21348         stop ost1 || error "cannot stop ost1"
21349         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21350 }
21351 run_test 232b "failed data version lock should not block umount"
21352
21353 test_233a() {
21354         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21355                 skip "Need MDS version at least 2.3.64"
21356         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21357
21358         local fid=$($LFS path2fid $MOUNT)
21359
21360         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21361                 error "cannot access $MOUNT using its FID '$fid'"
21362 }
21363 run_test 233a "checking that OBF of the FS root succeeds"
21364
21365 test_233b() {
21366         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21367                 skip "Need MDS version at least 2.5.90"
21368         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21369
21370         local fid=$($LFS path2fid $MOUNT/.lustre)
21371
21372         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21373                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21374
21375         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21376         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21377                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21378 }
21379 run_test 233b "checking that OBF of the FS .lustre succeeds"
21380
21381 test_234() {
21382         local p="$TMP/sanityN-$TESTNAME.parameters"
21383         save_lustre_params client "llite.*.xattr_cache" > $p
21384         lctl set_param llite.*.xattr_cache 1 ||
21385                 skip_env "xattr cache is not supported"
21386
21387         mkdir -p $DIR/$tdir || error "mkdir failed"
21388         touch $DIR/$tdir/$tfile || error "touch failed"
21389         # OBD_FAIL_LLITE_XATTR_ENOMEM
21390         $LCTL set_param fail_loc=0x1405
21391         getfattr -n user.attr $DIR/$tdir/$tfile &&
21392                 error "getfattr should have failed with ENOMEM"
21393         $LCTL set_param fail_loc=0x0
21394         rm -rf $DIR/$tdir
21395
21396         restore_lustre_params < $p
21397         rm -f $p
21398 }
21399 run_test 234 "xattr cache should not crash on ENOMEM"
21400
21401 test_235() {
21402         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21403                 skip "Need MDS version at least 2.4.52"
21404
21405         flock_deadlock $DIR/$tfile
21406         local RC=$?
21407         case $RC in
21408                 0)
21409                 ;;
21410                 124) error "process hangs on a deadlock"
21411                 ;;
21412                 *) error "error executing flock_deadlock $DIR/$tfile"
21413                 ;;
21414         esac
21415 }
21416 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21417
21418 #LU-2935
21419 test_236() {
21420         check_swap_layouts_support
21421
21422         local ref1=/etc/passwd
21423         local ref2=/etc/group
21424         local file1=$DIR/$tdir/f1
21425         local file2=$DIR/$tdir/f2
21426
21427         test_mkdir -c1 $DIR/$tdir
21428         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21429         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21430         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21431         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21432         local fd=$(free_fd)
21433         local cmd="exec $fd<>$file2"
21434         eval $cmd
21435         rm $file2
21436         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21437                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21438         cmd="exec $fd>&-"
21439         eval $cmd
21440         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21441
21442         #cleanup
21443         rm -rf $DIR/$tdir
21444 }
21445 run_test 236 "Layout swap on open unlinked file"
21446
21447 # LU-4659 linkea consistency
21448 test_238() {
21449         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21450                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21451                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21452                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21453
21454         touch $DIR/$tfile
21455         ln $DIR/$tfile $DIR/$tfile.lnk
21456         touch $DIR/$tfile.new
21457         mv $DIR/$tfile.new $DIR/$tfile
21458         local fid1=$($LFS path2fid $DIR/$tfile)
21459         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21460         local path1=$($LFS fid2path $FSNAME "$fid1")
21461         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21462         local path2=$($LFS fid2path $FSNAME "$fid2")
21463         [ $tfile.lnk == $path2 ] ||
21464                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21465         rm -f $DIR/$tfile*
21466 }
21467 run_test 238 "Verify linkea consistency"
21468
21469 test_239A() { # was test_239
21470         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21471                 skip "Need MDS version at least 2.5.60"
21472
21473         local list=$(comma_list $(mdts_nodes))
21474
21475         mkdir -p $DIR/$tdir
21476         createmany -o $DIR/$tdir/f- 5000
21477         unlinkmany $DIR/$tdir/f- 5000
21478         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21479                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21480         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21481                         osp.*MDT*.sync_in_flight" | calc_sum)
21482         [ "$changes" -eq 0 ] || error "$changes not synced"
21483 }
21484 run_test 239A "osp_sync test"
21485
21486 test_239a() { #LU-5297
21487         remote_mds_nodsh && skip "remote MDS with nodsh"
21488
21489         touch $DIR/$tfile
21490         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21491         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21492         chgrp $RUNAS_GID $DIR/$tfile
21493         wait_delete_completed
21494 }
21495 run_test 239a "process invalid osp sync record correctly"
21496
21497 test_239b() { #LU-5297
21498         remote_mds_nodsh && skip "remote MDS with nodsh"
21499
21500         touch $DIR/$tfile1
21501         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21502         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21503         chgrp $RUNAS_GID $DIR/$tfile1
21504         wait_delete_completed
21505         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21506         touch $DIR/$tfile2
21507         chgrp $RUNAS_GID $DIR/$tfile2
21508         wait_delete_completed
21509 }
21510 run_test 239b "process osp sync record with ENOMEM error correctly"
21511
21512 test_240() {
21513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21514         remote_mds_nodsh && skip "remote MDS with nodsh"
21515
21516         mkdir -p $DIR/$tdir
21517
21518         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21519                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21520         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21521                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21522
21523         umount_client $MOUNT || error "umount failed"
21524         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21525         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21526         mount_client $MOUNT || error "failed to mount client"
21527
21528         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21529         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21530 }
21531 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21532
21533 test_241_bio() {
21534         local count=$1
21535         local bsize=$2
21536
21537         for LOOP in $(seq $count); do
21538                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21539                 cancel_lru_locks $OSC || true
21540         done
21541 }
21542
21543 test_241_dio() {
21544         local count=$1
21545         local bsize=$2
21546
21547         for LOOP in $(seq $1); do
21548                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21549                         2>/dev/null
21550         done
21551 }
21552
21553 test_241a() { # was test_241
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         cancel_lru_locks $OSC
21560         test_241_bio 1000 $bsize &
21561         PID=$!
21562         test_241_dio 1000 $bsize
21563         wait $PID
21564 }
21565 run_test 241a "bio vs dio"
21566
21567 test_241b() {
21568         local bsize=$PAGE_SIZE
21569
21570         (( bsize < 40960 )) && bsize=40960
21571         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21572         ls -la $DIR/$tfile
21573         test_241_dio 1000 $bsize &
21574         PID=$!
21575         test_241_dio 1000 $bsize
21576         wait $PID
21577 }
21578 run_test 241b "dio vs dio"
21579
21580 test_242() {
21581         remote_mds_nodsh && skip "remote MDS with nodsh"
21582
21583         mkdir_on_mdt0 $DIR/$tdir
21584         touch $DIR/$tdir/$tfile
21585
21586         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21587         do_facet mds1 lctl set_param fail_loc=0x105
21588         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21589
21590         do_facet mds1 lctl set_param fail_loc=0
21591         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21592 }
21593 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21594
21595 test_243()
21596 {
21597         test_mkdir $DIR/$tdir
21598         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21599 }
21600 run_test 243 "various group lock tests"
21601
21602 test_244a()
21603 {
21604         test_mkdir $DIR/$tdir
21605         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21606         sendfile_grouplock $DIR/$tdir/$tfile || \
21607                 error "sendfile+grouplock failed"
21608         rm -rf $DIR/$tdir
21609 }
21610 run_test 244a "sendfile with group lock tests"
21611
21612 test_244b()
21613 {
21614         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21615
21616         local threads=50
21617         local size=$((1024*1024))
21618
21619         test_mkdir $DIR/$tdir
21620         for i in $(seq 1 $threads); do
21621                 local file=$DIR/$tdir/file_$((i / 10))
21622                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21623                 local pids[$i]=$!
21624         done
21625         for i in $(seq 1 $threads); do
21626                 wait ${pids[$i]}
21627         done
21628 }
21629 run_test 244b "multi-threaded write with group lock"
21630
21631 test_245a() {
21632         local flagname="multi_mod_rpcs"
21633         local connect_data_name="max_mod_rpcs"
21634         local out
21635
21636         # check if multiple modify RPCs flag is set
21637         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21638                 grep "connect_flags:")
21639         echo "$out"
21640
21641         echo "$out" | grep -qw $flagname
21642         if [ $? -ne 0 ]; then
21643                 echo "connect flag $flagname is not set"
21644                 return
21645         fi
21646
21647         # check if multiple modify RPCs data is set
21648         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21649         echo "$out"
21650
21651         echo "$out" | grep -qw $connect_data_name ||
21652                 error "import should have connect data $connect_data_name"
21653 }
21654 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21655
21656 test_245b() {
21657         local flagname="multi_mod_rpcs"
21658         local connect_data_name="max_mod_rpcs"
21659         local out
21660
21661         remote_mds_nodsh && skip "remote MDS with nodsh"
21662         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21663
21664         # check if multiple modify RPCs flag is set
21665         out=$(do_facet mds1 \
21666               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21667               grep "connect_flags:")
21668         echo "$out"
21669
21670         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21671
21672         # check if multiple modify RPCs data is set
21673         out=$(do_facet mds1 \
21674               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21675
21676         [[ "$out" =~ $connect_data_name ]] ||
21677                 {
21678                         echo "$out"
21679                         error "missing connect data $connect_data_name"
21680                 }
21681 }
21682 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21683
21684 cleanup_247() {
21685         local submount=$1
21686
21687         trap 0
21688         umount_client $submount
21689         rmdir $submount
21690 }
21691
21692 test_247a() {
21693         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21694                 grep -q subtree ||
21695                 skip_env "Fileset feature is not supported"
21696
21697         local submount=${MOUNT}_$tdir
21698
21699         mkdir $MOUNT/$tdir
21700         mkdir -p $submount || error "mkdir $submount failed"
21701         FILESET="$FILESET/$tdir" mount_client $submount ||
21702                 error "mount $submount failed"
21703         trap "cleanup_247 $submount" EXIT
21704         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21705         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21706                 error "read $MOUNT/$tdir/$tfile failed"
21707         cleanup_247 $submount
21708 }
21709 run_test 247a "mount subdir as fileset"
21710
21711 test_247b() {
21712         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21713                 skip_env "Fileset feature is not supported"
21714
21715         local submount=${MOUNT}_$tdir
21716
21717         rm -rf $MOUNT/$tdir
21718         mkdir -p $submount || error "mkdir $submount failed"
21719         SKIP_FILESET=1
21720         FILESET="$FILESET/$tdir" mount_client $submount &&
21721                 error "mount $submount should fail"
21722         rmdir $submount
21723 }
21724 run_test 247b "mount subdir that dose not exist"
21725
21726 test_247c() {
21727         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21728                 skip_env "Fileset feature is not supported"
21729
21730         local submount=${MOUNT}_$tdir
21731
21732         mkdir -p $MOUNT/$tdir/dir1
21733         mkdir -p $submount || error "mkdir $submount failed"
21734         trap "cleanup_247 $submount" EXIT
21735         FILESET="$FILESET/$tdir" mount_client $submount ||
21736                 error "mount $submount failed"
21737         local fid=$($LFS path2fid $MOUNT/)
21738         $LFS fid2path $submount $fid && error "fid2path should fail"
21739         cleanup_247 $submount
21740 }
21741 run_test 247c "running fid2path outside subdirectory root"
21742
21743 test_247d() {
21744         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21745                 skip "Fileset feature is not supported"
21746
21747         local submount=${MOUNT}_$tdir
21748
21749         mkdir -p $MOUNT/$tdir/dir1
21750         mkdir -p $submount || error "mkdir $submount failed"
21751         FILESET="$FILESET/$tdir" mount_client $submount ||
21752                 error "mount $submount failed"
21753         trap "cleanup_247 $submount" EXIT
21754
21755         local td=$submount/dir1
21756         local fid=$($LFS path2fid $td)
21757         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21758
21759         # check that we get the same pathname back
21760         local rootpath
21761         local found
21762         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21763                 echo "$rootpath $fid"
21764                 found=$($LFS fid2path $rootpath "$fid")
21765                 [ -n "$found" ] || error "fid2path should succeed"
21766                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21767         done
21768         # check wrong root path format
21769         rootpath=$submount"_wrong"
21770         found=$($LFS fid2path $rootpath "$fid")
21771         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21772
21773         cleanup_247 $submount
21774 }
21775 run_test 247d "running fid2path inside subdirectory root"
21776
21777 # LU-8037
21778 test_247e() {
21779         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21780                 grep -q subtree ||
21781                 skip "Fileset feature is not supported"
21782
21783         local submount=${MOUNT}_$tdir
21784
21785         mkdir $MOUNT/$tdir
21786         mkdir -p $submount || error "mkdir $submount failed"
21787         FILESET="$FILESET/.." mount_client $submount &&
21788                 error "mount $submount should fail"
21789         rmdir $submount
21790 }
21791 run_test 247e "mount .. as fileset"
21792
21793 test_247f() {
21794         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21795         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21796                 skip "Need at least version 2.14.50.162"
21797         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21798                 skip "Fileset feature is not supported"
21799
21800         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21801         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21802                 error "mkdir remote failed"
21803         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21804                 error "mkdir remote/subdir failed"
21805         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21806                 error "mkdir striped failed"
21807         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21808
21809         local submount=${MOUNT}_$tdir
21810
21811         mkdir -p $submount || error "mkdir $submount failed"
21812         stack_trap "rmdir $submount"
21813
21814         local dir
21815         local fileset=$FILESET
21816         local mdts=$(comma_list $(mdts_nodes))
21817
21818         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21819         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
21820                 $tdir/striped/subdir $tdir/striped/.; do
21821                 FILESET="$fileset/$dir" mount_client $submount ||
21822                         error "mount $dir failed"
21823                 umount_client $submount
21824         done
21825 }
21826 run_test 247f "mount striped or remote directory as fileset"
21827
21828 test_subdir_mount_lock()
21829 {
21830         local testdir=$1
21831         local submount=${MOUNT}_$(basename $testdir)
21832
21833         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
21834
21835         mkdir -p $submount || error "mkdir $submount failed"
21836         stack_trap "rmdir $submount"
21837
21838         FILESET="$fileset/$testdir" mount_client $submount ||
21839                 error "mount $FILESET failed"
21840         stack_trap "umount $submount"
21841
21842         local mdts=$(comma_list $(mdts_nodes))
21843
21844         local nrpcs
21845
21846         stat $submount > /dev/null || error "stat $submount failed"
21847         cancel_lru_locks $MDC
21848         stat $submount > /dev/null || error "stat $submount failed"
21849         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21850         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21851         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21852         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21853                 awk '/getattr/ {sum += $2} END {print sum}')
21854
21855         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21856 }
21857
21858 test_247g() {
21859         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21860
21861         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21862                 error "mkdir $tdir failed"
21863         test_subdir_mount_lock $tdir
21864 }
21865 run_test 247g "striped directory submount revalidate ROOT from cache"
21866
21867 test_247h() {
21868         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21869         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
21870                 skip "Need MDS version at least 2.15.51"
21871
21872         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21873         test_subdir_mount_lock $tdir
21874         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
21875         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
21876                 error "mkdir $tdir.1 failed"
21877         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
21878 }
21879 run_test 247h "remote directory submount revalidate ROOT from cache"
21880
21881 test_248a() {
21882         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21883         [ -z "$fast_read_sav" ] && skip "no fast read support"
21884
21885         # create a large file for fast read verification
21886         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21887
21888         # make sure the file is created correctly
21889         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21890                 { rm -f $DIR/$tfile; skip "file creation error"; }
21891
21892         echo "Test 1: verify that fast read is 4 times faster on cache read"
21893
21894         # small read with fast read enabled
21895         $LCTL set_param -n llite.*.fast_read=1
21896         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21897                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21898                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21899         # small read with fast read disabled
21900         $LCTL set_param -n llite.*.fast_read=0
21901         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21902                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21903                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21904
21905         # verify that fast read is 4 times faster for cache read
21906         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21907                 error_not_in_vm "fast read was not 4 times faster: " \
21908                            "$t_fast vs $t_slow"
21909
21910         echo "Test 2: verify the performance between big and small read"
21911         $LCTL set_param -n llite.*.fast_read=1
21912
21913         # 1k non-cache read
21914         cancel_lru_locks osc
21915         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21916                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21917                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21918
21919         # 1M non-cache read
21920         cancel_lru_locks osc
21921         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21922                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21923                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21924
21925         # verify that big IO is not 4 times faster than small IO
21926         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21927                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21928
21929         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21930         rm -f $DIR/$tfile
21931 }
21932 run_test 248a "fast read verification"
21933
21934 test_248b() {
21935         # Default short_io_bytes=16384, try both smaller and larger sizes.
21936         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21937         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21938         echo "bs=53248 count=113 normal buffered write"
21939         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21940                 error "dd of initial data file failed"
21941         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21942
21943         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21944         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21945                 error "dd with sync normal writes failed"
21946         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21947
21948         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21949         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21950                 error "dd with sync small writes failed"
21951         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21952
21953         cancel_lru_locks osc
21954
21955         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21956         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21957         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21958         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21959                 iflag=direct || error "dd with O_DIRECT small read failed"
21960         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21961         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21962                 error "compare $TMP/$tfile.1 failed"
21963
21964         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21965         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21966
21967         # just to see what the maximum tunable value is, and test parsing
21968         echo "test invalid parameter 2MB"
21969         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21970                 error "too-large short_io_bytes allowed"
21971         echo "test maximum parameter 512KB"
21972         # if we can set a larger short_io_bytes, run test regardless of version
21973         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21974                 # older clients may not allow setting it this large, that's OK
21975                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21976                         skip "Need at least client version 2.13.50"
21977                 error "medium short_io_bytes failed"
21978         fi
21979         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21980         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21981
21982         echo "test large parameter 64KB"
21983         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21984         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21985
21986         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21987         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21988                 error "dd with sync large writes failed"
21989         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21990
21991         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21992         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21993         num=$((113 * 4096 / PAGE_SIZE))
21994         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21995         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21996                 error "dd with O_DIRECT large writes failed"
21997         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21998                 error "compare $DIR/$tfile.3 failed"
21999
22000         cancel_lru_locks osc
22001
22002         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22003         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22004                 error "dd with O_DIRECT large read failed"
22005         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22006                 error "compare $TMP/$tfile.2 failed"
22007
22008         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22009         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22010                 error "dd with O_DIRECT large read failed"
22011         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22012                 error "compare $TMP/$tfile.3 failed"
22013 }
22014 run_test 248b "test short_io read and write for both small and large sizes"
22015
22016 test_249() { # LU-7890
22017         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22018                 skip "Need at least version 2.8.54"
22019
22020         rm -f $DIR/$tfile
22021         $LFS setstripe -c 1 $DIR/$tfile
22022         # Offset 2T == 4k * 512M
22023         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22024                 error "dd to 2T offset failed"
22025 }
22026 run_test 249 "Write above 2T file size"
22027
22028 test_250() {
22029         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22030          && skip "no 16TB file size limit on ZFS"
22031
22032         $LFS setstripe -c 1 $DIR/$tfile
22033         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22034         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22035         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22036         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22037                 conv=notrunc,fsync && error "append succeeded"
22038         return 0
22039 }
22040 run_test 250 "Write above 16T limit"
22041
22042 test_251() {
22043         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22044
22045         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22046         #Skip once - writing the first stripe will succeed
22047         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22048         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22049                 error "short write happened"
22050
22051         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22052         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22053                 error "short read happened"
22054
22055         rm -f $DIR/$tfile
22056 }
22057 run_test 251 "Handling short read and write correctly"
22058
22059 test_252() {
22060         remote_mds_nodsh && skip "remote MDS with nodsh"
22061         remote_ost_nodsh && skip "remote OST with nodsh"
22062         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22063                 skip_env "ldiskfs only test"
22064         fi
22065
22066         local tgt
22067         local dev
22068         local out
22069         local uuid
22070         local num
22071         local gen
22072
22073         # check lr_reader on OST0000
22074         tgt=ost1
22075         dev=$(facet_device $tgt)
22076         out=$(do_facet $tgt $LR_READER $dev)
22077         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22078         echo "$out"
22079         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22080         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22081                 error "Invalid uuid returned by $LR_READER on target $tgt"
22082         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22083
22084         # check lr_reader -c on MDT0000
22085         tgt=mds1
22086         dev=$(facet_device $tgt)
22087         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22088                 skip "$LR_READER does not support additional options"
22089         fi
22090         out=$(do_facet $tgt $LR_READER -c $dev)
22091         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22092         echo "$out"
22093         num=$(echo "$out" | grep -c "mdtlov")
22094         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22095                 error "Invalid number of mdtlov clients returned by $LR_READER"
22096         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22097
22098         # check lr_reader -cr on MDT0000
22099         out=$(do_facet $tgt $LR_READER -cr $dev)
22100         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22101         echo "$out"
22102         echo "$out" | grep -q "^reply_data:$" ||
22103                 error "$LR_READER should have returned 'reply_data' section"
22104         num=$(echo "$out" | grep -c "client_generation")
22105         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22106 }
22107 run_test 252 "check lr_reader tool"
22108
22109 test_253() {
22110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22111         remote_mds_nodsh && skip "remote MDS with nodsh"
22112         remote_mgs_nodsh && skip "remote MGS with nodsh"
22113
22114         local ostidx=0
22115         local rc=0
22116         local ost_name=$(ostname_from_index $ostidx)
22117
22118         # on the mdt's osc
22119         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22120         do_facet $SINGLEMDS $LCTL get_param -n \
22121                 osp.$mdtosc_proc1.reserved_mb_high ||
22122                 skip  "remote MDS does not support reserved_mb_high"
22123
22124         rm -rf $DIR/$tdir
22125         wait_mds_ost_sync
22126         wait_delete_completed
22127         mkdir $DIR/$tdir
22128
22129         pool_add $TESTNAME || error "Pool creation failed"
22130         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22131
22132         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22133                 error "Setstripe failed"
22134
22135         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22136
22137         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22138                     grep "watermarks")
22139         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22140
22141         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22142                         osp.$mdtosc_proc1.prealloc_status)
22143         echo "prealloc_status $oa_status"
22144
22145         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22146                 error "File creation should fail"
22147
22148         #object allocation was stopped, but we still able to append files
22149         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22150                 oflag=append || error "Append failed"
22151
22152         rm -f $DIR/$tdir/$tfile.0
22153
22154         # For this test, we want to delete the files we created to go out of
22155         # space but leave the watermark, so we remain nearly out of space
22156         ost_watermarks_enospc_delete_files $tfile $ostidx
22157
22158         wait_delete_completed
22159
22160         sleep_maxage
22161
22162         for i in $(seq 10 12); do
22163                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22164                         2>/dev/null || error "File creation failed after rm"
22165         done
22166
22167         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22168                         osp.$mdtosc_proc1.prealloc_status)
22169         echo "prealloc_status $oa_status"
22170
22171         if (( oa_status != 0 )); then
22172                 error "Object allocation still disable after rm"
22173         fi
22174 }
22175 run_test 253 "Check object allocation limit"
22176
22177 test_254() {
22178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22179         remote_mds_nodsh && skip "remote MDS with nodsh"
22180
22181         local mdt=$(facet_svc $SINGLEMDS)
22182
22183         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22184                 skip "MDS does not support changelog_size"
22185
22186         local cl_user
22187
22188         changelog_register || error "changelog_register failed"
22189
22190         changelog_clear 0 || error "changelog_clear failed"
22191
22192         local size1=$(do_facet $SINGLEMDS \
22193                       $LCTL get_param -n mdd.$mdt.changelog_size)
22194         echo "Changelog size $size1"
22195
22196         rm -rf $DIR/$tdir
22197         $LFS mkdir -i 0 $DIR/$tdir
22198         # change something
22199         mkdir -p $DIR/$tdir/pics/2008/zachy
22200         touch $DIR/$tdir/pics/2008/zachy/timestamp
22201         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22202         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22203         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22204         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22205         rm $DIR/$tdir/pics/desktop.jpg
22206
22207         local size2=$(do_facet $SINGLEMDS \
22208                       $LCTL get_param -n mdd.$mdt.changelog_size)
22209         echo "Changelog size after work $size2"
22210
22211         (( $size2 > $size1 )) ||
22212                 error "new Changelog size=$size2 less than old size=$size1"
22213 }
22214 run_test 254 "Check changelog size"
22215
22216 ladvise_no_type()
22217 {
22218         local type=$1
22219         local file=$2
22220
22221         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22222                 awk -F: '{print $2}' | grep $type > /dev/null
22223         if [ $? -ne 0 ]; then
22224                 return 0
22225         fi
22226         return 1
22227 }
22228
22229 ladvise_no_ioctl()
22230 {
22231         local file=$1
22232
22233         lfs ladvise -a willread $file > /dev/null 2>&1
22234         if [ $? -eq 0 ]; then
22235                 return 1
22236         fi
22237
22238         lfs ladvise -a willread $file 2>&1 |
22239                 grep "Inappropriate ioctl for device" > /dev/null
22240         if [ $? -eq 0 ]; then
22241                 return 0
22242         fi
22243         return 1
22244 }
22245
22246 percent() {
22247         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22248 }
22249
22250 # run a random read IO workload
22251 # usage: random_read_iops <filename> <filesize> <iosize>
22252 random_read_iops() {
22253         local file=$1
22254         local fsize=$2
22255         local iosize=${3:-4096}
22256
22257         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22258                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22259 }
22260
22261 drop_file_oss_cache() {
22262         local file="$1"
22263         local nodes="$2"
22264
22265         $LFS ladvise -a dontneed $file 2>/dev/null ||
22266                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22267 }
22268
22269 ladvise_willread_performance()
22270 {
22271         local repeat=10
22272         local average_origin=0
22273         local average_cache=0
22274         local average_ladvise=0
22275
22276         for ((i = 1; i <= $repeat; i++)); do
22277                 echo "Iter $i/$repeat: reading without willread hint"
22278                 cancel_lru_locks osc
22279                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22280                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22281                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22282                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22283
22284                 cancel_lru_locks osc
22285                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22286                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22287                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22288
22289                 cancel_lru_locks osc
22290                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22291                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22292                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22293                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22294                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22295         done
22296         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22297         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22298         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22299
22300         speedup_cache=$(percent $average_cache $average_origin)
22301         speedup_ladvise=$(percent $average_ladvise $average_origin)
22302
22303         echo "Average uncached read: $average_origin"
22304         echo "Average speedup with OSS cached read: " \
22305                 "$average_cache = +$speedup_cache%"
22306         echo "Average speedup with ladvise willread: " \
22307                 "$average_ladvise = +$speedup_ladvise%"
22308
22309         local lowest_speedup=20
22310         if (( ${average_cache%.*} < $lowest_speedup )); then
22311                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22312                      " got $average_cache%. Skipping ladvise willread check."
22313                 return 0
22314         fi
22315
22316         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22317         # it is still good to run until then to exercise 'ladvise willread'
22318         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22319                 [ "$ost1_FSTYPE" = "zfs" ] &&
22320                 echo "osd-zfs does not support dontneed or drop_caches" &&
22321                 return 0
22322
22323         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22324         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22325                 error_not_in_vm "Speedup with willread is less than " \
22326                         "$lowest_speedup%, got $average_ladvise%"
22327 }
22328
22329 test_255a() {
22330         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22331                 skip "lustre < 2.8.54 does not support ladvise "
22332         remote_ost_nodsh && skip "remote OST with nodsh"
22333
22334         stack_trap "rm -f $DIR/$tfile"
22335         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22336
22337         ladvise_no_type willread $DIR/$tfile &&
22338                 skip "willread ladvise is not supported"
22339
22340         ladvise_no_ioctl $DIR/$tfile &&
22341                 skip "ladvise ioctl is not supported"
22342
22343         local size_mb=100
22344         local size=$((size_mb * 1048576))
22345         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22346                 error "dd to $DIR/$tfile failed"
22347
22348         lfs ladvise -a willread $DIR/$tfile ||
22349                 error "Ladvise failed with no range argument"
22350
22351         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22352                 error "Ladvise failed with no -l or -e argument"
22353
22354         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22355                 error "Ladvise failed with only -e argument"
22356
22357         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22358                 error "Ladvise failed with only -l argument"
22359
22360         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22361                 error "End offset should not be smaller than start offset"
22362
22363         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22364                 error "End offset should not be equal to start offset"
22365
22366         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22367                 error "Ladvise failed with overflowing -s argument"
22368
22369         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22370                 error "Ladvise failed with overflowing -e argument"
22371
22372         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22373                 error "Ladvise failed with overflowing -l argument"
22374
22375         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22376                 error "Ladvise succeeded with conflicting -l and -e arguments"
22377
22378         echo "Synchronous ladvise should wait"
22379         local delay=4
22380 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22381         do_nodes $(comma_list $(osts_nodes)) \
22382                 $LCTL set_param fail_val=$delay fail_loc=0x237
22383
22384         local start_ts=$SECONDS
22385         lfs ladvise -a willread $DIR/$tfile ||
22386                 error "Ladvise failed with no range argument"
22387         local end_ts=$SECONDS
22388         local inteval_ts=$((end_ts - start_ts))
22389
22390         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22391                 error "Synchronous advice didn't wait reply"
22392         fi
22393
22394         echo "Asynchronous ladvise shouldn't wait"
22395         local start_ts=$SECONDS
22396         lfs ladvise -a willread -b $DIR/$tfile ||
22397                 error "Ladvise failed with no range argument"
22398         local end_ts=$SECONDS
22399         local inteval_ts=$((end_ts - start_ts))
22400
22401         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22402                 error "Asynchronous advice blocked"
22403         fi
22404
22405         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22406         ladvise_willread_performance
22407 }
22408 run_test 255a "check 'lfs ladvise -a willread'"
22409
22410 facet_meminfo() {
22411         local facet=$1
22412         local info=$2
22413
22414         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22415 }
22416
22417 test_255b() {
22418         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22419                 skip "lustre < 2.8.54 does not support ladvise "
22420         remote_ost_nodsh && skip "remote OST with nodsh"
22421
22422         stack_trap "rm -f $DIR/$tfile"
22423         lfs setstripe -c 1 -i 0 $DIR/$tfile
22424
22425         ladvise_no_type dontneed $DIR/$tfile &&
22426                 skip "dontneed ladvise is not supported"
22427
22428         ladvise_no_ioctl $DIR/$tfile &&
22429                 skip "ladvise ioctl is not supported"
22430
22431         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22432                 [ "$ost1_FSTYPE" = "zfs" ] &&
22433                 skip "zfs-osd does not support 'ladvise dontneed'"
22434
22435         local size_mb=100
22436         local size=$((size_mb * 1048576))
22437         # In order to prevent disturbance of other processes, only check 3/4
22438         # of the memory usage
22439         local kibibytes=$((size_mb * 1024 * 3 / 4))
22440
22441         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22442                 error "dd to $DIR/$tfile failed"
22443
22444         #force write to complete before dropping OST cache & checking memory
22445         sync
22446
22447         local total=$(facet_meminfo ost1 MemTotal)
22448         echo "Total memory: $total KiB"
22449
22450         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22451         local before_read=$(facet_meminfo ost1 Cached)
22452         echo "Cache used before read: $before_read KiB"
22453
22454         lfs ladvise -a willread $DIR/$tfile ||
22455                 error "Ladvise willread failed"
22456         local after_read=$(facet_meminfo ost1 Cached)
22457         echo "Cache used after read: $after_read KiB"
22458
22459         lfs ladvise -a dontneed $DIR/$tfile ||
22460                 error "Ladvise dontneed again failed"
22461         local no_read=$(facet_meminfo ost1 Cached)
22462         echo "Cache used after dontneed ladvise: $no_read KiB"
22463
22464         if [ $total -lt $((before_read + kibibytes)) ]; then
22465                 echo "Memory is too small, abort checking"
22466                 return 0
22467         fi
22468
22469         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22470                 error "Ladvise willread should use more memory" \
22471                         "than $kibibytes KiB"
22472         fi
22473
22474         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22475                 error "Ladvise dontneed should release more memory" \
22476                         "than $kibibytes KiB"
22477         fi
22478 }
22479 run_test 255b "check 'lfs ladvise -a dontneed'"
22480
22481 test_255c() {
22482         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22483                 skip "lustre < 2.10.50 does not support lockahead"
22484
22485         local ost1_imp=$(get_osc_import_name client ost1)
22486         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22487                          cut -d'.' -f2)
22488         local count
22489         local new_count
22490         local difference
22491         local i
22492         local rc
22493
22494         test_mkdir -p $DIR/$tdir
22495         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22496
22497         #test 10 returns only success/failure
22498         i=10
22499         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22500         rc=$?
22501         if [ $rc -eq 255 ]; then
22502                 error "Ladvise test${i} failed, ${rc}"
22503         fi
22504
22505         #test 11 counts lock enqueue requests, all others count new locks
22506         i=11
22507         count=$(do_facet ost1 \
22508                 $LCTL get_param -n ost.OSS.ost.stats)
22509         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22510
22511         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22512         rc=$?
22513         if [ $rc -eq 255 ]; then
22514                 error "Ladvise test${i} failed, ${rc}"
22515         fi
22516
22517         new_count=$(do_facet ost1 \
22518                 $LCTL get_param -n ost.OSS.ost.stats)
22519         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22520                    awk '{ print $2 }')
22521
22522         difference="$((new_count - count))"
22523         if [ $difference -ne $rc ]; then
22524                 error "Ladvise test${i}, bad enqueue count, returned " \
22525                       "${rc}, actual ${difference}"
22526         fi
22527
22528         for i in $(seq 12 21); do
22529                 # If we do not do this, we run the risk of having too many
22530                 # locks and starting lock cancellation while we are checking
22531                 # lock counts.
22532                 cancel_lru_locks osc
22533
22534                 count=$($LCTL get_param -n \
22535                        ldlm.namespaces.$imp_name.lock_unused_count)
22536
22537                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22538                 rc=$?
22539                 if [ $rc -eq 255 ]; then
22540                         error "Ladvise test ${i} failed, ${rc}"
22541                 fi
22542
22543                 new_count=$($LCTL get_param -n \
22544                        ldlm.namespaces.$imp_name.lock_unused_count)
22545                 difference="$((new_count - count))"
22546
22547                 # Test 15 output is divided by 100 to map down to valid return
22548                 if [ $i -eq 15 ]; then
22549                         rc="$((rc * 100))"
22550                 fi
22551
22552                 if [ $difference -ne $rc ]; then
22553                         error "Ladvise test ${i}, bad lock count, returned " \
22554                               "${rc}, actual ${difference}"
22555                 fi
22556         done
22557
22558         #test 22 returns only success/failure
22559         i=22
22560         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22561         rc=$?
22562         if [ $rc -eq 255 ]; then
22563                 error "Ladvise test${i} failed, ${rc}"
22564         fi
22565 }
22566 run_test 255c "suite of ladvise lockahead tests"
22567
22568 test_256() {
22569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22570         remote_mds_nodsh && skip "remote MDS with nodsh"
22571         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22572         changelog_users $SINGLEMDS | grep "^cl" &&
22573                 skip "active changelog user"
22574
22575         local cl_user
22576         local cat_sl
22577         local mdt_dev
22578
22579         mdt_dev=$(facet_device $SINGLEMDS)
22580         echo $mdt_dev
22581
22582         changelog_register || error "changelog_register failed"
22583
22584         rm -rf $DIR/$tdir
22585         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22586
22587         changelog_clear 0 || error "changelog_clear failed"
22588
22589         # change something
22590         touch $DIR/$tdir/{1..10}
22591
22592         # stop the MDT
22593         stop $SINGLEMDS || error "Fail to stop MDT"
22594
22595         # remount the MDT
22596         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22597                 error "Fail to start MDT"
22598
22599         #after mount new plainllog is used
22600         touch $DIR/$tdir/{11..19}
22601         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22602         stack_trap "rm -f $tmpfile"
22603         cat_sl=$(do_facet $SINGLEMDS "sync; \
22604                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22605                  llog_reader $tmpfile | grep -c type=1064553b")
22606         do_facet $SINGLEMDS llog_reader $tmpfile
22607
22608         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22609
22610         changelog_clear 0 || error "changelog_clear failed"
22611
22612         cat_sl=$(do_facet $SINGLEMDS "sync; \
22613                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22614                  llog_reader $tmpfile | grep -c type=1064553b")
22615
22616         if (( cat_sl == 2 )); then
22617                 error "Empty plain llog was not deleted from changelog catalog"
22618         elif (( cat_sl != 1 )); then
22619                 error "Active plain llog shouldn't be deleted from catalog"
22620         fi
22621 }
22622 run_test 256 "Check llog delete for empty and not full state"
22623
22624 test_257() {
22625         remote_mds_nodsh && skip "remote MDS with nodsh"
22626         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22627                 skip "Need MDS version at least 2.8.55"
22628
22629         test_mkdir $DIR/$tdir
22630
22631         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22632                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22633         stat $DIR/$tdir
22634
22635 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22636         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22637         local facet=mds$((mdtidx + 1))
22638         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22639         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22640
22641         stop $facet || error "stop MDS failed"
22642         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22643                 error "start MDS fail"
22644         wait_recovery_complete $facet
22645 }
22646 run_test 257 "xattr locks are not lost"
22647
22648 # Verify we take the i_mutex when security requires it
22649 test_258a() {
22650 #define OBD_FAIL_IMUTEX_SEC 0x141c
22651         $LCTL set_param fail_loc=0x141c
22652         touch $DIR/$tfile
22653         chmod u+s $DIR/$tfile
22654         chmod a+rwx $DIR/$tfile
22655         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22656         RC=$?
22657         if [ $RC -ne 0 ]; then
22658                 error "error, failed to take i_mutex, rc=$?"
22659         fi
22660         rm -f $DIR/$tfile
22661 }
22662 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22663
22664 # Verify we do NOT take the i_mutex in the normal case
22665 test_258b() {
22666 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22667         $LCTL set_param fail_loc=0x141d
22668         touch $DIR/$tfile
22669         chmod a+rwx $DIR
22670         chmod a+rw $DIR/$tfile
22671         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22672         RC=$?
22673         if [ $RC -ne 0 ]; then
22674                 error "error, took i_mutex unnecessarily, rc=$?"
22675         fi
22676         rm -f $DIR/$tfile
22677
22678 }
22679 run_test 258b "verify i_mutex security behavior"
22680
22681 test_259() {
22682         local file=$DIR/$tfile
22683         local before
22684         local after
22685
22686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22687
22688         stack_trap "rm -f $file" EXIT
22689
22690         wait_delete_completed
22691         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22692         echo "before: $before"
22693
22694         $LFS setstripe -i 0 -c 1 $file
22695         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22696         sync_all_data
22697         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22698         echo "after write: $after"
22699
22700 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22701         do_facet ost1 $LCTL set_param fail_loc=0x2301
22702         $TRUNCATE $file 0
22703         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22704         echo "after truncate: $after"
22705
22706         stop ost1
22707         do_facet ost1 $LCTL set_param fail_loc=0
22708         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22709         sleep 2
22710         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22711         echo "after restart: $after"
22712         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22713                 error "missing truncate?"
22714
22715         return 0
22716 }
22717 run_test 259 "crash at delayed truncate"
22718
22719 test_260() {
22720 #define OBD_FAIL_MDC_CLOSE               0x806
22721         $LCTL set_param fail_loc=0x80000806
22722         touch $DIR/$tfile
22723
22724 }
22725 run_test 260 "Check mdc_close fail"
22726
22727 ### Data-on-MDT sanity tests ###
22728 test_270a() {
22729         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22730                 skip "Need MDS version at least 2.10.55 for DoM"
22731
22732         # create DoM file
22733         local dom=$DIR/$tdir/dom_file
22734         local tmp=$DIR/$tdir/tmp_file
22735
22736         mkdir_on_mdt0 $DIR/$tdir
22737
22738         # basic checks for DoM component creation
22739         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22740                 error "Can set MDT layout to non-first entry"
22741
22742         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22743                 error "Can define multiple entries as MDT layout"
22744
22745         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22746
22747         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22748         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22749         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22750
22751         local mdtidx=$($LFS getstripe -m $dom)
22752         local mdtname=MDT$(printf %04x $mdtidx)
22753         local facet=mds$((mdtidx + 1))
22754         local space_check=1
22755
22756         # Skip free space checks with ZFS
22757         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22758
22759         # write
22760         sync
22761         local size_tmp=$((65536 * 3))
22762         local mdtfree1=$(do_facet $facet \
22763                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22764
22765         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22766         # check also direct IO along write
22767         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22768         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22769         sync
22770         cmp $tmp $dom || error "file data is different"
22771         [ $(stat -c%s $dom) == $size_tmp ] ||
22772                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22773         if [ $space_check == 1 ]; then
22774                 local mdtfree2=$(do_facet $facet \
22775                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22776
22777                 # increase in usage from by $size_tmp
22778                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22779                         error "MDT free space wrong after write: " \
22780                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22781         fi
22782
22783         # truncate
22784         local size_dom=10000
22785
22786         $TRUNCATE $dom $size_dom
22787         [ $(stat -c%s $dom) == $size_dom ] ||
22788                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22789         if [ $space_check == 1 ]; then
22790                 mdtfree1=$(do_facet $facet \
22791                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22792                 # decrease in usage from $size_tmp to new $size_dom
22793                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22794                   $(((size_tmp - size_dom) / 1024)) ] ||
22795                         error "MDT free space is wrong after truncate: " \
22796                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22797         fi
22798
22799         # append
22800         cat $tmp >> $dom
22801         sync
22802         size_dom=$((size_dom + size_tmp))
22803         [ $(stat -c%s $dom) == $size_dom ] ||
22804                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22805         if [ $space_check == 1 ]; then
22806                 mdtfree2=$(do_facet $facet \
22807                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22808                 # increase in usage by $size_tmp from previous
22809                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22810                         error "MDT free space is wrong after append: " \
22811                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22812         fi
22813
22814         # delete
22815         rm $dom
22816         if [ $space_check == 1 ]; then
22817                 mdtfree1=$(do_facet $facet \
22818                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22819                 # decrease in usage by $size_dom from previous
22820                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22821                         error "MDT free space is wrong after removal: " \
22822                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22823         fi
22824
22825         # combined striping
22826         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22827                 error "Can't create DoM + OST striping"
22828
22829         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22830         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22831         # check also direct IO along write
22832         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22833         sync
22834         cmp $tmp $dom || error "file data is different"
22835         [ $(stat -c%s $dom) == $size_tmp ] ||
22836                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22837         rm $dom $tmp
22838
22839         return 0
22840 }
22841 run_test 270a "DoM: basic functionality tests"
22842
22843 test_270b() {
22844         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22845                 skip "Need MDS version at least 2.10.55"
22846
22847         local dom=$DIR/$tdir/dom_file
22848         local max_size=1048576
22849
22850         mkdir -p $DIR/$tdir
22851         $LFS setstripe -E $max_size -L mdt $dom
22852
22853         # truncate over the limit
22854         $TRUNCATE $dom $(($max_size + 1)) &&
22855                 error "successful truncate over the maximum size"
22856         # write over the limit
22857         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22858                 error "successful write over the maximum size"
22859         # append over the limit
22860         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22861         echo "12345" >> $dom && error "successful append over the maximum size"
22862         rm $dom
22863
22864         return 0
22865 }
22866 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22867
22868 test_270c() {
22869         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22870                 skip "Need MDS version at least 2.10.55"
22871
22872         mkdir -p $DIR/$tdir
22873         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22874
22875         # check files inherit DoM EA
22876         touch $DIR/$tdir/first
22877         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22878                 error "bad pattern"
22879         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22880                 error "bad stripe count"
22881         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22882                 error "bad stripe size"
22883
22884         # check directory inherits DoM EA and uses it as default
22885         mkdir $DIR/$tdir/subdir
22886         touch $DIR/$tdir/subdir/second
22887         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22888                 error "bad pattern in sub-directory"
22889         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22890                 error "bad stripe count in sub-directory"
22891         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22892                 error "bad stripe size in sub-directory"
22893         return 0
22894 }
22895 run_test 270c "DoM: DoM EA inheritance tests"
22896
22897 test_270d() {
22898         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22899                 skip "Need MDS version at least 2.10.55"
22900
22901         mkdir -p $DIR/$tdir
22902         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22903
22904         # inherit default DoM striping
22905         mkdir $DIR/$tdir/subdir
22906         touch $DIR/$tdir/subdir/f1
22907
22908         # change default directory striping
22909         $LFS setstripe -c 1 $DIR/$tdir/subdir
22910         touch $DIR/$tdir/subdir/f2
22911         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22912                 error "wrong default striping in file 2"
22913         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22914                 error "bad pattern in file 2"
22915         return 0
22916 }
22917 run_test 270d "DoM: change striping from DoM to RAID0"
22918
22919 test_270e() {
22920         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22921                 skip "Need MDS version at least 2.10.55"
22922
22923         mkdir -p $DIR/$tdir/dom
22924         mkdir -p $DIR/$tdir/norm
22925         DOMFILES=20
22926         NORMFILES=10
22927         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22928         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22929
22930         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22931         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22932
22933         # find DoM files by layout
22934         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22935         [ $NUM -eq  $DOMFILES ] ||
22936                 error "lfs find -L: found $NUM, expected $DOMFILES"
22937         echo "Test 1: lfs find 20 DOM files by layout: OK"
22938
22939         # there should be 1 dir with default DOM striping
22940         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22941         [ $NUM -eq  1 ] ||
22942                 error "lfs find -L: found $NUM, expected 1 dir"
22943         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22944
22945         # find DoM files by stripe size
22946         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22947         [ $NUM -eq  $DOMFILES ] ||
22948                 error "lfs find -S: found $NUM, expected $DOMFILES"
22949         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22950
22951         # find files by stripe offset except DoM files
22952         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22953         [ $NUM -eq  $NORMFILES ] ||
22954                 error "lfs find -i: found $NUM, expected $NORMFILES"
22955         echo "Test 5: lfs find no DOM files by stripe index: OK"
22956         return 0
22957 }
22958 run_test 270e "DoM: lfs find with DoM files test"
22959
22960 test_270f() {
22961         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22962                 skip "Need MDS version at least 2.10.55"
22963
22964         local mdtname=${FSNAME}-MDT0000-mdtlov
22965         local dom=$DIR/$tdir/dom_file
22966         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22967                                                 lod.$mdtname.dom_stripesize)
22968         local dom_limit=131072
22969
22970         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22971         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22972                                                 lod.$mdtname.dom_stripesize)
22973         [ ${dom_limit} -eq ${dom_current} ] ||
22974                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22975
22976         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22977         $LFS setstripe -d $DIR/$tdir
22978         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22979                 error "Can't set directory default striping"
22980
22981         # exceed maximum stripe size
22982         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22983                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22984         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22985                 error "Able to create DoM component size more than LOD limit"
22986
22987         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22988         dom_current=$(do_facet mds1 $LCTL get_param -n \
22989                                                 lod.$mdtname.dom_stripesize)
22990         [ 0 -eq ${dom_current} ] ||
22991                 error "Can't set zero DoM stripe limit"
22992         rm $dom
22993
22994         # attempt to create DoM file on server with disabled DoM should
22995         # remove DoM entry from layout and be succeed
22996         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22997                 error "Can't create DoM file (DoM is disabled)"
22998         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22999                 error "File has DoM component while DoM is disabled"
23000         rm $dom
23001
23002         # attempt to create DoM file with only DoM stripe should return error
23003         $LFS setstripe -E $dom_limit -L mdt $dom &&
23004                 error "Able to create DoM-only file while DoM is disabled"
23005
23006         # too low values to be aligned with smallest stripe size 64K
23007         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23008         dom_current=$(do_facet mds1 $LCTL get_param -n \
23009                                                 lod.$mdtname.dom_stripesize)
23010         [ 30000 -eq ${dom_current} ] &&
23011                 error "Can set too small DoM stripe limit"
23012
23013         # 64K is a minimal stripe size in Lustre, expect limit of that size
23014         [ 65536 -eq ${dom_current} ] ||
23015                 error "Limit is not set to 64K but ${dom_current}"
23016
23017         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23018         dom_current=$(do_facet mds1 $LCTL get_param -n \
23019                                                 lod.$mdtname.dom_stripesize)
23020         echo $dom_current
23021         [ 2147483648 -eq ${dom_current} ] &&
23022                 error "Can set too large DoM stripe limit"
23023
23024         do_facet mds1 $LCTL set_param -n \
23025                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23026         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23027                 error "Can't create DoM component size after limit change"
23028         do_facet mds1 $LCTL set_param -n \
23029                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23030         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23031                 error "Can't create DoM file after limit decrease"
23032         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23033                 error "Can create big DoM component after limit decrease"
23034         touch ${dom}_def ||
23035                 error "Can't create file with old default layout"
23036
23037         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23038         return 0
23039 }
23040 run_test 270f "DoM: maximum DoM stripe size checks"
23041
23042 test_270g() {
23043         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23044                 skip "Need MDS version at least 2.13.52"
23045         local dom=$DIR/$tdir/$tfile
23046
23047         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23048         local lodname=${FSNAME}-MDT0000-mdtlov
23049
23050         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23051         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23052         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23053         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23054
23055         local dom_limit=1024
23056         local dom_threshold="50%"
23057
23058         $LFS setstripe -d $DIR/$tdir
23059         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23060                 error "Can't set directory default striping"
23061
23062         do_facet mds1 $LCTL set_param -n \
23063                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23064         # set 0 threshold and create DOM file to change tunable stripesize
23065         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23066         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23067                 error "Failed to create $dom file"
23068         # now tunable dom_cur_stripesize should reach maximum
23069         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23070                                         lod.${lodname}.dom_stripesize_cur_kb)
23071         [[ $dom_current == $dom_limit ]] ||
23072                 error "Current DOM stripesize is not maximum"
23073         rm $dom
23074
23075         # set threshold for further tests
23076         do_facet mds1 $LCTL set_param -n \
23077                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23078         echo "DOM threshold is $dom_threshold free space"
23079         local dom_def
23080         local dom_set
23081         # Spoof bfree to exceed threshold
23082         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23083         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23084         for spfree in 40 20 0 15 30 55; do
23085                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23086                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23087                         error "Failed to create $dom file"
23088                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23089                                         lod.${lodname}.dom_stripesize_cur_kb)
23090                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23091                 [[ $dom_def != $dom_current ]] ||
23092                         error "Default stripe size was not changed"
23093                 if (( spfree > 0 )) ; then
23094                         dom_set=$($LFS getstripe -S $dom)
23095                         (( dom_set == dom_def * 1024 )) ||
23096                                 error "DOM component size is still old"
23097                 else
23098                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23099                                 error "DoM component is set with no free space"
23100                 fi
23101                 rm $dom
23102                 dom_current=$dom_def
23103         done
23104 }
23105 run_test 270g "DoM: default DoM stripe size depends on free space"
23106
23107 test_270h() {
23108         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23109                 skip "Need MDS version at least 2.13.53"
23110
23111         local mdtname=${FSNAME}-MDT0000-mdtlov
23112         local dom=$DIR/$tdir/$tfile
23113         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23114
23115         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23116         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23117
23118         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23119         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23120                 error "can't create OST file"
23121         # mirrored file with DOM entry in the second mirror
23122         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23123                 error "can't create mirror with DoM component"
23124
23125         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23126
23127         # DOM component in the middle and has other enries in the same mirror,
23128         # should succeed but lost DoM component
23129         $LFS setstripe --copy=${dom}_1 $dom ||
23130                 error "Can't create file from OST|DOM mirror layout"
23131         # check new file has no DoM layout after all
23132         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23133                 error "File has DoM component while DoM is disabled"
23134 }
23135 run_test 270h "DoM: DoM stripe removal when disabled on server"
23136
23137 test_270i() {
23138         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23139                 skip "Need MDS version at least 2.14.54"
23140
23141         mkdir $DIR/$tdir
23142         # DoM with plain layout
23143         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23144                 error "default plain layout with DoM must fail"
23145         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23146                 error "setstripe plain file layout with DoM must fail"
23147         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23148                 error "default DoM layout with bad striping must fail"
23149         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23150                 error "setstripe to DoM layout with bad striping must fail"
23151         return 0
23152 }
23153 run_test 270i "DoM: setting invalid DoM striping should fail"
23154
23155 test_271a() {
23156         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23157                 skip "Need MDS version at least 2.10.55"
23158
23159         local dom=$DIR/$tdir/dom
23160
23161         mkdir -p $DIR/$tdir
23162
23163         $LFS setstripe -E 1024K -L mdt $dom
23164
23165         lctl set_param -n mdc.*.stats=clear
23166         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23167         cat $dom > /dev/null
23168         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23169         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23170         ls $dom
23171         rm -f $dom
23172 }
23173 run_test 271a "DoM: data is cached for read after write"
23174
23175 test_271b() {
23176         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23177                 skip "Need MDS version at least 2.10.55"
23178
23179         local dom=$DIR/$tdir/dom
23180
23181         mkdir -p $DIR/$tdir
23182
23183         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23184
23185         lctl set_param -n mdc.*.stats=clear
23186         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23187         cancel_lru_locks mdc
23188         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23189         # second stat to check size is cached on client
23190         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23191         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23192         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23193         rm -f $dom
23194 }
23195 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23196
23197 test_271ba() {
23198         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23199                 skip "Need MDS version at least 2.10.55"
23200
23201         local dom=$DIR/$tdir/dom
23202
23203         mkdir -p $DIR/$tdir
23204
23205         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23206
23207         lctl set_param -n mdc.*.stats=clear
23208         lctl set_param -n osc.*.stats=clear
23209         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23210         cancel_lru_locks mdc
23211         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23212         # second stat to check size is cached on client
23213         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23214         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23215         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23216         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23217         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23218         rm -f $dom
23219 }
23220 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23221
23222
23223 get_mdc_stats() {
23224         local mdtidx=$1
23225         local param=$2
23226         local mdt=MDT$(printf %04x $mdtidx)
23227
23228         if [ -z $param ]; then
23229                 lctl get_param -n mdc.*$mdt*.stats
23230         else
23231                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23232         fi
23233 }
23234
23235 test_271c() {
23236         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23237                 skip "Need MDS version at least 2.10.55"
23238
23239         local dom=$DIR/$tdir/dom
23240
23241         mkdir -p $DIR/$tdir
23242
23243         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23244
23245         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23246         local facet=mds$((mdtidx + 1))
23247
23248         cancel_lru_locks mdc
23249         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23250         createmany -o $dom 1000
23251         lctl set_param -n mdc.*.stats=clear
23252         smalliomany -w $dom 1000 200
23253         get_mdc_stats $mdtidx
23254         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23255         # Each file has 1 open, 1 IO enqueues, total 2000
23256         # but now we have also +1 getxattr for security.capability, total 3000
23257         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23258         unlinkmany $dom 1000
23259
23260         cancel_lru_locks mdc
23261         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23262         createmany -o $dom 1000
23263         lctl set_param -n mdc.*.stats=clear
23264         smalliomany -w $dom 1000 200
23265         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23266         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23267         # for OPEN and IO lock.
23268         [ $((enq - enq_2)) -ge 1000 ] ||
23269                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23270         unlinkmany $dom 1000
23271         return 0
23272 }
23273 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23274
23275 cleanup_271def_tests() {
23276         trap 0
23277         rm -f $1
23278 }
23279
23280 test_271d() {
23281         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23282                 skip "Need MDS version at least 2.10.57"
23283
23284         local dom=$DIR/$tdir/dom
23285         local tmp=$TMP/$tfile
23286         trap "cleanup_271def_tests $tmp" EXIT
23287
23288         mkdir -p $DIR/$tdir
23289
23290         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23291
23292         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23293
23294         cancel_lru_locks mdc
23295         dd if=/dev/urandom of=$tmp bs=1000 count=1
23296         dd if=$tmp of=$dom bs=1000 count=1
23297         cancel_lru_locks mdc
23298
23299         cat /etc/hosts >> $tmp
23300         lctl set_param -n mdc.*.stats=clear
23301
23302         # append data to the same file it should update local page
23303         echo "Append to the same page"
23304         cat /etc/hosts >> $dom
23305         local num=$(get_mdc_stats $mdtidx ost_read)
23306         local ra=$(get_mdc_stats $mdtidx req_active)
23307         local rw=$(get_mdc_stats $mdtidx req_waittime)
23308
23309         [ -z $num ] || error "$num READ RPC occured"
23310         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23311         echo "... DONE"
23312
23313         # compare content
23314         cmp $tmp $dom || error "file miscompare"
23315
23316         cancel_lru_locks mdc
23317         lctl set_param -n mdc.*.stats=clear
23318
23319         echo "Open and read file"
23320         cat $dom > /dev/null
23321         local num=$(get_mdc_stats $mdtidx ost_read)
23322         local ra=$(get_mdc_stats $mdtidx req_active)
23323         local rw=$(get_mdc_stats $mdtidx req_waittime)
23324
23325         [ -z $num ] || error "$num READ RPC occured"
23326         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23327         echo "... DONE"
23328
23329         # compare content
23330         cmp $tmp $dom || error "file miscompare"
23331
23332         return 0
23333 }
23334 run_test 271d "DoM: read on open (1K file in reply buffer)"
23335
23336 test_271f() {
23337         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23338                 skip "Need MDS version at least 2.10.57"
23339
23340         local dom=$DIR/$tdir/dom
23341         local tmp=$TMP/$tfile
23342         trap "cleanup_271def_tests $tmp" EXIT
23343
23344         mkdir -p $DIR/$tdir
23345
23346         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23347
23348         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23349
23350         cancel_lru_locks mdc
23351         dd if=/dev/urandom of=$tmp bs=265000 count=1
23352         dd if=$tmp of=$dom bs=265000 count=1
23353         cancel_lru_locks mdc
23354         cat /etc/hosts >> $tmp
23355         lctl set_param -n mdc.*.stats=clear
23356
23357         echo "Append to the same page"
23358         cat /etc/hosts >> $dom
23359         local num=$(get_mdc_stats $mdtidx ost_read)
23360         local ra=$(get_mdc_stats $mdtidx req_active)
23361         local rw=$(get_mdc_stats $mdtidx req_waittime)
23362
23363         [ -z $num ] || error "$num READ RPC occured"
23364         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23365         echo "... DONE"
23366
23367         # compare content
23368         cmp $tmp $dom || error "file miscompare"
23369
23370         cancel_lru_locks mdc
23371         lctl set_param -n mdc.*.stats=clear
23372
23373         echo "Open and read file"
23374         cat $dom > /dev/null
23375         local num=$(get_mdc_stats $mdtidx ost_read)
23376         local ra=$(get_mdc_stats $mdtidx req_active)
23377         local rw=$(get_mdc_stats $mdtidx req_waittime)
23378
23379         [ -z $num ] && num=0
23380         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23381         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23382         echo "... DONE"
23383
23384         # compare content
23385         cmp $tmp $dom || error "file miscompare"
23386
23387         return 0
23388 }
23389 run_test 271f "DoM: read on open (200K file and read tail)"
23390
23391 test_271g() {
23392         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23393                 skip "Skipping due to old client or server version"
23394
23395         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23396         # to get layout
23397         $CHECKSTAT -t file $DIR1/$tfile
23398
23399         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23400         MULTIOP_PID=$!
23401         sleep 1
23402         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23403         $LCTL set_param fail_loc=0x80000314
23404         rm $DIR1/$tfile || error "Unlink fails"
23405         RC=$?
23406         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23407         [ $RC -eq 0 ] || error "Failed write to stale object"
23408 }
23409 run_test 271g "Discard DoM data vs client flush race"
23410
23411 test_272a() {
23412         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23413                 skip "Need MDS version at least 2.11.50"
23414
23415         local dom=$DIR/$tdir/dom
23416         mkdir -p $DIR/$tdir
23417
23418         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23419         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23420                 error "failed to write data into $dom"
23421         local old_md5=$(md5sum $dom)
23422
23423         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23424                 error "failed to migrate to the same DoM component"
23425
23426         local new_md5=$(md5sum $dom)
23427
23428         [ "$old_md5" == "$new_md5" ] ||
23429                 error "md5sum differ: $old_md5, $new_md5"
23430
23431         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23432                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23433 }
23434 run_test 272a "DoM migration: new layout with the same DOM component"
23435
23436 test_272b() {
23437         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23438                 skip "Need MDS version at least 2.11.50"
23439
23440         local dom=$DIR/$tdir/dom
23441         mkdir -p $DIR/$tdir
23442         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23443
23444         local mdtidx=$($LFS getstripe -m $dom)
23445         local mdtname=MDT$(printf %04x $mdtidx)
23446         local facet=mds$((mdtidx + 1))
23447
23448         local mdtfree1=$(do_facet $facet \
23449                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23450         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23451                 error "failed to write data into $dom"
23452         local old_md5=$(md5sum $dom)
23453         cancel_lru_locks mdc
23454         local mdtfree1=$(do_facet $facet \
23455                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23456
23457         $LFS migrate -c2 $dom ||
23458                 error "failed to migrate to the new composite layout"
23459         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23460                 error "MDT stripe was not removed"
23461
23462         cancel_lru_locks mdc
23463         local new_md5=$(md5sum $dom)
23464         [ "$old_md5" == "$new_md5" ] ||
23465                 error "$old_md5 != $new_md5"
23466
23467         # Skip free space checks with ZFS
23468         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23469                 local mdtfree2=$(do_facet $facet \
23470                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23471                 [ $mdtfree2 -gt $mdtfree1 ] ||
23472                         error "MDT space is not freed after migration"
23473         fi
23474         return 0
23475 }
23476 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23477
23478 test_272c() {
23479         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23480                 skip "Need MDS version at least 2.11.50"
23481
23482         local dom=$DIR/$tdir/$tfile
23483         mkdir -p $DIR/$tdir
23484         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23485
23486         local mdtidx=$($LFS getstripe -m $dom)
23487         local mdtname=MDT$(printf %04x $mdtidx)
23488         local facet=mds$((mdtidx + 1))
23489
23490         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23491                 error "failed to write data into $dom"
23492         local old_md5=$(md5sum $dom)
23493         cancel_lru_locks mdc
23494         local mdtfree1=$(do_facet $facet \
23495                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23496
23497         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23498                 error "failed to migrate to the new composite layout"
23499         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23500                 error "MDT stripe was not removed"
23501
23502         cancel_lru_locks mdc
23503         local new_md5=$(md5sum $dom)
23504         [ "$old_md5" == "$new_md5" ] ||
23505                 error "$old_md5 != $new_md5"
23506
23507         # Skip free space checks with ZFS
23508         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23509                 local mdtfree2=$(do_facet $facet \
23510                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23511                 [ $mdtfree2 -gt $mdtfree1 ] ||
23512                         error "MDS space is not freed after migration"
23513         fi
23514         return 0
23515 }
23516 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23517
23518 test_272d() {
23519         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23520                 skip "Need MDS version at least 2.12.55"
23521
23522         local dom=$DIR/$tdir/$tfile
23523         mkdir -p $DIR/$tdir
23524         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23525
23526         local mdtidx=$($LFS getstripe -m $dom)
23527         local mdtname=MDT$(printf %04x $mdtidx)
23528         local facet=mds$((mdtidx + 1))
23529
23530         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23531                 error "failed to write data into $dom"
23532         local old_md5=$(md5sum $dom)
23533         cancel_lru_locks mdc
23534         local mdtfree1=$(do_facet $facet \
23535                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23536
23537         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23538                 error "failed mirroring to the new composite layout"
23539         $LFS mirror resync $dom ||
23540                 error "failed mirror resync"
23541         $LFS mirror split --mirror-id 1 -d $dom ||
23542                 error "failed mirror split"
23543
23544         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23545                 error "MDT stripe was not removed"
23546
23547         cancel_lru_locks mdc
23548         local new_md5=$(md5sum $dom)
23549         [ "$old_md5" == "$new_md5" ] ||
23550                 error "$old_md5 != $new_md5"
23551
23552         # Skip free space checks with ZFS
23553         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23554                 local mdtfree2=$(do_facet $facet \
23555                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23556                 [ $mdtfree2 -gt $mdtfree1 ] ||
23557                         error "MDS space is not freed after DOM mirror deletion"
23558         fi
23559         return 0
23560 }
23561 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23562
23563 test_272e() {
23564         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23565                 skip "Need MDS version at least 2.12.55"
23566
23567         local dom=$DIR/$tdir/$tfile
23568         mkdir -p $DIR/$tdir
23569         $LFS setstripe -c 2 $dom
23570
23571         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23572                 error "failed to write data into $dom"
23573         local old_md5=$(md5sum $dom)
23574         cancel_lru_locks
23575
23576         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23577                 error "failed mirroring to the DOM layout"
23578         $LFS mirror resync $dom ||
23579                 error "failed mirror resync"
23580         $LFS mirror split --mirror-id 1 -d $dom ||
23581                 error "failed mirror split"
23582
23583         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23584                 error "MDT stripe wasn't set"
23585
23586         cancel_lru_locks
23587         local new_md5=$(md5sum $dom)
23588         [ "$old_md5" == "$new_md5" ] ||
23589                 error "$old_md5 != $new_md5"
23590
23591         return 0
23592 }
23593 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23594
23595 test_272f() {
23596         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23597                 skip "Need MDS version at least 2.12.55"
23598
23599         local dom=$DIR/$tdir/$tfile
23600         mkdir -p $DIR/$tdir
23601         $LFS setstripe -c 2 $dom
23602
23603         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23604                 error "failed to write data into $dom"
23605         local old_md5=$(md5sum $dom)
23606         cancel_lru_locks
23607
23608         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23609                 error "failed migrating to the DOM file"
23610
23611         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23612                 error "MDT stripe wasn't set"
23613
23614         cancel_lru_locks
23615         local new_md5=$(md5sum $dom)
23616         [ "$old_md5" != "$new_md5" ] &&
23617                 error "$old_md5 != $new_md5"
23618
23619         return 0
23620 }
23621 run_test 272f "DoM migration: OST-striped file to DOM file"
23622
23623 test_273a() {
23624         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23625                 skip "Need MDS version at least 2.11.50"
23626
23627         # Layout swap cannot be done if either file has DOM component,
23628         # this will never be supported, migration should be used instead
23629
23630         local dom=$DIR/$tdir/$tfile
23631         mkdir -p $DIR/$tdir
23632
23633         $LFS setstripe -c2 ${dom}_plain
23634         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23635         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23636                 error "can swap layout with DoM component"
23637         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23638                 error "can swap layout with DoM component"
23639
23640         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23641         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23642                 error "can swap layout with DoM component"
23643         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23644                 error "can swap layout with DoM component"
23645         return 0
23646 }
23647 run_test 273a "DoM: layout swapping should fail with DOM"
23648
23649 test_273b() {
23650         mkdir -p $DIR/$tdir
23651         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23652
23653 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23654         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23655
23656         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23657 }
23658 run_test 273b "DoM: race writeback and object destroy"
23659
23660 test_275() {
23661         remote_ost_nodsh && skip "remote OST with nodsh"
23662         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23663                 skip "Need OST version >= 2.10.57"
23664
23665         local file=$DIR/$tfile
23666         local oss
23667
23668         oss=$(comma_list $(osts_nodes))
23669
23670         dd if=/dev/urandom of=$file bs=1M count=2 ||
23671                 error "failed to create a file"
23672         cancel_lru_locks osc
23673
23674         #lock 1
23675         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23676                 error "failed to read a file"
23677
23678 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23679         $LCTL set_param fail_loc=0x8000031f
23680
23681         cancel_lru_locks osc &
23682         sleep 1
23683
23684 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23685         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23686         #IO takes another lock, but matches the PENDING one
23687         #and places it to the IO RPC
23688         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23689                 error "failed to read a file with PENDING lock"
23690 }
23691 run_test 275 "Read on a canceled duplicate lock"
23692
23693 test_276() {
23694         remote_ost_nodsh && skip "remote OST with nodsh"
23695         local pid
23696
23697         do_facet ost1 "(while true; do \
23698                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23699                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23700         pid=$!
23701
23702         for LOOP in $(seq 20); do
23703                 stop ost1
23704                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23705         done
23706         kill -9 $pid
23707         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23708                 rm $TMP/sanity_276_pid"
23709 }
23710 run_test 276 "Race between mount and obd_statfs"
23711
23712 test_277() {
23713         $LCTL set_param ldlm.namespaces.*.lru_size=0
23714         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23715         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23716                         grep ^used_mb | awk '{print $2}')
23717         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23718         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23719                 oflag=direct conv=notrunc
23720         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23721                         grep ^used_mb | awk '{print $2}')
23722         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23723 }
23724 run_test 277 "Direct IO shall drop page cache"
23725
23726 test_278() {
23727         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23728         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23729         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23730                 skip "needs the same host for mdt1 mdt2" && return
23731
23732         local pid1
23733         local pid2
23734
23735 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23736         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23737         stop mds2 &
23738         pid2=$!
23739
23740         stop mds1
23741
23742         echo "Starting MDTs"
23743         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23744         wait $pid2
23745 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23746 #will return NULL
23747         do_facet mds2 $LCTL set_param fail_loc=0
23748
23749         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23750         wait_recovery_complete mds2
23751 }
23752 run_test 278 "Race starting MDS between MDTs stop/start"
23753
23754 test_280() {
23755         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23756                 skip "Need MGS version at least 2.13.52"
23757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23758         combined_mgs_mds || skip "needs combined MGS/MDT"
23759
23760         umount_client $MOUNT
23761 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23762         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23763
23764         mount_client $MOUNT &
23765         sleep 1
23766         stop mgs || error "stop mgs failed"
23767         #for a race mgs would crash
23768         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23769         # make sure we unmount client before remounting
23770         wait
23771         umount_client $MOUNT
23772         mount_client $MOUNT || error "mount client failed"
23773 }
23774 run_test 280 "Race between MGS umount and client llog processing"
23775
23776 cleanup_test_300() {
23777         trap 0
23778         umask $SAVE_UMASK
23779 }
23780 test_striped_dir() {
23781         local mdt_index=$1
23782         local stripe_count
23783         local stripe_index
23784
23785         mkdir -p $DIR/$tdir
23786
23787         SAVE_UMASK=$(umask)
23788         trap cleanup_test_300 RETURN EXIT
23789
23790         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23791                                                 $DIR/$tdir/striped_dir ||
23792                 error "set striped dir error"
23793
23794         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23795         [ "$mode" = "755" ] || error "expect 755 got $mode"
23796
23797         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23798                 error "getdirstripe failed"
23799         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23800         if [ "$stripe_count" != "2" ]; then
23801                 error "1:stripe_count is $stripe_count, expect 2"
23802         fi
23803         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23804         if [ "$stripe_count" != "2" ]; then
23805                 error "2:stripe_count is $stripe_count, expect 2"
23806         fi
23807
23808         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23809         if [ "$stripe_index" != "$mdt_index" ]; then
23810                 error "stripe_index is $stripe_index, expect $mdt_index"
23811         fi
23812
23813         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23814                 error "nlink error after create striped dir"
23815
23816         mkdir $DIR/$tdir/striped_dir/a
23817         mkdir $DIR/$tdir/striped_dir/b
23818
23819         stat $DIR/$tdir/striped_dir/a ||
23820                 error "create dir under striped dir failed"
23821         stat $DIR/$tdir/striped_dir/b ||
23822                 error "create dir under striped dir failed"
23823
23824         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23825                 error "nlink error after mkdir"
23826
23827         rmdir $DIR/$tdir/striped_dir/a
23828         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23829                 error "nlink error after rmdir"
23830
23831         rmdir $DIR/$tdir/striped_dir/b
23832         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23833                 error "nlink error after rmdir"
23834
23835         chattr +i $DIR/$tdir/striped_dir
23836         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23837                 error "immutable flags not working under striped dir!"
23838         chattr -i $DIR/$tdir/striped_dir
23839
23840         rmdir $DIR/$tdir/striped_dir ||
23841                 error "rmdir striped dir error"
23842
23843         cleanup_test_300
23844
23845         true
23846 }
23847
23848 test_300a() {
23849         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23850                 skip "skipped for lustre < 2.7.0"
23851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23852         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23853
23854         test_striped_dir 0 || error "failed on striped dir on MDT0"
23855         test_striped_dir 1 || error "failed on striped dir on MDT0"
23856 }
23857 run_test 300a "basic striped dir sanity test"
23858
23859 test_300b() {
23860         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23861                 skip "skipped for lustre < 2.7.0"
23862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23863         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23864
23865         local i
23866         local mtime1
23867         local mtime2
23868         local mtime3
23869
23870         test_mkdir $DIR/$tdir || error "mkdir fail"
23871         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23872                 error "set striped dir error"
23873         for i in {0..9}; do
23874                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23875                 sleep 1
23876                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23877                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23878                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23879                 sleep 1
23880                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23881                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23882                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23883         done
23884         true
23885 }
23886 run_test 300b "check ctime/mtime for striped dir"
23887
23888 test_300c() {
23889         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23890                 skip "skipped for lustre < 2.7.0"
23891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23893
23894         local file_count
23895
23896         mkdir_on_mdt0 $DIR/$tdir
23897         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23898                 error "set striped dir error"
23899
23900         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23901                 error "chown striped dir failed"
23902
23903         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23904                 error "create 5k files failed"
23905
23906         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23907
23908         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23909
23910         rm -rf $DIR/$tdir
23911 }
23912 run_test 300c "chown && check ls under striped directory"
23913
23914 test_300d() {
23915         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23916                 skip "skipped for lustre < 2.7.0"
23917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23919
23920         local stripe_count
23921         local file
23922
23923         mkdir -p $DIR/$tdir
23924         $LFS setstripe -c 2 $DIR/$tdir
23925
23926         #local striped directory
23927         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23928                 error "set striped dir error"
23929         #look at the directories for debug purposes
23930         ls -l $DIR/$tdir
23931         $LFS getdirstripe $DIR/$tdir
23932         ls -l $DIR/$tdir/striped_dir
23933         $LFS getdirstripe $DIR/$tdir/striped_dir
23934         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23935                 error "create 10 files failed"
23936
23937         #remote striped directory
23938         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23939                 error "set striped dir error"
23940         #look at the directories for debug purposes
23941         ls -l $DIR/$tdir
23942         $LFS getdirstripe $DIR/$tdir
23943         ls -l $DIR/$tdir/remote_striped_dir
23944         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23945         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23946                 error "create 10 files failed"
23947
23948         for file in $(find $DIR/$tdir); do
23949                 stripe_count=$($LFS getstripe -c $file)
23950                 [ $stripe_count -eq 2 ] ||
23951                         error "wrong stripe $stripe_count for $file"
23952         done
23953
23954         rm -rf $DIR/$tdir
23955 }
23956 run_test 300d "check default stripe under striped directory"
23957
23958 test_300e() {
23959         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23960                 skip "Need MDS version at least 2.7.55"
23961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23962         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23963
23964         local stripe_count
23965         local file
23966
23967         mkdir -p $DIR/$tdir
23968
23969         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23970                 error "set striped dir error"
23971
23972         touch $DIR/$tdir/striped_dir/a
23973         touch $DIR/$tdir/striped_dir/b
23974         touch $DIR/$tdir/striped_dir/c
23975
23976         mkdir $DIR/$tdir/striped_dir/dir_a
23977         mkdir $DIR/$tdir/striped_dir/dir_b
23978         mkdir $DIR/$tdir/striped_dir/dir_c
23979
23980         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23981                 error "set striped adir under striped dir error"
23982
23983         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23984                 error "set striped bdir under striped dir error"
23985
23986         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23987                 error "set striped cdir under striped dir error"
23988
23989         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23990                 error "rename dir under striped dir fails"
23991
23992         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23993                 error "rename dir under different stripes fails"
23994
23995         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23996                 error "rename file under striped dir should succeed"
23997
23998         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23999                 error "rename dir under striped dir should succeed"
24000
24001         rm -rf $DIR/$tdir
24002 }
24003 run_test 300e "check rename under striped directory"
24004
24005 test_300f() {
24006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24008         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24009                 skip "Need MDS version at least 2.7.55"
24010
24011         local stripe_count
24012         local file
24013
24014         rm -rf $DIR/$tdir
24015         mkdir -p $DIR/$tdir
24016
24017         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24018                 error "set striped dir error"
24019
24020         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24021                 error "set striped dir error"
24022
24023         touch $DIR/$tdir/striped_dir/a
24024         mkdir $DIR/$tdir/striped_dir/dir_a
24025         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24026                 error "create striped dir under striped dir fails"
24027
24028         touch $DIR/$tdir/striped_dir1/b
24029         mkdir $DIR/$tdir/striped_dir1/dir_b
24030         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24031                 error "create striped dir under striped dir fails"
24032
24033         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24034                 error "rename dir under different striped dir should fail"
24035
24036         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24037                 error "rename striped dir under diff striped dir should fail"
24038
24039         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24040                 error "rename file under diff striped dirs fails"
24041
24042         rm -rf $DIR/$tdir
24043 }
24044 run_test 300f "check rename cross striped directory"
24045
24046 test_300_check_default_striped_dir()
24047 {
24048         local dirname=$1
24049         local default_count=$2
24050         local default_index=$3
24051         local stripe_count
24052         local stripe_index
24053         local dir_stripe_index
24054         local dir
24055
24056         echo "checking $dirname $default_count $default_index"
24057         $LFS setdirstripe -D -c $default_count -i $default_index \
24058                                 -H all_char $DIR/$tdir/$dirname ||
24059                 error "set default stripe on striped dir error"
24060         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24061         [ $stripe_count -eq $default_count ] ||
24062                 error "expect $default_count get $stripe_count for $dirname"
24063
24064         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24065         [ $stripe_index -eq $default_index ] ||
24066                 error "expect $default_index get $stripe_index for $dirname"
24067
24068         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24069                                                 error "create dirs failed"
24070
24071         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24072         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24073         for dir in $(find $DIR/$tdir/$dirname/*); do
24074                 stripe_count=$($LFS getdirstripe -c $dir)
24075                 (( $stripe_count == $default_count )) ||
24076                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24077                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24078                 error "stripe count $default_count != $stripe_count for $dir"
24079
24080                 stripe_index=$($LFS getdirstripe -i $dir)
24081                 [ $default_index -eq -1 ] ||
24082                         [ $stripe_index -eq $default_index ] ||
24083                         error "$stripe_index != $default_index for $dir"
24084
24085                 #check default stripe
24086                 stripe_count=$($LFS getdirstripe -D -c $dir)
24087                 [ $stripe_count -eq $default_count ] ||
24088                 error "default count $default_count != $stripe_count for $dir"
24089
24090                 stripe_index=$($LFS getdirstripe -D -i $dir)
24091                 [ $stripe_index -eq $default_index ] ||
24092                 error "default index $default_index != $stripe_index for $dir"
24093         done
24094         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24095 }
24096
24097 test_300g() {
24098         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24099         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24100                 skip "Need MDS version at least 2.7.55"
24101
24102         local dir
24103         local stripe_count
24104         local stripe_index
24105
24106         mkdir_on_mdt0 $DIR/$tdir
24107         mkdir $DIR/$tdir/normal_dir
24108
24109         #Checking when client cache stripe index
24110         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24111         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24112                 error "create striped_dir failed"
24113
24114         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24115                 error "create dir0 fails"
24116         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24117         [ $stripe_index -eq 0 ] ||
24118                 error "dir0 expect index 0 got $stripe_index"
24119
24120         mkdir $DIR/$tdir/striped_dir/dir1 ||
24121                 error "create dir1 fails"
24122         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24123         [ $stripe_index -eq 1 ] ||
24124                 error "dir1 expect index 1 got $stripe_index"
24125
24126         #check default stripe count/stripe index
24127         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24128         test_300_check_default_striped_dir normal_dir 1 0
24129         test_300_check_default_striped_dir normal_dir -1 1
24130         test_300_check_default_striped_dir normal_dir 2 -1
24131
24132         #delete default stripe information
24133         echo "delete default stripeEA"
24134         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24135                 error "set default stripe on striped dir error"
24136
24137         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24138         for dir in $(find $DIR/$tdir/normal_dir/*); do
24139                 stripe_count=$($LFS getdirstripe -c $dir)
24140                 [ $stripe_count -eq 0 ] ||
24141                         error "expect 1 get $stripe_count for $dir"
24142         done
24143 }
24144 run_test 300g "check default striped directory for normal directory"
24145
24146 test_300h() {
24147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24148         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24149                 skip "Need MDS version at least 2.7.55"
24150
24151         local dir
24152         local stripe_count
24153
24154         mkdir $DIR/$tdir
24155         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24156                 error "set striped dir error"
24157
24158         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24159         test_300_check_default_striped_dir striped_dir 1 0
24160         test_300_check_default_striped_dir striped_dir -1 1
24161         test_300_check_default_striped_dir striped_dir 2 -1
24162
24163         #delete default stripe information
24164         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24165                 error "set default stripe on striped dir error"
24166
24167         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24168         for dir in $(find $DIR/$tdir/striped_dir/*); do
24169                 stripe_count=$($LFS getdirstripe -c $dir)
24170                 [ $stripe_count -eq 0 ] ||
24171                         error "expect 1 get $stripe_count for $dir"
24172         done
24173 }
24174 run_test 300h "check default striped directory for striped directory"
24175
24176 test_300i() {
24177         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24178         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24179         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24180                 skip "Need MDS version at least 2.7.55"
24181
24182         local stripe_count
24183         local file
24184
24185         mkdir $DIR/$tdir
24186
24187         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24188                 error "set striped dir error"
24189
24190         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24191                 error "create files under striped dir failed"
24192
24193         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24194                 error "set striped hashdir error"
24195
24196         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24197                 error "create dir0 under hash dir failed"
24198         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24199                 error "create dir1 under hash dir failed"
24200         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24201                 error "create dir2 under hash dir failed"
24202
24203         # unfortunately, we need to umount to clear dir layout cache for now
24204         # once we fully implement dir layout, we can drop this
24205         umount_client $MOUNT || error "umount failed"
24206         mount_client $MOUNT || error "mount failed"
24207
24208         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24209         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24210         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24211
24212         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24213                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24214                         error "create crush2 dir $tdir/hashdir/d3 failed"
24215                 $LFS find -H crush2 $DIR/$tdir/hashdir
24216                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24217                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24218
24219                 # mkdir with an invalid hash type (hash=fail_val) from client
24220                 # should be replaced on MDS with a valid (default) hash type
24221                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24222                 $LCTL set_param fail_loc=0x1901 fail_val=99
24223                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24224
24225                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24226                 local expect=$(do_facet mds1 \
24227                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24228                 [[ $hash == $expect ]] ||
24229                         error "d99 hash '$hash' != expected hash '$expect'"
24230         fi
24231
24232         #set the stripe to be unknown hash type on read
24233         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24234         $LCTL set_param fail_loc=0x1901 fail_val=99
24235         for ((i = 0; i < 10; i++)); do
24236                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24237                         error "stat f-$i failed"
24238                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24239         done
24240
24241         touch $DIR/$tdir/striped_dir/f0 &&
24242                 error "create under striped dir with unknown hash should fail"
24243
24244         $LCTL set_param fail_loc=0
24245
24246         umount_client $MOUNT || error "umount failed"
24247         mount_client $MOUNT || error "mount failed"
24248
24249         return 0
24250 }
24251 run_test 300i "client handle unknown hash type striped directory"
24252
24253 test_300j() {
24254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24256         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24257                 skip "Need MDS version at least 2.7.55"
24258
24259         local stripe_count
24260         local file
24261
24262         mkdir $DIR/$tdir
24263
24264         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24265         $LCTL set_param fail_loc=0x1702
24266         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24267                 error "set striped dir error"
24268
24269         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24270                 error "create files under striped dir failed"
24271
24272         $LCTL set_param fail_loc=0
24273
24274         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24275
24276         return 0
24277 }
24278 run_test 300j "test large update record"
24279
24280 test_300k() {
24281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24283         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24284                 skip "Need MDS version at least 2.7.55"
24285
24286         # this test needs a huge transaction
24287         local kb
24288         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24289              osd*.$FSNAME-MDT0000.kbytestotal")
24290         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24291
24292         local stripe_count
24293         local file
24294
24295         mkdir $DIR/$tdir
24296
24297         #define OBD_FAIL_LARGE_STRIPE   0x1703
24298         $LCTL set_param fail_loc=0x1703
24299         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24300                 error "set striped dir error"
24301         $LCTL set_param fail_loc=0
24302
24303         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24304                 error "getstripeddir fails"
24305         rm -rf $DIR/$tdir/striped_dir ||
24306                 error "unlink striped dir fails"
24307
24308         return 0
24309 }
24310 run_test 300k "test large striped directory"
24311
24312 test_300l() {
24313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24315         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24316                 skip "Need MDS version at least 2.7.55"
24317
24318         local stripe_index
24319
24320         test_mkdir -p $DIR/$tdir/striped_dir
24321         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24322                         error "chown $RUNAS_ID failed"
24323         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24324                 error "set default striped dir failed"
24325
24326         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24327         $LCTL set_param fail_loc=0x80000158
24328         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24329
24330         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24331         [ $stripe_index -eq 1 ] ||
24332                 error "expect 1 get $stripe_index for $dir"
24333 }
24334 run_test 300l "non-root user to create dir under striped dir with stale layout"
24335
24336 test_300m() {
24337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24338         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24339         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24340                 skip "Need MDS version at least 2.7.55"
24341
24342         mkdir -p $DIR/$tdir/striped_dir
24343         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24344                 error "set default stripes dir error"
24345
24346         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24347
24348         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24349         [ $stripe_count -eq 0 ] ||
24350                         error "expect 0 get $stripe_count for a"
24351
24352         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24353                 error "set default stripes dir error"
24354
24355         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24356
24357         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24358         [ $stripe_count -eq 0 ] ||
24359                         error "expect 0 get $stripe_count for b"
24360
24361         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24362                 error "set default stripes dir error"
24363
24364         mkdir $DIR/$tdir/striped_dir/c &&
24365                 error "default stripe_index is invalid, mkdir c should fails"
24366
24367         rm -rf $DIR/$tdir || error "rmdir fails"
24368 }
24369 run_test 300m "setstriped directory on single MDT FS"
24370
24371 cleanup_300n() {
24372         local list=$(comma_list $(mdts_nodes))
24373
24374         trap 0
24375         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24376 }
24377
24378 test_300n() {
24379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24381         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24382                 skip "Need MDS version at least 2.7.55"
24383         remote_mds_nodsh && skip "remote MDS with nodsh"
24384
24385         local stripe_index
24386         local list=$(comma_list $(mdts_nodes))
24387
24388         trap cleanup_300n RETURN EXIT
24389         mkdir -p $DIR/$tdir
24390         chmod 777 $DIR/$tdir
24391         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24392                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24393                 error "create striped dir succeeds with gid=0"
24394
24395         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24396         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24397                 error "create striped dir fails with gid=-1"
24398
24399         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24400         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24401                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24402                 error "set default striped dir succeeds with gid=0"
24403
24404
24405         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24406         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24407                 error "set default striped dir fails with gid=-1"
24408
24409
24410         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24411         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24412                                         error "create test_dir fails"
24413         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24414                                         error "create test_dir1 fails"
24415         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24416                                         error "create test_dir2 fails"
24417         cleanup_300n
24418 }
24419 run_test 300n "non-root user to create dir under striped dir with default EA"
24420
24421 test_300o() {
24422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24423         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24424         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24425                 skip "Need MDS version at least 2.7.55"
24426
24427         local numfree1
24428         local numfree2
24429
24430         mkdir -p $DIR/$tdir
24431
24432         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24433         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24434         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24435                 skip "not enough free inodes $numfree1 $numfree2"
24436         fi
24437
24438         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24439         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24440         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24441                 skip "not enough free space $numfree1 $numfree2"
24442         fi
24443
24444         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24445                 error "setdirstripe fails"
24446
24447         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24448                 error "create dirs fails"
24449
24450         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24451         ls $DIR/$tdir/striped_dir > /dev/null ||
24452                 error "ls striped dir fails"
24453         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24454                 error "unlink big striped dir fails"
24455 }
24456 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24457
24458 test_300p() {
24459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24461         remote_mds_nodsh && skip "remote MDS with nodsh"
24462
24463         mkdir_on_mdt0 $DIR/$tdir
24464
24465         #define OBD_FAIL_OUT_ENOSPC     0x1704
24466         do_facet mds2 lctl set_param fail_loc=0x80001704
24467         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24468                  && error "create striped directory should fail"
24469
24470         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24471
24472         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24473         true
24474 }
24475 run_test 300p "create striped directory without space"
24476
24477 test_300q() {
24478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24479         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24480
24481         local fd=$(free_fd)
24482         local cmd="exec $fd<$tdir"
24483         cd $DIR
24484         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24485         eval $cmd
24486         cmd="exec $fd<&-"
24487         trap "eval $cmd" EXIT
24488         cd $tdir || error "cd $tdir fails"
24489         rmdir  ../$tdir || error "rmdir $tdir fails"
24490         mkdir local_dir && error "create dir succeeds"
24491         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24492         eval $cmd
24493         return 0
24494 }
24495 run_test 300q "create remote directory under orphan directory"
24496
24497 test_300r() {
24498         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24499                 skip "Need MDS version at least 2.7.55" && return
24500         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24501
24502         mkdir $DIR/$tdir
24503
24504         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24505                 error "set striped dir error"
24506
24507         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24508                 error "getstripeddir fails"
24509
24510         local stripe_count
24511         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24512                       awk '/lmv_stripe_count:/ { print $2 }')
24513
24514         [ $MDSCOUNT -ne $stripe_count ] &&
24515                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24516
24517         rm -rf $DIR/$tdir/striped_dir ||
24518                 error "unlink striped dir fails"
24519 }
24520 run_test 300r "test -1 striped directory"
24521
24522 test_300s_helper() {
24523         local count=$1
24524
24525         local stripe_dir=$DIR/$tdir/striped_dir.$count
24526
24527         $LFS mkdir -c $count $stripe_dir ||
24528                 error "lfs mkdir -c error"
24529
24530         $LFS getdirstripe $stripe_dir ||
24531                 error "lfs getdirstripe fails"
24532
24533         local stripe_count
24534         stripe_count=$($LFS getdirstripe $stripe_dir |
24535                       awk '/lmv_stripe_count:/ { print $2 }')
24536
24537         [ $count -ne $stripe_count ] &&
24538                 error_noexit "bad stripe count $stripe_count expected $count"
24539
24540         local dupe_stripes
24541         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24542                 awk '/0x/ {count[$1] += 1}; END {
24543                         for (idx in count) {
24544                                 if (count[idx]>1) {
24545                                         print "index " idx " count " count[idx]
24546                                 }
24547                         }
24548                 }')
24549
24550         if [[ -n "$dupe_stripes" ]] ; then
24551                 lfs getdirstripe $stripe_dir
24552                 error_noexit "Dupe MDT above: $dupe_stripes "
24553         fi
24554
24555         rm -rf $stripe_dir ||
24556                 error_noexit "unlink $stripe_dir fails"
24557 }
24558
24559 test_300s() {
24560         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24561                 skip "Need MDS version at least 2.7.55" && return
24562         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24563
24564         mkdir $DIR/$tdir
24565         for count in $(seq 2 $MDSCOUNT); do
24566                 test_300s_helper $count
24567         done
24568 }
24569 run_test 300s "test lfs mkdir -c without -i"
24570
24571 test_300t() {
24572         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24573                 skip "need MDS 2.14.55 or later"
24574         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24575
24576         local testdir="$DIR/$tdir/striped_dir"
24577         local dir1=$testdir/dir1
24578         local dir2=$testdir/dir2
24579
24580         mkdir -p $testdir
24581
24582         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24583                 error "failed to set default stripe count for $testdir"
24584
24585         mkdir $dir1
24586         local stripe_count=$($LFS getdirstripe -c $dir1)
24587
24588         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24589
24590         local max_count=$((MDSCOUNT - 1))
24591         local mdts=$(comma_list $(mdts_nodes))
24592
24593         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24594         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24595
24596         mkdir $dir2
24597         stripe_count=$($LFS getdirstripe -c $dir2)
24598
24599         (( $stripe_count == $max_count )) || error "wrong stripe count"
24600 }
24601 run_test 300t "test max_mdt_stripecount"
24602
24603 prepare_remote_file() {
24604         mkdir $DIR/$tdir/src_dir ||
24605                 error "create remote source failed"
24606
24607         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24608                  error "cp to remote source failed"
24609         touch $DIR/$tdir/src_dir/a
24610
24611         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24612                 error "create remote target dir failed"
24613
24614         touch $DIR/$tdir/tgt_dir/b
24615
24616         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24617                 error "rename dir cross MDT failed!"
24618
24619         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24620                 error "src_child still exists after rename"
24621
24622         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24623                 error "missing file(a) after rename"
24624
24625         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24626                 error "diff after rename"
24627 }
24628
24629 test_310a() {
24630         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24632
24633         local remote_file=$DIR/$tdir/tgt_dir/b
24634
24635         mkdir -p $DIR/$tdir
24636
24637         prepare_remote_file || error "prepare remote file failed"
24638
24639         #open-unlink file
24640         $OPENUNLINK $remote_file $remote_file ||
24641                 error "openunlink $remote_file failed"
24642         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24643 }
24644 run_test 310a "open unlink remote file"
24645
24646 test_310b() {
24647         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24649
24650         local remote_file=$DIR/$tdir/tgt_dir/b
24651
24652         mkdir -p $DIR/$tdir
24653
24654         prepare_remote_file || error "prepare remote file failed"
24655
24656         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24657         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24658         $CHECKSTAT -t file $remote_file || error "check file failed"
24659 }
24660 run_test 310b "unlink remote file with multiple links while open"
24661
24662 test_310c() {
24663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24664         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24665
24666         local remote_file=$DIR/$tdir/tgt_dir/b
24667
24668         mkdir -p $DIR/$tdir
24669
24670         prepare_remote_file || error "prepare remote file failed"
24671
24672         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24673         multiop_bg_pause $remote_file O_uc ||
24674                         error "mulitop failed for remote file"
24675         MULTIPID=$!
24676         $MULTIOP $DIR/$tfile Ouc
24677         kill -USR1 $MULTIPID
24678         wait $MULTIPID
24679 }
24680 run_test 310c "open-unlink remote file with multiple links"
24681
24682 #LU-4825
24683 test_311() {
24684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24685         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24686         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24687                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24688         remote_mds_nodsh && skip "remote MDS with nodsh"
24689
24690         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24691         local mdts=$(comma_list $(mdts_nodes))
24692
24693         mkdir -p $DIR/$tdir
24694         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24695         createmany -o $DIR/$tdir/$tfile. 1000
24696
24697         # statfs data is not real time, let's just calculate it
24698         old_iused=$((old_iused + 1000))
24699
24700         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24701                         osp.*OST0000*MDT0000.create_count")
24702         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24703                                 osp.*OST0000*MDT0000.max_create_count")
24704         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24705
24706         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24707         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24708         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24709
24710         unlinkmany $DIR/$tdir/$tfile. 1000
24711
24712         do_nodes $mdts "$LCTL set_param -n \
24713                         osp.*OST0000*.max_create_count=$max_count"
24714         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24715                 do_nodes $mdts "$LCTL set_param -n \
24716                                 osp.*OST0000*.create_count=$count"
24717         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24718                         grep "=0" && error "create_count is zero"
24719
24720         local new_iused
24721         for i in $(seq 120); do
24722                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24723                 # system may be too busy to destroy all objs in time, use
24724                 # a somewhat small value to not fail autotest
24725                 [ $((old_iused - new_iused)) -gt 400 ] && break
24726                 sleep 1
24727         done
24728
24729         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24730         [ $((old_iused - new_iused)) -gt 400 ] ||
24731                 error "objs not destroyed after unlink"
24732 }
24733 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24734
24735 zfs_get_objid()
24736 {
24737         local ost=$1
24738         local tf=$2
24739         local fid=($($LFS getstripe $tf | grep 0x))
24740         local seq=${fid[3]#0x}
24741         local objid=${fid[1]}
24742
24743         local vdevdir=$(dirname $(facet_vdevice $ost))
24744         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24745         local zfs_zapid=$(do_facet $ost $cmd |
24746                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24747                           awk '/Object/{getline; print $1}')
24748         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24749                           awk "/$objid = /"'{printf $3}')
24750
24751         echo $zfs_objid
24752 }
24753
24754 zfs_object_blksz() {
24755         local ost=$1
24756         local objid=$2
24757
24758         local vdevdir=$(dirname $(facet_vdevice $ost))
24759         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24760         local blksz=$(do_facet $ost $cmd $objid |
24761                       awk '/dblk/{getline; printf $4}')
24762
24763         case "${blksz: -1}" in
24764                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24765                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24766                 *) ;;
24767         esac
24768
24769         echo $blksz
24770 }
24771
24772 test_312() { # LU-4856
24773         remote_ost_nodsh && skip "remote OST with nodsh"
24774         [ "$ost1_FSTYPE" = "zfs" ] ||
24775                 skip_env "the test only applies to zfs"
24776
24777         local max_blksz=$(do_facet ost1 \
24778                           $ZFS get -p recordsize $(facet_device ost1) |
24779                           awk '!/VALUE/{print $3}')
24780         local tf=$DIR/$tfile
24781
24782         $LFS setstripe -c1 $tf
24783         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
24784
24785         # Get ZFS object id
24786         local zfs_objid=$(zfs_get_objid $facet $tf)
24787         # block size change by sequential overwrite
24788         local bs
24789
24790         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24791                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24792
24793                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
24794                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
24795         done
24796         rm -f $tf
24797
24798         $LFS setstripe -c1 $tf
24799         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24800
24801         # block size change by sequential append write
24802         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24803         zfs_objid=$(zfs_get_objid $facet $tf)
24804         local count
24805
24806         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24807                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24808                         oflag=sync conv=notrunc
24809
24810                 blksz=$(zfs_object_blksz $facet $zfs_objid)
24811                 (( $blksz == 2 * count * PAGE_SIZE )) ||
24812                         error "blksz error, actual $blksz, " \
24813                                 "expected: 2 * $count * $PAGE_SIZE"
24814         done
24815         rm -f $tf
24816
24817         # random write
24818         $LFS setstripe -c1 $tf
24819         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24820         zfs_objid=$(zfs_get_objid $facet $tf)
24821
24822         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24823         blksz=$(zfs_object_blksz $facet $zfs_objid)
24824         (( blksz == PAGE_SIZE )) ||
24825                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24826
24827         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24828         blksz=$(zfs_object_blksz $facet $zfs_objid)
24829         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
24830
24831         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24832         blksz=$(zfs_object_blksz $facet $zfs_objid)
24833         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
24834 }
24835 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24836
24837 test_313() {
24838         remote_ost_nodsh && skip "remote OST with nodsh"
24839
24840         local file=$DIR/$tfile
24841
24842         rm -f $file
24843         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24844
24845         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24846         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24847         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24848                 error "write should failed"
24849         do_facet ost1 "$LCTL set_param fail_loc=0"
24850         rm -f $file
24851 }
24852 run_test 313 "io should fail after last_rcvd update fail"
24853
24854 test_314() {
24855         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24856
24857         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24858         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24859         rm -f $DIR/$tfile
24860         wait_delete_completed
24861         do_facet ost1 "$LCTL set_param fail_loc=0"
24862 }
24863 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24864
24865 test_315() { # LU-618
24866         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24867
24868         local file=$DIR/$tfile
24869         rm -f $file
24870
24871         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24872                 error "multiop file write failed"
24873         $MULTIOP $file oO_RDONLY:r4063232_c &
24874         PID=$!
24875
24876         sleep 2
24877
24878         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24879         kill -USR1 $PID
24880
24881         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24882         rm -f $file
24883 }
24884 run_test 315 "read should be accounted"
24885
24886 test_316() {
24887         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24888         large_xattr_enabled || skip "ea_inode feature disabled"
24889
24890         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24891         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24892         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24893         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24894
24895         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24896 }
24897 run_test 316 "lfs migrate of file with large_xattr enabled"
24898
24899 test_317() {
24900         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24901                 skip "Need MDS version at least 2.11.53"
24902         if [ "$ost1_FSTYPE" == "zfs" ]; then
24903                 skip "LU-10370: no implementation for ZFS"
24904         fi
24905
24906         local trunc_sz
24907         local grant_blk_size
24908
24909         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24910                         awk '/grant_block_size:/ { print $2; exit; }')
24911         #
24912         # Create File of size 5M. Truncate it to below size's and verify
24913         # blocks count.
24914         #
24915         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24916                 error "Create file $DIR/$tfile failed"
24917         stack_trap "rm -f $DIR/$tfile" EXIT
24918
24919         for trunc_sz in 2097152 4097 4000 509 0; do
24920                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24921                         error "truncate $tfile to $trunc_sz failed"
24922                 local sz=$(stat --format=%s $DIR/$tfile)
24923                 local blk=$(stat --format=%b $DIR/$tfile)
24924                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24925                                      grant_blk_size) * 8))
24926
24927                 if [[ $blk -ne $trunc_blk ]]; then
24928                         $(which stat) $DIR/$tfile
24929                         error "Expected Block $trunc_blk got $blk for $tfile"
24930                 fi
24931
24932                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24933                         error "Expected Size $trunc_sz got $sz for $tfile"
24934         done
24935
24936         #
24937         # sparse file test
24938         # Create file with a hole and write actual 65536 bytes which aligned
24939         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24940         #
24941         local bs=65536
24942         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24943                 error "Create file : $DIR/$tfile"
24944
24945         #
24946         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24947         # blocks. The block count must drop to 8.
24948         #
24949         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24950                 ((bs - grant_blk_size) + 1)))
24951         $TRUNCATE $DIR/$tfile $trunc_sz ||
24952                 error "truncate $tfile to $trunc_sz failed"
24953
24954         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24955         sz=$(stat --format=%s $DIR/$tfile)
24956         blk=$(stat --format=%b $DIR/$tfile)
24957
24958         if [[ $blk -ne $trunc_bsz ]]; then
24959                 $(which stat) $DIR/$tfile
24960                 error "Expected Block $trunc_bsz got $blk for $tfile"
24961         fi
24962
24963         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24964                 error "Expected Size $trunc_sz got $sz for $tfile"
24965 }
24966 run_test 317 "Verify blocks get correctly update after truncate"
24967
24968 test_318() {
24969         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24970         local old_max_active=$($LCTL get_param -n \
24971                             ${llite_name}.max_read_ahead_async_active \
24972                             2>/dev/null)
24973
24974         $LCTL set_param llite.*.max_read_ahead_async_active=256
24975         local max_active=$($LCTL get_param -n \
24976                            ${llite_name}.max_read_ahead_async_active \
24977                            2>/dev/null)
24978         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24979
24980         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24981                 error "set max_read_ahead_async_active should succeed"
24982
24983         $LCTL set_param llite.*.max_read_ahead_async_active=512
24984         max_active=$($LCTL get_param -n \
24985                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24986         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24987
24988         # restore @max_active
24989         [ $old_max_active -ne 0 ] && $LCTL set_param \
24990                 llite.*.max_read_ahead_async_active=$old_max_active
24991
24992         local old_threshold=$($LCTL get_param -n \
24993                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24994         local max_per_file_mb=$($LCTL get_param -n \
24995                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24996
24997         local invalid=$(($max_per_file_mb + 1))
24998         $LCTL set_param \
24999                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25000                         && error "set $invalid should fail"
25001
25002         local valid=$(($invalid - 1))
25003         $LCTL set_param \
25004                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25005                         error "set $valid should succeed"
25006         local threshold=$($LCTL get_param -n \
25007                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25008         [ $threshold -eq $valid ] || error \
25009                 "expect threshold $valid got $threshold"
25010         $LCTL set_param \
25011                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25012 }
25013 run_test 318 "Verify async readahead tunables"
25014
25015 test_319() {
25016         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25017
25018         local before=$(date +%s)
25019         local evict
25020         local mdir=$DIR/$tdir
25021         local file=$mdir/xxx
25022
25023         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25024         touch $file
25025
25026 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25027         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25028         $LFS migrate -m1 $mdir &
25029
25030         sleep 1
25031         dd if=$file of=/dev/null
25032         wait
25033         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25034           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25035
25036         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25037 }
25038 run_test 319 "lost lease lock on migrate error"
25039
25040 test_398a() { # LU-4198
25041         local ost1_imp=$(get_osc_import_name client ost1)
25042         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25043                          cut -d'.' -f2)
25044
25045         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25046         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25047
25048         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25049         # request a new lock on client
25050         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25051
25052         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25053         #local lock_count=$($LCTL get_param -n \
25054         #                  ldlm.namespaces.$imp_name.lru_size)
25055         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25056
25057         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25058
25059         # no lock cached, should use lockless DIO and not enqueue new lock
25060         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25061                 conv=notrunc ||
25062                 error "dio write failed"
25063         lock_count=$($LCTL get_param -n \
25064                      ldlm.namespaces.$imp_name.lru_size)
25065         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25066
25067         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25068
25069         # no lock cached, should use locked DIO append
25070         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25071                 conv=notrunc || error "DIO append failed"
25072         lock_count=$($LCTL get_param -n \
25073                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25074         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25075 }
25076 run_test 398a "direct IO should cancel lock otherwise lockless"
25077
25078 test_398b() { # LU-4198
25079         which fio || skip_env "no fio installed"
25080         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25081
25082         local size=48
25083         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25084
25085         local njobs=4
25086         # Single page, multiple pages, stripe size, 4*stripe size
25087         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25088                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25089                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25090                         --numjobs=$njobs --fallocate=none \
25091                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25092                         --filename=$DIR/$tfile &
25093                 bg_pid=$!
25094
25095                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25096                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25097                         --numjobs=$njobs --fallocate=none \
25098                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25099                         --filename=$DIR/$tfile || true
25100                 wait $bg_pid
25101         done
25102
25103         evict=$(do_facet client $LCTL get_param \
25104                 osc.$FSNAME-OST*-osc-*/state |
25105             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25106
25107         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25108                 (do_facet client $LCTL get_param \
25109                         osc.$FSNAME-OST*-osc-*/state;
25110                     error "eviction happened: $evict before:$before")
25111
25112         rm -f $DIR/$tfile
25113 }
25114 run_test 398b "DIO and buffer IO race"
25115
25116 test_398c() { # LU-4198
25117         local ost1_imp=$(get_osc_import_name client ost1)
25118         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25119                          cut -d'.' -f2)
25120
25121         which fio || skip_env "no fio installed"
25122
25123         saved_debug=$($LCTL get_param -n debug)
25124         $LCTL set_param debug=0
25125
25126         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25127         ((size /= 1024)) # by megabytes
25128         ((size /= 2)) # write half of the OST at most
25129         [ $size -gt 40 ] && size=40 #reduce test time anyway
25130
25131         $LFS setstripe -c 1 $DIR/$tfile
25132
25133         # it seems like ldiskfs reserves more space than necessary if the
25134         # writing blocks are not mapped, so it extends the file firstly
25135         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25136         cancel_lru_locks osc
25137
25138         # clear and verify rpc_stats later
25139         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25140
25141         local njobs=4
25142         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25143         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25144                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25145                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25146                 --filename=$DIR/$tfile
25147         [ $? -eq 0 ] || error "fio write error"
25148
25149         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25150                 error "Locks were requested while doing AIO"
25151
25152         # get the percentage of 1-page I/O
25153         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25154                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25155                 awk '{print $7}')
25156         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25157
25158         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25159         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25160                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25161                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25162                 --filename=$DIR/$tfile
25163         [ $? -eq 0 ] || error "fio mixed read write error"
25164
25165         echo "AIO with large block size ${size}M"
25166         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25167                 --numjobs=1 --fallocate=none --ioengine=libaio \
25168                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25169                 --filename=$DIR/$tfile
25170         [ $? -eq 0 ] || error "fio large block size failed"
25171
25172         rm -f $DIR/$tfile
25173         $LCTL set_param debug="$saved_debug"
25174 }
25175 run_test 398c "run fio to test AIO"
25176
25177 test_398d() { #  LU-13846
25178         which aiocp || skip_env "no aiocp installed"
25179         local aio_file=$DIR/$tfile.aio
25180
25181         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25182
25183         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25184         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25185         stack_trap "rm -f $DIR/$tfile $aio_file"
25186
25187         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25188
25189         # make sure we don't crash and fail properly
25190         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25191                 error "aio not aligned with PAGE SIZE should fail"
25192
25193         rm -f $DIR/$tfile $aio_file
25194 }
25195 run_test 398d "run aiocp to verify block size > stripe size"
25196
25197 test_398e() {
25198         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25199         touch $DIR/$tfile.new
25200         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25201 }
25202 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25203
25204 test_398f() { #  LU-14687
25205         which aiocp || skip_env "no aiocp installed"
25206         local aio_file=$DIR/$tfile.aio
25207
25208         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25209
25210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25211         stack_trap "rm -f $DIR/$tfile $aio_file"
25212
25213         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25214         $LCTL set_param fail_loc=0x1418
25215         # make sure we don't crash and fail properly
25216         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25217                 error "aio with page allocation failure succeeded"
25218         $LCTL set_param fail_loc=0
25219         diff $DIR/$tfile $aio_file
25220         [[ $? != 0 ]] || error "no diff after failed aiocp"
25221 }
25222 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25223
25224 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25225 # stripe and i/o size must be > stripe size
25226 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25227 # single RPC in flight.  This test shows async DIO submission is working by
25228 # showing multiple RPCs in flight.
25229 test_398g() { #  LU-13798
25230         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25231
25232         # We need to do some i/o first to acquire enough grant to put our RPCs
25233         # in flight; otherwise a new connection may not have enough grant
25234         # available
25235         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25236                 error "parallel dio failed"
25237         stack_trap "rm -f $DIR/$tfile"
25238
25239         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25240         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25241         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25242         stack_trap "$LCTL set_param -n $pages_per_rpc"
25243
25244         # Recreate file so it's empty
25245         rm -f $DIR/$tfile
25246         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25247         #Pause rpc completion to guarantee we see multiple rpcs in flight
25248         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25249         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25250         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25251
25252         # Clear rpc stats
25253         $LCTL set_param osc.*.rpc_stats=c
25254
25255         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25256                 error "parallel dio failed"
25257         stack_trap "rm -f $DIR/$tfile"
25258
25259         $LCTL get_param osc.*-OST0000-*.rpc_stats
25260         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25261                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25262                 grep "8:" | awk '{print $8}')
25263         # We look at the "8 rpcs in flight" field, and verify A) it is present
25264         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25265         # as expected for an 8M DIO to a file with 1M stripes.
25266         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25267
25268         # Verify turning off parallel dio works as expected
25269         # Clear rpc stats
25270         $LCTL set_param osc.*.rpc_stats=c
25271         $LCTL set_param llite.*.parallel_dio=0
25272         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25273
25274         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25275                 error "dio with parallel dio disabled failed"
25276
25277         # Ideally, we would see only one RPC in flight here, but there is an
25278         # unavoidable race between i/o completion and RPC in flight counting,
25279         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25280         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25281         # So instead we just verify it's always < 8.
25282         $LCTL get_param osc.*-OST0000-*.rpc_stats
25283         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25284                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25285                 grep '^$' -B1 | grep . | awk '{print $1}')
25286         [ $ret != "8:" ] ||
25287                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25288 }
25289 run_test 398g "verify parallel dio async RPC submission"
25290
25291 test_398h() { #  LU-13798
25292         local dio_file=$DIR/$tfile.dio
25293
25294         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25295
25296         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25297         stack_trap "rm -f $DIR/$tfile $dio_file"
25298
25299         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25300                 error "parallel dio failed"
25301         diff $DIR/$tfile $dio_file
25302         [[ $? == 0 ]] || error "file diff after aiocp"
25303 }
25304 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25305
25306 test_398i() { #  LU-13798
25307         local dio_file=$DIR/$tfile.dio
25308
25309         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25310
25311         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25312         stack_trap "rm -f $DIR/$tfile $dio_file"
25313
25314         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25315         $LCTL set_param fail_loc=0x1418
25316         # make sure we don't crash and fail properly
25317         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25318                 error "parallel dio page allocation failure succeeded"
25319         diff $DIR/$tfile $dio_file
25320         [[ $? != 0 ]] || error "no diff after failed aiocp"
25321 }
25322 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25323
25324 test_398j() { #  LU-13798
25325         # Stripe size > RPC size but less than i/o size tests split across
25326         # stripes and RPCs for individual i/o op
25327         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25328
25329         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25330         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25331         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25332         stack_trap "$LCTL set_param -n $pages_per_rpc"
25333
25334         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25335                 error "parallel dio write failed"
25336         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25337
25338         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25339                 error "parallel dio read failed"
25340         diff $DIR/$tfile $DIR/$tfile.2
25341         [[ $? == 0 ]] || error "file diff after parallel dio read"
25342 }
25343 run_test 398j "test parallel dio where stripe size > rpc_size"
25344
25345 test_398k() { #  LU-13798
25346         wait_delete_completed
25347         wait_mds_ost_sync
25348
25349         # 4 stripe file; we will cause out of space on OST0
25350         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25351
25352         # Fill OST0 (if it's not too large)
25353         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25354                    head -n1)
25355         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25356                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25357         fi
25358         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25359         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25360                 error "dd should fill OST0"
25361         stack_trap "rm -f $DIR/$tfile.1"
25362
25363         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25364         err=$?
25365
25366         ls -la $DIR/$tfile
25367         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25368                 error "file is not 0 bytes in size"
25369
25370         # dd above should not succeed, but don't error until here so we can
25371         # get debug info above
25372         [[ $err != 0 ]] ||
25373                 error "parallel dio write with enospc succeeded"
25374         stack_trap "rm -f $DIR/$tfile"
25375 }
25376 run_test 398k "test enospc on first stripe"
25377
25378 test_398l() { #  LU-13798
25379         wait_delete_completed
25380         wait_mds_ost_sync
25381
25382         # 4 stripe file; we will cause out of space on OST0
25383         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25384         # happens on the second i/o chunk we issue
25385         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25386
25387         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25388         stack_trap "rm -f $DIR/$tfile"
25389
25390         # Fill OST0 (if it's not too large)
25391         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25392                    head -n1)
25393         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25394                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25395         fi
25396         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25397         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25398                 error "dd should fill OST0"
25399         stack_trap "rm -f $DIR/$tfile.1"
25400
25401         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25402         err=$?
25403         stack_trap "rm -f $DIR/$tfile.2"
25404
25405         # Check that short write completed as expected
25406         ls -la $DIR/$tfile.2
25407         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25408                 error "file is not 1M in size"
25409
25410         # dd above should not succeed, but don't error until here so we can
25411         # get debug info above
25412         [[ $err != 0 ]] ||
25413                 error "parallel dio write with enospc succeeded"
25414
25415         # Truncate source file to same length as output file and diff them
25416         $TRUNCATE $DIR/$tfile 1048576
25417         diff $DIR/$tfile $DIR/$tfile.2
25418         [[ $? == 0 ]] || error "data incorrect after short write"
25419 }
25420 run_test 398l "test enospc on intermediate stripe/RPC"
25421
25422 test_398m() { #  LU-13798
25423         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25424
25425         # Set up failure on OST0, the first stripe:
25426         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25427         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25428         # OST0 is on ost1, OST1 is on ost2.
25429         # So this fail_val specifies OST0
25430         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25431         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25432
25433         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25434                 error "parallel dio write with failure on first stripe succeeded"
25435         stack_trap "rm -f $DIR/$tfile"
25436         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25437
25438         # Place data in file for read
25439         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25440                 error "parallel dio write failed"
25441
25442         # Fail read on OST0, first stripe
25443         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25444         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25445         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25446                 error "parallel dio read with error on first stripe succeeded"
25447         rm -f $DIR/$tfile.2
25448         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25449
25450         # Switch to testing on OST1, second stripe
25451         # Clear file contents, maintain striping
25452         echo > $DIR/$tfile
25453         # Set up failure on OST1, second stripe:
25454         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25455         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25456
25457         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25458                 error "parallel dio write with failure on second stripe succeeded"
25459         stack_trap "rm -f $DIR/$tfile"
25460         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25461
25462         # Place data in file for read
25463         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25464                 error "parallel dio write failed"
25465
25466         # Fail read on OST1, second stripe
25467         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25468         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25469         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25470                 error "parallel dio read with error on second stripe succeeded"
25471         rm -f $DIR/$tfile.2
25472         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25473 }
25474 run_test 398m "test RPC failures with parallel dio"
25475
25476 # Parallel submission of DIO should not cause problems for append, but it's
25477 # important to verify.
25478 test_398n() { #  LU-13798
25479         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25480
25481         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25482                 error "dd to create source file failed"
25483         stack_trap "rm -f $DIR/$tfile"
25484
25485         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25486                 error "parallel dio write with failure on second stripe succeeded"
25487         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25488         diff $DIR/$tfile $DIR/$tfile.1
25489         [[ $? == 0 ]] || error "data incorrect after append"
25490
25491 }
25492 run_test 398n "test append with parallel DIO"
25493
25494 test_398o() {
25495         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25496 }
25497 run_test 398o "right kms with DIO"
25498
25499 test_fake_rw() {
25500         local read_write=$1
25501         if [ "$read_write" = "write" ]; then
25502                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25503         elif [ "$read_write" = "read" ]; then
25504                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25505         else
25506                 error "argument error"
25507         fi
25508
25509         # turn off debug for performance testing
25510         local saved_debug=$($LCTL get_param -n debug)
25511         $LCTL set_param debug=0
25512
25513         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25514
25515         # get ost1 size - $FSNAME-OST0000
25516         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25517         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25518         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25519
25520         if [ "$read_write" = "read" ]; then
25521                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25522         fi
25523
25524         local start_time=$(date +%s.%N)
25525         $dd_cmd bs=1M count=$blocks oflag=sync ||
25526                 error "real dd $read_write error"
25527         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25528
25529         if [ "$read_write" = "write" ]; then
25530                 rm -f $DIR/$tfile
25531         fi
25532
25533         # define OBD_FAIL_OST_FAKE_RW           0x238
25534         do_facet ost1 $LCTL set_param fail_loc=0x238
25535
25536         local start_time=$(date +%s.%N)
25537         $dd_cmd bs=1M count=$blocks oflag=sync ||
25538                 error "fake dd $read_write error"
25539         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25540
25541         if [ "$read_write" = "write" ]; then
25542                 # verify file size
25543                 cancel_lru_locks osc
25544                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25545                         error "$tfile size not $blocks MB"
25546         fi
25547         do_facet ost1 $LCTL set_param fail_loc=0
25548
25549         echo "fake $read_write $duration_fake vs. normal $read_write" \
25550                 "$duration in seconds"
25551         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25552                 error_not_in_vm "fake write is slower"
25553
25554         $LCTL set_param -n debug="$saved_debug"
25555         rm -f $DIR/$tfile
25556 }
25557 test_399a() { # LU-7655 for OST fake write
25558         remote_ost_nodsh && skip "remote OST with nodsh"
25559
25560         test_fake_rw write
25561 }
25562 run_test 399a "fake write should not be slower than normal write"
25563
25564 test_399b() { # LU-8726 for OST fake read
25565         remote_ost_nodsh && skip "remote OST with nodsh"
25566         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25567                 skip_env "ldiskfs only test"
25568         fi
25569
25570         test_fake_rw read
25571 }
25572 run_test 399b "fake read should not be slower than normal read"
25573
25574 test_400a() { # LU-1606, was conf-sanity test_74
25575         if ! which $CC > /dev/null 2>&1; then
25576                 skip_env "$CC is not installed"
25577         fi
25578
25579         local extra_flags=''
25580         local out=$TMP/$tfile
25581         local prefix=/usr/include/lustre
25582         local prog
25583
25584         # Oleg removes .c files in his test rig so test if any c files exist
25585         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25586                 skip_env "Needed .c test files are missing"
25587
25588         if ! [[ -d $prefix ]]; then
25589                 # Assume we're running in tree and fixup the include path.
25590                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25591                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25592                 extra_flags+=" -L$LUSTRE/utils/.libs"
25593         fi
25594
25595         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25596                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25597                         error "client api broken"
25598         done
25599         rm -f $out
25600 }
25601 run_test 400a "Lustre client api program can compile and link"
25602
25603 test_400b() { # LU-1606, LU-5011
25604         local header
25605         local out=$TMP/$tfile
25606         local prefix=/usr/include/linux/lustre
25607
25608         # We use a hard coded prefix so that this test will not fail
25609         # when run in tree. There are headers in lustre/include/lustre/
25610         # that are not packaged (like lustre_idl.h) and have more
25611         # complicated include dependencies (like config.h and lnet/types.h).
25612         # Since this test about correct packaging we just skip them when
25613         # they don't exist (see below) rather than try to fixup cppflags.
25614
25615         if ! which $CC > /dev/null 2>&1; then
25616                 skip_env "$CC is not installed"
25617         fi
25618
25619         for header in $prefix/*.h; do
25620                 if ! [[ -f "$header" ]]; then
25621                         continue
25622                 fi
25623
25624                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25625                         continue # lustre_ioctl.h is internal header
25626                 fi
25627
25628                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25629                         error "cannot compile '$header'"
25630         done
25631         rm -f $out
25632 }
25633 run_test 400b "packaged headers can be compiled"
25634
25635 test_401a() { #LU-7437
25636         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25637         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25638
25639         #count the number of parameters by "list_param -R"
25640         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25641         #count the number of parameters by listing proc files
25642         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25643         echo "proc_dirs='$proc_dirs'"
25644         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25645         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25646                       sort -u | wc -l)
25647
25648         [ $params -eq $procs ] ||
25649                 error "found $params parameters vs. $procs proc files"
25650
25651         # test the list_param -D option only returns directories
25652         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25653         #count the number of parameters by listing proc directories
25654         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25655                 sort -u | wc -l)
25656
25657         [ $params -eq $procs ] ||
25658                 error "found $params parameters vs. $procs proc files"
25659 }
25660 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25661
25662 test_401b() {
25663         # jobid_var may not allow arbitrary values, so use jobid_name
25664         # if available
25665         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25666                 local testname=jobid_name tmp='testing%p'
25667         else
25668                 local testname=jobid_var tmp=testing
25669         fi
25670
25671         local save=$($LCTL get_param -n $testname)
25672
25673         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25674                 error "no error returned when setting bad parameters"
25675
25676         local jobid_new=$($LCTL get_param -n foe $testname baz)
25677         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25678
25679         $LCTL set_param -n fog=bam $testname=$save bat=fog
25680         local jobid_old=$($LCTL get_param -n foe $testname bag)
25681         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25682 }
25683 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25684
25685 test_401c() {
25686         # jobid_var may not allow arbitrary values, so use jobid_name
25687         # if available
25688         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25689                 local testname=jobid_name
25690         else
25691                 local testname=jobid_var
25692         fi
25693
25694         local jobid_var_old=$($LCTL get_param -n $testname)
25695         local jobid_var_new
25696
25697         $LCTL set_param $testname= &&
25698                 error "no error returned for 'set_param a='"
25699
25700         jobid_var_new=$($LCTL get_param -n $testname)
25701         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25702                 error "$testname was changed by setting without value"
25703
25704         $LCTL set_param $testname &&
25705                 error "no error returned for 'set_param a'"
25706
25707         jobid_var_new=$($LCTL get_param -n $testname)
25708         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25709                 error "$testname was changed by setting without value"
25710 }
25711 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25712
25713 test_401d() {
25714         # jobid_var may not allow arbitrary values, so use jobid_name
25715         # if available
25716         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25717                 local testname=jobid_name new_value='foo=bar%p'
25718         else
25719                 local testname=jobid_var new_valuie=foo=bar
25720         fi
25721
25722         local jobid_var_old=$($LCTL get_param -n $testname)
25723         local jobid_var_new
25724
25725         $LCTL set_param $testname=$new_value ||
25726                 error "'set_param a=b' did not accept a value containing '='"
25727
25728         jobid_var_new=$($LCTL get_param -n $testname)
25729         [[ "$jobid_var_new" == "$new_value" ]] ||
25730                 error "'set_param a=b' failed on a value containing '='"
25731
25732         # Reset the $testname to test the other format
25733         $LCTL set_param $testname=$jobid_var_old
25734         jobid_var_new=$($LCTL get_param -n $testname)
25735         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25736                 error "failed to reset $testname"
25737
25738         $LCTL set_param $testname $new_value ||
25739                 error "'set_param a b' did not accept a value containing '='"
25740
25741         jobid_var_new=$($LCTL get_param -n $testname)
25742         [[ "$jobid_var_new" == "$new_value" ]] ||
25743                 error "'set_param a b' failed on a value containing '='"
25744
25745         $LCTL set_param $testname $jobid_var_old
25746         jobid_var_new=$($LCTL get_param -n $testname)
25747         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25748                 error "failed to reset $testname"
25749 }
25750 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25751
25752 test_401e() { # LU-14779
25753         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25754                 error "lctl list_param MGC* failed"
25755         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25756         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25757                 error "lctl get_param lru_size failed"
25758 }
25759 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25760
25761 test_402() {
25762         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25763         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25764                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25765         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25766                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25767                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25768         remote_mds_nodsh && skip "remote MDS with nodsh"
25769
25770         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25771 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25772         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25773         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25774                 echo "Touch failed - OK"
25775 }
25776 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25777
25778 test_403() {
25779         local file1=$DIR/$tfile.1
25780         local file2=$DIR/$tfile.2
25781         local tfile=$TMP/$tfile
25782
25783         rm -f $file1 $file2 $tfile
25784
25785         touch $file1
25786         ln $file1 $file2
25787
25788         # 30 sec OBD_TIMEOUT in ll_getattr()
25789         # right before populating st_nlink
25790         $LCTL set_param fail_loc=0x80001409
25791         stat -c %h $file1 > $tfile &
25792
25793         # create an alias, drop all locks and reclaim the dentry
25794         < $file2
25795         cancel_lru_locks mdc
25796         cancel_lru_locks osc
25797         sysctl -w vm.drop_caches=2
25798
25799         wait
25800
25801         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25802
25803         rm -f $tfile $file1 $file2
25804 }
25805 run_test 403 "i_nlink should not drop to zero due to aliasing"
25806
25807 test_404() { # LU-6601
25808         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25809                 skip "Need server version newer than 2.8.52"
25810         remote_mds_nodsh && skip "remote MDS with nodsh"
25811
25812         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25813                 awk '/osp .*-osc-MDT/ { print $4}')
25814
25815         local osp
25816         for osp in $mosps; do
25817                 echo "Deactivate: " $osp
25818                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25819                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25820                         awk -vp=$osp '$4 == p { print $2 }')
25821                 [ $stat = IN ] || {
25822                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25823                         error "deactivate error"
25824                 }
25825                 echo "Activate: " $osp
25826                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25827                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25828                         awk -vp=$osp '$4 == p { print $2 }')
25829                 [ $stat = UP ] || {
25830                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25831                         error "activate error"
25832                 }
25833         done
25834 }
25835 run_test 404 "validate manual {de}activated works properly for OSPs"
25836
25837 test_405() {
25838         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25839         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25840                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25841                         skip "Layout swap lock is not supported"
25842
25843         check_swap_layouts_support
25844         check_swap_layout_no_dom $DIR
25845
25846         test_mkdir $DIR/$tdir
25847         swap_lock_test -d $DIR/$tdir ||
25848                 error "One layout swap locked test failed"
25849 }
25850 run_test 405 "Various layout swap lock tests"
25851
25852 test_406() {
25853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25854         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25855         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25857         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25858                 skip "Need MDS version at least 2.8.50"
25859
25860         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25861         local test_pool=$TESTNAME
25862
25863         pool_add $test_pool || error "pool_add failed"
25864         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25865                 error "pool_add_targets failed"
25866
25867         save_layout_restore_at_exit $MOUNT
25868
25869         # parent set default stripe count only, child will stripe from both
25870         # parent and fs default
25871         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25872                 error "setstripe $MOUNT failed"
25873         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25874         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25875         for i in $(seq 10); do
25876                 local f=$DIR/$tdir/$tfile.$i
25877                 touch $f || error "touch failed"
25878                 local count=$($LFS getstripe -c $f)
25879                 [ $count -eq $OSTCOUNT ] ||
25880                         error "$f stripe count $count != $OSTCOUNT"
25881                 local offset=$($LFS getstripe -i $f)
25882                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25883                 local size=$($LFS getstripe -S $f)
25884                 [ $size -eq $((def_stripe_size * 2)) ] ||
25885                         error "$f stripe size $size != $((def_stripe_size * 2))"
25886                 local pool=$($LFS getstripe -p $f)
25887                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25888         done
25889
25890         # change fs default striping, delete parent default striping, now child
25891         # will stripe from new fs default striping only
25892         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25893                 error "change $MOUNT default stripe failed"
25894         $LFS setstripe -c 0 $DIR/$tdir ||
25895                 error "delete $tdir default stripe failed"
25896         for i in $(seq 11 20); do
25897                 local f=$DIR/$tdir/$tfile.$i
25898                 touch $f || error "touch $f failed"
25899                 local count=$($LFS getstripe -c $f)
25900                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25901                 local offset=$($LFS getstripe -i $f)
25902                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25903                 local size=$($LFS getstripe -S $f)
25904                 [ $size -eq $def_stripe_size ] ||
25905                         error "$f stripe size $size != $def_stripe_size"
25906                 local pool=$($LFS getstripe -p $f)
25907                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25908         done
25909
25910         unlinkmany $DIR/$tdir/$tfile. 1 20
25911
25912         local f=$DIR/$tdir/$tfile
25913         pool_remove_all_targets $test_pool $f
25914         pool_remove $test_pool $f
25915 }
25916 run_test 406 "DNE support fs default striping"
25917
25918 test_407() {
25919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25920         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25921                 skip "Need MDS version at least 2.8.55"
25922         remote_mds_nodsh && skip "remote MDS with nodsh"
25923
25924         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25925                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25926         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25927                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25928         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25929
25930         #define OBD_FAIL_DT_TXN_STOP    0x2019
25931         for idx in $(seq $MDSCOUNT); do
25932                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25933         done
25934         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25935         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25936                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25937         true
25938 }
25939 run_test 407 "transaction fail should cause operation fail"
25940
25941 test_408() {
25942         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25943
25944         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25945         lctl set_param fail_loc=0x8000040a
25946         # let ll_prepare_partial_page() fail
25947         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25948
25949         rm -f $DIR/$tfile
25950
25951         # create at least 100 unused inodes so that
25952         # shrink_icache_memory(0) should not return 0
25953         touch $DIR/$tfile-{0..100}
25954         rm -f $DIR/$tfile-{0..100}
25955         sync
25956
25957         echo 2 > /proc/sys/vm/drop_caches
25958 }
25959 run_test 408 "drop_caches should not hang due to page leaks"
25960
25961 test_409()
25962 {
25963         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25964
25965         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25966         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25967         touch $DIR/$tdir/guard || error "(2) Fail to create"
25968
25969         local PREFIX=$(str_repeat 'A' 128)
25970         echo "Create 1K hard links start at $(date)"
25971         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25972                 error "(3) Fail to hard link"
25973
25974         echo "Links count should be right although linkEA overflow"
25975         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25976         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25977         [ $linkcount -eq 1001 ] ||
25978                 error "(5) Unexpected hard links count: $linkcount"
25979
25980         echo "List all links start at $(date)"
25981         ls -l $DIR/$tdir/foo > /dev/null ||
25982                 error "(6) Fail to list $DIR/$tdir/foo"
25983
25984         echo "Unlink hard links start at $(date)"
25985         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25986                 error "(7) Fail to unlink"
25987         echo "Unlink hard links finished at $(date)"
25988 }
25989 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25990
25991 test_410()
25992 {
25993         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25994                 skip "Need client version at least 2.9.59"
25995         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25996                 skip "Need MODULES build"
25997
25998         # Create a file, and stat it from the kernel
25999         local testfile=$DIR/$tfile
26000         touch $testfile
26001
26002         local run_id=$RANDOM
26003         local my_ino=$(stat --format "%i" $testfile)
26004
26005         # Try to insert the module. This will always fail as the
26006         # module is designed to not be inserted.
26007         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26008             &> /dev/null
26009
26010         # Anything but success is a test failure
26011         dmesg | grep -q \
26012             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26013             error "no inode match"
26014 }
26015 run_test 410 "Test inode number returned from kernel thread"
26016
26017 cleanup_test411_cgroup() {
26018         trap 0
26019         rmdir "$1"
26020 }
26021
26022 test_411() {
26023         local cg_basedir=/sys/fs/cgroup/memory
26024         # LU-9966
26025         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26026                 skip "no setup for cgroup"
26027
26028         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26029                 error "test file creation failed"
26030         cancel_lru_locks osc
26031
26032         # Create a very small memory cgroup to force a slab allocation error
26033         local cgdir=$cg_basedir/osc_slab_alloc
26034         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26035         trap "cleanup_test411_cgroup $cgdir" EXIT
26036         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26037         echo 1M > $cgdir/memory.limit_in_bytes
26038
26039         # Should not LBUG, just be killed by oom-killer
26040         # dd will return 0 even allocation failure in some environment.
26041         # So don't check return value
26042         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26043         cleanup_test411_cgroup $cgdir
26044
26045         return 0
26046 }
26047 run_test 411 "Slab allocation error with cgroup does not LBUG"
26048
26049 test_412() {
26050         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26051         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26052                 skip "Need server version at least 2.10.55"
26053
26054         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26055                 error "mkdir failed"
26056         $LFS getdirstripe $DIR/$tdir
26057         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26058         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26059                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26060         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26061         [ $stripe_count -eq 2 ] ||
26062                 error "expect 2 get $stripe_count"
26063
26064         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26065
26066         local index
26067         local index2
26068
26069         # subdirs should be on the same MDT as parent
26070         for i in $(seq 0 $((MDSCOUNT - 1))); do
26071                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26072                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26073                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26074                 (( index == i )) || error "mdt$i/sub on MDT$index"
26075         done
26076
26077         # stripe offset -1, ditto
26078         for i in {1..10}; do
26079                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26080                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26081                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26082                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26083                 (( index == index2 )) ||
26084                         error "qos$i on MDT$index, sub on MDT$index2"
26085         done
26086
26087         local testdir=$DIR/$tdir/inherit
26088
26089         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26090         # inherit 2 levels
26091         for i in 1 2; do
26092                 testdir=$testdir/s$i
26093                 mkdir $testdir || error "mkdir $testdir failed"
26094                 index=$($LFS getstripe -m $testdir)
26095                 (( index == 1 )) ||
26096                         error "$testdir on MDT$index"
26097         done
26098
26099         # not inherit any more
26100         testdir=$testdir/s3
26101         mkdir $testdir || error "mkdir $testdir failed"
26102         getfattr -d -m dmv $testdir | grep dmv &&
26103                 error "default LMV set on $testdir" || true
26104 }
26105 run_test 412 "mkdir on specific MDTs"
26106
26107 TEST413_COUNT=${TEST413_COUNT:-200}
26108 generate_uneven_mdts() {
26109         local threshold=$1
26110         local lmv_qos_maxage
26111         local lod_qos_maxage
26112         local ffree
26113         local bavail
26114         local max
26115         local min
26116         local max_index
26117         local min_index
26118         local tmp
26119         local i
26120
26121         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26122         $LCTL set_param lmv.*.qos_maxage=1
26123         stack_trap "$LCTL set_param \
26124                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26125         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26126                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26127         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26128                 lod.*.mdt_qos_maxage=1
26129         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26130                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26131
26132         echo
26133         echo "Check for uneven MDTs: "
26134
26135         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26136         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26137         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26138
26139         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26140         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26141         max_index=0
26142         min_index=0
26143         for ((i = 1; i < ${#ffree[@]}; i++)); do
26144                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26145                 if [ $tmp -gt $max ]; then
26146                         max=$tmp
26147                         max_index=$i
26148                 fi
26149                 if [ $tmp -lt $min ]; then
26150                         min=$tmp
26151                         min_index=$i
26152                 fi
26153         done
26154
26155         (( ${ffree[min_index]} > 0 )) ||
26156                 skip "no free files in MDT$min_index"
26157         (( ${ffree[min_index]} < 10000000 )) ||
26158                 skip "too many free files in MDT$min_index"
26159
26160         # Check if we need to generate uneven MDTs
26161         local diff=$(((max - min) * 100 / min))
26162         local testdir=$DIR/$tdir-fillmdt
26163         local start
26164
26165         i=0
26166         while (( diff < threshold )); do
26167                 mkdir -p $testdir
26168                 # generate uneven MDTs, create till $threshold% diff
26169                 echo -n "weight diff=$diff% must be > $threshold% ..."
26170                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26171                 testdir=$DIR/$tdir-fillmdt/$i
26172                 [ -d $testdir ] && continue
26173                 $LFS mkdir -i $min_index $testdir ||
26174                         error "mkdir $testdir failed"
26175                 $LFS setstripe -E 1M -L mdt $testdir ||
26176                         error "setstripe $testdir failed"
26177                 start=$SECONDS
26178                 for ((F=0; F < TEST413_COUNT; F++)); do
26179                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26180                                 /dev/null 2>&1 || error "dd $F failed"
26181                 done
26182                 sync; sleep 1; sync
26183
26184                 # wait for QOS to update
26185                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26186
26187                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26188                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26189                 max=$(((${ffree[max_index]} >> 8) *
26190                         (${bavail[max_index]} * bsize >> 16)))
26191                 min=$(((${ffree[min_index]} >> 8) *
26192                         (${bavail[min_index]} * bsize >> 16)))
26193                 diff=$(((max - min) * 100 / min))
26194                 i=$((i + 1))
26195         done
26196
26197         echo "MDT filesfree available: ${ffree[*]}"
26198         echo "MDT blocks available: ${bavail[*]}"
26199         echo "weight diff=$diff%"
26200 }
26201
26202 test_qos_mkdir() {
26203         local mkdir_cmd=$1
26204         local stripe_count=$2
26205         local mdts=$(comma_list $(mdts_nodes))
26206
26207         local testdir
26208         local lmv_qos_prio_free
26209         local lmv_qos_threshold_rr
26210         local lmv_qos_maxage
26211         local lod_qos_prio_free
26212         local lod_qos_threshold_rr
26213         local lod_qos_maxage
26214         local count
26215         local i
26216
26217         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26218         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26219         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26220                 head -n1)
26221         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26222         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26223         stack_trap "$LCTL set_param \
26224                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26225         stack_trap "$LCTL set_param \
26226                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26227         stack_trap "$LCTL set_param \
26228                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26229
26230         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26231                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26232         lod_qos_prio_free=${lod_qos_prio_free%%%}
26233         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26234                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26235         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26236         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26237                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26238         stack_trap "do_nodes $mdts $LCTL set_param \
26239                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26240         stack_trap "do_nodes $mdts $LCTL set_param \
26241                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26242         stack_trap "do_nodes $mdts $LCTL set_param \
26243                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26244
26245         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26246         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26247
26248         testdir=$DIR/$tdir-s$stripe_count/rr
26249
26250         local stripe_index=$($LFS getstripe -m $testdir)
26251         local test_mkdir_rr=true
26252
26253         getfattr -d -m dmv -e hex $testdir | grep dmv
26254         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26255                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26256                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26257                         test_mkdir_rr=false
26258         fi
26259
26260         echo
26261         $test_mkdir_rr &&
26262                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26263                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26264
26265         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26266         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26267                 eval $mkdir_cmd $testdir/subdir$i ||
26268                         error "$mkdir_cmd subdir$i failed"
26269         done
26270
26271         for (( i = 0; i < $MDSCOUNT; i++ )); do
26272                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26273                 echo "$count directories created on MDT$i"
26274                 if $test_mkdir_rr; then
26275                         (( $count == 100 )) ||
26276                                 error "subdirs are not evenly distributed"
26277                 elif (( $i == $stripe_index )); then
26278                         (( $count == 100 * MDSCOUNT )) ||
26279                                 error "$count subdirs created on MDT$i"
26280                 else
26281                         (( $count == 0 )) ||
26282                                 error "$count subdirs created on MDT$i"
26283                 fi
26284
26285                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26286                         count=$($LFS getdirstripe $testdir/* |
26287                                 grep -c -P "^\s+$i\t")
26288                         echo "$count stripes created on MDT$i"
26289                         # deviation should < 5% of average
26290                         (( $count >= 95 * stripe_count &&
26291                            $count <= 105 * stripe_count)) ||
26292                                 error "stripes are not evenly distributed"
26293                 fi
26294         done
26295
26296         echo
26297         echo "Check for uneven MDTs: "
26298
26299         local ffree
26300         local bavail
26301         local max
26302         local min
26303         local max_index
26304         local min_index
26305         local tmp
26306
26307         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26308         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26309         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26310
26311         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26312         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26313         max_index=0
26314         min_index=0
26315         for ((i = 1; i < ${#ffree[@]}; i++)); do
26316                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26317                 if [ $tmp -gt $max ]; then
26318                         max=$tmp
26319                         max_index=$i
26320                 fi
26321                 if [ $tmp -lt $min ]; then
26322                         min=$tmp
26323                         min_index=$i
26324                 fi
26325         done
26326
26327         (( ${ffree[min_index]} > 0 )) ||
26328                 skip "no free files in MDT$min_index"
26329         (( ${ffree[min_index]} < 10000000 )) ||
26330                 skip "too many free files in MDT$min_index"
26331
26332         echo "MDT filesfree available: ${ffree[*]}"
26333         echo "MDT blocks available: ${bavail[*]}"
26334         echo "weight diff=$(((max - min) * 100 / min))%"
26335         echo
26336         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26337
26338         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26339         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26340         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26341         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26342         # decrease statfs age, so that it can be updated in time
26343         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26344         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26345
26346         sleep 1
26347
26348         testdir=$DIR/$tdir-s$stripe_count/qos
26349         local num=200
26350
26351         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26352         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26353                 eval $mkdir_cmd $testdir/subdir$i ||
26354                         error "$mkdir_cmd subdir$i failed"
26355         done
26356
26357         max=0
26358         for (( i = 0; i < $MDSCOUNT; i++ )); do
26359                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26360                 (( count > max )) && max=$count
26361                 echo "$count directories created on MDT$i"
26362         done
26363
26364         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26365
26366         # D-value should > 10% of averge
26367         (( max - min > num / 10 )) ||
26368                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26369
26370         # ditto for stripes
26371         if (( stripe_count > 1 )); then
26372                 max=0
26373                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26374                         count=$($LFS getdirstripe $testdir/* |
26375                                 grep -c -P "^\s+$i\t")
26376                         (( count > max )) && max=$count
26377                         echo "$count stripes created on MDT$i"
26378                 done
26379
26380                 min=$($LFS getdirstripe $testdir/* |
26381                         grep -c -P "^\s+$min_index\t")
26382                 (( max - min > num * stripe_count / 10 )) ||
26383                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26384         fi
26385 }
26386
26387 most_full_mdt() {
26388         local ffree
26389         local bavail
26390         local bsize
26391         local min
26392         local min_index
26393         local tmp
26394
26395         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26396         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26397         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26398
26399         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26400         min_index=0
26401         for ((i = 1; i < ${#ffree[@]}; i++)); do
26402                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26403                 (( tmp < min )) && min=$tmp && min_index=$i
26404         done
26405
26406         echo -n $min_index
26407 }
26408
26409 test_413a() {
26410         [ $MDSCOUNT -lt 2 ] &&
26411                 skip "We need at least 2 MDTs for this test"
26412
26413         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26414                 skip "Need server version at least 2.12.52"
26415
26416         local stripe_count
26417
26418         generate_uneven_mdts 100
26419         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26420                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26421                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26422                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26423                         error "mkdir failed"
26424                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26425         done
26426 }
26427 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26428
26429 test_413b() {
26430         [ $MDSCOUNT -lt 2 ] &&
26431                 skip "We need at least 2 MDTs for this test"
26432
26433         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26434                 skip "Need server version at least 2.12.52"
26435
26436         local testdir
26437         local stripe_count
26438
26439         generate_uneven_mdts 100
26440         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26441                 testdir=$DIR/$tdir-s$stripe_count
26442                 mkdir $testdir || error "mkdir $testdir failed"
26443                 mkdir $testdir/rr || error "mkdir rr failed"
26444                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26445                         error "mkdir qos failed"
26446                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26447                         $testdir/rr || error "setdirstripe rr failed"
26448                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26449                         error "setdirstripe failed"
26450                 test_qos_mkdir "mkdir" $stripe_count
26451         done
26452 }
26453 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26454
26455 test_413c() {
26456         (( $MDSCOUNT >= 2 )) ||
26457                 skip "We need at least 2 MDTs for this test"
26458
26459         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26460                 skip "Need server version at least 2.14.51"
26461
26462         local testdir
26463         local inherit
26464         local inherit_rr
26465
26466         testdir=$DIR/${tdir}-s1
26467         mkdir $testdir || error "mkdir $testdir failed"
26468         mkdir $testdir/rr || error "mkdir rr failed"
26469         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26470         # default max_inherit is -1, default max_inherit_rr is 0
26471         $LFS setdirstripe -D -c 1 $testdir/rr ||
26472                 error "setdirstripe rr failed"
26473         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26474                 error "setdirstripe qos failed"
26475         test_qos_mkdir "mkdir" 1
26476
26477         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26478         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26479         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26480         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26481         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26482
26483         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26484         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26485         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26486         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26487         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26488         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26489         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26490                 error "level2 shouldn't have default LMV" || true
26491 }
26492 run_test 413c "mkdir with default LMV max inherit rr"
26493
26494 test_413d() {
26495         (( MDSCOUNT >= 2 )) ||
26496                 skip "We need at least 2 MDTs for this test"
26497
26498         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26499                 skip "Need server version at least 2.14.51"
26500
26501         local lmv_qos_threshold_rr
26502
26503         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26504                 head -n1)
26505         stack_trap "$LCTL set_param \
26506                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26507
26508         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26509         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26510         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26511                 error "$tdir shouldn't have default LMV"
26512         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26513                 error "mkdir sub failed"
26514
26515         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26516
26517         (( count == 100 )) || error "$count subdirs on MDT0"
26518 }
26519 run_test 413d "inherit ROOT default LMV"
26520
26521 test_413e() {
26522         (( MDSCOUNT >= 2 )) ||
26523                 skip "We need at least 2 MDTs for this test"
26524         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26525                 skip "Need server version at least 2.14.55"
26526
26527         local testdir=$DIR/$tdir
26528         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26529         local max_inherit
26530         local sub_max_inherit
26531
26532         mkdir -p $testdir || error "failed to create $testdir"
26533
26534         # set default max-inherit to -1 if stripe count is 0 or 1
26535         $LFS setdirstripe -D -c 1 $testdir ||
26536                 error "failed to set default LMV"
26537         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26538         (( max_inherit == -1 )) ||
26539                 error "wrong max_inherit value $max_inherit"
26540
26541         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26542         $LFS setdirstripe -D -c -1 $testdir ||
26543                 error "failed to set default LMV"
26544         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26545         (( max_inherit > 0 )) ||
26546                 error "wrong max_inherit value $max_inherit"
26547
26548         # and the subdir will decrease the max_inherit by 1
26549         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26550         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26551         (( sub_max_inherit == max_inherit - 1)) ||
26552                 error "wrong max-inherit of subdir $sub_max_inherit"
26553
26554         # check specified --max-inherit and warning message
26555         stack_trap "rm -f $tmpfile"
26556         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26557                 error "failed to set default LMV"
26558         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26559         (( max_inherit == -1 )) ||
26560                 error "wrong max_inherit value $max_inherit"
26561
26562         # check the warning messages
26563         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26564                 error "failed to detect warning string"
26565         fi
26566 }
26567 run_test 413e "check default max-inherit value"
26568
26569 test_fs_dmv_inherit()
26570 {
26571         local testdir=$DIR/$tdir
26572
26573         local count
26574         local inherit
26575         local inherit_rr
26576
26577         for i in 1 2 3; do
26578                 mkdir $testdir || error "mkdir $testdir failed"
26579                 count=$($LFS getdirstripe -D -c $testdir)
26580                 (( count == 1 )) ||
26581                         error "$testdir default LMV count mismatch $count != 1"
26582                 inherit=$($LFS getdirstripe -D -X $testdir)
26583                 (( inherit == 3 - i )) ||
26584                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26585                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26586                 (( inherit_rr == 3 - i )) ||
26587                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26588                 testdir=$testdir/sub
26589         done
26590
26591         mkdir $testdir || error "mkdir $testdir failed"
26592         count=$($LFS getdirstripe -D -c $testdir)
26593         (( count == 0 )) ||
26594                 error "$testdir default LMV count not zero: $count"
26595 }
26596
26597 test_413f() {
26598         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26599
26600         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26601                 skip "Need server version at least 2.14.55"
26602
26603         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26604                 error "dump $DIR default LMV failed"
26605         stack_trap "setfattr --restore=$TMP/dmv.ea"
26606
26607         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26608                 error "set $DIR default LMV failed"
26609
26610         test_fs_dmv_inherit
26611 }
26612 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26613
26614 test_413g() {
26615         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26616
26617         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26618         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26619                 error "dump $DIR default LMV failed"
26620         stack_trap "setfattr --restore=$TMP/dmv.ea"
26621
26622         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26623                 error "set $DIR default LMV failed"
26624
26625         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26626                 error "mount $MOUNT2 failed"
26627         stack_trap "umount_client $MOUNT2"
26628
26629         local saved_DIR=$DIR
26630
26631         export DIR=$MOUNT2
26632
26633         stack_trap "export DIR=$saved_DIR"
26634
26635         # first check filesystem-wide default LMV inheritance
26636         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26637
26638         # then check subdirs are spread to all MDTs
26639         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26640
26641         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26642
26643         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26644 }
26645 run_test 413g "enforce ROOT default LMV on subdir mount"
26646
26647 test_413h() {
26648         (( MDSCOUNT >= 2 )) ||
26649                 skip "We need at least 2 MDTs for this test"
26650
26651         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26652                 skip "Need server version at least 2.15.50.6"
26653
26654         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26655
26656         stack_trap "$LCTL set_param \
26657                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26658         $LCTL set_param lmv.*.qos_maxage=1
26659
26660         local depth=5
26661         local rr_depth=4
26662         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26663         local count=$((MDSCOUNT * 20))
26664
26665         generate_uneven_mdts 50
26666
26667         mkdir -p $dir || error "mkdir $dir failed"
26668         stack_trap "rm -rf $dir"
26669         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26670                 --max-inherit-rr=$rr_depth $dir
26671
26672         for ((d=0; d < depth + 2; d++)); do
26673                 log "dir=$dir:"
26674                 for ((sub=0; sub < count; sub++)); do
26675                         mkdir $dir/d$sub
26676                 done
26677                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26678                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26679                 # subdirs within $rr_depth should be created round-robin
26680                 if (( d < rr_depth )); then
26681                         (( ${num[0]} != count )) ||
26682                                 error "all objects created on MDT ${num[1]}"
26683                 fi
26684
26685                 dir=$dir/d0
26686         done
26687 }
26688 run_test 413h "don't stick to parent for round-robin dirs"
26689
26690 test_413z() {
26691         local pids=""
26692         local subdir
26693         local pid
26694
26695         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26696                 unlinkmany $subdir/f. $TEST413_COUNT &
26697                 pids="$pids $!"
26698         done
26699
26700         for pid in $pids; do
26701                 wait $pid
26702         done
26703 }
26704 run_test 413z "413 test cleanup"
26705
26706 test_414() {
26707 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26708         $LCTL set_param fail_loc=0x80000521
26709         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26710         rm -f $DIR/$tfile
26711 }
26712 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26713
26714 test_415() {
26715         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26716         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
26717                 skip "Need server version at least 2.11.52"
26718
26719         # LU-11102
26720         local total=500
26721         local max=120
26722
26723         # this test may be slow on ZFS
26724         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
26725
26726         # though this test is designed for striped directory, let's test normal
26727         # directory too since lock is always saved as CoS lock.
26728         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26729         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26730         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
26731         # if looping with ONLY_REPEAT, wait for previous deletions to finish
26732         wait_delete_completed_mds
26733
26734         # run a loop without concurrent touch to measure rename duration.
26735         # only for test debug/robustness, NOT part of COS functional test.
26736         local start_time=$SECONDS
26737         for ((i = 0; i < total; i++)); do
26738                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26739                         > /dev/null
26740         done
26741         local baseline=$((SECONDS - start_time))
26742         echo "rename $total files without 'touch' took $baseline sec"
26743
26744         (
26745                 while true; do
26746                         touch $DIR/$tdir
26747                 done
26748         ) &
26749         local setattr_pid=$!
26750
26751         # rename files back to original name so unlinkmany works
26752         start_time=$SECONDS
26753         for ((i = 0; i < total; i++)); do
26754                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
26755                         > /dev/null
26756         done
26757         local duration=$((SECONDS - start_time))
26758
26759         kill -9 $setattr_pid
26760
26761         echo "rename $total files with 'touch' took $duration sec"
26762         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
26763         (( duration <= max )) || error "rename took $duration > $max sec"
26764 }
26765 run_test 415 "lock revoke is not missing"
26766
26767 test_416() {
26768         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26769                 skip "Need server version at least 2.11.55"
26770
26771         # define OBD_FAIL_OSD_TXN_START    0x19a
26772         do_facet mds1 lctl set_param fail_loc=0x19a
26773
26774         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26775
26776         true
26777 }
26778 run_test 416 "transaction start failure won't cause system hung"
26779
26780 cleanup_417() {
26781         trap 0
26782         do_nodes $(comma_list $(mdts_nodes)) \
26783                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26784         do_nodes $(comma_list $(mdts_nodes)) \
26785                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26786         do_nodes $(comma_list $(mdts_nodes)) \
26787                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26788 }
26789
26790 test_417() {
26791         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26792         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26793                 skip "Need MDS version at least 2.11.56"
26794
26795         trap cleanup_417 RETURN EXIT
26796
26797         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26798         do_nodes $(comma_list $(mdts_nodes)) \
26799                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26800         $LFS migrate -m 0 $DIR/$tdir.1 &&
26801                 error "migrate dir $tdir.1 should fail"
26802
26803         do_nodes $(comma_list $(mdts_nodes)) \
26804                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26805         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26806                 error "create remote dir $tdir.2 should fail"
26807
26808         do_nodes $(comma_list $(mdts_nodes)) \
26809                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26810         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26811                 error "create striped dir $tdir.3 should fail"
26812         true
26813 }
26814 run_test 417 "disable remote dir, striped dir and dir migration"
26815
26816 # Checks that the outputs of df [-i] and lfs df [-i] match
26817 #
26818 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26819 check_lfs_df() {
26820         local dir=$2
26821         local inodes
26822         local df_out
26823         local lfs_df_out
26824         local count
26825         local passed=false
26826
26827         # blocks or inodes
26828         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26829
26830         for count in {1..100}; do
26831                 do_nodes "$CLIENTS" \
26832                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26833                 sync; sleep 0.2
26834
26835                 # read the lines of interest
26836                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26837                         error "df $inodes $dir | tail -n +2 failed"
26838                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26839                         error "lfs df $inodes $dir | grep summary: failed"
26840
26841                 # skip first substrings of each output as they are different
26842                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26843                 # compare the two outputs
26844                 passed=true
26845                 #  skip "available" on MDT until LU-13997 is fixed.
26846                 #for i in {1..5}; do
26847                 for i in 1 2 4 5; do
26848                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26849                 done
26850                 $passed && break
26851         done
26852
26853         if ! $passed; then
26854                 df -P $inodes $dir
26855                 echo
26856                 lfs df $inodes $dir
26857                 error "df and lfs df $1 output mismatch: "      \
26858                       "df ${inodes}: ${df_out[*]}, "            \
26859                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26860         fi
26861 }
26862
26863 test_418() {
26864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26865
26866         local dir=$DIR/$tdir
26867         local numfiles=$((RANDOM % 4096 + 2))
26868         local numblocks=$((RANDOM % 256 + 1))
26869
26870         wait_delete_completed
26871         test_mkdir $dir
26872
26873         # check block output
26874         check_lfs_df blocks $dir
26875         # check inode output
26876         check_lfs_df inodes $dir
26877
26878         # create a single file and retest
26879         echo "Creating a single file and testing"
26880         createmany -o $dir/$tfile- 1 &>/dev/null ||
26881                 error "creating 1 file in $dir failed"
26882         check_lfs_df blocks $dir
26883         check_lfs_df inodes $dir
26884
26885         # create a random number of files
26886         echo "Creating $((numfiles - 1)) files and testing"
26887         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26888                 error "creating $((numfiles - 1)) files in $dir failed"
26889
26890         # write a random number of blocks to the first test file
26891         echo "Writing $numblocks 4K blocks and testing"
26892         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26893                 count=$numblocks &>/dev/null ||
26894                 error "dd to $dir/${tfile}-0 failed"
26895
26896         # retest
26897         check_lfs_df blocks $dir
26898         check_lfs_df inodes $dir
26899
26900         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26901                 error "unlinking $numfiles files in $dir failed"
26902 }
26903 run_test 418 "df and lfs df outputs match"
26904
26905 test_419()
26906 {
26907         local dir=$DIR/$tdir
26908
26909         mkdir -p $dir
26910         touch $dir/file
26911
26912         cancel_lru_locks mdc
26913
26914         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26915         $LCTL set_param fail_loc=0x1410
26916         cat $dir/file
26917         $LCTL set_param fail_loc=0
26918         rm -rf $dir
26919 }
26920 run_test 419 "Verify open file by name doesn't crash kernel"
26921
26922 test_420()
26923 {
26924         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26925                 skip "Need MDS version at least 2.12.53"
26926
26927         local SAVE_UMASK=$(umask)
26928         local dir=$DIR/$tdir
26929         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26930
26931         mkdir -p $dir
26932         umask 0000
26933         mkdir -m03777 $dir/testdir
26934         ls -dn $dir/testdir
26935         # Need to remove trailing '.' when SELinux is enabled
26936         local dirperms=$(ls -dn $dir/testdir |
26937                          awk '{ sub(/\.$/, "", $1); print $1}')
26938         [ $dirperms == "drwxrwsrwt" ] ||
26939                 error "incorrect perms on $dir/testdir"
26940
26941         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26942                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26943         ls -n $dir/testdir/testfile
26944         local fileperms=$(ls -n $dir/testdir/testfile |
26945                           awk '{ sub(/\.$/, "", $1); print $1}')
26946         [ $fileperms == "-rwxr-xr-x" ] ||
26947                 error "incorrect perms on $dir/testdir/testfile"
26948
26949         umask $SAVE_UMASK
26950 }
26951 run_test 420 "clear SGID bit on non-directories for non-members"
26952
26953 test_421a() {
26954         local cnt
26955         local fid1
26956         local fid2
26957
26958         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26959                 skip "Need MDS version at least 2.12.54"
26960
26961         test_mkdir $DIR/$tdir
26962         createmany -o $DIR/$tdir/f 3
26963         cnt=$(ls -1 $DIR/$tdir | wc -l)
26964         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26965
26966         fid1=$(lfs path2fid $DIR/$tdir/f1)
26967         fid2=$(lfs path2fid $DIR/$tdir/f2)
26968         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26969
26970         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26971         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26972
26973         cnt=$(ls -1 $DIR/$tdir | wc -l)
26974         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26975
26976         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26977         createmany -o $DIR/$tdir/f 3
26978         cnt=$(ls -1 $DIR/$tdir | wc -l)
26979         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26980
26981         fid1=$(lfs path2fid $DIR/$tdir/f1)
26982         fid2=$(lfs path2fid $DIR/$tdir/f2)
26983         echo "remove using fsname $FSNAME"
26984         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26985
26986         cnt=$(ls -1 $DIR/$tdir | wc -l)
26987         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26988 }
26989 run_test 421a "simple rm by fid"
26990
26991 test_421b() {
26992         local cnt
26993         local FID1
26994         local FID2
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         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27002         MULTIPID=$!
27003
27004         FID1=$(lfs path2fid $DIR/$tdir/f1)
27005         FID2=$(lfs path2fid $DIR/$tdir/f2)
27006         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27007
27008         kill -USR1 $MULTIPID
27009         wait
27010
27011         cnt=$(ls $DIR/$tdir | wc -l)
27012         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27013 }
27014 run_test 421b "rm by fid on open file"
27015
27016 test_421c() {
27017         local cnt
27018         local FIDS
27019
27020         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27021                 skip "Need MDS version at least 2.12.54"
27022
27023         test_mkdir $DIR/$tdir
27024         createmany -o $DIR/$tdir/f 3
27025         touch $DIR/$tdir/$tfile
27026         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27027         cnt=$(ls -1 $DIR/$tdir | wc -l)
27028         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27029
27030         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27031         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27032
27033         cnt=$(ls $DIR/$tdir | wc -l)
27034         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27035 }
27036 run_test 421c "rm by fid against hardlinked files"
27037
27038 test_421d() {
27039         local cnt
27040         local FIDS
27041
27042         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27043                 skip "Need MDS version at least 2.12.54"
27044
27045         test_mkdir $DIR/$tdir
27046         createmany -o $DIR/$tdir/f 4097
27047         cnt=$(ls -1 $DIR/$tdir | wc -l)
27048         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27049
27050         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27051         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27052
27053         cnt=$(ls $DIR/$tdir | wc -l)
27054         rm -rf $DIR/$tdir
27055         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27056 }
27057 run_test 421d "rmfid en masse"
27058
27059 test_421e() {
27060         local cnt
27061         local FID
27062
27063         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27064         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27065                 skip "Need MDS version at least 2.12.54"
27066
27067         mkdir -p $DIR/$tdir
27068         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27069         createmany -o $DIR/$tdir/striped_dir/f 512
27070         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27071         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27072
27073         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27074                 sed "s/[/][^:]*://g")
27075         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27076
27077         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27078         rm -rf $DIR/$tdir
27079         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27080 }
27081 run_test 421e "rmfid in DNE"
27082
27083 test_421f() {
27084         local cnt
27085         local FID
27086
27087         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27088                 skip "Need MDS version at least 2.12.54"
27089
27090         test_mkdir $DIR/$tdir
27091         touch $DIR/$tdir/f
27092         cnt=$(ls -1 $DIR/$tdir | wc -l)
27093         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27094
27095         FID=$(lfs path2fid $DIR/$tdir/f)
27096         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27097         # rmfid should fail
27098         cnt=$(ls -1 $DIR/$tdir | wc -l)
27099         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27100
27101         chmod a+rw $DIR/$tdir
27102         ls -la $DIR/$tdir
27103         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27104         # rmfid should fail
27105         cnt=$(ls -1 $DIR/$tdir | wc -l)
27106         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27107
27108         rm -f $DIR/$tdir/f
27109         $RUNAS touch $DIR/$tdir/f
27110         FID=$(lfs path2fid $DIR/$tdir/f)
27111         echo "rmfid as root"
27112         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27113         cnt=$(ls -1 $DIR/$tdir | wc -l)
27114         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27115
27116         rm -f $DIR/$tdir/f
27117         $RUNAS touch $DIR/$tdir/f
27118         cnt=$(ls -1 $DIR/$tdir | wc -l)
27119         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27120         FID=$(lfs path2fid $DIR/$tdir/f)
27121         # rmfid w/o user_fid2path mount option should fail
27122         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27123         cnt=$(ls -1 $DIR/$tdir | wc -l)
27124         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27125
27126         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27127         stack_trap "rmdir $tmpdir"
27128         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27129                 error "failed to mount client'"
27130         stack_trap "umount_client $tmpdir"
27131
27132         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27133         # rmfid should succeed
27134         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27135         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27136
27137         # rmfid shouldn't allow to remove files due to dir's permission
27138         chmod a+rwx $tmpdir/$tdir
27139         touch $tmpdir/$tdir/f
27140         ls -la $tmpdir/$tdir
27141         FID=$(lfs path2fid $tmpdir/$tdir/f)
27142         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27143         return 0
27144 }
27145 run_test 421f "rmfid checks permissions"
27146
27147 test_421g() {
27148         local cnt
27149         local FIDS
27150
27151         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27152         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27153                 skip "Need MDS version at least 2.12.54"
27154
27155         mkdir -p $DIR/$tdir
27156         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27157         createmany -o $DIR/$tdir/striped_dir/f 512
27158         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27159         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27160
27161         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27162                 sed "s/[/][^:]*://g")
27163
27164         rm -f $DIR/$tdir/striped_dir/f1*
27165         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27166         removed=$((512 - cnt))
27167
27168         # few files have been just removed, so we expect
27169         # rmfid to fail on their fids
27170         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27171         [ $removed != $errors ] && error "$errors != $removed"
27172
27173         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27174         rm -rf $DIR/$tdir
27175         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27176 }
27177 run_test 421g "rmfid to return errors properly"
27178
27179 test_422() {
27180         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27181         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27182         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27183         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27184         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27185
27186         local amc=$(at_max_get client)
27187         local amo=$(at_max_get mds1)
27188         local timeout=`lctl get_param -n timeout`
27189
27190         at_max_set 0 client
27191         at_max_set 0 mds1
27192
27193 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27194         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27195                         fail_val=$(((2*timeout + 10)*1000))
27196         touch $DIR/$tdir/d3/file &
27197         sleep 2
27198 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27199         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27200                         fail_val=$((2*timeout + 5))
27201         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27202         local pid=$!
27203         sleep 1
27204         kill -9 $pid
27205         sleep $((2 * timeout))
27206         echo kill $pid
27207         kill -9 $pid
27208         lctl mark touch
27209         touch $DIR/$tdir/d2/file3
27210         touch $DIR/$tdir/d2/file4
27211         touch $DIR/$tdir/d2/file5
27212
27213         wait
27214         at_max_set $amc client
27215         at_max_set $amo mds1
27216
27217         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27218         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27219                 error "Watchdog is always throttled"
27220 }
27221 run_test 422 "kill a process with RPC in progress"
27222
27223 stat_test() {
27224     df -h $MOUNT &
27225     df -h $MOUNT &
27226     df -h $MOUNT &
27227     df -h $MOUNT &
27228     df -h $MOUNT &
27229     df -h $MOUNT &
27230 }
27231
27232 test_423() {
27233     local _stats
27234     # ensure statfs cache is expired
27235     sleep 2;
27236
27237     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27238     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27239
27240     return 0
27241 }
27242 run_test 423 "statfs should return a right data"
27243
27244 test_424() {
27245 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27246         $LCTL set_param fail_loc=0x80000522
27247         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27248         rm -f $DIR/$tfile
27249 }
27250 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27251
27252 test_425() {
27253         test_mkdir -c -1 $DIR/$tdir
27254         $LFS setstripe -c -1 $DIR/$tdir
27255
27256         lru_resize_disable "" 100
27257         stack_trap "lru_resize_enable" EXIT
27258
27259         sleep 5
27260
27261         for i in $(seq $((MDSCOUNT * 125))); do
27262                 local t=$DIR/$tdir/$tfile_$i
27263
27264                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27265                         error_noexit "Create file $t"
27266         done
27267         stack_trap "rm -rf $DIR/$tdir" EXIT
27268
27269         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27270                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27271                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27272
27273                 [ $lock_count -le $lru_size ] ||
27274                         error "osc lock count $lock_count > lru size $lru_size"
27275         done
27276
27277         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27278                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27279                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27280
27281                 [ $lock_count -le $lru_size ] ||
27282                         error "mdc lock count $lock_count > lru size $lru_size"
27283         done
27284 }
27285 run_test 425 "lock count should not exceed lru size"
27286
27287 test_426() {
27288         splice-test -r $DIR/$tfile
27289         splice-test -rd $DIR/$tfile
27290         splice-test $DIR/$tfile
27291         splice-test -d $DIR/$tfile
27292 }
27293 run_test 426 "splice test on Lustre"
27294
27295 test_427() {
27296         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27297         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27298                 skip "Need MDS version at least 2.12.4"
27299         local log
27300
27301         mkdir $DIR/$tdir
27302         mkdir $DIR/$tdir/1
27303         mkdir $DIR/$tdir/2
27304         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27305         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27306
27307         $LFS getdirstripe $DIR/$tdir/1/dir
27308
27309         #first setfattr for creating updatelog
27310         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27311
27312 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27313         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27314         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27315         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27316
27317         sleep 2
27318         fail mds2
27319         wait_recovery_complete mds2 $((2*TIMEOUT))
27320
27321         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27322         echo $log | grep "get update log failed" &&
27323                 error "update log corruption is detected" || true
27324 }
27325 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27326
27327 test_428() {
27328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27329         local cache_limit=$CACHE_MAX
27330
27331         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27332         $LCTL set_param -n llite.*.max_cached_mb=64
27333
27334         mkdir $DIR/$tdir
27335         $LFS setstripe -c 1 $DIR/$tdir
27336         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27337         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27338         #test write
27339         for f in $(seq 4); do
27340                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27341         done
27342         wait
27343
27344         cancel_lru_locks osc
27345         # Test read
27346         for f in $(seq 4); do
27347                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27348         done
27349         wait
27350 }
27351 run_test 428 "large block size IO should not hang"
27352
27353 test_429() { # LU-7915 / LU-10948
27354         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27355         local testfile=$DIR/$tfile
27356         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27357         local new_flag=1
27358         local first_rpc
27359         local second_rpc
27360         local third_rpc
27361
27362         $LCTL get_param $ll_opencache_threshold_count ||
27363                 skip "client does not have opencache parameter"
27364
27365         set_opencache $new_flag
27366         stack_trap "restore_opencache"
27367         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27368                 error "enable opencache failed"
27369         touch $testfile
27370         # drop MDC DLM locks
27371         cancel_lru_locks mdc
27372         # clear MDC RPC stats counters
27373         $LCTL set_param $mdc_rpcstats=clear
27374
27375         # According to the current implementation, we need to run 3 times
27376         # open & close file to verify if opencache is enabled correctly.
27377         # 1st, RPCs are sent for lookup/open and open handle is released on
27378         #      close finally.
27379         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27380         #      so open handle won't be released thereafter.
27381         # 3rd, No RPC is sent out.
27382         $MULTIOP $testfile oc || error "multiop failed"
27383         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27384         echo "1st: $first_rpc RPCs in flight"
27385
27386         $MULTIOP $testfile oc || error "multiop failed"
27387         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27388         echo "2nd: $second_rpc RPCs in flight"
27389
27390         $MULTIOP $testfile oc || error "multiop failed"
27391         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27392         echo "3rd: $third_rpc RPCs in flight"
27393
27394         #verify no MDC RPC is sent
27395         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27396 }
27397 run_test 429 "verify if opencache flag on client side does work"
27398
27399 lseek_test_430() {
27400         local offset
27401         local file=$1
27402
27403         # data at [200K, 400K)
27404         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27405                 error "256K->512K dd fails"
27406         # data at [2M, 3M)
27407         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27408                 error "2M->3M dd fails"
27409         # data at [4M, 5M)
27410         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27411                 error "4M->5M dd fails"
27412         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27413         # start at first component hole #1
27414         printf "Seeking hole from 1000 ... "
27415         offset=$(lseek_test -l 1000 $file)
27416         echo $offset
27417         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27418         printf "Seeking data from 1000 ... "
27419         offset=$(lseek_test -d 1000 $file)
27420         echo $offset
27421         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27422
27423         # start at first component data block
27424         printf "Seeking hole from 300000 ... "
27425         offset=$(lseek_test -l 300000 $file)
27426         echo $offset
27427         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27428         printf "Seeking data from 300000 ... "
27429         offset=$(lseek_test -d 300000 $file)
27430         echo $offset
27431         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27432
27433         # start at the first component but beyond end of object size
27434         printf "Seeking hole from 1000000 ... "
27435         offset=$(lseek_test -l 1000000 $file)
27436         echo $offset
27437         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27438         printf "Seeking data from 1000000 ... "
27439         offset=$(lseek_test -d 1000000 $file)
27440         echo $offset
27441         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27442
27443         # start at second component stripe 2 (empty file)
27444         printf "Seeking hole from 1500000 ... "
27445         offset=$(lseek_test -l 1500000 $file)
27446         echo $offset
27447         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27448         printf "Seeking data from 1500000 ... "
27449         offset=$(lseek_test -d 1500000 $file)
27450         echo $offset
27451         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27452
27453         # start at second component stripe 1 (all data)
27454         printf "Seeking hole from 3000000 ... "
27455         offset=$(lseek_test -l 3000000 $file)
27456         echo $offset
27457         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27458         printf "Seeking data from 3000000 ... "
27459         offset=$(lseek_test -d 3000000 $file)
27460         echo $offset
27461         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27462
27463         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27464                 error "2nd dd fails"
27465         echo "Add data block at 640K...1280K"
27466
27467         # start at before new data block, in hole
27468         printf "Seeking hole from 600000 ... "
27469         offset=$(lseek_test -l 600000 $file)
27470         echo $offset
27471         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27472         printf "Seeking data from 600000 ... "
27473         offset=$(lseek_test -d 600000 $file)
27474         echo $offset
27475         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27476
27477         # start at the first component new data block
27478         printf "Seeking hole from 1000000 ... "
27479         offset=$(lseek_test -l 1000000 $file)
27480         echo $offset
27481         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27482         printf "Seeking data from 1000000 ... "
27483         offset=$(lseek_test -d 1000000 $file)
27484         echo $offset
27485         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27486
27487         # start at second component stripe 2, new data
27488         printf "Seeking hole from 1200000 ... "
27489         offset=$(lseek_test -l 1200000 $file)
27490         echo $offset
27491         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27492         printf "Seeking data from 1200000 ... "
27493         offset=$(lseek_test -d 1200000 $file)
27494         echo $offset
27495         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27496
27497         # start beyond file end
27498         printf "Using offset > filesize ... "
27499         lseek_test -l 4000000 $file && error "lseek should fail"
27500         printf "Using offset > filesize ... "
27501         lseek_test -d 4000000 $file && error "lseek should fail"
27502
27503         printf "Done\n\n"
27504 }
27505
27506 test_430a() {
27507         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27508                 skip "MDT does not support SEEK_HOLE"
27509
27510         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27511                 skip "OST does not support SEEK_HOLE"
27512
27513         local file=$DIR/$tdir/$tfile
27514
27515         mkdir -p $DIR/$tdir
27516
27517         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27518         # OST stripe #1 will have continuous data at [1M, 3M)
27519         # OST stripe #2 is empty
27520         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27521         lseek_test_430 $file
27522         rm $file
27523         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27524         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27525         lseek_test_430 $file
27526         rm $file
27527         $LFS setstripe -c2 -S 512K $file
27528         echo "Two stripes, stripe size 512K"
27529         lseek_test_430 $file
27530         rm $file
27531         # FLR with stale mirror
27532         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27533                        -N -c2 -S 1M $file
27534         echo "Mirrored file:"
27535         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27536         echo "Plain 2 stripes 1M"
27537         lseek_test_430 $file
27538         rm $file
27539 }
27540 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27541
27542 test_430b() {
27543         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27544                 skip "OST does not support SEEK_HOLE"
27545
27546         local offset
27547         local file=$DIR/$tdir/$tfile
27548
27549         mkdir -p $DIR/$tdir
27550         # Empty layout lseek should fail
27551         $MCREATE $file
27552         # seek from 0
27553         printf "Seeking hole from 0 ... "
27554         lseek_test -l 0 $file && error "lseek should fail"
27555         printf "Seeking data from 0 ... "
27556         lseek_test -d 0 $file && error "lseek should fail"
27557         rm $file
27558
27559         # 1M-hole file
27560         $LFS setstripe -E 1M -c2 -E eof $file
27561         $TRUNCATE $file 1048576
27562         printf "Seeking hole from 1000000 ... "
27563         offset=$(lseek_test -l 1000000 $file)
27564         echo $offset
27565         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27566         printf "Seeking data from 1000000 ... "
27567         lseek_test -d 1000000 $file && error "lseek should fail"
27568         rm $file
27569
27570         # full component followed by non-inited one
27571         $LFS setstripe -E 1M -c2 -E eof $file
27572         dd if=/dev/urandom of=$file bs=1M count=1
27573         printf "Seeking hole from 1000000 ... "
27574         offset=$(lseek_test -l 1000000 $file)
27575         echo $offset
27576         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27577         printf "Seeking hole from 1048576 ... "
27578         lseek_test -l 1048576 $file && error "lseek should fail"
27579         # init second component and truncate back
27580         echo "123" >> $file
27581         $TRUNCATE $file 1048576
27582         printf "Seeking hole from 1000000 ... "
27583         offset=$(lseek_test -l 1000000 $file)
27584         echo $offset
27585         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27586         printf "Seeking hole from 1048576 ... "
27587         lseek_test -l 1048576 $file && error "lseek should fail"
27588         # boundary checks for big values
27589         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27590         offset=$(lseek_test -d 0 $file.10g)
27591         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27592         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27593         offset=$(lseek_test -d 0 $file.100g)
27594         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27595         return 0
27596 }
27597 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27598
27599 test_430c() {
27600         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27601                 skip "OST does not support SEEK_HOLE"
27602
27603         local file=$DIR/$tdir/$tfile
27604         local start
27605
27606         mkdir -p $DIR/$tdir
27607         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27608
27609         # cp version 8.33+ prefers lseek over fiemap
27610         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27611                 start=$SECONDS
27612                 time cp $file /dev/null
27613                 (( SECONDS - start < 5 )) ||
27614                         error "cp: too long runtime $((SECONDS - start))"
27615
27616         fi
27617         # tar version 1.29+ supports SEEK_HOLE/DATA
27618         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27619                 start=$SECONDS
27620                 time tar cS $file - | cat > /dev/null
27621                 (( SECONDS - start < 5 )) ||
27622                         error "tar: too long runtime $((SECONDS - start))"
27623         fi
27624 }
27625 run_test 430c "lseek: external tools check"
27626
27627 test_431() { # LU-14187
27628         local file=$DIR/$tdir/$tfile
27629
27630         mkdir -p $DIR/$tdir
27631         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27632         dd if=/dev/urandom of=$file bs=4k count=1
27633         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27634         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27635         #define OBD_FAIL_OST_RESTART_IO 0x251
27636         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27637         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27638         cp $file $file.0
27639         cancel_lru_locks
27640         sync_all_data
27641         echo 3 > /proc/sys/vm/drop_caches
27642         diff  $file $file.0 || error "data diff"
27643 }
27644 run_test 431 "Restart transaction for IO"
27645
27646 cleanup_test_432() {
27647         do_facet mgs $LCTL nodemap_activate 0
27648         wait_nm_sync active
27649 }
27650
27651 test_432() {
27652         local tmpdir=$TMP/dir432
27653
27654         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27655                 skip "Need MDS version at least 2.14.52"
27656
27657         stack_trap cleanup_test_432 EXIT
27658         mkdir $DIR/$tdir
27659         mkdir $tmpdir
27660
27661         do_facet mgs $LCTL nodemap_activate 1
27662         wait_nm_sync active
27663         do_facet mgs $LCTL nodemap_modify --name default \
27664                 --property admin --value 1
27665         do_facet mgs $LCTL nodemap_modify --name default \
27666                 --property trusted --value 1
27667         cancel_lru_locks mdc
27668         wait_nm_sync default admin_nodemap
27669         wait_nm_sync default trusted_nodemap
27670
27671         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27672                grep -ci "Operation not permitted") -ne 0 ]; then
27673                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27674         fi
27675 }
27676 run_test 432 "mv dir from outside Lustre"
27677
27678 test_433() {
27679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27680
27681         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27682                 skip "inode cache not supported"
27683
27684         $LCTL set_param llite.*.inode_cache=0
27685         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27686
27687         local count=256
27688         local before
27689         local after
27690
27691         cancel_lru_locks mdc
27692         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27693         createmany -m $DIR/$tdir/f $count
27694         createmany -d $DIR/$tdir/d $count
27695         ls -l $DIR/$tdir > /dev/null
27696         stack_trap "rm -rf $DIR/$tdir"
27697
27698         before=$(num_objects)
27699         cancel_lru_locks mdc
27700         after=$(num_objects)
27701
27702         # sometimes even @before is less than 2 * count
27703         while (( before - after < count )); do
27704                 sleep 1
27705                 after=$(num_objects)
27706                 wait=$((wait + 1))
27707                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27708                 if (( wait > 60 )); then
27709                         error "inode slab grew from $before to $after"
27710                 fi
27711         done
27712
27713         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27714 }
27715 run_test 433 "ldlm lock cancel releases dentries and inodes"
27716
27717 test_434() {
27718         local file
27719         local getxattr_count
27720         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27721         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27722
27723         [[ $(getenforce) == "Disabled" ]] ||
27724                 skip "lsm selinux module have to be disabled for this test"
27725
27726         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27727                 error "fail to create $DIR/$tdir/ on MDT0000"
27728
27729         touch $DIR/$tdir/$tfile-{001..100}
27730
27731         # disable the xattr cache
27732         save_lustre_params client "llite.*.xattr_cache" > $p
27733         lctl set_param llite.*.xattr_cache=0
27734         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27735
27736         # clear clients mdc stats
27737         clear_stats $mdc_stat_param ||
27738                 error "fail to clear stats on mdc MDT0000"
27739
27740         for file in $DIR/$tdir/$tfile-{001..100}; do
27741                 getfattr -n security.selinux $file |&
27742                         grep -q "Operation not supported" ||
27743                         error "getxattr on security.selinux should return EOPNOTSUPP"
27744         done
27745
27746         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27747         (( getxattr_count < 100 )) ||
27748                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27749 }
27750 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27751
27752 prep_801() {
27753         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27754         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27755                 skip "Need server version at least 2.9.55"
27756
27757         start_full_debug_logging
27758 }
27759
27760 post_801() {
27761         stop_full_debug_logging
27762 }
27763
27764 barrier_stat() {
27765         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27766                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27767                            awk '/The barrier for/ { print $7 }')
27768                 echo $st
27769         else
27770                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27771                 echo \'$st\'
27772         fi
27773 }
27774
27775 barrier_expired() {
27776         local expired
27777
27778         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27779                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27780                           awk '/will be expired/ { print $7 }')
27781         else
27782                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27783         fi
27784
27785         echo $expired
27786 }
27787
27788 test_801a() {
27789         prep_801
27790
27791         echo "Start barrier_freeze at: $(date)"
27792         #define OBD_FAIL_BARRIER_DELAY          0x2202
27793         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27794         # Do not reduce barrier time - See LU-11873
27795         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27796
27797         sleep 2
27798         local b_status=$(barrier_stat)
27799         echo "Got barrier status at: $(date)"
27800         [ "$b_status" = "'freezing_p1'" ] ||
27801                 error "(1) unexpected barrier status $b_status"
27802
27803         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27804         wait
27805         b_status=$(barrier_stat)
27806         [ "$b_status" = "'frozen'" ] ||
27807                 error "(2) unexpected barrier status $b_status"
27808
27809         local expired=$(barrier_expired)
27810         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27811         sleep $((expired + 3))
27812
27813         b_status=$(barrier_stat)
27814         [ "$b_status" = "'expired'" ] ||
27815                 error "(3) unexpected barrier status $b_status"
27816
27817         # Do not reduce barrier time - See LU-11873
27818         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27819                 error "(4) fail to freeze barrier"
27820
27821         b_status=$(barrier_stat)
27822         [ "$b_status" = "'frozen'" ] ||
27823                 error "(5) unexpected barrier status $b_status"
27824
27825         echo "Start barrier_thaw at: $(date)"
27826         #define OBD_FAIL_BARRIER_DELAY          0x2202
27827         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27828         do_facet mgs $LCTL barrier_thaw $FSNAME &
27829
27830         sleep 2
27831         b_status=$(barrier_stat)
27832         echo "Got barrier status at: $(date)"
27833         [ "$b_status" = "'thawing'" ] ||
27834                 error "(6) unexpected barrier status $b_status"
27835
27836         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27837         wait
27838         b_status=$(barrier_stat)
27839         [ "$b_status" = "'thawed'" ] ||
27840                 error "(7) unexpected barrier status $b_status"
27841
27842         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27843         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27844         do_facet mgs $LCTL barrier_freeze $FSNAME
27845
27846         b_status=$(barrier_stat)
27847         [ "$b_status" = "'failed'" ] ||
27848                 error "(8) unexpected barrier status $b_status"
27849
27850         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27851         do_facet mgs $LCTL barrier_thaw $FSNAME
27852
27853         post_801
27854 }
27855 run_test 801a "write barrier user interfaces and stat machine"
27856
27857 test_801b() {
27858         prep_801
27859
27860         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27861         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27862         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27863         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27864         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27865
27866         cancel_lru_locks mdc
27867
27868         # 180 seconds should be long enough
27869         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27870
27871         local b_status=$(barrier_stat)
27872         [ "$b_status" = "'frozen'" ] ||
27873                 error "(6) unexpected barrier status $b_status"
27874
27875         mkdir $DIR/$tdir/d0/d10 &
27876         mkdir_pid=$!
27877
27878         touch $DIR/$tdir/d1/f13 &
27879         touch_pid=$!
27880
27881         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27882         ln_pid=$!
27883
27884         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27885         mv_pid=$!
27886
27887         rm -f $DIR/$tdir/d4/f12 &
27888         rm_pid=$!
27889
27890         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27891
27892         # To guarantee taht the 'stat' is not blocked
27893         b_status=$(barrier_stat)
27894         [ "$b_status" = "'frozen'" ] ||
27895                 error "(8) unexpected barrier status $b_status"
27896
27897         # let above commands to run at background
27898         sleep 5
27899
27900         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27901         ps -p $touch_pid || error "(10) touch should be blocked"
27902         ps -p $ln_pid || error "(11) link should be blocked"
27903         ps -p $mv_pid || error "(12) rename should be blocked"
27904         ps -p $rm_pid || error "(13) unlink should be blocked"
27905
27906         b_status=$(barrier_stat)
27907         [ "$b_status" = "'frozen'" ] ||
27908                 error "(14) unexpected barrier status $b_status"
27909
27910         do_facet mgs $LCTL barrier_thaw $FSNAME
27911         b_status=$(barrier_stat)
27912         [ "$b_status" = "'thawed'" ] ||
27913                 error "(15) unexpected barrier status $b_status"
27914
27915         wait $mkdir_pid || error "(16) mkdir should succeed"
27916         wait $touch_pid || error "(17) touch should succeed"
27917         wait $ln_pid || error "(18) link should succeed"
27918         wait $mv_pid || error "(19) rename should succeed"
27919         wait $rm_pid || error "(20) unlink should succeed"
27920
27921         post_801
27922 }
27923 run_test 801b "modification will be blocked by write barrier"
27924
27925 test_801c() {
27926         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27927
27928         prep_801
27929
27930         stop mds2 || error "(1) Fail to stop mds2"
27931
27932         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27933
27934         local b_status=$(barrier_stat)
27935         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27936                 do_facet mgs $LCTL barrier_thaw $FSNAME
27937                 error "(2) unexpected barrier status $b_status"
27938         }
27939
27940         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27941                 error "(3) Fail to rescan barrier bitmap"
27942
27943         # Do not reduce barrier time - See LU-11873
27944         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27945
27946         b_status=$(barrier_stat)
27947         [ "$b_status" = "'frozen'" ] ||
27948                 error "(4) unexpected barrier status $b_status"
27949
27950         do_facet mgs $LCTL barrier_thaw $FSNAME
27951         b_status=$(barrier_stat)
27952         [ "$b_status" = "'thawed'" ] ||
27953                 error "(5) unexpected barrier status $b_status"
27954
27955         local devname=$(mdsdevname 2)
27956
27957         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27958
27959         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27960                 error "(7) Fail to rescan barrier bitmap"
27961
27962         post_801
27963 }
27964 run_test 801c "rescan barrier bitmap"
27965
27966 test_802b() {
27967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27968         remote_mds_nodsh && skip "remote MDS with nodsh"
27969
27970         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27971                 skip "readonly option not available"
27972
27973         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27974
27975         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27976                 error "(2) Fail to copy"
27977
27978         # write back all cached data before setting MDT to readonly
27979         cancel_lru_locks
27980         sync_all_data
27981
27982         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27983         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27984
27985         echo "Modify should be refused"
27986         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27987
27988         echo "Read should be allowed"
27989         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27990                 error "(7) Read should succeed under ro mode"
27991
27992         # disable readonly
27993         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27994 }
27995 run_test 802b "be able to set MDTs to readonly"
27996
27997 test_803a() {
27998         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27999         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28000                 skip "MDS needs to be newer than 2.10.54"
28001
28002         mkdir_on_mdt0 $DIR/$tdir
28003         # Create some objects on all MDTs to trigger related logs objects
28004         for idx in $(seq $MDSCOUNT); do
28005                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28006                         $DIR/$tdir/dir${idx} ||
28007                         error "Fail to create $DIR/$tdir/dir${idx}"
28008         done
28009
28010         wait_delete_completed # ensure old test cleanups are finished
28011         sleep 3
28012         echo "before create:"
28013         $LFS df -i $MOUNT
28014         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28015
28016         for i in {1..10}; do
28017                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28018                         error "Fail to create $DIR/$tdir/foo$i"
28019         done
28020
28021         # sync ZFS-on-MDS to refresh statfs data
28022         wait_zfs_commit mds1
28023         sleep 3
28024         echo "after create:"
28025         $LFS df -i $MOUNT
28026         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28027
28028         # allow for an llog to be cleaned up during the test
28029         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28030                 error "before ($before_used) + 10 > after ($after_used)"
28031
28032         for i in {1..10}; do
28033                 rm -rf $DIR/$tdir/foo$i ||
28034                         error "Fail to remove $DIR/$tdir/foo$i"
28035         done
28036
28037         # sync ZFS-on-MDS to refresh statfs data
28038         wait_zfs_commit mds1
28039         wait_delete_completed
28040         sleep 3 # avoid MDT return cached statfs
28041         echo "after unlink:"
28042         $LFS df -i $MOUNT
28043         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28044
28045         # allow for an llog to be created during the test
28046         [ $after_used -le $((before_used + 1)) ] ||
28047                 error "after ($after_used) > before ($before_used) + 1"
28048 }
28049 run_test 803a "verify agent object for remote object"
28050
28051 test_803b() {
28052         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28053         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28054                 skip "MDS needs to be newer than 2.13.56"
28055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28056
28057         for i in $(seq 0 $((MDSCOUNT - 1))); do
28058                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28059         done
28060
28061         local before=0
28062         local after=0
28063
28064         local tmp
28065
28066         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28067         for i in $(seq 0 $((MDSCOUNT - 1))); do
28068                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28069                         awk '/getattr/ { print $2 }')
28070                 before=$((before + tmp))
28071         done
28072         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28073         for i in $(seq 0 $((MDSCOUNT - 1))); do
28074                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28075                         awk '/getattr/ { print $2 }')
28076                 after=$((after + tmp))
28077         done
28078
28079         [ $before -eq $after ] || error "getattr count $before != $after"
28080 }
28081 run_test 803b "remote object can getattr from cache"
28082
28083 test_804() {
28084         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28085         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28086                 skip "MDS needs to be newer than 2.10.54"
28087         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28088
28089         mkdir -p $DIR/$tdir
28090         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28091                 error "Fail to create $DIR/$tdir/dir0"
28092
28093         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28094         local dev=$(mdsdevname 2)
28095
28096         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28097                 grep ${fid} || error "NOT found agent entry for dir0"
28098
28099         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28100                 error "Fail to create $DIR/$tdir/dir1"
28101
28102         touch $DIR/$tdir/dir1/foo0 ||
28103                 error "Fail to create $DIR/$tdir/dir1/foo0"
28104         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28105         local rc=0
28106
28107         for idx in $(seq $MDSCOUNT); do
28108                 dev=$(mdsdevname $idx)
28109                 do_facet mds${idx} \
28110                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28111                         grep ${fid} && rc=$idx
28112         done
28113
28114         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28115                 error "Fail to rename foo0 to foo1"
28116         if [ $rc -eq 0 ]; then
28117                 for idx in $(seq $MDSCOUNT); do
28118                         dev=$(mdsdevname $idx)
28119                         do_facet mds${idx} \
28120                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28121                         grep ${fid} && rc=$idx
28122                 done
28123         fi
28124
28125         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28126                 error "Fail to rename foo1 to foo2"
28127         if [ $rc -eq 0 ]; then
28128                 for idx in $(seq $MDSCOUNT); do
28129                         dev=$(mdsdevname $idx)
28130                         do_facet mds${idx} \
28131                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28132                         grep ${fid} && rc=$idx
28133                 done
28134         fi
28135
28136         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28137
28138         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28139                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28140         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28141                 error "Fail to rename foo2 to foo0"
28142         unlink $DIR/$tdir/dir1/foo0 ||
28143                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28144         rm -rf $DIR/$tdir/dir0 ||
28145                 error "Fail to rm $DIR/$tdir/dir0"
28146
28147         for idx in $(seq $MDSCOUNT); do
28148                 rc=0
28149
28150                 stop mds${idx}
28151                 dev=$(mdsdevname $idx)
28152                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28153                         rc=$?
28154                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28155                         error "mount mds$idx failed"
28156                 df $MOUNT > /dev/null 2>&1
28157
28158                 # e2fsck should not return error
28159                 [ $rc -eq 0 ] ||
28160                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28161         done
28162 }
28163 run_test 804 "verify agent entry for remote entry"
28164
28165 cleanup_805() {
28166         do_facet $SINGLEMDS zfs set quota=$old $fsset
28167         unlinkmany $DIR/$tdir/f- 1000000
28168         trap 0
28169 }
28170
28171 test_805() {
28172         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28173         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28174         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28175                 skip "netfree not implemented before 0.7"
28176         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28177                 skip "Need MDS version at least 2.10.57"
28178
28179         local fsset
28180         local freekb
28181         local usedkb
28182         local old
28183         local quota
28184         local pref="osd-zfs.$FSNAME-MDT0000."
28185
28186         # limit available space on MDS dataset to meet nospace issue
28187         # quickly. then ZFS 0.7.2 can use reserved space if asked
28188         # properly (using netfree flag in osd_declare_destroy()
28189         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28190         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28191                 gawk '{print $3}')
28192         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28193         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28194         let "usedkb=usedkb-freekb"
28195         let "freekb=freekb/2"
28196         if let "freekb > 5000"; then
28197                 let "freekb=5000"
28198         fi
28199         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28200         trap cleanup_805 EXIT
28201         mkdir_on_mdt0 $DIR/$tdir
28202         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28203                 error "Can't set PFL layout"
28204         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28205         rm -rf $DIR/$tdir || error "not able to remove"
28206         do_facet $SINGLEMDS zfs set quota=$old $fsset
28207         trap 0
28208 }
28209 run_test 805 "ZFS can remove from full fs"
28210
28211 # Size-on-MDS test
28212 check_lsom_data()
28213 {
28214         local file=$1
28215         local expect=$(stat -c %s $file)
28216
28217         check_lsom_size $1 $expect
28218
28219         local blocks=$($LFS getsom -b $file)
28220         expect=$(stat -c %b $file)
28221         [[ $blocks == $expect ]] ||
28222                 error "$file expected blocks: $expect, got: $blocks"
28223 }
28224
28225 check_lsom_size()
28226 {
28227         local size
28228         local expect=$2
28229
28230         cancel_lru_locks mdc
28231
28232         size=$($LFS getsom -s $1)
28233         [[ $size == $expect ]] ||
28234                 error "$file expected size: $expect, got: $size"
28235 }
28236
28237 test_806() {
28238         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28239                 skip "Need MDS version at least 2.11.52"
28240
28241         local bs=1048576
28242
28243         touch $DIR/$tfile || error "touch $tfile failed"
28244
28245         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28246         save_lustre_params client "llite.*.xattr_cache" > $save
28247         lctl set_param llite.*.xattr_cache=0
28248         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28249
28250         # single-threaded write
28251         echo "Test SOM for single-threaded write"
28252         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28253                 error "write $tfile failed"
28254         check_lsom_size $DIR/$tfile $bs
28255
28256         local num=32
28257         local size=$(($num * $bs))
28258         local offset=0
28259         local i
28260
28261         echo "Test SOM for single client multi-threaded($num) write"
28262         $TRUNCATE $DIR/$tfile 0
28263         for ((i = 0; i < $num; i++)); do
28264                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28265                 local pids[$i]=$!
28266                 offset=$((offset + $bs))
28267         done
28268         for (( i=0; i < $num; i++ )); do
28269                 wait ${pids[$i]}
28270         done
28271         check_lsom_size $DIR/$tfile $size
28272
28273         $TRUNCATE $DIR/$tfile 0
28274         for ((i = 0; i < $num; i++)); do
28275                 offset=$((offset - $bs))
28276                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28277                 local pids[$i]=$!
28278         done
28279         for (( i=0; i < $num; i++ )); do
28280                 wait ${pids[$i]}
28281         done
28282         check_lsom_size $DIR/$tfile $size
28283
28284         # multi-client writes
28285         num=$(get_node_count ${CLIENTS//,/ })
28286         size=$(($num * $bs))
28287         offset=0
28288         i=0
28289
28290         echo "Test SOM for multi-client ($num) writes"
28291         $TRUNCATE $DIR/$tfile 0
28292         for client in ${CLIENTS//,/ }; do
28293                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28294                 local pids[$i]=$!
28295                 i=$((i + 1))
28296                 offset=$((offset + $bs))
28297         done
28298         for (( i=0; i < $num; i++ )); do
28299                 wait ${pids[$i]}
28300         done
28301         check_lsom_size $DIR/$tfile $offset
28302
28303         i=0
28304         $TRUNCATE $DIR/$tfile 0
28305         for client in ${CLIENTS//,/ }; do
28306                 offset=$((offset - $bs))
28307                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28308                 local pids[$i]=$!
28309                 i=$((i + 1))
28310         done
28311         for (( i=0; i < $num; i++ )); do
28312                 wait ${pids[$i]}
28313         done
28314         check_lsom_size $DIR/$tfile $size
28315
28316         # verify truncate
28317         echo "Test SOM for truncate"
28318         $TRUNCATE $DIR/$tfile 1048576
28319         check_lsom_size $DIR/$tfile 1048576
28320         $TRUNCATE $DIR/$tfile 1234
28321         check_lsom_size $DIR/$tfile 1234
28322
28323         # verify SOM blocks count
28324         echo "Verify SOM block count"
28325         $TRUNCATE $DIR/$tfile 0
28326         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28327                 error "failed to write file $tfile"
28328         check_lsom_data $DIR/$tfile
28329 }
28330 run_test 806 "Verify Lazy Size on MDS"
28331
28332 test_807() {
28333         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28335                 skip "Need MDS version at least 2.11.52"
28336
28337         # Registration step
28338         changelog_register || error "changelog_register failed"
28339         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28340         changelog_users $SINGLEMDS | grep -q $cl_user ||
28341                 error "User $cl_user not found in changelog_users"
28342
28343         rm -rf $DIR/$tdir || error "rm $tdir failed"
28344         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28345         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28346         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28347         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28348                 error "truncate $tdir/trunc failed"
28349
28350         local bs=1048576
28351         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28352                 error "write $tfile failed"
28353
28354         # multi-client wirtes
28355         local num=$(get_node_count ${CLIENTS//,/ })
28356         local offset=0
28357         local i=0
28358
28359         echo "Test SOM for multi-client ($num) writes"
28360         touch $DIR/$tfile || error "touch $tfile failed"
28361         $TRUNCATE $DIR/$tfile 0
28362         for client in ${CLIENTS//,/ }; do
28363                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28364                 local pids[$i]=$!
28365                 i=$((i + 1))
28366                 offset=$((offset + $bs))
28367         done
28368         for (( i=0; i < $num; i++ )); do
28369                 wait ${pids[$i]}
28370         done
28371
28372         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28373         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28374         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28375         check_lsom_data $DIR/$tdir/trunc
28376         check_lsom_data $DIR/$tdir/single_dd
28377         check_lsom_data $DIR/$tfile
28378
28379         rm -rf $DIR/$tdir
28380         # Deregistration step
28381         changelog_deregister || error "changelog_deregister failed"
28382 }
28383 run_test 807 "verify LSOM syncing tool"
28384
28385 check_som_nologged()
28386 {
28387         local lines=$($LFS changelog $FSNAME-MDT0000 |
28388                 grep 'x=trusted.som' | wc -l)
28389         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28390 }
28391
28392 test_808() {
28393         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28394                 skip "Need MDS version at least 2.11.55"
28395
28396         # Registration step
28397         changelog_register || error "changelog_register failed"
28398
28399         touch $DIR/$tfile || error "touch $tfile failed"
28400         check_som_nologged
28401
28402         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28403                 error "write $tfile failed"
28404         check_som_nologged
28405
28406         $TRUNCATE $DIR/$tfile 1234
28407         check_som_nologged
28408
28409         $TRUNCATE $DIR/$tfile 1048576
28410         check_som_nologged
28411
28412         # Deregistration step
28413         changelog_deregister || error "changelog_deregister failed"
28414 }
28415 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28416
28417 check_som_nodata()
28418 {
28419         $LFS getsom $1
28420         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28421 }
28422
28423 test_809() {
28424         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28425                 skip "Need MDS version at least 2.11.56"
28426
28427         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28428                 error "failed to create DoM-only file $DIR/$tfile"
28429         touch $DIR/$tfile || error "touch $tfile failed"
28430         check_som_nodata $DIR/$tfile
28431
28432         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28433                 error "write $tfile failed"
28434         check_som_nodata $DIR/$tfile
28435
28436         $TRUNCATE $DIR/$tfile 1234
28437         check_som_nodata $DIR/$tfile
28438
28439         $TRUNCATE $DIR/$tfile 4097
28440         check_som_nodata $DIR/$file
28441 }
28442 run_test 809 "Verify no SOM xattr store for DoM-only files"
28443
28444 test_810() {
28445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28446         $GSS && skip_env "could not run with gss"
28447         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28448                 skip "OST < 2.12.58 doesn't align checksum"
28449
28450         set_checksums 1
28451         stack_trap "set_checksums $ORIG_CSUM" EXIT
28452         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28453
28454         local csum
28455         local before
28456         local after
28457         for csum in $CKSUM_TYPES; do
28458                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28459                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28460                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28461                         eval set -- $i
28462                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28463                         before=$(md5sum $DIR/$tfile)
28464                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28465                         after=$(md5sum $DIR/$tfile)
28466                         [ "$before" == "$after" ] ||
28467                                 error "$csum: $before != $after bs=$1 seek=$2"
28468                 done
28469         done
28470 }
28471 run_test 810 "partial page writes on ZFS (LU-11663)"
28472
28473 test_812a() {
28474         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28475                 skip "OST < 2.12.51 doesn't support this fail_loc"
28476
28477         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28478         # ensure ost1 is connected
28479         stat $DIR/$tfile >/dev/null || error "can't stat"
28480         wait_osc_import_state client ost1 FULL
28481         # no locks, no reqs to let the connection idle
28482         cancel_lru_locks osc
28483
28484         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28485 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28486         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28487         wait_osc_import_state client ost1 CONNECTING
28488         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28489
28490         stat $DIR/$tfile >/dev/null || error "can't stat file"
28491 }
28492 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28493
28494 test_812b() { # LU-12378
28495         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28496                 skip "OST < 2.12.51 doesn't support this fail_loc"
28497
28498         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28499         # ensure ost1 is connected
28500         stat $DIR/$tfile >/dev/null || error "can't stat"
28501         wait_osc_import_state client ost1 FULL
28502         # no locks, no reqs to let the connection idle
28503         cancel_lru_locks osc
28504
28505         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28506 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28507         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28508         wait_osc_import_state client ost1 CONNECTING
28509         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28510
28511         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28512         wait_osc_import_state client ost1 IDLE
28513 }
28514 run_test 812b "do not drop no resend request for idle connect"
28515
28516 test_812c() {
28517         local old
28518
28519         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28520
28521         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28522         $LFS getstripe $DIR/$tfile
28523         $LCTL set_param osc.*.idle_timeout=10
28524         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28525         # ensure ost1 is connected
28526         stat $DIR/$tfile >/dev/null || error "can't stat"
28527         wait_osc_import_state client ost1 FULL
28528         # no locks, no reqs to let the connection idle
28529         cancel_lru_locks osc
28530
28531 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28532         $LCTL set_param fail_loc=0x80000533
28533         sleep 15
28534         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28535 }
28536 run_test 812c "idle import vs lock enqueue race"
28537
28538 test_813() {
28539         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28540         [ -z "$file_heat_sav" ] && skip "no file heat support"
28541
28542         local readsample
28543         local writesample
28544         local readbyte
28545         local writebyte
28546         local readsample1
28547         local writesample1
28548         local readbyte1
28549         local writebyte1
28550
28551         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28552         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28553
28554         $LCTL set_param -n llite.*.file_heat=1
28555         echo "Turn on file heat"
28556         echo "Period second: $period_second, Decay percentage: $decay_pct"
28557
28558         echo "QQQQ" > $DIR/$tfile
28559         echo "QQQQ" > $DIR/$tfile
28560         echo "QQQQ" > $DIR/$tfile
28561         cat $DIR/$tfile > /dev/null
28562         cat $DIR/$tfile > /dev/null
28563         cat $DIR/$tfile > /dev/null
28564         cat $DIR/$tfile > /dev/null
28565
28566         local out=$($LFS heat_get $DIR/$tfile)
28567
28568         $LFS heat_get $DIR/$tfile
28569         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28570         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28571         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28572         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28573
28574         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28575         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28576         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28577         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28578
28579         sleep $((period_second + 3))
28580         echo "Sleep $((period_second + 3)) seconds..."
28581         # The recursion formula to calculate the heat of the file f is as
28582         # follow:
28583         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28584         # Where Hi is the heat value in the period between time points i*I and
28585         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28586         # to the weight of Ci.
28587         out=$($LFS heat_get $DIR/$tfile)
28588         $LFS heat_get $DIR/$tfile
28589         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28590         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28591         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28592         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28593
28594         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28595                 error "read sample ($readsample) is wrong"
28596         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28597                 error "write sample ($writesample) is wrong"
28598         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28599                 error "read bytes ($readbyte) is wrong"
28600         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28601                 error "write bytes ($writebyte) is wrong"
28602
28603         echo "QQQQ" > $DIR/$tfile
28604         echo "QQQQ" > $DIR/$tfile
28605         echo "QQQQ" > $DIR/$tfile
28606         cat $DIR/$tfile > /dev/null
28607         cat $DIR/$tfile > /dev/null
28608         cat $DIR/$tfile > /dev/null
28609         cat $DIR/$tfile > /dev/null
28610
28611         sleep $((period_second + 3))
28612         echo "Sleep $((period_second + 3)) seconds..."
28613
28614         out=$($LFS heat_get $DIR/$tfile)
28615         $LFS heat_get $DIR/$tfile
28616         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28617         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28618         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28619         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28620
28621         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28622                 4 * $decay_pct) / 100") -eq 1 ] ||
28623                 error "read sample ($readsample1) is wrong"
28624         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28625                 3 * $decay_pct) / 100") -eq 1 ] ||
28626                 error "write sample ($writesample1) is wrong"
28627         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28628                 20 * $decay_pct) / 100") -eq 1 ] ||
28629                 error "read bytes ($readbyte1) is wrong"
28630         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28631                 15 * $decay_pct) / 100") -eq 1 ] ||
28632                 error "write bytes ($writebyte1) is wrong"
28633
28634         echo "Turn off file heat for the file $DIR/$tfile"
28635         $LFS heat_set -o $DIR/$tfile
28636
28637         echo "QQQQ" > $DIR/$tfile
28638         echo "QQQQ" > $DIR/$tfile
28639         echo "QQQQ" > $DIR/$tfile
28640         cat $DIR/$tfile > /dev/null
28641         cat $DIR/$tfile > /dev/null
28642         cat $DIR/$tfile > /dev/null
28643         cat $DIR/$tfile > /dev/null
28644
28645         out=$($LFS heat_get $DIR/$tfile)
28646         $LFS heat_get $DIR/$tfile
28647         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28648         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28649         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28650         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28651
28652         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28653         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28654         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28655         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28656
28657         echo "Trun on file heat for the file $DIR/$tfile"
28658         $LFS heat_set -O $DIR/$tfile
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 -gt 0 ] || error "read sample ($readsample) is wrong"
28676         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28677         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28678         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28679
28680         $LFS heat_set -c $DIR/$tfile
28681         $LCTL set_param -n llite.*.file_heat=0
28682         echo "Turn off file heat support for the Lustre filesystem"
28683
28684         echo "QQQQ" > $DIR/$tfile
28685         echo "QQQQ" > $DIR/$tfile
28686         echo "QQQQ" > $DIR/$tfile
28687         cat $DIR/$tfile > /dev/null
28688         cat $DIR/$tfile > /dev/null
28689         cat $DIR/$tfile > /dev/null
28690         cat $DIR/$tfile > /dev/null
28691
28692         out=$($LFS heat_get $DIR/$tfile)
28693         $LFS heat_get $DIR/$tfile
28694         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28695         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28696         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28697         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28698
28699         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28700         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28701         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28702         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28703
28704         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28705         rm -f $DIR/$tfile
28706 }
28707 run_test 813 "File heat verfication"
28708
28709 test_814()
28710 {
28711         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28712         echo -n y >> $DIR/$tfile
28713         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28714         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28715 }
28716 run_test 814 "sparse cp works as expected (LU-12361)"
28717
28718 test_815()
28719 {
28720         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28721         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28722 }
28723 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28724
28725 test_816() {
28726         local ost1_imp=$(get_osc_import_name client ost1)
28727         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28728                          cut -d'.' -f2)
28729
28730         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28731         # ensure ost1 is connected
28732
28733         stat $DIR/$tfile >/dev/null || error "can't stat"
28734         wait_osc_import_state client ost1 FULL
28735         # no locks, no reqs to let the connection idle
28736         cancel_lru_locks osc
28737         lru_resize_disable osc
28738         local before
28739         local now
28740         before=$($LCTL get_param -n \
28741                  ldlm.namespaces.$imp_name.lru_size)
28742
28743         wait_osc_import_state client ost1 IDLE
28744         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28745         now=$($LCTL get_param -n \
28746               ldlm.namespaces.$imp_name.lru_size)
28747         [ $before == $now ] || error "lru_size changed $before != $now"
28748 }
28749 run_test 816 "do not reset lru_resize on idle reconnect"
28750
28751 cleanup_817() {
28752         umount $tmpdir
28753         exportfs -u localhost:$DIR/nfsexp
28754         rm -rf $DIR/nfsexp
28755 }
28756
28757 test_817() {
28758         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28759
28760         mkdir -p $DIR/nfsexp
28761         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28762                 error "failed to export nfs"
28763
28764         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28765         stack_trap cleanup_817 EXIT
28766
28767         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28768                 error "failed to mount nfs to $tmpdir"
28769
28770         cp /bin/true $tmpdir
28771         $DIR/nfsexp/true || error "failed to execute 'true' command"
28772 }
28773 run_test 817 "nfsd won't cache write lock for exec file"
28774
28775 test_818() {
28776         test_mkdir -i0 -c1 $DIR/$tdir
28777         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28778         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28779         stop $SINGLEMDS
28780
28781         # restore osp-syn threads
28782         stack_trap "fail $SINGLEMDS"
28783
28784         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28785         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28786         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28787                 error "start $SINGLEMDS failed"
28788         rm -rf $DIR/$tdir
28789
28790         local testid=$(echo $TESTNAME | tr '_' ' ')
28791
28792         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28793                 grep "run LFSCK" || error "run LFSCK is not suggested"
28794 }
28795 run_test 818 "unlink with failed llog"
28796
28797 test_819a() {
28798         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28799         cancel_lru_locks osc
28800         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28801         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28802         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28803         rm -f $TDIR/$tfile
28804 }
28805 run_test 819a "too big niobuf in read"
28806
28807 test_819b() {
28808         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28809         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28810         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28811         cancel_lru_locks osc
28812         sleep 1
28813         rm -f $TDIR/$tfile
28814 }
28815 run_test 819b "too big niobuf in write"
28816
28817
28818 function test_820_start_ost() {
28819         sleep 5
28820
28821         for num in $(seq $OSTCOUNT); do
28822                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28823         done
28824 }
28825
28826 test_820() {
28827         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28828
28829         mkdir $DIR/$tdir
28830         umount_client $MOUNT || error "umount failed"
28831         for num in $(seq $OSTCOUNT); do
28832                 stop ost$num
28833         done
28834
28835         # mount client with no active OSTs
28836         # so that the client can't initialize max LOV EA size
28837         # from OSC notifications
28838         mount_client $MOUNT || error "mount failed"
28839         # delay OST starting to keep this 0 max EA size for a while
28840         test_820_start_ost &
28841
28842         # create a directory on MDS2
28843         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28844                 error "Failed to create directory"
28845         # open intent should update default EA size
28846         # see mdc_update_max_ea_from_body()
28847         # notice this is the very first RPC to MDS2
28848         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28849         ret=$?
28850         echo $out
28851         # With SSK, this situation can lead to -EPERM being returned.
28852         # In that case, simply retry.
28853         if [ $ret -ne 0 ] && $SHARED_KEY; then
28854                 if echo "$out" | grep -q "not permitted"; then
28855                         cp /etc/services $DIR/$tdir/mds2
28856                         ret=$?
28857                 fi
28858         fi
28859         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28860 }
28861 run_test 820 "update max EA from open intent"
28862
28863 test_823() {
28864         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28865         local OST_MAX_PRECREATE=20000
28866
28867         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28868                 skip "Need MDS version at least 2.14.56"
28869
28870         save_lustre_params mds1 \
28871                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28872         do_facet $SINGLEMDS "$LCTL set_param -n \
28873                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28874         do_facet $SINGLEMDS "$LCTL set_param -n \
28875                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28876
28877         stack_trap "restore_lustre_params < $p; rm $p"
28878
28879         do_facet $SINGLEMDS "$LCTL set_param -n \
28880                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28881
28882         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28883                       osp.$FSNAME-OST0000*MDT0000.create_count")
28884         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28885                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28886         local expect_count=$(((($max/2)/256) * 256))
28887
28888         log "setting create_count to 100200:"
28889         log " -result- count: $count with max: $max, expecting: $expect_count"
28890
28891         [[ $count -eq expect_count ]] ||
28892                 error "Create count not set to max precreate."
28893 }
28894 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28895
28896 test_831() {
28897         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28898                 skip "Need MDS version 2.14.56"
28899
28900         local sync_changes=$(do_facet $SINGLEMDS \
28901                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28902
28903         [ "$sync_changes" -gt 100 ] &&
28904                 skip "Sync changes $sync_changes > 100 already"
28905
28906         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28907
28908         $LFS mkdir -i 0 $DIR/$tdir
28909         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28910
28911         save_lustre_params mds1 \
28912                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28913         save_lustre_params mds1 \
28914                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28915
28916         do_facet mds1 "$LCTL set_param -n \
28917                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28918                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28919         stack_trap "restore_lustre_params < $p" EXIT
28920
28921         createmany -o $DIR/$tdir/f- 1000
28922         unlinkmany $DIR/$tdir/f- 1000 &
28923         local UNLINK_PID=$!
28924
28925         while sleep 1; do
28926                 sync_changes=$(do_facet mds1 \
28927                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28928                 # the check in the code is racy, fail the test
28929                 # if the value above the limit by 10.
28930                 [ $sync_changes -gt 110 ] && {
28931                         kill -2 $UNLINK_PID
28932                         wait
28933                         error "osp changes throttling failed, $sync_changes>110"
28934                 }
28935                 kill -0 $UNLINK_PID 2> /dev/null || break
28936         done
28937         wait
28938 }
28939 run_test 831 "throttling unlink/setattr queuing on OSP"
28940
28941 test_832() {
28942         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
28943         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
28944                 skip "Need MDS version 2.15.52+"
28945         is_rmentry_supported || skip "rm_entry not supported"
28946
28947         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28948         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
28949         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
28950                 error "mkdir remote_dir failed"
28951         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
28952                 error "mkdir striped_dir failed"
28953         touch $DIR/$tdir/file || error "touch file failed"
28954         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
28955         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
28956 }
28957 run_test 832 "lfs rm_entry"
28958
28959 #
28960 # tests that do cleanup/setup should be run at the end
28961 #
28962
28963 test_900() {
28964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28965         local ls
28966
28967         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28968         $LCTL set_param fail_loc=0x903
28969
28970         cancel_lru_locks MGC
28971
28972         FAIL_ON_ERROR=true cleanup
28973         FAIL_ON_ERROR=true setup
28974 }
28975 run_test 900 "umount should not race with any mgc requeue thread"
28976
28977 # LUS-6253/LU-11185
28978 test_901() {
28979         local old
28980         local count
28981         local oldc
28982         local newc
28983         local olds
28984         local news
28985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28986
28987         # some get_param have a bug to handle dot in param name
28988         cancel_lru_locks MGC
28989         old=$(mount -t lustre | wc -l)
28990         # 1 config+sptlrpc
28991         # 2 params
28992         # 3 nodemap
28993         # 4 IR
28994         old=$((old * 4))
28995         oldc=0
28996         count=0
28997         while [ $old -ne $oldc ]; do
28998                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28999                 sleep 1
29000                 ((count++))
29001                 if [ $count -ge $TIMEOUT ]; then
29002                         error "too large timeout"
29003                 fi
29004         done
29005         umount_client $MOUNT || error "umount failed"
29006         mount_client $MOUNT || error "mount failed"
29007         cancel_lru_locks MGC
29008         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29009
29010         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29011
29012         return 0
29013 }
29014 run_test 901 "don't leak a mgc lock on client umount"
29015
29016 # LU-13377
29017 test_902() {
29018         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29019                 skip "client does not have LU-13377 fix"
29020         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29021         $LCTL set_param fail_loc=0x1415
29022         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29023         cancel_lru_locks osc
29024         rm -f $DIR/$tfile
29025 }
29026 run_test 902 "test short write doesn't hang lustre"
29027
29028 # LU-14711
29029 test_903() {
29030         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29031         echo "blah" > $DIR/${tfile}-2
29032         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29033         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29034         $LCTL set_param fail_loc=0x417 fail_val=20
29035
29036         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29037         sleep 1 # To start the destroy
29038         wait_destroy_complete 150 || error "Destroy taking too long"
29039         cat $DIR/$tfile > /dev/null || error "Evicted"
29040 }
29041 run_test 903 "Test long page discard does not cause evictions"
29042
29043 test_904() {
29044         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29045         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29046                 grep -q project || skip "skip project quota not supported"
29047
29048         local testfile="$DIR/$tdir/$tfile"
29049         local xattr="trusted.projid"
29050         local projid
29051         local mdts=$(comma_list $(mdts_nodes))
29052         local saved=$(do_facet mds1 $LCTL get_param -n \
29053                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29054
29055         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29056         stack_trap "do_nodes $mdts $LCTL set_param \
29057                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29058
29059         mkdir -p $DIR/$tdir
29060         touch $testfile
29061         #hide projid xattr on server
29062         $LFS project -p 1 $testfile ||
29063                 error "set $testfile project id failed"
29064         getfattr -m - $testfile | grep $xattr &&
29065                 error "do not show trusted.projid when disabled on server"
29066         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29067         #should be hidden when projid is 0
29068         $LFS project -p 0 $testfile ||
29069                 error "set $testfile project id failed"
29070         getfattr -m - $testfile | grep $xattr &&
29071                 error "do not show trusted.projid with project ID 0"
29072
29073         #still can getxattr explicitly
29074         projid=$(getfattr -n $xattr $testfile |
29075                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29076         [ $projid == "0" ] ||
29077                 error "projid expected 0 not $projid"
29078
29079         #set the projid via setxattr
29080         setfattr -n $xattr -v "1000" $testfile ||
29081                 error "setattr failed with $?"
29082         projid=($($LFS project $testfile))
29083         [ ${projid[0]} == "1000" ] ||
29084                 error "projid expected 1000 not $projid"
29085
29086         #check the new projid via getxattr
29087         $LFS project -p 1001 $testfile ||
29088                 error "set $testfile project id failed"
29089         getfattr -m - $testfile | grep $xattr ||
29090                 error "should show trusted.projid when project ID != 0"
29091         projid=$(getfattr -n $xattr $testfile |
29092                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29093         [ $projid == "1001" ] ||
29094                 error "projid expected 1001 not $projid"
29095
29096         #try to set invalid projid
29097         setfattr -n $xattr -v "4294967295" $testfile &&
29098                 error "set invalid projid should fail"
29099
29100         #remove the xattr means setting projid to 0
29101         setfattr -x $xattr $testfile ||
29102                 error "setfattr failed with $?"
29103         projid=($($LFS project $testfile))
29104         [ ${projid[0]} == "0" ] ||
29105                 error "projid expected 0 not $projid"
29106
29107         #should be hidden when parent has inherit flag and same projid
29108         $LFS project -srp 1002 $DIR/$tdir ||
29109                 error "set $tdir project id failed"
29110         getfattr -m - $testfile | grep $xattr &&
29111                 error "do not show trusted.projid with inherit flag"
29112
29113         #still can getxattr explicitly
29114         projid=$(getfattr -n $xattr $testfile |
29115                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29116         [ $projid == "1002" ] ||
29117                 error "projid expected 1002 not $projid"
29118 }
29119 run_test 904 "virtual project ID xattr"
29120
29121 # LU-8582
29122 test_905() {
29123         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29124                 skip "lustre < 2.8.54 does not support ladvise"
29125
29126         remote_ost_nodsh && skip "remote OST with nodsh"
29127         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29128
29129         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29130
29131         #define OBD_FAIL_OST_OPCODE 0x253
29132         # OST_LADVISE = 21
29133         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29134         $LFS ladvise -a willread $DIR/$tfile &&
29135                 error "unexpected success of ladvise with fault injection"
29136         $LFS ladvise -a willread $DIR/$tfile |&
29137                 grep -q "Operation not supported"
29138         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29139 }
29140 run_test 905 "bad or new opcode should not stuck client"
29141
29142 test_906() {
29143         grep -q io_uring_setup /proc/kallsyms ||
29144                 skip "Client OS does not support io_uring I/O engine"
29145         io_uring_probe || skip "kernel does not support io_uring fully"
29146         which fio || skip_env "no fio installed"
29147         fio --enghelp | grep -q io_uring ||
29148                 skip_env "fio does not support io_uring I/O engine"
29149
29150         local file=$DIR/$tfile
29151         local ioengine="io_uring"
29152         local numjobs=2
29153         local size=50M
29154
29155         fio --name=seqwrite --ioengine=$ioengine        \
29156                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29157                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29158                 error "fio seqwrite $file failed"
29159
29160         fio --name=seqread --ioengine=$ioengine \
29161                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29162                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29163                 error "fio seqread $file failed"
29164
29165         rm -f $file || error "rm -f $file failed"
29166 }
29167 run_test 906 "Simple test for io_uring I/O engine via fio"
29168
29169
29170 complete $SECONDS
29171 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29172 check_and_cleanup_lustre
29173 if [ "$I_MOUNTED" != "yes" ]; then
29174         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29175 fi
29176 exit_status