Whamcloud - gitweb
6ad6e5088a975cc8ca5817c421130d45cf5ea78a
[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 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
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 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 #                                  5              12     8   12  15   (min)"
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10366 410
116                 fi
117         fi
118 fi
119
120 build_test_filter
121 FAIL_ON_ERROR=false
122
123 cleanup() {
124         echo -n "cln.."
125         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
126         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
127 }
128 setup() {
129         echo -n "mnt.."
130         load_modules
131         setupall || exit 10
132         echo "done"
133 }
134
135 check_swap_layouts_support()
136 {
137         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
138                 skip "Does not support layout lock."
139 }
140
141 check_swap_layout_no_dom()
142 {
143         local FOLDER=$1
144         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
145         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
146 }
147
148 check_and_setup_lustre
149 DIR=${DIR:-$MOUNT}
150 assert_DIR
151
152 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
153
154 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
155 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
156 rm -rf $DIR/[Rdfs][0-9]*
157
158 # $RUNAS_ID may get set incorrectly somewhere else
159 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
160         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
161
162 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
163
164 if [ "${ONLY}" = "MOUNT" ] ; then
165         echo "Lustre is up, please go on"
166         exit
167 fi
168
169 echo "preparing for tests involving mounts"
170 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
171 touch $EXT2_DEV
172 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
173 echo # add a newline after mke2fs.
174
175 umask 077
176
177 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
178
179 # ensure all internal functions know we want full debug
180 export PTLDEBUG=all
181 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
182
183 test_0a() {
184         touch $DIR/$tfile
185         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
186         rm $DIR/$tfile
187         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
188 }
189 run_test 0a "touch; rm ====================="
190
191 test_0b() {
192         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
193         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
194 }
195 run_test 0b "chmod 0755 $DIR ============================="
196
197 test_0c() {
198         $LCTL get_param mdc.*.import | grep "state: FULL" ||
199                 error "import not FULL"
200         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
201                 error "bad target"
202 }
203 run_test 0c "check import proc"
204
205 test_0d() { # LU-3397
206         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
207                 skip "proc exports not supported before 2.10.57"
208
209         local mgs_exp="mgs.MGS.exports"
210         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
211         local exp_client_nid
212         local exp_client_version
213         local exp_val
214         local imp_val
215         local temp_imp=$DIR/$tfile.import
216         local temp_exp=$DIR/$tfile.export
217
218         # save mgc import file to $temp_imp
219         $LCTL get_param mgc.*.import | tee $temp_imp
220         # Check if client uuid is found in MGS export
221         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
222                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
223                         $client_uuid ] &&
224                         break;
225         done
226         # save mgs export file to $temp_exp
227         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
228
229         # Compare the value of field "connect_flags"
230         imp_val=$(grep "connect_flags" $temp_imp)
231         exp_val=$(grep "connect_flags" $temp_exp)
232         [ "$exp_val" == "$imp_val" ] ||
233                 error "export flags '$exp_val' != import flags '$imp_val'"
234
235         # Compare client versions.  Only compare top-3 fields for compatibility
236         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
237         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
238         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
239         [ "$exp_val" == "$imp_val" ] ||
240                 error "exp version '$exp_client_version'($exp_val) != " \
241                         "'$(lustre_build_version client)'($imp_val)"
242 }
243 run_test 0d "check export proc ============================="
244
245 test_0e() { # LU-13417
246         (( $MDSCOUNT > 1 )) ||
247                 skip "We need at least 2 MDTs for this test"
248
249         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
250                 skip "Need server version at least 2.14.51"
251
252         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
253         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
254
255         [ $default_lmv_count -eq 1 ] ||
256                 error "$MOUNT default stripe count $default_lmv_count"
257
258         [ $default_lmv_index -eq -1 ] ||
259                 error "$MOUNT default stripe index $default_lmv_index"
260
261         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
262         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
263
264         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
265         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
266
267         [ $mdt_index1 -eq $mdt_index2 ] &&
268                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
269
270         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
271 }
272 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
273
274 test_1() {
275         test_mkdir $DIR/$tdir
276         test_mkdir $DIR/$tdir/d2
277         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
278         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
279         rmdir $DIR/$tdir/d2
280         rmdir $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
282 }
283 run_test 1 "mkdir; remkdir; rmdir"
284
285 test_2() {
286         test_mkdir $DIR/$tdir
287         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
288         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
289         rm -r $DIR/$tdir
290         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
291 }
292 run_test 2 "mkdir; touch; rmdir; check file"
293
294 test_3() {
295         test_mkdir $DIR/$tdir
296         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
297         touch $DIR/$tdir/$tfile
298         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
299         rm -r $DIR/$tdir
300         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
301 }
302 run_test 3 "mkdir; touch; rmdir; check dir"
303
304 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
305 test_4() {
306         test_mkdir -i 1 $DIR/$tdir
307
308         touch $DIR/$tdir/$tfile ||
309                 error "Create file under remote directory failed"
310
311         rmdir $DIR/$tdir &&
312                 error "Expect error removing in-use dir $DIR/$tdir"
313
314         test -d $DIR/$tdir || error "Remote directory disappeared"
315
316         rm -rf $DIR/$tdir || error "remove remote dir error"
317 }
318 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
319
320 test_5() {
321         test_mkdir $DIR/$tdir
322         test_mkdir $DIR/$tdir/d2
323         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
324         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
325         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
326 }
327 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
328
329 test_6a() {
330         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
331         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile does not have perm 0666 or UID $UID"
334         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
335         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
336                 error "$tfile should be 0666 and owned by UID $UID"
337 }
338 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
339
340 test_6c() {
341         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
342
343         touch $DIR/$tfile
344         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
348         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
349                 error "$tfile should be owned by UID $RUNAS_ID"
350 }
351 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
352
353 test_6e() {
354         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
355
356         touch $DIR/$tfile
357         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by GID $UID"
360         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
361         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
362                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
363 }
364 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
365
366 test_6g() {
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         test_mkdir $DIR/$tdir
370         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
371         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
372         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
373         test_mkdir $DIR/$tdir/d/subdir
374         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
375                 error "$tdir/d/subdir should be GID $RUNAS_GID"
376         if [[ $MDSCOUNT -gt 1 ]]; then
377                 # check remote dir sgid inherite
378                 $LFS mkdir -i 0 $DIR/$tdir.local ||
379                         error "mkdir $tdir.local failed"
380                 chmod g+s $DIR/$tdir.local ||
381                         error "chmod $tdir.local failed"
382                 chgrp $RUNAS_GID $DIR/$tdir.local ||
383                         error "chgrp $tdir.local failed"
384                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
385                         error "mkdir $tdir.remote failed"
386                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
387                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
388                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
389                         error "$tdir.remote should be mode 02755"
390         fi
391 }
392 run_test 6g "verify new dir in sgid dir inherits group"
393
394 test_6h() { # bug 7331
395         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
396
397         touch $DIR/$tfile || error "touch failed"
398         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
399         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
400                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
401         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
402                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
403 }
404 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
405
406 test_7a() {
407         test_mkdir $DIR/$tdir
408         $MCREATE $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tdir/$tfile should be mode 0666"
412 }
413 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
414
415 test_7b() {
416         if [ ! -d $DIR/$tdir ]; then
417                 test_mkdir $DIR/$tdir
418         fi
419         $MCREATE $DIR/$tdir/$tfile
420         echo -n foo > $DIR/$tdir/$tfile
421         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
422         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
423 }
424 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
425
426 test_8() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
431                 error "$tfile mode not 0666"
432 }
433 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
434
435 test_9() {
436         test_mkdir $DIR/$tdir
437         test_mkdir $DIR/$tdir/d2
438         test_mkdir $DIR/$tdir/d2/d3
439         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
440 }
441 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
442
443 test_10() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         touch $DIR/$tdir/d2/$tfile
447         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
448                 error "$tdir/d2/$tfile not a file"
449 }
450 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
451
452 test_11() {
453         test_mkdir $DIR/$tdir
454         test_mkdir $DIR/$tdir/d2
455         chmod 0666 $DIR/$tdir/d2
456         chmod 0705 $DIR/$tdir/d2
457         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
458                 error "$tdir/d2 mode not 0705"
459 }
460 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
461
462 test_12() {
463         test_mkdir $DIR/$tdir
464         touch $DIR/$tdir/$tfile
465         chmod 0666 $DIR/$tdir/$tfile
466         chmod 0654 $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
468                 error "$tdir/d2 mode not 0654"
469 }
470 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
471
472 test_13() {
473         test_mkdir $DIR/$tdir
474         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
475         >  $DIR/$tdir/$tfile
476         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
477                 error "$tdir/$tfile size not 0 after truncate"
478 }
479 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
480
481 test_14() {
482         test_mkdir $DIR/$tdir
483         touch $DIR/$tdir/$tfile
484         rm $DIR/$tdir/$tfile
485         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
486 }
487 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
488
489 test_15() {
490         test_mkdir $DIR/$tdir
491         touch $DIR/$tdir/$tfile
492         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
493         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
494                 error "$tdir/${tfile_2} not a file after rename"
495         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
496 }
497 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
498
499 test_16() {
500         test_mkdir $DIR/$tdir
501         touch $DIR/$tdir/$tfile
502         rm -rf $DIR/$tdir/$tfile
503         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
504 }
505 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
506
507 test_17a() {
508         test_mkdir $DIR/$tdir
509         touch $DIR/$tdir/$tfile
510         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
511         ls -l $DIR/$tdir
512         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
513                 error "$tdir/l-exist not a symlink"
514         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
515                 error "$tdir/l-exist not referencing a file"
516         rm -f $DIR/$tdir/l-exist
517         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
518 }
519 run_test 17a "symlinks: create, remove (real)"
520
521 test_17b() {
522         test_mkdir $DIR/$tdir
523         ln -s no-such-file $DIR/$tdir/l-dangle
524         ls -l $DIR/$tdir
525         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
526                 error "$tdir/l-dangle not referencing no-such-file"
527         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
528                 error "$tdir/l-dangle not referencing non-existent file"
529         rm -f $DIR/$tdir/l-dangle
530         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
531 }
532 run_test 17b "symlinks: create, remove (dangling)"
533
534 test_17c() { # bug 3440 - don't save failed open RPC for replay
535         test_mkdir $DIR/$tdir
536         ln -s foo $DIR/$tdir/$tfile
537         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
538 }
539 run_test 17c "symlinks: open dangling (should return error)"
540
541 test_17d() {
542         test_mkdir $DIR/$tdir
543         ln -s foo $DIR/$tdir/$tfile
544         touch $DIR/$tdir/$tfile || error "creating to new symlink"
545 }
546 run_test 17d "symlinks: create dangling"
547
548 test_17e() {
549         test_mkdir $DIR/$tdir
550         local foo=$DIR/$tdir/$tfile
551         ln -s $foo $foo || error "create symlink failed"
552         ls -l $foo || error "ls -l failed"
553         ls $foo && error "ls not failed" || true
554 }
555 run_test 17e "symlinks: create recursive symlink (should return error)"
556
557 test_17f() {
558         test_mkdir $DIR/$tdir
559         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
562         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
563         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
564         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
565         ls -l  $DIR/$tdir
566 }
567 run_test 17f "symlinks: long and very long symlink name"
568
569 # str_repeat(S, N) generate a string that is string S repeated N times
570 str_repeat() {
571         local s=$1
572         local n=$2
573         local ret=''
574         while [ $((n -= 1)) -ge 0 ]; do
575                 ret=$ret$s
576         done
577         echo $ret
578 }
579
580 # Long symlinks and LU-2241
581 test_17g() {
582         test_mkdir $DIR/$tdir
583         local TESTS="59 60 61 4094 4095"
584
585         # Fix for inode size boundary in 2.1.4
586         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
587                 TESTS="4094 4095"
588
589         # Patch not applied to 2.2 or 2.3 branches
590         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
591         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
592                 TESTS="4094 4095"
593
594         for i in $TESTS; do
595                 local SYMNAME=$(str_repeat 'x' $i)
596                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
597                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
598         done
599 }
600 run_test 17g "symlinks: really long symlink name and inode boundaries"
601
602 test_17h() { #bug 17378
603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
604         remote_mds_nodsh && skip "remote MDS with nodsh"
605
606         local mdt_idx
607
608         test_mkdir $DIR/$tdir
609         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
610         $LFS setstripe -c -1 $DIR/$tdir
611         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
612         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
613         touch $DIR/$tdir/$tfile || true
614 }
615 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
616
617 test_17i() { #bug 20018
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local foo=$DIR/$tdir/$tfile
622         local mdt_idx
623
624         test_mkdir -c1 $DIR/$tdir
625         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
626         ln -s $foo $foo || error "create symlink failed"
627 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
628         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
629         ls -l $foo && error "error not detected"
630         return 0
631 }
632 run_test 17i "don't panic on short symlink (should return error)"
633
634 test_17k() { #bug 22301
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [[ -z "$(which rsync 2>/dev/null)" ]] &&
637                 skip "no rsync command"
638         rsync --help | grep -q xattr ||
639                 skip_env "$(rsync --version | head -n1) does not support xattrs"
640         test_mkdir $DIR/$tdir
641         test_mkdir $DIR/$tdir.new
642         touch $DIR/$tdir/$tfile
643         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
644         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
645                 error "rsync failed with xattrs enabled"
646 }
647 run_test 17k "symlinks: rsync with xattrs enabled"
648
649 test_17l() { # LU-279
650         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
651                 skip "no getfattr command"
652
653         test_mkdir $DIR/$tdir
654         touch $DIR/$tdir/$tfile
655         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
656         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
657                 # -h to not follow symlinks. -m '' to list all the xattrs.
658                 # grep to remove first line: '# file: $path'.
659                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
660                 do
661                         lgetxattr_size_check $path $xattr ||
662                                 error "lgetxattr_size_check $path $xattr failed"
663                 done
664         done
665 }
666 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
667
668 # LU-1540
669 test_17m() {
670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
671         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
672         remote_mds_nodsh && skip "remote MDS with nodsh"
673         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
674         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
675                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
676
677         local short_sym="0123456789"
678         local wdir=$DIR/$tdir
679         local i
680
681         test_mkdir $wdir
682         long_sym=$short_sym
683         # create a long symlink file
684         for ((i = 0; i < 4; ++i)); do
685                 long_sym=${long_sym}${long_sym}
686         done
687
688         echo "create 512 short and long symlink files under $wdir"
689         for ((i = 0; i < 256; ++i)); do
690                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
691                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
692         done
693
694         echo "erase them"
695         rm -f $wdir/*
696         sync
697         wait_delete_completed
698
699         echo "recreate the 512 symlink files with a shorter string"
700         for ((i = 0; i < 512; ++i)); do
701                 # rewrite the symlink file with a shorter string
702                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
703                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
704         done
705
706         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
707
708         echo "stop and checking mds${mds_index}:"
709         # e2fsck should not return error
710         stop mds${mds_index}
711         local devname=$(mdsdevname $mds_index)
712         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
713         rc=$?
714
715         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
716                 error "start mds${mds_index} failed"
717         df $MOUNT > /dev/null 2>&1
718         [ $rc -eq 0 ] ||
719                 error "e2fsck detected error for short/long symlink: rc=$rc"
720         rm -f $wdir/*
721 }
722 run_test 17m "run e2fsck against MDT which contains short/long symlink"
723
724 check_fs_consistency_17n() {
725         local mdt_index
726         local rc=0
727
728         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
729         # so it only check MDT1/MDT2 instead of all of MDTs.
730         for mdt_index in 1 2; do
731                 # e2fsck should not return error
732                 stop mds${mdt_index}
733                 local devname=$(mdsdevname $mdt_index)
734                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
735                         rc=$((rc + $?))
736
737                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
738                         error "mount mds$mdt_index failed"
739                 df $MOUNT > /dev/null 2>&1
740         done
741         return $rc
742 }
743
744 test_17n() {
745         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
747         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
750         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
751                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
752
753         local i
754
755         test_mkdir $DIR/$tdir
756         for ((i=0; i<10; i++)); do
757                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
758                         error "create remote dir error $i"
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761         done
762
763         check_fs_consistency_17n ||
764                 error "e2fsck report error after create files under remote dir"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n ||
772                 error "e2fsck report error after unlink files under remote dir"
773
774         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
775                 skip "lustre < 2.4.50 does not support migrate mv"
776
777         for ((i = 0; i < 10; i++)); do
778                 mkdir -p $DIR/$tdir/remote_dir_${i}
779                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
780                         error "create files under remote dir failed $i"
781                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
782                         error "migrate remote dir error $i"
783         done
784         check_fs_consistency_17n || error "e2fsck report error after migration"
785
786         for ((i = 0; i < 10; i++)); do
787                 rm -rf $DIR/$tdir/remote_dir_${i} ||
788                         error "destroy remote dir error $i"
789         done
790
791         check_fs_consistency_17n || error "e2fsck report error after unlink"
792 }
793 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
794
795 test_17o() {
796         remote_mds_nodsh && skip "remote MDS with nodsh"
797         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
798                 skip "Need MDS version at least 2.3.64"
799
800         local wdir=$DIR/${tdir}o
801         local mdt_index
802         local rc=0
803
804         test_mkdir $wdir
805         touch $wdir/$tfile
806         mdt_index=$($LFS getstripe -m $wdir/$tfile)
807         mdt_index=$((mdt_index + 1))
808
809         cancel_lru_locks mdc
810         #fail mds will wait the failover finish then set
811         #following fail_loc to avoid interfer the recovery process.
812         fail mds${mdt_index}
813
814         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
815         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
816         ls -l $wdir/$tfile && rc=1
817         do_facet mds${mdt_index} lctl set_param fail_loc=0
818         [[ $rc -eq 0 ]] || error "stat file should fail"
819 }
820 run_test 17o "stat file with incompat LMA feature"
821
822 test_18() {
823         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
824         ls $DIR || error "Failed to ls $DIR: $?"
825 }
826 run_test 18 "touch .../f ; ls ... =============================="
827
828 test_19a() {
829         touch $DIR/$tfile
830         ls -l $DIR
831         rm $DIR/$tfile
832         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
833 }
834 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
835
836 test_19b() {
837         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
838 }
839 run_test 19b "ls -l .../f19 (should return error) =============="
840
841 test_19c() {
842         [ $RUNAS_ID -eq $UID ] &&
843                 skip_env "RUNAS_ID = UID = $UID -- skipping"
844
845         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
846 }
847 run_test 19c "$RUNAS touch .../f19 (should return error) =="
848
849 test_19d() {
850         cat $DIR/f19 && error || true
851 }
852 run_test 19d "cat .../f19 (should return error) =============="
853
854 test_20() {
855         touch $DIR/$tfile
856         rm $DIR/$tfile
857         touch $DIR/$tfile
858         rm $DIR/$tfile
859         touch $DIR/$tfile
860         rm $DIR/$tfile
861         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
862 }
863 run_test 20 "touch .../f ; ls -l ..."
864
865 test_21() {
866         test_mkdir $DIR/$tdir
867         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
868         ln -s dangle $DIR/$tdir/link
869         echo foo >> $DIR/$tdir/link
870         cat $DIR/$tdir/dangle
871         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
872         $CHECKSTAT -f -t file $DIR/$tdir/link ||
873                 error "$tdir/link not linked to a file"
874 }
875 run_test 21 "write to dangling link"
876
877 test_22() {
878         local wdir=$DIR/$tdir
879         test_mkdir $wdir
880         chown $RUNAS_ID:$RUNAS_GID $wdir
881         (cd $wdir || error "cd $wdir failed";
882                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
883                 $RUNAS tar xf -)
884         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
885         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
886         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
887                 error "checkstat -u failed"
888 }
889 run_test 22 "unpack tar archive as non-root user"
890
891 # was test_23
892 test_23a() {
893         test_mkdir $DIR/$tdir
894         local file=$DIR/$tdir/$tfile
895
896         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
897         openfile -f O_CREAT:O_EXCL $file &&
898                 error "$file recreate succeeded" || true
899 }
900 run_test 23a "O_CREAT|O_EXCL in subdir"
901
902 test_23b() { # bug 18988
903         test_mkdir $DIR/$tdir
904         local file=$DIR/$tdir/$tfile
905
906         rm -f $file
907         echo foo > $file || error "write filed"
908         echo bar >> $file || error "append filed"
909         $CHECKSTAT -s 8 $file || error "wrong size"
910         rm $file
911 }
912 run_test 23b "O_APPEND check"
913
914 # LU-9409, size with O_APPEND and tiny writes
915 test_23c() {
916         local file=$DIR/$tfile
917
918         # single dd
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
920         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
921         rm -f $file
922
923         # racing tiny writes
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
925         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
926         wait
927         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
928         rm -f $file
929
930         #racing tiny & normal writes
931         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
933         wait
934         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
935         rm -f $file
936
937         #racing tiny & normal writes 2, ugly numbers
938         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
940         wait
941         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
942         rm -f $file
943 }
944 run_test 23c "O_APPEND size checks for tiny writes"
945
946 # LU-11069 file offset is correct after appending writes
947 test_23d() {
948         local file=$DIR/$tfile
949         local offset
950
951         echo CentaurHauls > $file
952         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
953         if ((offset != 26)); then
954                 error "wrong offset, expected 26, got '$offset'"
955         fi
956 }
957 run_test 23d "file offset is correct after appending writes"
958
959 # rename sanity
960 test_24a() {
961         echo '-- same directory rename'
962         test_mkdir $DIR/$tdir
963         touch $DIR/$tdir/$tfile.1
964         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24a "rename file to non-existent target"
968
969 test_24b() {
970         test_mkdir $DIR/$tdir
971         touch $DIR/$tdir/$tfile.{1,2}
972         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
973         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
974         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
975 }
976 run_test 24b "rename file to existing target"
977
978 test_24c() {
979         test_mkdir $DIR/$tdir
980         test_mkdir $DIR/$tdir/d$testnum.1
981         mv $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 24c "rename directory to non-existent target"
986
987 test_24d() {
988         test_mkdir -c1 $DIR/$tdir
989         test_mkdir -c1 $DIR/$tdir/d$testnum.1
990         test_mkdir -c1 $DIR/$tdir/d$testnum.2
991         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
992         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
993         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
994 }
995 run_test 24d "rename directory to existing target"
996
997 test_24e() {
998         echo '-- cross directory renames --'
999         test_mkdir $DIR/R5a
1000         test_mkdir $DIR/R5b
1001         touch $DIR/R5a/f
1002         mv $DIR/R5a/f $DIR/R5b/g
1003         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1004         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1005 }
1006 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1007
1008 test_24f() {
1009         test_mkdir $DIR/R6a
1010         test_mkdir $DIR/R6b
1011         touch $DIR/R6a/f $DIR/R6b/g
1012         mv $DIR/R6a/f $DIR/R6b/g
1013         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1014         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1015 }
1016 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1017
1018 test_24g() {
1019         test_mkdir $DIR/R7a
1020         test_mkdir $DIR/R7b
1021         test_mkdir $DIR/R7a/d
1022         mv $DIR/R7a/d $DIR/R7b/e
1023         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1024         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1025 }
1026 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1027
1028 test_24h() {
1029         test_mkdir -c1 $DIR/R8a
1030         test_mkdir -c1 $DIR/R8b
1031         test_mkdir -c1 $DIR/R8a/d
1032         test_mkdir -c1 $DIR/R8b/e
1033         mrename $DIR/R8a/d $DIR/R8b/e
1034         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1035         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1036 }
1037 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1038
1039 test_24i() {
1040         echo "-- rename error cases"
1041         test_mkdir $DIR/R9
1042         test_mkdir $DIR/R9/a
1043         touch $DIR/R9/f
1044         mrename $DIR/R9/f $DIR/R9/a
1045         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1046         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1047         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1048 }
1049 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1050
1051 test_24j() {
1052         test_mkdir $DIR/R10
1053         mrename $DIR/R10/f $DIR/R10/g
1054         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1055         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1056         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1057 }
1058 run_test 24j "source does not exist ============================"
1059
1060 test_24k() {
1061         test_mkdir $DIR/R11a
1062         test_mkdir $DIR/R11a/d
1063         touch $DIR/R11a/f
1064         mv $DIR/R11a/f $DIR/R11a/d
1065         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1066         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1067 }
1068 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1069
1070 # bug 2429 - rename foo foo foo creates invalid file
1071 test_24l() {
1072         f="$DIR/f24l"
1073         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1074 }
1075 run_test 24l "Renaming a file to itself ========================"
1076
1077 test_24m() {
1078         f="$DIR/f24m"
1079         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1080         # on ext3 this does not remove either the source or target files
1081         # though the "expected" operation would be to remove the source
1082         $CHECKSTAT -t file ${f} || error "${f} missing"
1083         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1084 }
1085 run_test 24m "Renaming a file to a hard link to itself ========="
1086
1087 test_24n() {
1088     f="$DIR/f24n"
1089     # this stats the old file after it was renamed, so it should fail
1090     touch ${f}
1091     $CHECKSTAT ${f} || error "${f} missing"
1092     mv ${f} ${f}.rename
1093     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1094     $CHECKSTAT -a ${f} || error "${f} exists"
1095 }
1096 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1097
1098 test_24o() {
1099         test_mkdir $DIR/$tdir
1100         rename_many -s random -v -n 10 $DIR/$tdir
1101 }
1102 run_test 24o "rename of files during htree split"
1103
1104 test_24p() {
1105         test_mkdir $DIR/R12a
1106         test_mkdir $DIR/R12b
1107         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1108         mrename $DIR/R12a $DIR/R12b
1109         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1110         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1111         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1112         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1113 }
1114 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1115
1116 cleanup_multiop_pause() {
1117         trap 0
1118         kill -USR1 $MULTIPID
1119 }
1120
1121 test_24q() {
1122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1123
1124         test_mkdir $DIR/R13a
1125         test_mkdir $DIR/R13b
1126         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1127         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1128         MULTIPID=$!
1129
1130         trap cleanup_multiop_pause EXIT
1131         mrename $DIR/R13a $DIR/R13b
1132         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1133         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1134         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1135         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1136         cleanup_multiop_pause
1137         wait $MULTIPID || error "multiop close failed"
1138 }
1139 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1140
1141 test_24r() { #bug 3789
1142         test_mkdir $DIR/R14a
1143         test_mkdir $DIR/R14a/b
1144         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1145         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1146         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1147 }
1148 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1149
1150 test_24s() {
1151         test_mkdir $DIR/R15a
1152         test_mkdir $DIR/R15a/b
1153         test_mkdir $DIR/R15a/b/c
1154         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1155         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1156         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1157 }
1158 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1159
1160 test_24t() {
1161         test_mkdir $DIR/R16a
1162         test_mkdir $DIR/R16a/b
1163         test_mkdir $DIR/R16a/b/c
1164         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1165         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1166         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1167 }
1168 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1169
1170 test_24u() { # bug12192
1171         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1172         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1173 }
1174 run_test 24u "create stripe file"
1175
1176 simple_cleanup_common() {
1177         local createmany=$1
1178         local rc=0
1179
1180         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1181
1182         local start=$SECONDS
1183
1184         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1185         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1186         rc=$?
1187         wait_delete_completed
1188         echo "cleanup time $((SECONDS - start))"
1189         return $rc
1190 }
1191
1192 max_pages_per_rpc() {
1193         local mdtname="$(printf "MDT%04x" ${1:-0})"
1194         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1195 }
1196
1197 test_24v() {
1198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1199
1200         local nrfiles=${COUNT:-100000}
1201         local fname="$DIR/$tdir/$tfile"
1202
1203         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1204         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1205
1206         test_mkdir "$(dirname $fname)"
1207         # assume MDT0000 has the fewest inodes
1208         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1209         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1210         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1211
1212         stack_trap "simple_cleanup_common $nrfiles"
1213
1214         createmany -m "$fname" $nrfiles
1215
1216         cancel_lru_locks mdc
1217         lctl set_param mdc.*.stats clear
1218
1219         # was previously test_24D: LU-6101
1220         # readdir() returns correct number of entries after cursor reload
1221         local num_ls=$(ls $DIR/$tdir | wc -l)
1222         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1223         local num_all=$(ls -a $DIR/$tdir | wc -l)
1224         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1225                 [ $num_all -ne $((nrfiles + 2)) ]; then
1226                         error "Expected $nrfiles files, got $num_ls " \
1227                                 "($num_uniq unique $num_all .&..)"
1228         fi
1229         # LU-5 large readdir
1230         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1231         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1232         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1233         # take into account of overhead in lu_dirpage header and end mark in
1234         # each page, plus one in rpc_num calculation.
1235         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1236         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1237         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1238         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1239         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1240         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1241         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1242         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1243                 error "large readdir doesn't take effect: " \
1244                       "$mds_readpage should be about $rpc_max"
1245 }
1246 run_test 24v "list large directory (test hash collision, b=17560)"
1247
1248 test_24w() { # bug21506
1249         SZ1=234852
1250         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1251         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1252         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1253         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1254         [[ "$SZ1" -eq "$SZ2" ]] ||
1255                 error "Error reading at the end of the file $tfile"
1256 }
1257 run_test 24w "Reading a file larger than 4Gb"
1258
1259 test_24x() {
1260         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1262         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1263                 skip "Need MDS version at least 2.7.56"
1264
1265         local MDTIDX=1
1266         local remote_dir=$DIR/$tdir/remote_dir
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $MDTIDX $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $DIR/$tdir/src_dir
1273         touch $DIR/$tdir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename dir cross MDT failed!"
1279
1280         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1281                 error "rename file cross MDT failed!"
1282
1283         touch $DIR/$tdir/ln_file
1284         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1285                 error "ln file cross MDT failed"
1286
1287         rm -rf $DIR/$tdir || error "Can not delete directories"
1288 }
1289 run_test 24x "cross MDT rename/link"
1290
1291 test_24y() {
1292         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1294
1295         local remote_dir=$DIR/$tdir/remote_dir
1296         local mdtidx=1
1297
1298         test_mkdir $DIR/$tdir
1299         $LFS mkdir -i $mdtidx $remote_dir ||
1300                 error "create remote directory failed"
1301
1302         test_mkdir $remote_dir/src_dir
1303         touch $remote_dir/src_file
1304         test_mkdir $remote_dir/tgt_dir
1305         touch $remote_dir/tgt_file
1306
1307         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1308                 error "rename subdir in the same remote dir failed!"
1309
1310         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1311                 error "rename files in the same remote dir failed!"
1312
1313         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1314                 error "link files in the same remote dir failed!"
1315
1316         rm -rf $DIR/$tdir || error "Can not delete directories"
1317 }
1318 run_test 24y "rename/link on the same dir should succeed"
1319
1320 test_24z() {
1321         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1322         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1323                 skip "Need MDS version at least 2.12.51"
1324
1325         local index
1326
1327         for index in 0 1; do
1328                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1329                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1330         done
1331
1332         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1333
1334         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1335         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1336
1337         local mdts=$(comma_list $(mdts_nodes))
1338
1339         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1340         stack_trap "do_nodes $mdts $LCTL \
1341                 set_param mdt.*.enable_remote_rename=1" EXIT
1342
1343         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1344
1345         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1346         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1347 }
1348 run_test 24z "cross-MDT rename is done as cp"
1349
1350 test_24A() { # LU-3182
1351         local NFILES=5000
1352
1353         test_mkdir $DIR/$tdir
1354         stack_trap "simple_cleanup_common $NFILES"
1355         createmany -m $DIR/$tdir/$tfile $NFILES
1356         local t=$(ls $DIR/$tdir | wc -l)
1357         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1358         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1359
1360         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1361                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1362 }
1363 run_test 24A "readdir() returns correct number of entries."
1364
1365 test_24B() { # LU-4805
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         local count
1369
1370         test_mkdir $DIR/$tdir
1371         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1372                 error "create striped dir failed"
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 2 ] || error "Expected 2, got $count"
1376
1377         touch $DIR/$tdir/striped_dir/a
1378
1379         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1380         [ $count -eq 3 ] || error "Expected 3, got $count"
1381
1382         touch $DIR/$tdir/striped_dir/.f
1383
1384         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1385         [ $count -eq 4 ] || error "Expected 4, got $count"
1386
1387         rm -rf $DIR/$tdir || error "Can not delete directories"
1388 }
1389 run_test 24B "readdir for striped dir return correct number of entries"
1390
1391 test_24C() {
1392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1393
1394         mkdir $DIR/$tdir
1395         mkdir $DIR/$tdir/d0
1396         mkdir $DIR/$tdir/d1
1397
1398         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1399                 error "create striped dir failed"
1400
1401         cd $DIR/$tdir/d0/striped_dir
1402
1403         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1404         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1405         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1406
1407         [ "$d0_ino" = "$parent_ino" ] ||
1408                 error ".. wrong, expect $d0_ino, get $parent_ino"
1409
1410         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1411                 error "mv striped dir failed"
1412
1413         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1414
1415         [ "$d1_ino" = "$parent_ino" ] ||
1416                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1417 }
1418 run_test 24C "check .. in striped dir"
1419
1420 test_24E() {
1421         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1423
1424         mkdir -p $DIR/$tdir
1425         mkdir $DIR/$tdir/src_dir
1426         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1427                 error "create remote source failed"
1428
1429         touch $DIR/$tdir/src_dir/src_child/a
1430
1431         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1432                 error "create remote target dir failed"
1433
1434         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1435                 error "create remote target child failed"
1436
1437         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1438                 error "rename dir cross MDT failed!"
1439
1440         find $DIR/$tdir
1441
1442         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1443                 error "src_child still exists after rename"
1444
1445         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1446                 error "missing file(a) after rename"
1447
1448         rm -rf $DIR/$tdir || error "Can not delete directories"
1449 }
1450 run_test 24E "cross MDT rename/link"
1451
1452 test_24F () {
1453         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1454
1455         local repeats=1000
1456         [ "$SLOW" = "no" ] && repeats=100
1457
1458         mkdir -p $DIR/$tdir
1459
1460         echo "$repeats repeats"
1461         for ((i = 0; i < repeats; i++)); do
1462                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1463                 touch $DIR/$tdir/test/a || error "touch fails"
1464                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1465                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1466         done
1467
1468         true
1469 }
1470 run_test 24F "hash order vs readdir (LU-11330)"
1471
1472 test_24G () {
1473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1474
1475         local ino1
1476         local ino2
1477
1478         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1479         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1480         touch $DIR/$tdir-0/f1 || error "touch f1"
1481         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1482         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1483         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1484         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1485         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1486 }
1487 run_test 24G "migrate symlink in rename"
1488
1489 test_24H() {
1490         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1491         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1492                 skip "MDT1 should be on another node"
1493
1494         test_mkdir -i 1 -c 1 $DIR/$tdir
1495 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1496         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1497         touch $DIR/$tdir/$tfile || error "touch failed"
1498 }
1499 run_test 24H "repeat FLD_QUERY rpc"
1500
1501 test_25a() {
1502         echo '== symlink sanity ============================================='
1503
1504         test_mkdir $DIR/d25
1505         ln -s d25 $DIR/s25
1506         touch $DIR/s25/foo ||
1507                 error "File creation in symlinked directory failed"
1508 }
1509 run_test 25a "create file in symlinked directory ==============="
1510
1511 test_25b() {
1512         [ ! -d $DIR/d25 ] && test_25a
1513         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1514 }
1515 run_test 25b "lookup file in symlinked directory ==============="
1516
1517 test_26a() {
1518         test_mkdir $DIR/d26
1519         test_mkdir $DIR/d26/d26-2
1520         ln -s d26/d26-2 $DIR/s26
1521         touch $DIR/s26/foo || error "File creation failed"
1522 }
1523 run_test 26a "multiple component symlink ======================="
1524
1525 test_26b() {
1526         test_mkdir -p $DIR/$tdir/d26-2
1527         ln -s $tdir/d26-2/foo $DIR/s26-2
1528         touch $DIR/s26-2 || error "File creation failed"
1529 }
1530 run_test 26b "multiple component symlink at end of lookup ======"
1531
1532 test_26c() {
1533         test_mkdir $DIR/d26.2
1534         touch $DIR/d26.2/foo
1535         ln -s d26.2 $DIR/s26.2-1
1536         ln -s s26.2-1 $DIR/s26.2-2
1537         ln -s s26.2-2 $DIR/s26.2-3
1538         chmod 0666 $DIR/s26.2-3/foo
1539 }
1540 run_test 26c "chain of symlinks"
1541
1542 # recursive symlinks (bug 439)
1543 test_26d() {
1544         ln -s d26-3/foo $DIR/d26-3
1545 }
1546 run_test 26d "create multiple component recursive symlink"
1547
1548 test_26e() {
1549         [ ! -h $DIR/d26-3 ] && test_26d
1550         rm $DIR/d26-3
1551 }
1552 run_test 26e "unlink multiple component recursive symlink"
1553
1554 # recursive symlinks (bug 7022)
1555 test_26f() {
1556         test_mkdir $DIR/$tdir
1557         test_mkdir $DIR/$tdir/$tfile
1558         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1559         test_mkdir -p lndir/bar1
1560         test_mkdir $DIR/$tdir/$tfile/$tfile
1561         cd $tfile                || error "cd $tfile failed"
1562         ln -s .. dotdot          || error "ln dotdot failed"
1563         ln -s dotdot/lndir lndir || error "ln lndir failed"
1564         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1565         output=`ls $tfile/$tfile/lndir/bar1`
1566         [ "$output" = bar1 ] && error "unexpected output"
1567         rm -r $tfile             || error "rm $tfile failed"
1568         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1569 }
1570 run_test 26f "rm -r of a directory which has recursive symlink"
1571
1572 test_27a() {
1573         test_mkdir $DIR/$tdir
1574         $LFS getstripe $DIR/$tdir
1575         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1576         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1577         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1578 }
1579 run_test 27a "one stripe file"
1580
1581 test_27b() {
1582         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1583
1584         test_mkdir $DIR/$tdir
1585         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1586         $LFS getstripe -c $DIR/$tdir/$tfile
1587         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1588                 error "two-stripe file doesn't have two stripes"
1589
1590         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1591 }
1592 run_test 27b "create and write to two stripe file"
1593
1594 # 27c family tests specific striping, setstripe -o
1595 test_27ca() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="1"
1599
1600         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1601         $LFS getstripe -i $DIR/$tdir/$tfile
1602         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1603                 error "stripe not on specified OST"
1604
1605         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1606 }
1607 run_test 27ca "one stripe on specified OST"
1608
1609 test_27cb() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1,0"
1613         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1614         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1615         echo "$getstripe"
1616
1617         # Strip getstripe output to a space separated list of OSTs
1618         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1619                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1620         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1621                 error "stripes not on specified OSTs"
1622
1623         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1624 }
1625 run_test 27cb "two stripes on specified OSTs"
1626
1627 test_27cc() {
1628         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1629         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1630                 skip "server does not support overstriping"
1631
1632         test_mkdir -p $DIR/$tdir
1633         local osts="0,0"
1634         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1635         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1636         echo "$getstripe"
1637
1638         # Strip getstripe output to a space separated list of OSTs
1639         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1640                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1641         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1642                 error "stripes not on specified OSTs"
1643
1644         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1645 }
1646 run_test 27cc "two stripes on the same OST"
1647
1648 test_27cd() {
1649         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1650         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1651                 skip "server does not support overstriping"
1652         test_mkdir -p $DIR/$tdir
1653         local osts="0,1,1,0"
1654         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1655         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1656         echo "$getstripe"
1657
1658         # Strip getstripe output to a space separated list of OSTs
1659         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1660                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1661         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1662                 error "stripes not on specified OSTs"
1663
1664         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1665 }
1666 run_test 27cd "four stripes on two OSTs"
1667
1668 test_27ce() {
1669         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1670                 skip_env "too many osts, skipping"
1671         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1672                 skip "server does not support overstriping"
1673         # We do one more stripe than we have OSTs
1674         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1675                 skip_env "ea_inode feature disabled"
1676
1677         test_mkdir -p $DIR/$tdir
1678         local osts=""
1679         for i in $(seq 0 $OSTCOUNT);
1680         do
1681                 osts=$osts"0"
1682                 if [ $i -ne $OSTCOUNT ]; then
1683                         osts=$osts","
1684                 fi
1685         done
1686         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1687         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1688         echo "$getstripe"
1689
1690         # Strip getstripe output to a space separated list of OSTs
1691         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1692                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1693         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1694                 error "stripes not on specified OSTs"
1695
1696         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1697 }
1698 run_test 27ce "more stripes than OSTs with -o"
1699
1700 test_27cf() {
1701         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1702         local pid=0
1703
1704         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1705         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1706         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1707         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1708                 error "failed to set $osp_proc=0"
1709
1710         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1711         pid=$!
1712         sleep 1
1713         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1714         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1715                 error "failed to set $osp_proc=1"
1716         wait $pid
1717         [[ $pid -ne 0 ]] ||
1718                 error "should return error due to $osp_proc=0"
1719 }
1720 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1721
1722 test_27cg() {
1723         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1724                 skip "server does not support overstriping"
1725         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1726         large_xattr_enabled || skip_env "ea_inode feature disabled"
1727
1728         local osts="0"
1729
1730         for ((i=1;i<1000;i++)); do
1731                 osts+=",$((i % OSTCOUNT))"
1732         done
1733
1734         local mdts=$(comma_list $(mdts_nodes))
1735         local before=$(do_nodes $mdts \
1736                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1737                 awk '/many credits/{print $3}' |
1738                 calc_sum)
1739
1740         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1741         $LFS getstripe $DIR/$tfile | grep stripe
1742
1743         rm -f $DIR/$tfile || error "can't unlink"
1744
1745         after=$(do_nodes $mdts \
1746                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1747                 awk '/many credits/{print $3}' |
1748                 calc_sum)
1749
1750         (( before == after )) ||
1751                 error "too many credits happened: $after > $before"
1752 }
1753 run_test 27cg "1000 shouldn't cause too many credits"
1754
1755 test_27d() {
1756         test_mkdir $DIR/$tdir
1757         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1758                 error "setstripe failed"
1759         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1760         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1761 }
1762 run_test 27d "create file with default settings"
1763
1764 test_27e() {
1765         # LU-5839 adds check for existed layout before setting it
1766         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1767                 skip "Need MDS version at least 2.7.56"
1768
1769         test_mkdir $DIR/$tdir
1770         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1771         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1772         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1773 }
1774 run_test 27e "setstripe existing file (should return error)"
1775
1776 test_27f() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1779                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1780         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1781                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1782         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1783         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1784 }
1785 run_test 27f "setstripe with bad stripe size (should return error)"
1786
1787 test_27g() {
1788         test_mkdir $DIR/$tdir
1789         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1790         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1791                 error "$DIR/$tdir/$tfile has object"
1792 }
1793 run_test 27g "$LFS getstripe with no objects"
1794
1795 test_27ga() {
1796         test_mkdir $DIR/$tdir
1797         touch $DIR/$tdir/$tfile || error "touch failed"
1798         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1799         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1800         local rc=$?
1801         (( rc == 2 )) || error "getstripe did not return ENOENT"
1802
1803         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1804                         2>&1 > /dev/null)
1805         [[ $err_msg =~ "typo" ]] ||
1806                 error "expected message with correct filename, got '$err_msg'"
1807 }
1808 run_test 27ga "$LFS getstripe with missing file (should return error)"
1809
1810 test_27i() {
1811         test_mkdir $DIR/$tdir
1812         touch $DIR/$tdir/$tfile || error "touch failed"
1813         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1814                 error "missing objects"
1815 }
1816 run_test 27i "$LFS getstripe with some objects"
1817
1818 test_27j() {
1819         test_mkdir $DIR/$tdir
1820         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1821                 error "setstripe failed" || true
1822 }
1823 run_test 27j "setstripe with bad stripe offset (should return error)"
1824
1825 test_27k() { # bug 2844
1826         test_mkdir $DIR/$tdir
1827         local file=$DIR/$tdir/$tfile
1828         local ll_max_blksize=$((4 * 1024 * 1024))
1829         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1830         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1831         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1832         dd if=/dev/zero of=$file bs=4k count=1
1833         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1834         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1835 }
1836 run_test 27k "limit i_blksize for broken user apps"
1837
1838 test_27l() {
1839         mcreate $DIR/$tfile || error "creating file"
1840         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1841                 error "setstripe should have failed" || true
1842 }
1843 run_test 27l "check setstripe permissions (should return error)"
1844
1845 test_27m() {
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847
1848         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1849                 skip_env "multiple clients -- skipping"
1850
1851         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1852                    head -n1)
1853         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1854                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1855         fi
1856         stack_trap simple_cleanup_common
1857         test_mkdir $DIR/$tdir
1858         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1859         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1860                 error "dd should fill OST0"
1861         i=2
1862         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1863                 i=$((i + 1))
1864                 [ $i -gt 256 ] && break
1865         done
1866         i=$((i + 1))
1867         touch $DIR/$tdir/$tfile.$i
1868         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1869             awk '{print $1}'| grep -w "0") ] &&
1870                 error "OST0 was full but new created file still use it"
1871         i=$((i + 1))
1872         touch $DIR/$tdir/$tfile.$i
1873         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1874             awk '{print $1}'| grep -w "0") ] &&
1875                 error "OST0 was full but new created file still use it" || true
1876 }
1877 run_test 27m "create file while OST0 was full"
1878
1879 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1880 # if the OST isn't full anymore.
1881 reset_enospc() {
1882         local ostidx=${1:-""}
1883         local delay
1884         local ready
1885         local get_prealloc
1886
1887         local list=$(comma_list $(osts_nodes))
1888         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1889
1890         do_nodes $list lctl set_param fail_loc=0
1891         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1892         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1893                 awk '{print $1 * 2;exit;}')
1894         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1895                         grep -v \"^0$\""
1896         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1897 }
1898
1899 test_27n() {
1900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1902         remote_mds_nodsh && skip "remote MDS with nodsh"
1903         remote_ost_nodsh && skip "remote OST with nodsh"
1904
1905         reset_enospc
1906         rm -f $DIR/$tdir/$tfile
1907         exhaust_precreations 0 0x80000215
1908         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1909         touch $DIR/$tdir/$tfile || error "touch failed"
1910         $LFS getstripe $DIR/$tdir/$tfile
1911         reset_enospc
1912 }
1913 run_test 27n "create file with some full OSTs"
1914
1915 test_27o() {
1916         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919         remote_ost_nodsh && skip "remote OST with nodsh"
1920
1921         reset_enospc
1922         rm -f $DIR/$tdir/$tfile
1923         exhaust_all_precreations 0x215
1924
1925         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1926
1927         reset_enospc
1928         rm -rf $DIR/$tdir/*
1929 }
1930 run_test 27o "create file with all full OSTs (should error)"
1931
1932 function create_and_checktime() {
1933         local fname=$1
1934         local loops=$2
1935         local i
1936
1937         for ((i=0; i < $loops; i++)); do
1938                 local start=$SECONDS
1939                 multiop $fname-$i Oc
1940                 ((SECONDS-start < TIMEOUT)) ||
1941                         error "creation took " $((SECONDS-$start)) && return 1
1942         done
1943 }
1944
1945 test_27oo() {
1946         local mdts=$(comma_list $(mdts_nodes))
1947
1948         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1949                 skip "Need MDS version at least 2.13.57"
1950
1951         local f0=$DIR/${tfile}-0
1952         local f1=$DIR/${tfile}-1
1953
1954         wait_delete_completed
1955
1956         # refill precreated objects
1957         $LFS setstripe -i0 -c1 $f0
1958
1959         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1960         # force QoS allocation policy
1961         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1962         stack_trap "do_nodes $mdts $LCTL set_param \
1963                 lov.*.qos_threshold_rr=$saved" EXIT
1964         sleep_maxage
1965
1966         # one OST is unavailable, but still have few objects preallocated
1967         stop ost1
1968         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1969                 rm -rf $f1 $DIR/$tdir*" EXIT
1970
1971         for ((i=0; i < 7; i++)); do
1972                 mkdir $DIR/$tdir$i || error "can't create dir"
1973                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1974                         error "can't set striping"
1975         done
1976         for ((i=0; i < 7; i++)); do
1977                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1978         done
1979         wait
1980 }
1981 run_test 27oo "don't let few threads to reserve too many objects"
1982
1983 test_27p() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1992
1993         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1994         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_precreations 0 0x80000215
1998         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1999         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2000         $LFS getstripe $DIR/$tdir/$tfile
2001
2002         reset_enospc
2003 }
2004 run_test 27p "append to a truncated file with some full OSTs"
2005
2006 test_27q() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014
2015         mkdir_on_mdt0 $DIR/$tdir
2016         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2017         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2018                 error "truncate $DIR/$tdir/$tfile failed"
2019         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2020
2021         exhaust_all_precreations 0x215
2022
2023         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2024         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2025
2026         reset_enospc
2027 }
2028 run_test 27q "append to truncated file with all OSTs full (should error)"
2029
2030 test_27r() {
2031         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2033         remote_mds_nodsh && skip "remote MDS with nodsh"
2034         remote_ost_nodsh && skip "remote OST with nodsh"
2035
2036         reset_enospc
2037         rm -f $DIR/$tdir/$tfile
2038         exhaust_precreations 0 0x80000215
2039
2040         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2041
2042         reset_enospc
2043 }
2044 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2045
2046 test_27s() { # bug 10725
2047         test_mkdir $DIR/$tdir
2048         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2049         local stripe_count=0
2050         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2051         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2052                 error "stripe width >= 2^32 succeeded" || true
2053
2054 }
2055 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2056
2057 test_27t() { # bug 10864
2058         WDIR=$(pwd)
2059         WLFS=$(which lfs)
2060         cd $DIR
2061         touch $tfile
2062         $WLFS getstripe $tfile
2063         cd $WDIR
2064 }
2065 run_test 27t "check that utils parse path correctly"
2066
2067 test_27u() { # bug 4900
2068         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070
2071         local index
2072         local list=$(comma_list $(mdts_nodes))
2073
2074 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2075         do_nodes $list $LCTL set_param fail_loc=0x139
2076         test_mkdir -p $DIR/$tdir
2077         stack_trap "simple_cleanup_common 1000"
2078         createmany -o $DIR/$tdir/$tfile 1000
2079         do_nodes $list $LCTL set_param fail_loc=0
2080
2081         TLOG=$TMP/$tfile.getstripe
2082         $LFS getstripe $DIR/$tdir > $TLOG
2083         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2084         [[ $OBJS -gt 0 ]] &&
2085                 error "$OBJS objects created on OST-0. See $TLOG" ||
2086                 rm -f $TLOG
2087 }
2088 run_test 27u "skip object creation on OSC w/o objects"
2089
2090 test_27v() { # bug 4900
2091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2093         remote_mds_nodsh && skip "remote MDS with nodsh"
2094         remote_ost_nodsh && skip "remote OST with nodsh"
2095
2096         exhaust_all_precreations 0x215
2097         reset_enospc
2098
2099         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2100
2101         touch $DIR/$tdir/$tfile
2102         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2103         # all except ost1
2104         for (( i=1; i < OSTCOUNT; i++ )); do
2105                 do_facet ost$i lctl set_param fail_loc=0x705
2106         done
2107         local START=`date +%s`
2108         createmany -o $DIR/$tdir/$tfile 32
2109
2110         local FINISH=`date +%s`
2111         local TIMEOUT=`lctl get_param -n timeout`
2112         local PROCESS=$((FINISH - START))
2113         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2114                error "$FINISH - $START >= $TIMEOUT / 2"
2115         sleep $((TIMEOUT / 2 - PROCESS))
2116         reset_enospc
2117 }
2118 run_test 27v "skip object creation on slow OST"
2119
2120 test_27w() { # bug 10997
2121         test_mkdir $DIR/$tdir
2122         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2123         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2124                 error "stripe size $size != 65536" || true
2125         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2126                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2127 }
2128 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2129
2130 test_27wa() {
2131         [[ $OSTCOUNT -lt 2 ]] &&
2132                 skip_env "skipping multiple stripe count/offset test"
2133
2134         test_mkdir $DIR/$tdir
2135         for i in $(seq 1 $OSTCOUNT); do
2136                 offset=$((i - 1))
2137                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2138                         error "setstripe -c $i -i $offset failed"
2139                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2140                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2141                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2142                 [ $index -ne $offset ] &&
2143                         error "stripe offset $index != $offset" || true
2144         done
2145 }
2146 run_test 27wa "check $LFS setstripe -c -i options"
2147
2148 test_27x() {
2149         remote_ost_nodsh && skip "remote OST with nodsh"
2150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         OFFSET=$(($OSTCOUNT - 1))
2154         OSTIDX=0
2155         local OST=$(ostname_from_index $OSTIDX)
2156
2157         test_mkdir $DIR/$tdir
2158         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2159         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2160         sleep_maxage
2161         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2162         for i in $(seq 0 $OFFSET); do
2163                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2164                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2165                 error "OST0 was degraded but new created file still use it"
2166         done
2167         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2168 }
2169 run_test 27x "create files while OST0 is degraded"
2170
2171 test_27y() {
2172         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2173         remote_mds_nodsh && skip "remote MDS with nodsh"
2174         remote_ost_nodsh && skip "remote OST with nodsh"
2175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2176
2177         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2178         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2179                 osp.$mdtosc.prealloc_last_id)
2180         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2181                 osp.$mdtosc.prealloc_next_id)
2182         local fcount=$((last_id - next_id))
2183         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2184         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2185
2186         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2187                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2188         local OST_DEACTIVE_IDX=-1
2189         local OSC
2190         local OSTIDX
2191         local OST
2192
2193         for OSC in $MDS_OSCS; do
2194                 OST=$(osc_to_ost $OSC)
2195                 OSTIDX=$(index_from_ostuuid $OST)
2196                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2197                         OST_DEACTIVE_IDX=$OSTIDX
2198                 fi
2199                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2200                         echo $OSC "is Deactivated:"
2201                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2202                 fi
2203         done
2204
2205         OSTIDX=$(index_from_ostuuid $OST)
2206         test_mkdir $DIR/$tdir
2207         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2208
2209         for OSC in $MDS_OSCS; do
2210                 OST=$(osc_to_ost $OSC)
2211                 OSTIDX=$(index_from_ostuuid $OST)
2212                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2213                         echo $OST "is degraded:"
2214                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2215                                                 obdfilter.$OST.degraded=1
2216                 fi
2217         done
2218
2219         sleep_maxage
2220         createmany -o $DIR/$tdir/$tfile $fcount
2221
2222         for OSC in $MDS_OSCS; do
2223                 OST=$(osc_to_ost $OSC)
2224                 OSTIDX=$(index_from_ostuuid $OST)
2225                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2226                         echo $OST "is recovered from degraded:"
2227                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2228                                                 obdfilter.$OST.degraded=0
2229                 else
2230                         do_facet $SINGLEMDS lctl --device %$OSC activate
2231                 fi
2232         done
2233
2234         # all osp devices get activated, hence -1 stripe count restored
2235         local stripe_count=0
2236
2237         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2238         # devices get activated.
2239         sleep_maxage
2240         $LFS setstripe -c -1 $DIR/$tfile
2241         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2242         rm -f $DIR/$tfile
2243         [ $stripe_count -ne $OSTCOUNT ] &&
2244                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2245         return 0
2246 }
2247 run_test 27y "create files while OST0 is degraded and the rest inactive"
2248
2249 check_seq_oid()
2250 {
2251         log "check file $1"
2252
2253         lmm_count=$($LFS getstripe -c $1)
2254         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2255         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2256
2257         local old_ifs="$IFS"
2258         IFS=$'[:]'
2259         fid=($($LFS path2fid $1))
2260         IFS="$old_ifs"
2261
2262         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2263         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2264
2265         # compare lmm_seq and lu_fid->f_seq
2266         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2267         # compare lmm_object_id and lu_fid->oid
2268         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2269
2270         # check the trusted.fid attribute of the OST objects of the file
2271         local have_obdidx=false
2272         local stripe_nr=0
2273         $LFS getstripe $1 | while read obdidx oid hex seq; do
2274                 # skip lines up to and including "obdidx"
2275                 [ -z "$obdidx" ] && break
2276                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2277                 $have_obdidx || continue
2278
2279                 local ost=$((obdidx + 1))
2280                 local dev=$(ostdevname $ost)
2281                 local oid_hex
2282
2283                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2284
2285                 seq=$(echo $seq | sed -e "s/^0x//g")
2286                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2287                         oid_hex=$(echo $oid)
2288                 else
2289                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2290                 fi
2291                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2292
2293                 local ff=""
2294                 #
2295                 # Don't unmount/remount the OSTs if we don't need to do that.
2296                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2297                 # update too, until that use mount/ll_decode_filter_fid/mount.
2298                 # Re-enable when debugfs will understand new filter_fid.
2299                 #
2300                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2301                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2302                                 $dev 2>/dev/null" | grep "parent=")
2303                 fi
2304                 if [ -z "$ff" ]; then
2305                         stop ost$ost
2306                         mount_fstype ost$ost
2307                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2308                                 $(facet_mntpt ost$ost)/$obj_file)
2309                         unmount_fstype ost$ost
2310                         start ost$ost $dev $OST_MOUNT_OPTS
2311                         clients_up
2312                 fi
2313
2314                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2315
2316                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2317
2318                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2319                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2320                 #
2321                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2322                 #       stripe_size=1048576 component_id=1 component_start=0 \
2323                 #       component_end=33554432
2324                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2325                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2326                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2327                 local ff_pstripe
2328                 if grep -q 'stripe=' <<<$ff; then
2329                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2330                 else
2331                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2332                         # into f_ver in this case.  See comment on ff_parent.
2333                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2334                 fi
2335
2336                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2337                 [ $ff_pseq = $lmm_seq ] ||
2338                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2339                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2340                 [ $ff_poid = $lmm_oid ] ||
2341                         error "FF parent OID $ff_poid != $lmm_oid"
2342                 (($ff_pstripe == $stripe_nr)) ||
2343                         error "FF stripe $ff_pstripe != $stripe_nr"
2344
2345                 stripe_nr=$((stripe_nr + 1))
2346                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2347                         continue
2348                 if grep -q 'stripe_count=' <<<$ff; then
2349                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2350                                             -e 's/ .*//' <<<$ff)
2351                         [ $lmm_count = $ff_scnt ] ||
2352                                 error "FF stripe count $lmm_count != $ff_scnt"
2353                 fi
2354         done
2355 }
2356
2357 test_27z() {
2358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2359         remote_ost_nodsh && skip "remote OST with nodsh"
2360
2361         test_mkdir $DIR/$tdir
2362         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2363                 { error "setstripe -c -1 failed"; return 1; }
2364         # We need to send a write to every object to get parent FID info set.
2365         # This _should_ also work for setattr, but does not currently.
2366         # touch $DIR/$tdir/$tfile-1 ||
2367         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2368                 { error "dd $tfile-1 failed"; return 2; }
2369         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2370                 { error "setstripe -c -1 failed"; return 3; }
2371         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2372                 { error "dd $tfile-2 failed"; return 4; }
2373
2374         # make sure write RPCs have been sent to OSTs
2375         sync; sleep 5; sync
2376
2377         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2378         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2379 }
2380 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2381
2382 test_27A() { # b=19102
2383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2384
2385         save_layout_restore_at_exit $MOUNT
2386         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2387         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2388                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2389         local default_size=$($LFS getstripe -S $MOUNT)
2390         local default_offset=$($LFS getstripe -i $MOUNT)
2391         local dsize=$(do_facet $SINGLEMDS \
2392                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2393         [ $default_size -eq $dsize ] ||
2394                 error "stripe size $default_size != $dsize"
2395         [ $default_offset -eq -1 ] ||
2396                 error "stripe offset $default_offset != -1"
2397 }
2398 run_test 27A "check filesystem-wide default LOV EA values"
2399
2400 test_27B() { # LU-2523
2401         test_mkdir $DIR/$tdir
2402         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2403         touch $DIR/$tdir/f0
2404         # open f1 with O_LOV_DELAY_CREATE
2405         # rename f0 onto f1
2406         # call setstripe ioctl on open file descriptor for f1
2407         # close
2408         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2409                 $DIR/$tdir/f0
2410
2411         rm -f $DIR/$tdir/f1
2412         # open f1 with O_LOV_DELAY_CREATE
2413         # unlink f1
2414         # call setstripe ioctl on open file descriptor for f1
2415         # close
2416         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2417
2418         # Allow multiop to fail in imitation of NFS's busted semantics.
2419         true
2420 }
2421 run_test 27B "call setstripe on open unlinked file/rename victim"
2422
2423 # 27C family tests full striping and overstriping
2424 test_27Ca() { #LU-2871
2425         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2426
2427         declare -a ost_idx
2428         local index
2429         local found
2430         local i
2431         local j
2432
2433         test_mkdir $DIR/$tdir
2434         cd $DIR/$tdir
2435         for i in $(seq 0 $((OSTCOUNT - 1))); do
2436                 # set stripe across all OSTs starting from OST$i
2437                 $LFS setstripe -i $i -c -1 $tfile$i
2438                 # get striping information
2439                 ost_idx=($($LFS getstripe $tfile$i |
2440                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2441                 echo "OST Index: ${ost_idx[*]}"
2442
2443                 # check the layout
2444                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2445                         error "${#ost_idx[@]} != $OSTCOUNT"
2446
2447                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2448                         found=0
2449                         for j in "${ost_idx[@]}"; do
2450                                 if [ $index -eq $j ]; then
2451                                         found=1
2452                                         break
2453                                 fi
2454                         done
2455                         [ $found = 1 ] ||
2456                                 error "Can not find $index in ${ost_idx[*]}"
2457                 done
2458         done
2459 }
2460 run_test 27Ca "check full striping across all OSTs"
2461
2462 test_27Cb() {
2463         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2464                 skip "server does not support overstriping"
2465         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2466                 skip_env "too many osts, skipping"
2467
2468         test_mkdir -p $DIR/$tdir
2469         local setcount=$(($OSTCOUNT * 2))
2470         [ $setcount -lt 160 ] || large_xattr_enabled ||
2471                 skip_env "ea_inode feature disabled"
2472
2473         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2474                 error "setstripe failed"
2475
2476         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2477         [ $count -eq $setcount ] ||
2478                 error "stripe count $count, should be $setcount"
2479
2480         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2481                 error "overstriped should be set in pattern"
2482
2483         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2484                 error "dd failed"
2485 }
2486 run_test 27Cb "more stripes than OSTs with -C"
2487
2488 test_27Cc() {
2489         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2490                 skip "server does not support overstriping"
2491         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2492
2493         test_mkdir -p $DIR/$tdir
2494         local setcount=$(($OSTCOUNT - 1))
2495
2496         [ $setcount -lt 160 ] || large_xattr_enabled ||
2497                 skip_env "ea_inode feature disabled"
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2507                 error "overstriped should not be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511 }
2512 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2513
2514 test_27Cd() {
2515         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2516                 skip "server does not support overstriping"
2517         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2518         large_xattr_enabled || skip_env "ea_inode feature disabled"
2519
2520         force_new_seq_all
2521
2522         test_mkdir -p $DIR/$tdir
2523         local setcount=$LOV_MAX_STRIPE_COUNT
2524
2525         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2526                 error "setstripe failed"
2527
2528         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2529         [ $count -eq $setcount ] ||
2530                 error "stripe count $count, should be $setcount"
2531
2532         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2533                 error "overstriped should be set in pattern"
2534
2535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2536                 error "dd failed"
2537
2538         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2539 }
2540 run_test 27Cd "test maximum stripe count"
2541
2542 test_27Ce() {
2543         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2544                 skip "server does not support overstriping"
2545         test_mkdir -p $DIR/$tdir
2546
2547         pool_add $TESTNAME || error "Pool creation failed"
2548         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2549
2550         local setcount=8
2551
2552         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2553                 error "setstripe failed"
2554
2555         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2556         [ $count -eq $setcount ] ||
2557                 error "stripe count $count, should be $setcount"
2558
2559         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2560                 error "overstriped should be set in pattern"
2561
2562         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2563                 error "dd failed"
2564
2565         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2566 }
2567 run_test 27Ce "test pool with overstriping"
2568
2569 test_27Cf() {
2570         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2571                 skip "server does not support overstriping"
2572         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2573                 skip_env "too many osts, skipping"
2574
2575         test_mkdir -p $DIR/$tdir
2576
2577         local setcount=$(($OSTCOUNT * 2))
2578         [ $setcount -lt 160 ] || large_xattr_enabled ||
2579                 skip_env "ea_inode feature disabled"
2580
2581         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2582                 error "setstripe failed"
2583
2584         echo 1 > $DIR/$tdir/$tfile
2585
2586         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2587         [ $count -eq $setcount ] ||
2588                 error "stripe count $count, should be $setcount"
2589
2590         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2591                 error "overstriped should be set in pattern"
2592
2593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2594                 error "dd failed"
2595
2596         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2597 }
2598 run_test 27Cf "test default inheritance with overstriping"
2599
2600 test_27Cg() {
2601         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2602                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2603
2604         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2605         (( $? != 0 )) || error "must be an error for not existent OST#"
2606 }
2607 run_test 27Cg "test setstripe with wrong OST idx"
2608
2609 test_27D() {
2610         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2611         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2612         remote_mds_nodsh && skip "remote MDS with nodsh"
2613
2614         local POOL=${POOL:-testpool}
2615         local first_ost=0
2616         local last_ost=$(($OSTCOUNT - 1))
2617         local ost_step=1
2618         local ost_list=$(seq $first_ost $ost_step $last_ost)
2619         local ost_range="$first_ost $last_ost $ost_step"
2620
2621         test_mkdir $DIR/$tdir
2622         pool_add $POOL || error "pool_add failed"
2623         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2624
2625         local skip27D
2626         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2627                 skip27D+="-s 29"
2628         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2629                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2630                         skip27D+=" -s 30,31"
2631         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2632           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2633                 skip27D+=" -s 32,33"
2634         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2635                 skip27D+=" -s 34"
2636         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2637                 error "llapi_layout_test failed"
2638
2639         destroy_test_pools || error "destroy test pools failed"
2640 }
2641 run_test 27D "validate llapi_layout API"
2642
2643 # Verify that default_easize is increased from its initial value after
2644 # accessing a widely striped file.
2645 test_27E() {
2646         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2647         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2648                 skip "client does not have LU-3338 fix"
2649
2650         # 72 bytes is the minimum space required to store striping
2651         # information for a file striped across one OST:
2652         # (sizeof(struct lov_user_md_v3) +
2653         #  sizeof(struct lov_user_ost_data_v1))
2654         local min_easize=72
2655         $LCTL set_param -n llite.*.default_easize $min_easize ||
2656                 error "lctl set_param failed"
2657         local easize=$($LCTL get_param -n llite.*.default_easize)
2658
2659         [ $easize -eq $min_easize ] ||
2660                 error "failed to set default_easize"
2661
2662         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2663                 error "setstripe failed"
2664         # In order to ensure stat() call actually talks to MDS we need to
2665         # do something drastic to this file to shake off all lock, e.g.
2666         # rename it (kills lookup lock forcing cache cleaning)
2667         mv $DIR/$tfile $DIR/${tfile}-1
2668         ls -l $DIR/${tfile}-1
2669         rm $DIR/${tfile}-1
2670
2671         easize=$($LCTL get_param -n llite.*.default_easize)
2672
2673         [ $easize -gt $min_easize ] ||
2674                 error "default_easize not updated"
2675 }
2676 run_test 27E "check that default extended attribute size properly increases"
2677
2678 test_27F() { # LU-5346/LU-7975
2679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2680         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2681         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2682                 skip "Need MDS version at least 2.8.51"
2683         remote_ost_nodsh && skip "remote OST with nodsh"
2684
2685         test_mkdir $DIR/$tdir
2686         rm -f $DIR/$tdir/f0
2687         $LFS setstripe -c 2 $DIR/$tdir
2688
2689         # stop all OSTs to reproduce situation for LU-7975 ticket
2690         for num in $(seq $OSTCOUNT); do
2691                 stop ost$num
2692         done
2693
2694         # open/create f0 with O_LOV_DELAY_CREATE
2695         # truncate f0 to a non-0 size
2696         # close
2697         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2698
2699         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2700         # open/write it again to force delayed layout creation
2701         cat /etc/hosts > $DIR/$tdir/f0 &
2702         catpid=$!
2703
2704         # restart OSTs
2705         for num in $(seq $OSTCOUNT); do
2706                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2707                         error "ost$num failed to start"
2708         done
2709
2710         wait $catpid || error "cat failed"
2711
2712         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2713         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2714                 error "wrong stripecount"
2715
2716 }
2717 run_test 27F "Client resend delayed layout creation with non-zero size"
2718
2719 test_27G() { #LU-10629
2720         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2721                 skip "Need MDS version at least 2.11.51"
2722         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2723         remote_mds_nodsh && skip "remote MDS with nodsh"
2724         local POOL=${POOL:-testpool}
2725         local ostrange="0 0 1"
2726
2727         test_mkdir $DIR/$tdir
2728         touch $DIR/$tdir/$tfile.nopool
2729         pool_add $POOL || error "pool_add failed"
2730         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2731         $LFS setstripe -p $POOL $DIR/$tdir
2732
2733         local pool=$($LFS getstripe -p $DIR/$tdir)
2734
2735         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2736         touch $DIR/$tdir/$tfile.default
2737         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2738         $LFS find $DIR/$tdir -type f --pool $POOL
2739         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2740         [[ "$found" == "2" ]] ||
2741                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2742
2743         $LFS setstripe -d $DIR/$tdir
2744
2745         pool=$($LFS getstripe -p -d $DIR/$tdir)
2746
2747         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2748 }
2749 run_test 27G "Clear OST pool from stripe"
2750
2751 test_27H() {
2752         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2753                 skip "Need MDS version newer than 2.11.54"
2754         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2755         test_mkdir $DIR/$tdir
2756         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2757         touch $DIR/$tdir/$tfile
2758         $LFS getstripe -c $DIR/$tdir/$tfile
2759         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2760                 error "two-stripe file doesn't have two stripes"
2761
2762         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2763         $LFS getstripe -y $DIR/$tdir/$tfile
2764         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2765              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2766                 error "expected l_ost_idx: [02]$ not matched"
2767
2768         # make sure ost list has been cleared
2769         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2770         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2771                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2772         touch $DIR/$tdir/f3
2773         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2774 }
2775 run_test 27H "Set specific OSTs stripe"
2776
2777 test_27I() {
2778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2779         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2780         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2781                 skip "Need MDS version newer than 2.12.52"
2782         local pool=$TESTNAME
2783         local ostrange="1 1 1"
2784
2785         save_layout_restore_at_exit $MOUNT
2786         $LFS setstripe -c 2 -i 0 $MOUNT
2787         pool_add $pool || error "pool_add failed"
2788         pool_add_targets $pool $ostrange ||
2789                 error "pool_add_targets failed"
2790         test_mkdir $DIR/$tdir
2791         $LFS setstripe -p $pool $DIR/$tdir
2792         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2793         $LFS getstripe $DIR/$tdir/$tfile
2794 }
2795 run_test 27I "check that root dir striping does not break parent dir one"
2796
2797 test_27J() {
2798         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2799                 skip "Need MDS version newer than 2.12.51"
2800
2801         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2802         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2803         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2804            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2805                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2806
2807         test_mkdir $DIR/$tdir
2808         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2809         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2810
2811         # create foreign file (raw way)
2812         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2813                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2814
2815         ! $LFS setstripe --foreign --flags foo \
2816                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2817                         error "creating $tfile with '--flags foo' should fail"
2818
2819         ! $LFS setstripe --foreign --flags 0xffffffff \
2820                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2821                         error "creating $tfile w/ 0xffffffff flags should fail"
2822
2823         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2824                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2825
2826         # verify foreign file (raw way)
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2830         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2831                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2832         parse_foreign_file -f $DIR/$tdir/$tfile |
2833                 grep "lov_foreign_size: 73" ||
2834                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2835         parse_foreign_file -f $DIR/$tdir/$tfile |
2836                 grep "lov_foreign_type: 1" ||
2837                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2838         parse_foreign_file -f $DIR/$tdir/$tfile |
2839                 grep "lov_foreign_flags: 0x0000DA08" ||
2840                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2841         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2842                 grep "lov_foreign_value: 0x" |
2843                 sed -e 's/lov_foreign_value: 0x//')
2844         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2845         [[ $lov = ${lov2// /} ]] ||
2846                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2847
2848         # create foreign file (lfs + API)
2849         $LFS setstripe --foreign=none --flags 0xda08 \
2850                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2851                 error "$DIR/$tdir/${tfile}2: create failed"
2852
2853         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2854                 grep "lfm_magic:.*0x0BD70BD0" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2856         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2857         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2858                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2859         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2860                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2861         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2862                 grep "lfm_flags:.*0x0000DA08" ||
2863                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2864         $LFS getstripe $DIR/$tdir/${tfile}2 |
2865                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2866                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2867
2868         # modify striping should fail
2869         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2870                 error "$DIR/$tdir/$tfile: setstripe should fail"
2871         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2873
2874         # R/W should fail
2875         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2876         cat $DIR/$tdir/${tfile}2 &&
2877                 error "$DIR/$tdir/${tfile}2: read should fail"
2878         cat /etc/passwd > $DIR/$tdir/$tfile &&
2879                 error "$DIR/$tdir/$tfile: write should fail"
2880         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2881                 error "$DIR/$tdir/${tfile}2: write should fail"
2882
2883         # chmod should work
2884         chmod 222 $DIR/$tdir/$tfile ||
2885                 error "$DIR/$tdir/$tfile: chmod failed"
2886         chmod 222 $DIR/$tdir/${tfile}2 ||
2887                 error "$DIR/$tdir/${tfile}2: chmod failed"
2888
2889         # chown should work
2890         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2891                 error "$DIR/$tdir/$tfile: chown failed"
2892         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2893                 error "$DIR/$tdir/${tfile}2: chown failed"
2894
2895         # rename should work
2896         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2897                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2898         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2899                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2900
2901         #remove foreign file
2902         rm $DIR/$tdir/${tfile}.new ||
2903                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2904         rm $DIR/$tdir/${tfile}2.new ||
2905                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2906 }
2907 run_test 27J "basic ops on file with foreign LOV"
2908
2909 test_27K() {
2910         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2911                 skip "Need MDS version newer than 2.12.49"
2912
2913         test_mkdir $DIR/$tdir
2914         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2915         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2916
2917         # create foreign dir (raw way)
2918         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2919                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2920
2921         ! $LFS setdirstripe --foreign --flags foo \
2922                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2923                         error "creating $tdir with '--flags foo' should fail"
2924
2925         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2926                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2927                         error "creating $tdir w/ 0xffffffff flags should fail"
2928
2929         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2930                 error "create_foreign_dir FAILED"
2931
2932         # verify foreign dir (raw way)
2933         parse_foreign_dir -d $DIR/$tdir/$tdir |
2934                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2935                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2936         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2937                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2938         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2939                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2940         parse_foreign_dir -d $DIR/$tdir/$tdir |
2941                 grep "lmv_foreign_flags: 55813$" ||
2942                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2943         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2944                 grep "lmv_foreign_value: 0x" |
2945                 sed 's/lmv_foreign_value: 0x//')
2946         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2947                 sed 's/ //g')
2948         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2949
2950         # create foreign dir (lfs + API)
2951         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2952                 $DIR/$tdir/${tdir}2 ||
2953                 error "$DIR/$tdir/${tdir}2: create failed"
2954
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2956
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2958                 grep "lfm_magic:.*0x0CD50CD0" ||
2959                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2960         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2961         # - sizeof(lfm_type) - sizeof(lfm_flags)
2962         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2963                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2964         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2965                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2966         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2967                 grep "lfm_flags:.*0x0000DA05" ||
2968                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2969         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2970                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2971                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2972
2973         # file create in dir should fail
2974         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2975         touch $DIR/$tdir/${tdir}2/$tfile &&
2976                 error "$DIR/${tdir}2: file create should fail"
2977
2978         # chmod should work
2979         chmod 777 $DIR/$tdir/$tdir ||
2980                 error "$DIR/$tdir: chmod failed"
2981         chmod 777 $DIR/$tdir/${tdir}2 ||
2982                 error "$DIR/${tdir}2: chmod failed"
2983
2984         # chown should work
2985         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2986                 error "$DIR/$tdir: chown failed"
2987         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2988                 error "$DIR/${tdir}2: chown failed"
2989
2990         # rename should work
2991         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2992                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2993         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2994                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2995
2996         #remove foreign dir
2997         rmdir $DIR/$tdir/${tdir}.new ||
2998                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2999         rmdir $DIR/$tdir/${tdir}2.new ||
3000                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3001 }
3002 run_test 27K "basic ops on dir with foreign LMV"
3003
3004 test_27L() {
3005         remote_mds_nodsh && skip "remote MDS with nodsh"
3006
3007         local POOL=${POOL:-$TESTNAME}
3008
3009         pool_add $POOL || error "pool_add failed"
3010
3011         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3012                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3013                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3014 }
3015 run_test 27L "lfs pool_list gives correct pool name"
3016
3017 test_27M() {
3018         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3019                 skip "Need MDS version >= than 2.12.57"
3020         remote_mds_nodsh && skip "remote MDS with nodsh"
3021         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3022
3023         # Set default striping on directory
3024         local setcount=4
3025         local stripe_opt
3026         local mdts=$(comma_list $(mdts_nodes))
3027
3028         # if we run against a 2.12 server which lacks overstring support
3029         # then the connect_flag will not report overstriping, even if client
3030         # is 2.14+
3031         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3032                 stripe_opt="-C $setcount"
3033         elif (( $OSTCOUNT >= $setcount )); then
3034                 stripe_opt="-c $setcount"
3035         else
3036                 skip "server does not support overstriping"
3037         fi
3038
3039         test_mkdir $DIR/$tdir
3040
3041         # Validate existing append_* params and ensure restore
3042         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3043         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3044         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3045
3046         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3047         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3048         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3049
3050         $LFS setstripe $stripe_opt $DIR/$tdir
3051
3052         echo 1 > $DIR/$tdir/${tfile}.1
3053         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3054         (( $count == $setcount )) ||
3055                 error "(1) stripe count $count, should be $setcount"
3056
3057         local appendcount=$orig_count
3058         echo 1 >> $DIR/$tdir/${tfile}.2_append
3059         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3060         (( $count == $appendcount )) ||
3061                 error "(2)stripe count $count, should be $appendcount for append"
3062
3063         # Disable O_APPEND striping, verify it works
3064         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3065
3066         # Should now get the default striping, which is 4
3067         setcount=4
3068         echo 1 >> $DIR/$tdir/${tfile}.3_append
3069         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3070         (( $count == $setcount )) ||
3071                 error "(3) stripe count $count, should be $setcount"
3072
3073         # Try changing the stripe count for append files
3074         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3075
3076         # Append striping is now 2 (directory default is still 4)
3077         appendcount=2
3078         echo 1 >> $DIR/$tdir/${tfile}.4_append
3079         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3080         (( $count == $appendcount )) ||
3081                 error "(4) stripe count $count, should be $appendcount for append"
3082
3083         # Test append stripe count of -1
3084         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3085         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3086                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3087                 touch $DIR/$tdir/$tfile.specific.{1..128}
3088         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3089
3090         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3091         appendcount=$OSTCOUNT
3092         echo 1 >> $DIR/$tdir/${tfile}.5
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3094         (( $count == $appendcount )) ||
3095                 error "(5) stripe count $count, should be $appendcount for append"
3096
3097         # Set append striping back to default of 1
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3099
3100         # Try a new default striping, PFL + DOM
3101         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3102
3103         # Create normal DOM file, DOM returns stripe count == 0
3104         setcount=0
3105         touch $DIR/$tdir/${tfile}.6
3106         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3107         (( $count == $setcount )) ||
3108                 error "(6) stripe count $count, should be $setcount"
3109
3110         # Show
3111         appendcount=1
3112         echo 1 >> $DIR/$tdir/${tfile}.7_append
3113         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3114         (( $count == $appendcount )) ||
3115                 error "(7) stripe count $count, should be $appendcount for append"
3116
3117         # Clean up DOM layout
3118         $LFS setstripe -d $DIR/$tdir
3119
3120         save_layout_restore_at_exit $MOUNT
3121         # Now test that append striping works when layout is from root
3122         $LFS setstripe -c 2 $MOUNT
3123         # Make a special directory for this
3124         mkdir $DIR/${tdir}/${tdir}.2
3125
3126         # Verify for normal file
3127         setcount=2
3128         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3129         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3130         (( $count == $setcount )) ||
3131                 error "(8) stripe count $count, should be $setcount"
3132
3133         appendcount=1
3134         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3135         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3136         (( $count == $appendcount )) ||
3137                 error "(9) stripe count $count, should be $appendcount for append"
3138
3139         # Now test O_APPEND striping with pools
3140         pool_add $TESTNAME || error "pool creation failed"
3141         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3142         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3143
3144         echo 1 >> $DIR/$tdir/${tfile}.10_append
3145
3146         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3147         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3148
3149         # Check that count is still correct
3150         appendcount=1
3151         echo 1 >> $DIR/$tdir/${tfile}.11_append
3152         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3153         (( $count == $appendcount )) ||
3154                 error "(11) stripe count $count, should be $appendcount for append"
3155
3156         # Disable O_APPEND stripe count, verify pool works separately
3157         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3158
3159         echo 1 >> $DIR/$tdir/${tfile}.12_append
3160
3161         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3162         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3163
3164         # Remove pool setting, verify it's not applied
3165         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3166
3167         echo 1 >> $DIR/$tdir/${tfile}.13_append
3168
3169         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3170         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3171 }
3172 run_test 27M "test O_APPEND striping"
3173
3174 test_27N() {
3175         combined_mgs_mds && skip "needs separate MGS/MDT"
3176
3177         pool_add $TESTNAME || error "pool_add failed"
3178         do_facet mgs "$LCTL pool_list $FSNAME" |
3179                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3180                 error "lctl pool_list on MGS failed"
3181 }
3182 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3183
3184 clean_foreign_symlink() {
3185         trap 0
3186         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3187         for i in $DIR/$tdir/* ; do
3188                 $LFS unlink_foreign $i || true
3189         done
3190 }
3191
3192 test_27O() {
3193         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3194                 skip "Need MDS version newer than 2.12.51"
3195
3196         test_mkdir $DIR/$tdir
3197         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3198         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3199
3200         trap clean_foreign_symlink EXIT
3201
3202         # enable foreign_symlink behaviour
3203         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3204
3205         # foreign symlink LOV format is a partial path by default
3206
3207         # create foreign file (lfs + API)
3208         $LFS setstripe --foreign=symlink --flags 0xda05 \
3209                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3210                 error "$DIR/$tdir/${tfile}: create failed"
3211
3212         $LFS getstripe -v $DIR/$tdir/${tfile} |
3213                 grep "lfm_magic:.*0x0BD70BD0" ||
3214                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3215         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3216                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3217         $LFS getstripe -v $DIR/$tdir/${tfile} |
3218                 grep "lfm_flags:.*0x0000DA05" ||
3219                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3220         $LFS getstripe $DIR/$tdir/${tfile} |
3221                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3222                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3223
3224         # modify striping should fail
3225         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3226                 error "$DIR/$tdir/$tfile: setstripe should fail"
3227
3228         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3229         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3230         cat /etc/passwd > $DIR/$tdir/$tfile &&
3231                 error "$DIR/$tdir/$tfile: write should fail"
3232
3233         # rename should succeed
3234         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3235                 error "$DIR/$tdir/$tfile: rename has failed"
3236
3237         #remove foreign_symlink file should fail
3238         rm $DIR/$tdir/${tfile}.new &&
3239                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3240
3241         #test fake symlink
3242         mkdir /tmp/${uuid1} ||
3243                 error "/tmp/${uuid1}: mkdir has failed"
3244         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3245                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3246         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3247         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3248                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3249         #read should succeed now
3250         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3251                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3252         #write should succeed now
3253         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3254                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3255         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3256                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3257         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3258                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3259
3260         #check that getstripe still works
3261         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3262                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3263
3264         # chmod should still succeed
3265         chmod 644 $DIR/$tdir/${tfile}.new ||
3266                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3267
3268         # chown should still succeed
3269         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3270                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3271
3272         # rename should still succeed
3273         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3274                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3275
3276         #remove foreign_symlink file should still fail
3277         rm $DIR/$tdir/${tfile} &&
3278                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3279
3280         #use special ioctl() to unlink foreign_symlink file
3281         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3282                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3283
3284 }
3285 run_test 27O "basic ops on foreign file of symlink type"
3286
3287 test_27P() {
3288         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3289                 skip "Need MDS version newer than 2.12.49"
3290
3291         test_mkdir $DIR/$tdir
3292         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3293         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3294
3295         trap clean_foreign_symlink EXIT
3296
3297         # enable foreign_symlink behaviour
3298         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3299
3300         # foreign symlink LMV format is a partial path by default
3301
3302         # create foreign dir (lfs + API)
3303         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3304                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3305                 error "$DIR/$tdir/${tdir}: create failed"
3306
3307         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3308
3309         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3310                 grep "lfm_magic:.*0x0CD50CD0" ||
3311                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3312         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3313                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3314         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3315                 grep "lfm_flags:.*0x0000DA05" ||
3316                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3317         $LFS getdirstripe $DIR/$tdir/${tdir} |
3318                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3319                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3320
3321         # file create in dir should fail
3322         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3323         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3324
3325         # rename should succeed
3326         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3327                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3328
3329         #remove foreign_symlink dir should fail
3330         rmdir $DIR/$tdir/${tdir}.new &&
3331                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3332
3333         #test fake symlink
3334         mkdir -p /tmp/${uuid1}/${uuid2} ||
3335                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3336         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3337                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3338         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3339         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3340                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3341         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3342                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3343
3344         #check that getstripe fails now that foreign_symlink enabled
3345         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3346                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3347
3348         # file create in dir should work now
3349         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3350                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3351         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3352                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3353         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3354                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3355
3356         # chmod should still succeed
3357         chmod 755 $DIR/$tdir/${tdir}.new ||
3358                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3359
3360         # chown should still succeed
3361         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3362                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3363
3364         # rename should still succeed
3365         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3366                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3367
3368         #remove foreign_symlink dir should still fail
3369         rmdir $DIR/$tdir/${tdir} &&
3370                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3371
3372         #use special ioctl() to unlink foreign_symlink file
3373         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3374                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3375
3376         #created file should still exist
3377         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3378                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3379         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3380                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3381 }
3382 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3383
3384 test_27Q() {
3385         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3386         stack_trap "rm -f $TMP/$tfile*"
3387
3388         test_mkdir $DIR/$tdir-1
3389         test_mkdir $DIR/$tdir-2
3390
3391         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3392         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3393
3394         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3395         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3396
3397         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3398         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3399
3400         # Create some bad symlinks and ensure that we don't loop
3401         # forever or something. These should return ELOOP (40) and
3402         # ENOENT (2) but I don't want to test for that because there's
3403         # always some weirdo architecture that needs to ruin
3404         # everything by defining these error numbers differently.
3405
3406         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3407         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3408
3409         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3410         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3411
3412         return 0
3413 }
3414 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3415
3416 test_27R() {
3417         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3418                 skip "need MDS 2.14.55 or later"
3419         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3420
3421         local testdir="$DIR/$tdir"
3422         test_mkdir -p $testdir
3423         stack_trap "rm -rf $testdir"
3424         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3425
3426         local f1="$testdir/f1"
3427         touch $f1 || error "failed to touch $f1"
3428         local count=$($LFS getstripe -c $f1)
3429         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3430
3431         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3432         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3433
3434         local maxcount=$(($OSTCOUNT - 1))
3435         local mdts=$(comma_list $(mdts_nodes))
3436         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3437         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3438
3439         local f2="$testdir/f2"
3440         touch $f2 || error "failed to touch $f2"
3441         local count=$($LFS getstripe -c $f2)
3442         (( $count == $maxcount )) || error "wrong stripe count"
3443 }
3444 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3445
3446 test_27T() {
3447         [ $(facet_host client) == $(facet_host ost1) ] &&
3448                 skip "need ost1 and client on different nodes"
3449
3450 #define OBD_FAIL_OSC_NO_GRANT            0x411
3451         $LCTL set_param fail_loc=0x20000411 fail_val=1
3452 #define OBD_FAIL_OST_ENOSPC              0x215
3453         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3454         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3455         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3456                 error "multiop failed"
3457 }
3458 run_test 27T "no eio on close on partial write due to enosp"
3459
3460 test_27U() {
3461         local dir=$DIR/$tdir
3462         local file=$dir/$tfile
3463         local append_pool=${TESTNAME}-append
3464         local normal_pool=${TESTNAME}-normal
3465         local pool
3466         local stripe_count
3467         local stripe_count2
3468         local mdts=$(comma_list $(mdts_nodes))
3469
3470         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3471                 skip "Need MDS version at least 2.15.51 for append pool feature"
3472
3473         # Validate existing append_* params and ensure restore
3474         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3475         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3476         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3477
3478         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3479         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3480         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3481
3482         pool_add $append_pool || error "pool creation failed"
3483         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3484
3485         pool_add $normal_pool || error "pool creation failed"
3486         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3487
3488         test_mkdir $dir
3489         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3490
3491         echo XXX >> $file.1
3492         $LFS getstripe $file.1
3493
3494         pool=$($LFS getstripe -p $file.1)
3495         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3496
3497         stripe_count2=$($LFS getstripe -c $file.1)
3498         ((stripe_count2 == stripe_count)) ||
3499                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3500
3501         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3502
3503         echo XXX >> $file.2
3504         $LFS getstripe $file.2
3505
3506         pool=$($LFS getstripe -p $file.2)
3507         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3508
3509         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3510
3511         echo XXX >> $file.3
3512         $LFS getstripe $file.3
3513
3514         stripe_count2=$($LFS getstripe -c $file.3)
3515         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3516 }
3517 run_test 27U "append pool and stripe count work with composite default layout"
3518
3519 test_27V() {
3520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3521         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3522
3523         local dir=$DIR/$tdir
3524         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3525         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3526         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3527         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3528         local pid
3529
3530         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3531
3532         do_facet mds1 $LCTL set_param $lod_param=0
3533         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3534
3535         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3536         stack_trap "rm -rf $dir"
3537
3538         # exercise race in LU-16981 with deactivating OST while creating a file
3539         (
3540                 while true; do
3541                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3542                         sleep 0.1
3543                         do_facet mds1 \
3544                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3545                 done
3546         ) &
3547
3548         pid=$!
3549         stack_trap "kill -9 $pid"
3550
3551         # errors here are OK so ignore them (just don't want to crash)
3552         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3553
3554         return 0
3555 }
3556 run_test 27V "creating widely striped file races with deactivating OST"
3557
3558 # createtest also checks that device nodes are created and
3559 # then visible correctly (#2091)
3560 test_28() { # bug 2091
3561         test_mkdir $DIR/d28
3562         $CREATETEST $DIR/d28/ct || error "createtest failed"
3563 }
3564 run_test 28 "create/mknod/mkdir with bad file types ============"
3565
3566 test_29() {
3567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3568
3569         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3570                 disable_opencache
3571                 stack_trap "restore_opencache"
3572         }
3573
3574         sync; sleep 1; sync # flush out any dirty pages from previous tests
3575         cancel_lru_locks
3576         test_mkdir $DIR/d29
3577         touch $DIR/d29/foo
3578         log 'first d29'
3579         ls -l $DIR/d29
3580
3581         local locks_orig=$(total_used_locks mdc)
3582         (( $locks_orig != 0 )) || error "No mdc lock count"
3583
3584         local locks_unused_orig=$(total_unused_locks mdc)
3585
3586         log 'second d29'
3587         ls -l $DIR/d29
3588         log 'done'
3589
3590         local locks_current=$(total_used_locks mdc)
3591
3592         local locks_unused_current=$(total_unused_locks mdc)
3593
3594         if (( $locks_current > $locks_orig )); then
3595                 $LCTL set_param -n ldlm.dump_namespaces ""
3596                 error "CURRENT: $locks_current > $locks_orig"
3597         fi
3598         if (( $locks_unused_current > $locks_unused_orig )); then
3599                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3600         fi
3601 }
3602 run_test 29 "IT_GETATTR regression  ============================"
3603
3604 test_30a() { # was test_30
3605         cp $(which ls) $DIR || cp /bin/ls $DIR
3606         $DIR/ls / || error "Can't execute binary from lustre"
3607         rm $DIR/ls
3608 }
3609 run_test 30a "execute binary from Lustre (execve) =============="
3610
3611 test_30b() {
3612         cp `which ls` $DIR || cp /bin/ls $DIR
3613         chmod go+rx $DIR/ls
3614         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3615         rm $DIR/ls
3616 }
3617 run_test 30b "execute binary from Lustre as non-root ==========="
3618
3619 test_30c() { # b=22376
3620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3621
3622         cp $(which ls) $DIR || cp /bin/ls $DIR
3623         chmod a-rw $DIR/ls
3624         cancel_lru_locks mdc
3625         cancel_lru_locks osc
3626         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3627         rm -f $DIR/ls
3628 }
3629 run_test 30c "execute binary from Lustre without read perms ===="
3630
3631 test_30d() {
3632         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3633
3634         for i in {1..10}; do
3635                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3636                 local PID=$!
3637                 sleep 1
3638                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3639                 wait $PID || error "executing dd from Lustre failed"
3640                 rm -f $DIR/$tfile
3641         done
3642
3643         rm -f $DIR/dd
3644 }
3645 run_test 30d "execute binary from Lustre while clear locks"
3646
3647 test_31a() {
3648         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3649         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3650 }
3651 run_test 31a "open-unlink file =================================="
3652
3653 test_31b() {
3654         touch $DIR/f31 || error "touch $DIR/f31 failed"
3655         ln $DIR/f31 $DIR/f31b || error "ln failed"
3656         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3657         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3658 }
3659 run_test 31b "unlink file with multiple links while open ======="
3660
3661 test_31c() {
3662         touch $DIR/f31 || error "touch $DIR/f31 failed"
3663         ln $DIR/f31 $DIR/f31c || error "ln failed"
3664         multiop_bg_pause $DIR/f31 O_uc ||
3665                 error "multiop_bg_pause for $DIR/f31 failed"
3666         MULTIPID=$!
3667         $MULTIOP $DIR/f31c Ouc
3668         kill -USR1 $MULTIPID
3669         wait $MULTIPID
3670 }
3671 run_test 31c "open-unlink file with multiple links ============="
3672
3673 test_31d() {
3674         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3675         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3676 }
3677 run_test 31d "remove of open directory ========================="
3678
3679 test_31e() { # bug 2904
3680         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3681 }
3682 run_test 31e "remove of open non-empty directory ==============="
3683
3684 test_31f() { # bug 4554
3685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3686
3687         set -vx
3688         test_mkdir $DIR/d31f
3689         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3690         cp /etc/hosts $DIR/d31f
3691         ls -l $DIR/d31f
3692         $LFS getstripe $DIR/d31f/hosts
3693         multiop_bg_pause $DIR/d31f D_c || return 1
3694         MULTIPID=$!
3695
3696         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3697         test_mkdir $DIR/d31f
3698         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3699         cp /etc/hosts $DIR/d31f
3700         ls -l $DIR/d31f
3701         $LFS getstripe $DIR/d31f/hosts
3702         multiop_bg_pause $DIR/d31f D_c || return 1
3703         MULTIPID2=$!
3704
3705         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3706         wait $MULTIPID || error "first opendir $MULTIPID failed"
3707
3708         sleep 6
3709
3710         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3711         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3712         set +vx
3713 }
3714 run_test 31f "remove of open directory with open-unlink file ==="
3715
3716 test_31g() {
3717         echo "-- cross directory link --"
3718         test_mkdir -c1 $DIR/${tdir}ga
3719         test_mkdir -c1 $DIR/${tdir}gb
3720         touch $DIR/${tdir}ga/f
3721         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3722         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3723         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3724         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3725         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3726 }
3727 run_test 31g "cross directory link==============="
3728
3729 test_31h() {
3730         echo "-- cross directory link --"
3731         test_mkdir -c1 $DIR/${tdir}
3732         test_mkdir -c1 $DIR/${tdir}/dir
3733         touch $DIR/${tdir}/f
3734         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3735         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3736         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3737         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3738         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3739 }
3740 run_test 31h "cross directory link under child==============="
3741
3742 test_31i() {
3743         echo "-- cross directory link --"
3744         test_mkdir -c1 $DIR/$tdir
3745         test_mkdir -c1 $DIR/$tdir/dir
3746         touch $DIR/$tdir/dir/f
3747         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3748         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3749         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3750         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3751         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3752 }
3753 run_test 31i "cross directory link under parent==============="
3754
3755 test_31j() {
3756         test_mkdir -c1 -p $DIR/$tdir
3757         test_mkdir -c1 -p $DIR/$tdir/dir1
3758         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3759         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3760         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3761         return 0
3762 }
3763 run_test 31j "link for directory"
3764
3765 test_31k() {
3766         test_mkdir -c1 -p $DIR/$tdir
3767         touch $DIR/$tdir/s
3768         touch $DIR/$tdir/exist
3769         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3770         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3771         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3772         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3773         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3774         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3775         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3776         return 0
3777 }
3778 run_test 31k "link to file: the same, non-existing, dir"
3779
3780 test_31l() {
3781         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3782
3783         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3784         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3785                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3786
3787         touch $DIR/$tfile || error "create failed"
3788         mkdir $DIR/$tdir || error "mkdir failed"
3789         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3790 }
3791 run_test 31l "link to file: target dir has trailing slash"
3792
3793 test_31m() {
3794         mkdir $DIR/d31m
3795         touch $DIR/d31m/s
3796         mkdir $DIR/d31m2
3797         touch $DIR/d31m2/exist
3798         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3799         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3800         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3801         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3802         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3803         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3804         return 0
3805 }
3806 run_test 31m "link to file: the same, non-existing, dir"
3807
3808 test_31n() {
3809         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3810         nlink=$(stat --format=%h $DIR/$tfile)
3811         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3812         local fd=$(free_fd)
3813         local cmd="exec $fd<$DIR/$tfile"
3814         eval $cmd
3815         cmd="exec $fd<&-"
3816         trap "eval $cmd" EXIT
3817         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3818         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3819         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3820         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3821         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3822         eval $cmd
3823 }
3824 run_test 31n "check link count of unlinked file"
3825
3826 link_one() {
3827         local tempfile=$(mktemp $1_XXXXXX)
3828         link $tempfile $1 2> /dev/null &&
3829                 echo "$BASHPID: link $tempfile to $1 succeeded"
3830         unlink $tempfile
3831 }
3832
3833 test_31o() { # LU-2901
3834         test_mkdir $DIR/$tdir
3835         for LOOP in $(seq 100); do
3836                 rm -f $DIR/$tdir/$tfile*
3837                 for THREAD in $(seq 8); do
3838                         link_one $DIR/$tdir/$tfile.$LOOP &
3839                 done
3840                 wait
3841                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3842                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3843                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3844                         break || true
3845         done
3846 }
3847 run_test 31o "duplicate hard links with same filename"
3848
3849 test_31p() {
3850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3851
3852         test_mkdir $DIR/$tdir
3853         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3854         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3855
3856         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3857                 error "open unlink test1 failed"
3858         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3859                 error "open unlink test2 failed"
3860
3861         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3862                 error "test1 still exists"
3863         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3864                 error "test2 still exists"
3865 }
3866 run_test 31p "remove of open striped directory"
3867
3868 test_31q() {
3869         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3870
3871         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3872         index=$($LFS getdirstripe -i $DIR/$tdir)
3873         [ $index -eq 3 ] || error "first stripe index $index != 3"
3874         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3875         [ $index -eq 1 ] || error "second stripe index $index != 1"
3876
3877         # when "-c <stripe_count>" is set, the number of MDTs specified after
3878         # "-i" should equal to the stripe count
3879         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3880 }
3881 run_test 31q "create striped directory on specific MDTs"
3882
3883 #LU-14949
3884 test_31r() {
3885         touch $DIR/$tfile.target
3886         touch $DIR/$tfile.source
3887
3888         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3889         $LCTL set_param fail_loc=0x1419 fail_val=3
3890         cat $DIR/$tfile.target &
3891         CATPID=$!
3892
3893         # Guarantee open is waiting before we get here
3894         sleep 1
3895         mv $DIR/$tfile.source $DIR/$tfile.target
3896
3897         wait $CATPID
3898         RC=$?
3899         if [[ $RC -ne 0 ]]; then
3900                 error "open with cat failed, rc=$RC"
3901         fi
3902 }
3903 run_test 31r "open-rename(replace) race"
3904
3905 cleanup_test32_mount() {
3906         local rc=0
3907         trap 0
3908         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3909         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3910         losetup -d $loopdev || true
3911         rm -rf $DIR/$tdir
3912         return $rc
3913 }
3914
3915 test_32a() {
3916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3917
3918         echo "== more mountpoints and symlinks ================="
3919         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3920         trap cleanup_test32_mount EXIT
3921         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3922         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3923                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3924         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3925                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3926         cleanup_test32_mount
3927 }
3928 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3929
3930 test_32b() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3934         trap cleanup_test32_mount EXIT
3935         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3936         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3937                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3938         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3939                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3940         cleanup_test32_mount
3941 }
3942 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3943
3944 test_32c() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3948         trap cleanup_test32_mount EXIT
3949         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3950         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3951                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3952         test_mkdir -p $DIR/$tdir/d2/test_dir
3953         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3954                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3955         cleanup_test32_mount
3956 }
3957 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3958
3959 test_32d() {
3960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3961
3962         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3963         trap cleanup_test32_mount EXIT
3964         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3965         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3966                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3967         test_mkdir -p $DIR/$tdir/d2/test_dir
3968         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3969                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3970         cleanup_test32_mount
3971 }
3972 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3973
3974 test_32e() {
3975         rm -fr $DIR/$tdir
3976         test_mkdir -p $DIR/$tdir/tmp
3977         local tmp_dir=$DIR/$tdir/tmp
3978         ln -s $DIR/$tdir $tmp_dir/symlink11
3979         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3980         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3981         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3982 }
3983 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3984
3985 test_32f() {
3986         rm -fr $DIR/$tdir
3987         test_mkdir -p $DIR/$tdir/tmp
3988         local tmp_dir=$DIR/$tdir/tmp
3989         ln -s $DIR/$tdir $tmp_dir/symlink11
3990         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3991         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3992         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3993 }
3994 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3995
3996 test_32g() {
3997         local tmp_dir=$DIR/$tdir/tmp
3998         test_mkdir -p $tmp_dir
3999         test_mkdir $DIR/${tdir}2
4000         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4001         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4002         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4003         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4004         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4005         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4006 }
4007 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4008
4009 test_32h() {
4010         rm -fr $DIR/$tdir $DIR/${tdir}2
4011         tmp_dir=$DIR/$tdir/tmp
4012         test_mkdir -p $tmp_dir
4013         test_mkdir $DIR/${tdir}2
4014         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4015         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4016         ls $tmp_dir/symlink12 || error "listing symlink12"
4017         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4018 }
4019 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4020
4021 test_32i() {
4022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4023
4024         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4025         trap cleanup_test32_mount EXIT
4026         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4027         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4028                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4029         touch $DIR/$tdir/test_file
4030         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4031                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4032         cleanup_test32_mount
4033 }
4034 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4035
4036 test_32j() {
4037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4038
4039         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4040         trap cleanup_test32_mount EXIT
4041         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4042         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4043                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4044         touch $DIR/$tdir/test_file
4045         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4046                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4047         cleanup_test32_mount
4048 }
4049 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4050
4051 test_32k() {
4052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4053
4054         rm -fr $DIR/$tdir
4055         trap cleanup_test32_mount EXIT
4056         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4057         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4058                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4059         test_mkdir -p $DIR/$tdir/d2
4060         touch $DIR/$tdir/d2/test_file || error "touch failed"
4061         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4062                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4063         cleanup_test32_mount
4064 }
4065 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4066
4067 test_32l() {
4068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4069
4070         rm -fr $DIR/$tdir
4071         trap cleanup_test32_mount EXIT
4072         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4073         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4074                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4075         test_mkdir -p $DIR/$tdir/d2
4076         touch $DIR/$tdir/d2/test_file || error "touch failed"
4077         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4078                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4079         cleanup_test32_mount
4080 }
4081 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4082
4083 test_32m() {
4084         rm -fr $DIR/d32m
4085         test_mkdir -p $DIR/d32m/tmp
4086         TMP_DIR=$DIR/d32m/tmp
4087         ln -s $DIR $TMP_DIR/symlink11
4088         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4089         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4090                 error "symlink11 not a link"
4091         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4092                 error "symlink01 not a link"
4093 }
4094 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4095
4096 test_32n() {
4097         rm -fr $DIR/d32n
4098         test_mkdir -p $DIR/d32n/tmp
4099         TMP_DIR=$DIR/d32n/tmp
4100         ln -s $DIR $TMP_DIR/symlink11
4101         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4102         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4103         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4104 }
4105 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4106
4107 test_32o() {
4108         touch $DIR/$tfile
4109         test_mkdir -p $DIR/d32o/tmp
4110         TMP_DIR=$DIR/d32o/tmp
4111         ln -s $DIR/$tfile $TMP_DIR/symlink12
4112         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4113         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4114                 error "symlink12 not a link"
4115         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4116         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4117                 error "$DIR/d32o/tmp/symlink12 not file type"
4118         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4119                 error "$DIR/d32o/symlink02 not file type"
4120 }
4121 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4122
4123 test_32p() {
4124         log 32p_1
4125         rm -fr $DIR/d32p
4126         log 32p_2
4127         rm -f $DIR/$tfile
4128         log 32p_3
4129         touch $DIR/$tfile
4130         log 32p_4
4131         test_mkdir -p $DIR/d32p/tmp
4132         log 32p_5
4133         TMP_DIR=$DIR/d32p/tmp
4134         log 32p_6
4135         ln -s $DIR/$tfile $TMP_DIR/symlink12
4136         log 32p_7
4137         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4138         log 32p_8
4139         cat $DIR/d32p/tmp/symlink12 ||
4140                 error "Can't open $DIR/d32p/tmp/symlink12"
4141         log 32p_9
4142         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4143         log 32p_10
4144 }
4145 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4146
4147 test_32q() {
4148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4149
4150         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4151         trap cleanup_test32_mount EXIT
4152         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4153         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4154         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4155                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4156         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4157         cleanup_test32_mount
4158 }
4159 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4160
4161 test_32r() {
4162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4163
4164         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4165         trap cleanup_test32_mount EXIT
4166         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4167         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4168         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4169                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4170         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4171         cleanup_test32_mount
4172 }
4173 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4174
4175 test_33aa() {
4176         rm -f $DIR/$tfile
4177         touch $DIR/$tfile
4178         chmod 444 $DIR/$tfile
4179         chown $RUNAS_ID $DIR/$tfile
4180         log 33_1
4181         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4182         log 33_2
4183 }
4184 run_test 33aa "write file with mode 444 (should return error)"
4185
4186 test_33a() {
4187         rm -fr $DIR/$tdir
4188         test_mkdir $DIR/$tdir
4189         chown $RUNAS_ID $DIR/$tdir
4190         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4191                 error "$RUNAS create $tdir/$tfile failed"
4192         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4193                 error "open RDWR" || true
4194 }
4195 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4196
4197 test_33b() {
4198         rm -fr $DIR/$tdir
4199         test_mkdir $DIR/$tdir
4200         chown $RUNAS_ID $DIR/$tdir
4201         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4202 }
4203 run_test 33b "test open file with malformed flags (No panic)"
4204
4205 test_33c() {
4206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4207         remote_ost_nodsh && skip "remote OST with nodsh"
4208
4209         local ostnum
4210         local ostname
4211         local write_bytes
4212         local all_zeros
4213
4214         all_zeros=true
4215         test_mkdir $DIR/$tdir
4216         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4217
4218         sync
4219         for ostnum in $(seq $OSTCOUNT); do
4220                 # test-framework's OST numbering is one-based, while Lustre's
4221                 # is zero-based
4222                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4223                 # check if at least some write_bytes stats are counted
4224                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4225                               obdfilter.$ostname.stats |
4226                               awk '/^write_bytes/ {print $7}' )
4227                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4228                 if (( ${write_bytes:-0} > 0 )); then
4229                         all_zeros=false
4230                         break
4231                 fi
4232         done
4233
4234         $all_zeros || return 0
4235
4236         # Write four bytes
4237         echo foo > $DIR/$tdir/bar
4238         # Really write them
4239         sync
4240
4241         # Total up write_bytes after writing.  We'd better find non-zeros.
4242         for ostnum in $(seq $OSTCOUNT); do
4243                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4244                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4245                               obdfilter/$ostname/stats |
4246                               awk '/^write_bytes/ {print $7}' )
4247                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4248                 if (( ${write_bytes:-0} > 0 )); then
4249                         all_zeros=false
4250                         break
4251                 fi
4252         done
4253
4254         if $all_zeros; then
4255                 for ostnum in $(seq $OSTCOUNT); do
4256                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4257                         echo "Check write_bytes is in obdfilter.*.stats:"
4258                         do_facet ost$ostnum lctl get_param -n \
4259                                 obdfilter.$ostname.stats
4260                 done
4261                 error "OST not keeping write_bytes stats (b=22312)"
4262         fi
4263 }
4264 run_test 33c "test write_bytes stats"
4265
4266 test_33d() {
4267         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4269
4270         local MDTIDX=1
4271         local remote_dir=$DIR/$tdir/remote_dir
4272
4273         test_mkdir $DIR/$tdir
4274         $LFS mkdir -i $MDTIDX $remote_dir ||
4275                 error "create remote directory failed"
4276
4277         touch $remote_dir/$tfile
4278         chmod 444 $remote_dir/$tfile
4279         chown $RUNAS_ID $remote_dir/$tfile
4280
4281         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4282
4283         chown $RUNAS_ID $remote_dir
4284         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4285                                         error "create" || true
4286         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4287                                     error "open RDWR" || true
4288         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4289 }
4290 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4291
4292 test_33e() {
4293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4294
4295         mkdir $DIR/$tdir
4296
4297         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4298         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4299         mkdir $DIR/$tdir/local_dir
4300
4301         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4302         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4303         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4304
4305         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4306                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4307
4308         rmdir $DIR/$tdir/* || error "rmdir failed"
4309
4310         umask 777
4311         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4312         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4313         mkdir $DIR/$tdir/local_dir
4314
4315         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4316         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4317         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4318
4319         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4320                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4321
4322         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4323
4324         umask 000
4325         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4326         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4327         mkdir $DIR/$tdir/local_dir
4328
4329         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4330         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4331         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4332
4333         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4334                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4335 }
4336 run_test 33e "mkdir and striped directory should have same mode"
4337
4338 cleanup_33f() {
4339         trap 0
4340         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4341 }
4342
4343 test_33f() {
4344         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4345         remote_mds_nodsh && skip "remote MDS with nodsh"
4346
4347         mkdir $DIR/$tdir
4348         chmod go+rwx $DIR/$tdir
4349         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4350         trap cleanup_33f EXIT
4351
4352         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4353                 error "cannot create striped directory"
4354
4355         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4356                 error "cannot create files in striped directory"
4357
4358         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4359                 error "cannot remove files in striped directory"
4360
4361         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4362                 error "cannot remove striped directory"
4363
4364         cleanup_33f
4365 }
4366 run_test 33f "nonroot user can create, access, and remove a striped directory"
4367
4368 test_33g() {
4369         mkdir -p $DIR/$tdir/dir2
4370
4371         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4372         echo $err
4373         [[ $err =~ "exists" ]] || error "Not exists error"
4374 }
4375 run_test 33g "nonroot user create already existing root created file"
4376
4377 sub_33h() {
4378         local hash_type=$1
4379         local count=250
4380
4381         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4382                 error "lfs mkdir -H $hash_type $tdir failed"
4383         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4384
4385         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4386         local index2
4387         local fname
4388
4389         for fname in $DIR/$tdir/$tfile.bak \
4390                      $DIR/$tdir/$tfile.SAV \
4391                      $DIR/$tdir/$tfile.orig \
4392                      $DIR/$tdir/$tfile~; do
4393                 touch $fname || error "touch $fname failed"
4394                 index2=$($LFS getstripe -m $fname)
4395                 (( $index == $index2 )) ||
4396                         error "$fname MDT index mismatch $index != $index2"
4397         done
4398
4399         local failed=0
4400         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4401         local pattern
4402
4403         for pattern in ${patterns[*]}; do
4404                 echo "pattern $pattern"
4405                 fname=$DIR/$tdir/$pattern
4406                 for (( i = 0; i < $count; i++ )); do
4407                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4408                                 error "mktemp $DIR/$tdir/$pattern failed"
4409                         index2=$($LFS getstripe -m $fname)
4410                         (( $index == $index2 )) && continue
4411
4412                         failed=$((failed + 1))
4413                         echo "$fname MDT index mismatch $index != $index2"
4414                 done
4415         done
4416
4417         echo "$failed/$count MDT index mismatches, expect ~2-4"
4418         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4419
4420         local same=0
4421         local expect
4422
4423         # verify that "crush" is still broken with all files on same MDT,
4424         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4425         [[ "$hash_type" == "crush" ]] && expect=$count ||
4426                 expect=$((count / MDSCOUNT))
4427
4428         # crush2 doesn't put all-numeric suffixes on the same MDT,
4429         # filename like $tfile.12345678 should *not* be considered temp
4430         for pattern in ${patterns[*]}; do
4431                 local base=${pattern%%X*}
4432                 local suff=${pattern#$base}
4433
4434                 echo "pattern $pattern"
4435                 for (( i = 0; i < $count; i++ )); do
4436                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4437                         touch $fname || error "touch $fname failed"
4438                         index2=$($LFS getstripe -m $fname)
4439                         (( $index != $index2 )) && continue
4440
4441                         same=$((same + 1))
4442                 done
4443         done
4444
4445         # the number of "bad" hashes is random, as it depends on the random
4446         # filenames generated by "mktemp".  Allow some margin in the results.
4447         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4448         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4449            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4450                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4451         same=0
4452
4453         # crush2 doesn't put suffixes with special characters on the same MDT
4454         # filename like $tfile.txt.1234 should *not* be considered temp
4455         for pattern in ${patterns[*]}; do
4456                 local base=${pattern%%X*}
4457                 local suff=${pattern#$base}
4458
4459                 pattern=$base...${suff/XXX}
4460                 echo "pattern=$pattern"
4461                 for (( i = 0; i < $count; i++ )); do
4462                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4463                                 error "touch $fname failed"
4464                         index2=$($LFS getstripe -m $fname)
4465                         (( $index != $index2 )) && continue
4466
4467                         same=$((same + 1))
4468                 done
4469         done
4470
4471         # the number of "bad" hashes is random, as it depends on the random
4472         # filenames generated by "mktemp".  Allow some margin in the results.
4473         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4474         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4475            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4476                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4477 }
4478
4479 test_33h() {
4480         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4481         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4482                 skip "Need MDS version at least 2.13.50"
4483
4484         sub_33h crush
4485 }
4486 run_test 33h "temp file is located on the same MDT as target (crush)"
4487
4488 test_33hh() {
4489         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4490         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4491         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4492                 skip "Need MDS version at least 2.15.0 for crush2"
4493
4494         sub_33h crush2
4495 }
4496 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4497
4498 test_33i()
4499 {
4500         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4501
4502         local FNAME=$(str_repeat 'f' 250)
4503
4504         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4505         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4506
4507         local count
4508         local total
4509
4510         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4511
4512         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4513
4514         lctl --device %$MDC deactivate
4515         stack_trap "lctl --device %$MDC activate"
4516         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4517         total=$(\ls -l $DIR/$tdir | wc -l)
4518         # "ls -l" will list total in the first line
4519         total=$((total - 1))
4520         (( total + count == 1000 )) ||
4521                 error "ls list $total files, $count files on MDT1"
4522 }
4523 run_test 33i "striped directory can be accessed when one MDT is down"
4524
4525 test_33j() {
4526         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4527
4528         mkdir -p $DIR/$tdir/
4529
4530         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4531                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4532
4533         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4534                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4535
4536         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4537                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4538
4539         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4540                 error "-D was not specified, but still failed"
4541 }
4542 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4543
4544 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4545 test_34a() {
4546         rm -f $DIR/f34
4547         $MCREATE $DIR/f34 || error "mcreate failed"
4548         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4549                 error "getstripe failed"
4550         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4551         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4552                 error "getstripe failed"
4553         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4554                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4555 }
4556 run_test 34a "truncate file that has not been opened ==========="
4557
4558 test_34b() {
4559         [ ! -f $DIR/f34 ] && test_34a
4560         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4561                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4562         $OPENFILE -f O_RDONLY $DIR/f34
4563         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4564                 error "getstripe failed"
4565         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4566                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4567 }
4568 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4569
4570 test_34c() {
4571         [ ! -f $DIR/f34 ] && test_34a
4572         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4573                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4574         $OPENFILE -f O_RDWR $DIR/f34
4575         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4576                 error "$LFS getstripe failed"
4577         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4578                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4579 }
4580 run_test 34c "O_RDWR opening file-with-size works =============="
4581
4582 test_34d() {
4583         [ ! -f $DIR/f34 ] && test_34a
4584         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4585                 error "dd failed"
4586         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4587                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4588         rm $DIR/f34
4589 }
4590 run_test 34d "write to sparse file ============================="
4591
4592 test_34e() {
4593         rm -f $DIR/f34e
4594         $MCREATE $DIR/f34e || error "mcreate failed"
4595         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4596         $CHECKSTAT -s 1000 $DIR/f34e ||
4597                 error "Size of $DIR/f34e not equal to 1000 bytes"
4598         $OPENFILE -f O_RDWR $DIR/f34e
4599         $CHECKSTAT -s 1000 $DIR/f34e ||
4600                 error "Size of $DIR/f34e not equal to 1000 bytes"
4601 }
4602 run_test 34e "create objects, some with size and some without =="
4603
4604 test_34f() { # bug 6242, 6243
4605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4606
4607         SIZE34F=48000
4608         rm -f $DIR/f34f
4609         $MCREATE $DIR/f34f || error "mcreate failed"
4610         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4611         dd if=$DIR/f34f of=$TMP/f34f
4612         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4613         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4614         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4615         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4616         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4617 }
4618 run_test 34f "read from a file with no objects until EOF ======="
4619
4620 test_34g() {
4621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4622
4623         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4624                 error "dd failed"
4625         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4626         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4627                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4628         cancel_lru_locks osc
4629         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4630                 error "wrong size after lock cancel"
4631
4632         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4633         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4634                 error "expanding truncate failed"
4635         cancel_lru_locks osc
4636         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4637                 error "wrong expanded size after lock cancel"
4638 }
4639 run_test 34g "truncate long file ==============================="
4640
4641 test_34h() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643
4644         local gid=10
4645         local sz=1000
4646
4647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4648         sync # Flush the cache so that multiop below does not block on cache
4649              # flush when getting the group lock
4650         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4651         MULTIPID=$!
4652
4653         # Since just timed wait is not good enough, let's do a sync write
4654         # that way we are sure enough time for a roundtrip + processing
4655         # passed + 2 seconds of extra margin.
4656         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4657         rm $DIR/${tfile}-1
4658         sleep 2
4659
4660         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4661                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4662                 kill -9 $MULTIPID
4663         fi
4664         wait $MULTIPID
4665         local nsz=`stat -c %s $DIR/$tfile`
4666         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4667 }
4668 run_test 34h "ftruncate file under grouplock should not block"
4669
4670 test_35a() {
4671         cp /bin/sh $DIR/f35a
4672         chmod 444 $DIR/f35a
4673         chown $RUNAS_ID $DIR/f35a
4674         $RUNAS $DIR/f35a && error || true
4675         rm $DIR/f35a
4676 }
4677 run_test 35a "exec file with mode 444 (should return and not leak)"
4678
4679 test_36a() {
4680         rm -f $DIR/f36
4681         utime $DIR/f36 || error "utime failed for MDS"
4682 }
4683 run_test 36a "MDS utime check (mknod, utime)"
4684
4685 test_36b() {
4686         echo "" > $DIR/f36
4687         utime $DIR/f36 || error "utime failed for OST"
4688 }
4689 run_test 36b "OST utime check (open, utime)"
4690
4691 test_36c() {
4692         rm -f $DIR/d36/f36
4693         test_mkdir $DIR/d36
4694         chown $RUNAS_ID $DIR/d36
4695         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4696 }
4697 run_test 36c "non-root MDS utime check (mknod, utime)"
4698
4699 test_36d() {
4700         [ ! -d $DIR/d36 ] && test_36c
4701         echo "" > $DIR/d36/f36
4702         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4703 }
4704 run_test 36d "non-root OST utime check (open, utime)"
4705
4706 test_36e() {
4707         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4708
4709         test_mkdir $DIR/$tdir
4710         touch $DIR/$tdir/$tfile
4711         $RUNAS utime $DIR/$tdir/$tfile &&
4712                 error "utime worked, expected failure" || true
4713 }
4714 run_test 36e "utime on non-owned file (should return error)"
4715
4716 subr_36fh() {
4717         local fl="$1"
4718         local LANG_SAVE=$LANG
4719         local LC_LANG_SAVE=$LC_LANG
4720         export LANG=C LC_LANG=C # for date language
4721
4722         DATESTR="Dec 20  2000"
4723         test_mkdir $DIR/$tdir
4724         lctl set_param fail_loc=$fl
4725         date; date +%s
4726         cp /etc/hosts $DIR/$tdir/$tfile
4727         sync & # write RPC generated with "current" inode timestamp, but delayed
4728         sleep 1
4729         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4730         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4731         cancel_lru_locks $OSC
4732         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4733         date; date +%s
4734         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4735                 echo "BEFORE: $LS_BEFORE" && \
4736                 echo "AFTER : $LS_AFTER" && \
4737                 echo "WANT  : $DATESTR" && \
4738                 error "$DIR/$tdir/$tfile timestamps changed" || true
4739
4740         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4741 }
4742
4743 test_36f() {
4744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4745
4746         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4747         subr_36fh "0x80000214"
4748 }
4749 run_test 36f "utime on file racing with OST BRW write =========="
4750
4751 test_36g() {
4752         remote_ost_nodsh && skip "remote OST with nodsh"
4753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4754         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4755                 skip "Need MDS version at least 2.12.51"
4756
4757         local fmd_max_age
4758         local fmd
4759         local facet="ost1"
4760         local tgt="obdfilter"
4761
4762         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4763
4764         test_mkdir $DIR/$tdir
4765         fmd_max_age=$(do_facet $facet \
4766                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4767                 head -n 1")
4768
4769         echo "FMD max age: ${fmd_max_age}s"
4770         touch $DIR/$tdir/$tfile
4771         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4772                 gawk '{cnt=cnt+$1}  END{print cnt}')
4773         echo "FMD before: $fmd"
4774         [[ $fmd == 0 ]] &&
4775                 error "FMD wasn't create by touch"
4776         sleep $((fmd_max_age + 12))
4777         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4778                 gawk '{cnt=cnt+$1}  END{print cnt}')
4779         echo "FMD after: $fmd"
4780         [[ $fmd == 0 ]] ||
4781                 error "FMD wasn't expired by ping"
4782 }
4783 run_test 36g "FMD cache expiry ====================="
4784
4785 test_36h() {
4786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4787
4788         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4789         subr_36fh "0x80000227"
4790 }
4791 run_test 36h "utime on file racing with OST BRW write =========="
4792
4793 test_36i() {
4794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4795
4796         test_mkdir $DIR/$tdir
4797         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4798
4799         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4800         local new_mtime=$((mtime + 200))
4801
4802         #change Modify time of striped dir
4803         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4804                         error "change mtime failed"
4805
4806         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4807
4808         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4809 }
4810 run_test 36i "change mtime on striped directory"
4811
4812 # test_37 - duplicate with tests 32q 32r
4813
4814 test_38() {
4815         local file=$DIR/$tfile
4816         touch $file
4817         openfile -f O_DIRECTORY $file
4818         local RC=$?
4819         local ENOTDIR=20
4820         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4821         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4822 }
4823 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4824
4825 test_39a() { # was test_39
4826         touch $DIR/$tfile
4827         touch $DIR/${tfile}2
4828 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4829 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4830 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4831         sleep 2
4832         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4833         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4834                 echo "mtime"
4835                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4836                 echo "atime"
4837                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4838                 echo "ctime"
4839                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4840                 error "O_TRUNC didn't change timestamps"
4841         fi
4842 }
4843 run_test 39a "mtime changed on create"
4844
4845 test_39b() {
4846         test_mkdir -c1 $DIR/$tdir
4847         cp -p /etc/passwd $DIR/$tdir/fopen
4848         cp -p /etc/passwd $DIR/$tdir/flink
4849         cp -p /etc/passwd $DIR/$tdir/funlink
4850         cp -p /etc/passwd $DIR/$tdir/frename
4851         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4852
4853         sleep 1
4854         echo "aaaaaa" >> $DIR/$tdir/fopen
4855         echo "aaaaaa" >> $DIR/$tdir/flink
4856         echo "aaaaaa" >> $DIR/$tdir/funlink
4857         echo "aaaaaa" >> $DIR/$tdir/frename
4858
4859         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4860         local link_new=`stat -c %Y $DIR/$tdir/flink`
4861         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4862         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4863
4864         cat $DIR/$tdir/fopen > /dev/null
4865         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4866         rm -f $DIR/$tdir/funlink2
4867         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4868
4869         for (( i=0; i < 2; i++ )) ; do
4870                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4871                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4872                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4873                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4874
4875                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4876                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4877                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4878                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4879
4880                 cancel_lru_locks $OSC
4881                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4882         done
4883 }
4884 run_test 39b "mtime change on open, link, unlink, rename  ======"
4885
4886 # this should be set to past
4887 TEST_39_MTIME=`date -d "1 year ago" +%s`
4888
4889 # bug 11063
4890 test_39c() {
4891         touch $DIR1/$tfile
4892         sleep 2
4893         local mtime0=`stat -c %Y $DIR1/$tfile`
4894
4895         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4896         local mtime1=`stat -c %Y $DIR1/$tfile`
4897         [ "$mtime1" = $TEST_39_MTIME ] || \
4898                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4899
4900         local d1=`date +%s`
4901         echo hello >> $DIR1/$tfile
4902         local d2=`date +%s`
4903         local mtime2=`stat -c %Y $DIR1/$tfile`
4904         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4905                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4906
4907         mv $DIR1/$tfile $DIR1/$tfile-1
4908
4909         for (( i=0; i < 2; i++ )) ; do
4910                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4911                 [ "$mtime2" = "$mtime3" ] || \
4912                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4913
4914                 cancel_lru_locks $OSC
4915                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4916         done
4917 }
4918 run_test 39c "mtime change on rename ==========================="
4919
4920 # bug 21114
4921 test_39d() {
4922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4923
4924         touch $DIR1/$tfile
4925         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4926
4927         for (( i=0; i < 2; i++ )) ; do
4928                 local mtime=`stat -c %Y $DIR1/$tfile`
4929                 [ $mtime = $TEST_39_MTIME ] || \
4930                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4931
4932                 cancel_lru_locks $OSC
4933                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4934         done
4935 }
4936 run_test 39d "create, utime, stat =============================="
4937
4938 # bug 21114
4939 test_39e() {
4940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4941
4942         touch $DIR1/$tfile
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944
4945         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4946
4947         for (( i=0; i < 2; i++ )) ; do
4948                 local mtime2=`stat -c %Y $DIR1/$tfile`
4949                 [ $mtime2 = $TEST_39_MTIME ] || \
4950                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4951
4952                 cancel_lru_locks $OSC
4953                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4954         done
4955 }
4956 run_test 39e "create, stat, utime, stat ========================"
4957
4958 # bug 21114
4959 test_39f() {
4960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4961
4962         touch $DIR1/$tfile
4963         mtime1=`stat -c %Y $DIR1/$tfile`
4964
4965         sleep 2
4966         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime2=`stat -c %Y $DIR1/$tfile`
4970                 [ $mtime2 = $TEST_39_MTIME ] || \
4971                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4972
4973                 cancel_lru_locks $OSC
4974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4975         done
4976 }
4977 run_test 39f "create, stat, sleep, utime, stat ================="
4978
4979 # bug 11063
4980 test_39g() {
4981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4982
4983         echo hello >> $DIR1/$tfile
4984         local mtime1=`stat -c %Y $DIR1/$tfile`
4985
4986         sleep 2
4987         chmod o+r $DIR1/$tfile
4988
4989         for (( i=0; i < 2; i++ )) ; do
4990                 local mtime2=`stat -c %Y $DIR1/$tfile`
4991                 [ "$mtime1" = "$mtime2" ] || \
4992                         error "lost mtime: $mtime2, should be $mtime1"
4993
4994                 cancel_lru_locks $OSC
4995                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4996         done
4997 }
4998 run_test 39g "write, chmod, stat ==============================="
4999
5000 # bug 11063
5001 test_39h() {
5002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5003
5004         touch $DIR1/$tfile
5005         sleep 1
5006
5007         local d1=`date`
5008         echo hello >> $DIR1/$tfile
5009         local mtime1=`stat -c %Y $DIR1/$tfile`
5010
5011         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5012         local d2=`date`
5013         if [ "$d1" != "$d2" ]; then
5014                 echo "write and touch not within one second"
5015         else
5016                 for (( i=0; i < 2; i++ )) ; do
5017                         local mtime2=`stat -c %Y $DIR1/$tfile`
5018                         [ "$mtime2" = $TEST_39_MTIME ] || \
5019                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5020
5021                         cancel_lru_locks $OSC
5022                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5023                 done
5024         fi
5025 }
5026 run_test 39h "write, utime within one second, stat ============="
5027
5028 test_39i() {
5029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5030
5031         touch $DIR1/$tfile
5032         sleep 1
5033
5034         echo hello >> $DIR1/$tfile
5035         local mtime1=`stat -c %Y $DIR1/$tfile`
5036
5037         mv $DIR1/$tfile $DIR1/$tfile-1
5038
5039         for (( i=0; i < 2; i++ )) ; do
5040                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5041
5042                 [ "$mtime1" = "$mtime2" ] || \
5043                         error "lost mtime: $mtime2, should be $mtime1"
5044
5045                 cancel_lru_locks $OSC
5046                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5047         done
5048 }
5049 run_test 39i "write, rename, stat =============================="
5050
5051 test_39j() {
5052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5053
5054         start_full_debug_logging
5055         touch $DIR1/$tfile
5056         sleep 1
5057
5058         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5059         lctl set_param fail_loc=0x80000412
5060         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5061                 error "multiop failed"
5062         local multipid=$!
5063         local mtime1=`stat -c %Y $DIR1/$tfile`
5064
5065         mv $DIR1/$tfile $DIR1/$tfile-1
5066
5067         kill -USR1 $multipid
5068         wait $multipid || error "multiop close failed"
5069
5070         for (( i=0; i < 2; i++ )) ; do
5071                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5072                 [ "$mtime1" = "$mtime2" ] ||
5073                         error "mtime is lost on close: $mtime2, " \
5074                               "should be $mtime1"
5075
5076                 cancel_lru_locks
5077                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5078         done
5079         lctl set_param fail_loc=0
5080         stop_full_debug_logging
5081 }
5082 run_test 39j "write, rename, close, stat ======================="
5083
5084 test_39k() {
5085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5086
5087         touch $DIR1/$tfile
5088         sleep 1
5089
5090         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5091         local multipid=$!
5092         local mtime1=`stat -c %Y $DIR1/$tfile`
5093
5094         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5095
5096         kill -USR1 $multipid
5097         wait $multipid || error "multiop close failed"
5098
5099         for (( i=0; i < 2; i++ )) ; do
5100                 local mtime2=`stat -c %Y $DIR1/$tfile`
5101
5102                 [ "$mtime2" = $TEST_39_MTIME ] || \
5103                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5104
5105                 cancel_lru_locks
5106                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5107         done
5108 }
5109 run_test 39k "write, utime, close, stat ========================"
5110
5111 # this should be set to future
5112 TEST_39_ATIME=`date -d "1 year" +%s`
5113
5114 test_39l() {
5115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5116         remote_mds_nodsh && skip "remote MDS with nodsh"
5117
5118         local atime_diff=$(do_facet $SINGLEMDS \
5119                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5120         rm -rf $DIR/$tdir
5121         mkdir_on_mdt0 $DIR/$tdir
5122
5123         # test setting directory atime to future
5124         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5125         local atime=$(stat -c %X $DIR/$tdir)
5126         [ "$atime" = $TEST_39_ATIME ] ||
5127                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5128
5129         # test setting directory atime from future to now
5130         local now=$(date +%s)
5131         touch -a -d @$now $DIR/$tdir
5132
5133         atime=$(stat -c %X $DIR/$tdir)
5134         [ "$atime" -eq "$now"  ] ||
5135                 error "atime is not updated from future: $atime, $now"
5136
5137         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5138         sleep 3
5139
5140         # test setting directory atime when now > dir atime + atime_diff
5141         local d1=$(date +%s)
5142         ls $DIR/$tdir
5143         local d2=$(date +%s)
5144         cancel_lru_locks mdc
5145         atime=$(stat -c %X $DIR/$tdir)
5146         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5147                 error "atime is not updated  : $atime, should be $d2"
5148
5149         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5150         sleep 3
5151
5152         # test not setting directory atime when now < dir atime + atime_diff
5153         ls $DIR/$tdir
5154         cancel_lru_locks mdc
5155         atime=$(stat -c %X $DIR/$tdir)
5156         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5157                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5158
5159         do_facet $SINGLEMDS \
5160                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5161 }
5162 run_test 39l "directory atime update ==========================="
5163
5164 test_39m() {
5165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5166
5167         touch $DIR1/$tfile
5168         sleep 2
5169         local far_past_mtime=$(date -d "May 29 1953" +%s)
5170         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5171
5172         touch -m -d @$far_past_mtime $DIR1/$tfile
5173         touch -a -d @$far_past_atime $DIR1/$tfile
5174
5175         for (( i=0; i < 2; i++ )) ; do
5176                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5177                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5178                         error "atime or mtime set incorrectly"
5179
5180                 cancel_lru_locks $OSC
5181                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5182         done
5183 }
5184 run_test 39m "test atime and mtime before 1970"
5185
5186 test_39n() { # LU-3832
5187         remote_mds_nodsh && skip "remote MDS with nodsh"
5188
5189         local atime_diff=$(do_facet $SINGLEMDS \
5190                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5191         local atime0
5192         local atime1
5193         local atime2
5194
5195         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5196
5197         rm -rf $DIR/$tfile
5198         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5199         atime0=$(stat -c %X $DIR/$tfile)
5200
5201         sleep 5
5202         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5203         atime1=$(stat -c %X $DIR/$tfile)
5204
5205         sleep 5
5206         cancel_lru_locks mdc
5207         cancel_lru_locks osc
5208         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5209         atime2=$(stat -c %X $DIR/$tfile)
5210
5211         do_facet $SINGLEMDS \
5212                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5213
5214         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5215         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5216 }
5217 run_test 39n "check that O_NOATIME is honored"
5218
5219 test_39o() {
5220         TESTDIR=$DIR/$tdir/$tfile
5221         [ -e $TESTDIR ] && rm -rf $TESTDIR
5222         mkdir -p $TESTDIR
5223         cd $TESTDIR
5224         links1=2
5225         ls
5226         mkdir a b
5227         ls
5228         links2=$(stat -c %h .)
5229         [ $(($links1 + 2)) != $links2 ] &&
5230                 error "wrong links count $(($links1 + 2)) != $links2"
5231         rmdir b
5232         links3=$(stat -c %h .)
5233         [ $(($links1 + 1)) != $links3 ] &&
5234                 error "wrong links count $links1 != $links3"
5235         return 0
5236 }
5237 run_test 39o "directory cached attributes updated after create"
5238
5239 test_39p() {
5240         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5241
5242         local MDTIDX=1
5243         TESTDIR=$DIR/$tdir/$tdir
5244         [ -e $TESTDIR ] && rm -rf $TESTDIR
5245         test_mkdir -p $TESTDIR
5246         cd $TESTDIR
5247         links1=2
5248         ls
5249         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5250         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5251         ls
5252         links2=$(stat -c %h .)
5253         [ $(($links1 + 2)) != $links2 ] &&
5254                 error "wrong links count $(($links1 + 2)) != $links2"
5255         rmdir remote_dir2
5256         links3=$(stat -c %h .)
5257         [ $(($links1 + 1)) != $links3 ] &&
5258                 error "wrong links count $links1 != $links3"
5259         return 0
5260 }
5261 run_test 39p "remote directory cached attributes updated after create ========"
5262
5263 test_39r() {
5264         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5265                 skip "no atime update on old OST"
5266         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5267                 skip_env "ldiskfs only test"
5268         fi
5269
5270         local saved_adiff
5271         local ahost=$(facet_active_host ost1)
5272         saved_adiff=$(do_facet ost1 \
5273                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5274         stack_trap "do_facet ost1 \
5275                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5276
5277         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5278
5279         $LFS setstripe -i 0 $DIR/$tfile
5280         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5281                 error "can't write initial file"
5282         cancel_lru_locks osc
5283
5284         # exceed atime_diff and access file
5285         sleep 10
5286         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5287                 error "can't udpate atime"
5288
5289         # atime_cli value is in decimal
5290         local atime_cli=$(stat -c %X $DIR/$tfile)
5291         echo "client atime: $atime_cli"
5292
5293         local ostdev=$(ostdevname 1)
5294         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5295         local seq=${fid[3]#0x}
5296         local oid=${fid[1]}
5297         local oid_hex
5298
5299         if [ $seq == 0 ]; then
5300                 oid_hex=${fid[1]}
5301         else
5302                 oid_hex=${fid[2]#0x}
5303         fi
5304         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5305         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5306
5307         # allow atime update to be written to device
5308         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5309         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5310
5311         # Give enough time for server to get updated. Until then
5312         # the value read is defaulted to "0x00000000:00000000"
5313         # Wait until atime read via debugfs is not equal to zero.
5314         # Max limit to wait is 30 seconds.
5315         wait_update_cond $ahost                                         \
5316                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5317                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5318         # atime_ost value is in hex
5319         local atime_ost=$(do_facet ost1 "$cmd" |&
5320                           awk -F'[: ]' '/atime:/ { print $4 }')
5321         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5322         # convert Hex to decimal before comparing
5323         local atime_ost_dec=$((atime_ost))
5324
5325         # The test pass criteria is that the client time and server should
5326         # be same (2s gap accepted). This gap could arise due to VFS updating
5327         # the atime after the read(dd), stat and the updated time from the
5328         # inode
5329         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5330                 error "atime on client $atime_cli != ost $atime_ost_dec"
5331 }
5332 run_test 39r "lazy atime update on OST"
5333
5334 test_39q() { # LU-8041
5335         local testdir=$DIR/$tdir
5336         mkdir -p $testdir
5337         multiop_bg_pause $testdir D_c || error "multiop failed"
5338         local multipid=$!
5339         cancel_lru_locks mdc
5340         kill -USR1 $multipid
5341         local atime=$(stat -c %X $testdir)
5342         [ "$atime" -ne 0 ] || error "atime is zero"
5343 }
5344 run_test 39q "close won't zero out atime"
5345
5346 test_39s() {
5347         local atime0
5348         local atime1
5349         local atime2
5350         local atime3
5351         local atime4
5352
5353         umount_client $MOUNT
5354         mount_client $MOUNT relatime
5355
5356         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5357         atime0=$(stat -c %X $DIR/$tfile)
5358
5359         # First read updates atime
5360         sleep 1
5361         cat $DIR/$tfile >/dev/null
5362         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5363
5364         # Next reads do not update atime
5365         sleep 1
5366         cat $DIR/$tfile >/dev/null
5367         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5368
5369         # If mtime is greater than atime, atime is updated
5370         sleep 1
5371         touch -m $DIR/$tfile # (mtime = now)
5372         sleep 1
5373         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5374         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5375
5376         # Next reads do not update atime
5377         sleep 1
5378         cat $DIR/$tfile >/dev/null
5379         atime4=$(stat -c %X $DIR/$tfile)
5380
5381         # Remount the client to clear 'relatime' option
5382         remount_client $MOUNT
5383
5384         (( atime0 < atime1 )) ||
5385                 error "atime $atime0 should be smaller than $atime1"
5386         (( atime1 == atime2 )) ||
5387                 error "atime $atime1 was updated to $atime2"
5388         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5389         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5390 }
5391 run_test 39s "relatime is supported"
5392
5393 test_40() {
5394         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5395         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5396                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5397         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5398                 error "$tfile is not 4096 bytes in size"
5399 }
5400 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5401
5402 test_41() {
5403         # bug 1553
5404         small_write $DIR/f41 18
5405 }
5406 run_test 41 "test small file write + fstat ====================="
5407
5408 count_ost_writes() {
5409         lctl get_param -n ${OSC}.*.stats |
5410                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5411                         END { printf("%0.0f", writes) }'
5412 }
5413
5414 # decent default
5415 WRITEBACK_SAVE=500
5416 DIRTY_RATIO_SAVE=40
5417 MAX_DIRTY_RATIO=50
5418 BG_DIRTY_RATIO_SAVE=10
5419 MAX_BG_DIRTY_RATIO=25
5420
5421 start_writeback() {
5422         trap 0
5423         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5424         # dirty_ratio, dirty_background_ratio
5425         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5426                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5427                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5428                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5429         else
5430                 # if file not here, we are a 2.4 kernel
5431                 kill -CONT `pidof kupdated`
5432         fi
5433 }
5434
5435 stop_writeback() {
5436         # setup the trap first, so someone cannot exit the test at the
5437         # exact wrong time and mess up a machine
5438         trap start_writeback EXIT
5439         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5440         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5441                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5442                 sysctl -w vm.dirty_writeback_centisecs=0
5443                 sysctl -w vm.dirty_writeback_centisecs=0
5444                 # save and increase /proc/sys/vm/dirty_ratio
5445                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5446                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5447                 # save and increase /proc/sys/vm/dirty_background_ratio
5448                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5449                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5450         else
5451                 # if file not here, we are a 2.4 kernel
5452                 kill -STOP `pidof kupdated`
5453         fi
5454 }
5455
5456 # ensure that all stripes have some grant before we test client-side cache
5457 setup_test42() {
5458         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5459                 dd if=/dev/zero of=$i bs=4k count=1
5460                 rm $i
5461         done
5462 }
5463
5464 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5465 # file truncation, and file removal.
5466 test_42a() {
5467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5468
5469         setup_test42
5470         cancel_lru_locks $OSC
5471         stop_writeback
5472         sync; sleep 1; sync # just to be safe
5473         BEFOREWRITES=`count_ost_writes`
5474         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5475         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5476         AFTERWRITES=`count_ost_writes`
5477         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5478                 error "$BEFOREWRITES < $AFTERWRITES"
5479         start_writeback
5480 }
5481 run_test 42a "ensure that we don't flush on close"
5482
5483 test_42b() {
5484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5485
5486         setup_test42
5487         cancel_lru_locks $OSC
5488         stop_writeback
5489         sync
5490         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5491         BEFOREWRITES=$(count_ost_writes)
5492         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5493         AFTERWRITES=$(count_ost_writes)
5494         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5495                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5496         fi
5497         BEFOREWRITES=$(count_ost_writes)
5498         sync || error "sync: $?"
5499         AFTERWRITES=$(count_ost_writes)
5500         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5501                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5502         fi
5503         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5504         start_writeback
5505         return 0
5506 }
5507 run_test 42b "test destroy of file with cached dirty data ======"
5508
5509 # if these tests just want to test the effect of truncation,
5510 # they have to be very careful.  consider:
5511 # - the first open gets a {0,EOF}PR lock
5512 # - the first write conflicts and gets a {0, count-1}PW
5513 # - the rest of the writes are under {count,EOF}PW
5514 # - the open for truncate tries to match a {0,EOF}PR
5515 #   for the filesize and cancels the PWs.
5516 # any number of fixes (don't get {0,EOF} on open, match
5517 # composite locks, do smarter file size management) fix
5518 # this, but for now we want these tests to verify that
5519 # the cancellation with truncate intent works, so we
5520 # start the file with a full-file pw lock to match against
5521 # until the truncate.
5522 trunc_test() {
5523         test=$1
5524         file=$DIR/$test
5525         offset=$2
5526         cancel_lru_locks $OSC
5527         stop_writeback
5528         # prime the file with 0,EOF PW to match
5529         touch $file
5530         $TRUNCATE $file 0
5531         sync; sync
5532         # now the real test..
5533         dd if=/dev/zero of=$file bs=1024 count=100
5534         BEFOREWRITES=`count_ost_writes`
5535         $TRUNCATE $file $offset
5536         cancel_lru_locks $OSC
5537         AFTERWRITES=`count_ost_writes`
5538         start_writeback
5539 }
5540
5541 test_42c() {
5542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5543
5544         trunc_test 42c 1024
5545         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5546                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5547         rm $file
5548 }
5549 run_test 42c "test partial truncate of file with cached dirty data"
5550
5551 test_42d() {
5552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5553
5554         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5555         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5556         $LCTL set_param debug=+cache
5557
5558         trunc_test 42d 0
5559         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5560                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5561         rm $file
5562 }
5563 run_test 42d "test complete truncate of file with cached dirty data"
5564
5565 test_42e() { # bug22074
5566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5567
5568         local TDIR=$DIR/${tdir}e
5569         local pages=16 # hardcoded 16 pages, don't change it.
5570         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5571         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5572         local max_dirty_mb
5573         local warmup_files
5574
5575         test_mkdir $DIR/${tdir}e
5576         $LFS setstripe -c 1 $TDIR
5577         createmany -o $TDIR/f $files
5578
5579         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5580
5581         # we assume that with $OSTCOUNT files, at least one of them will
5582         # be allocated on OST0.
5583         warmup_files=$((OSTCOUNT * max_dirty_mb))
5584         createmany -o $TDIR/w $warmup_files
5585
5586         # write a large amount of data into one file and sync, to get good
5587         # avail_grant number from OST.
5588         for ((i=0; i<$warmup_files; i++)); do
5589                 idx=$($LFS getstripe -i $TDIR/w$i)
5590                 [ $idx -ne 0 ] && continue
5591                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5592                 break
5593         done
5594         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5595         sync
5596         $LCTL get_param $proc_osc0/cur_dirty_bytes
5597         $LCTL get_param $proc_osc0/cur_grant_bytes
5598
5599         # create as much dirty pages as we can while not to trigger the actual
5600         # RPCs directly. but depends on the env, VFS may trigger flush during this
5601         # period, hopefully we are good.
5602         for ((i=0; i<$warmup_files; i++)); do
5603                 idx=$($LFS getstripe -i $TDIR/w$i)
5604                 [ $idx -ne 0 ] && continue
5605                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5606         done
5607         $LCTL get_param $proc_osc0/cur_dirty_bytes
5608         $LCTL get_param $proc_osc0/cur_grant_bytes
5609
5610         # perform the real test
5611         $LCTL set_param $proc_osc0/rpc_stats 0
5612         for ((;i<$files; i++)); do
5613                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5614                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5615         done
5616         sync
5617         $LCTL get_param $proc_osc0/rpc_stats
5618
5619         local percent=0
5620         local have_ppr=false
5621         $LCTL get_param $proc_osc0/rpc_stats |
5622                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5623                         # skip lines until we are at the RPC histogram data
5624                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5625                         $have_ppr || continue
5626
5627                         # we only want the percent stat for < 16 pages
5628                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5629
5630                         percent=$((percent + WPCT))
5631                         if [[ $percent -gt 15 ]]; then
5632                                 error "less than 16-pages write RPCs" \
5633                                       "$percent% > 15%"
5634                                 break
5635                         fi
5636                 done
5637         rm -rf $TDIR
5638 }
5639 run_test 42e "verify sub-RPC writes are not done synchronously"
5640
5641 test_43A() { # was test_43
5642         test_mkdir $DIR/$tdir
5643         cp -p /bin/ls $DIR/$tdir/$tfile
5644         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5645         pid=$!
5646         # give multiop a chance to open
5647         sleep 1
5648
5649         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5650         kill -USR1 $pid
5651         # Wait for multiop to exit
5652         wait $pid
5653 }
5654 run_test 43A "execution of file opened for write should return -ETXTBSY"
5655
5656 test_43a() {
5657         test_mkdir $DIR/$tdir
5658         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5659         $DIR/$tdir/sleep 60 &
5660         SLEEP_PID=$!
5661         # Make sure exec of $tdir/sleep wins race with truncate
5662         sleep 1
5663         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5664         kill $SLEEP_PID
5665 }
5666 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5667
5668 test_43b() {
5669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5670
5671         test_mkdir $DIR/$tdir
5672         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5673         $DIR/$tdir/sleep 60 &
5674         SLEEP_PID=$!
5675         # Make sure exec of $tdir/sleep wins race with truncate
5676         sleep 1
5677         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5678         kill $SLEEP_PID
5679 }
5680 run_test 43b "truncate of file being executed should return -ETXTBSY"
5681
5682 test_43c() {
5683         local testdir="$DIR/$tdir"
5684         test_mkdir $testdir
5685         cp $SHELL $testdir/
5686         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5687                 ( cd $testdir && md5sum -c )
5688 }
5689 run_test 43c "md5sum of copy into lustre"
5690
5691 test_44A() { # was test_44
5692         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5693
5694         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5695         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5696 }
5697 run_test 44A "zero length read from a sparse stripe"
5698
5699 test_44a() {
5700         local nstripe=$($LFS getstripe -c -d $DIR)
5701         [ -z "$nstripe" ] && skip "can't get stripe info"
5702         [[ $nstripe -gt $OSTCOUNT ]] &&
5703                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5704
5705         local stride=$($LFS getstripe -S -d $DIR)
5706         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5707                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5708         fi
5709
5710         OFFSETS="0 $((stride/2)) $((stride-1))"
5711         for offset in $OFFSETS; do
5712                 for i in $(seq 0 $((nstripe-1))); do
5713                         local GLOBALOFFSETS=""
5714                         # size in Bytes
5715                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5716                         local myfn=$DIR/d44a-$size
5717                         echo "--------writing $myfn at $size"
5718                         ll_sparseness_write $myfn $size ||
5719                                 error "ll_sparseness_write"
5720                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5721                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5722                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5723
5724                         for j in $(seq 0 $((nstripe-1))); do
5725                                 # size in Bytes
5726                                 size=$((((j + $nstripe )*$stride + $offset)))
5727                                 ll_sparseness_write $myfn $size ||
5728                                         error "ll_sparseness_write"
5729                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5730                         done
5731                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5732                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5733                         rm -f $myfn
5734                 done
5735         done
5736 }
5737 run_test 44a "test sparse pwrite ==============================="
5738
5739 dirty_osc_total() {
5740         tot=0
5741         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5742                 tot=$(($tot + $d))
5743         done
5744         echo $tot
5745 }
5746 do_dirty_record() {
5747         before=`dirty_osc_total`
5748         echo executing "\"$*\""
5749         eval $*
5750         after=`dirty_osc_total`
5751         echo before $before, after $after
5752 }
5753 test_45() {
5754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5755
5756         f="$DIR/f45"
5757         # Obtain grants from OST if it supports it
5758         echo blah > ${f}_grant
5759         stop_writeback
5760         sync
5761         do_dirty_record "echo blah > $f"
5762         [[ $before -eq $after ]] && error "write wasn't cached"
5763         do_dirty_record "> $f"
5764         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5765         do_dirty_record "echo blah > $f"
5766         [[ $before -eq $after ]] && error "write wasn't cached"
5767         do_dirty_record "sync"
5768         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5769         do_dirty_record "echo blah > $f"
5770         [[ $before -eq $after ]] && error "write wasn't cached"
5771         do_dirty_record "cancel_lru_locks osc"
5772         [[ $before -gt $after ]] ||
5773                 error "lock cancellation didn't lower dirty count"
5774         start_writeback
5775 }
5776 run_test 45 "osc io page accounting ============================"
5777
5778 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5779 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5780 # objects offset and an assert hit when an rpc was built with 1023's mapped
5781 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5782 test_46() {
5783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5784
5785         f="$DIR/f46"
5786         stop_writeback
5787         sync
5788         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5789         sync
5790         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5791         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5792         sync
5793         start_writeback
5794 }
5795 run_test 46 "dirtying a previously written page ================"
5796
5797 # test_47 is removed "Device nodes check" is moved to test_28
5798
5799 test_48a() { # bug 2399
5800         [ "$mds1_FSTYPE" = "zfs" ] &&
5801         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5802                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5803
5804         test_mkdir $DIR/$tdir
5805         cd $DIR/$tdir
5806         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5807         test_mkdir $DIR/$tdir
5808         touch foo || error "'touch foo' failed after recreating cwd"
5809         test_mkdir bar
5810         touch .foo || error "'touch .foo' failed after recreating cwd"
5811         test_mkdir .bar
5812         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5813         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5814         cd . || error "'cd .' failed after recreating cwd"
5815         mkdir . && error "'mkdir .' worked after recreating cwd"
5816         rmdir . && error "'rmdir .' worked after recreating cwd"
5817         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5818         cd .. || error "'cd ..' failed after recreating cwd"
5819 }
5820 run_test 48a "Access renamed working dir (should return errors)="
5821
5822 test_48b() { # bug 2399
5823         rm -rf $DIR/$tdir
5824         test_mkdir $DIR/$tdir
5825         cd $DIR/$tdir
5826         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5827         touch foo && error "'touch foo' worked after removing cwd"
5828         mkdir foo && error "'mkdir foo' worked after removing cwd"
5829         touch .foo && error "'touch .foo' worked after removing cwd"
5830         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5831         ls . > /dev/null && error "'ls .' worked after removing cwd"
5832         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5833         mkdir . && error "'mkdir .' worked after removing cwd"
5834         rmdir . && error "'rmdir .' worked after removing cwd"
5835         ln -s . foo && error "'ln -s .' worked after removing cwd"
5836         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5837 }
5838 run_test 48b "Access removed working dir (should return errors)="
5839
5840 test_48c() { # bug 2350
5841         #lctl set_param debug=-1
5842         #set -vx
5843         rm -rf $DIR/$tdir
5844         test_mkdir -p $DIR/$tdir/dir
5845         cd $DIR/$tdir/dir
5846         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5847         $TRACE touch foo && error "touch foo worked after removing cwd"
5848         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5849         touch .foo && error "touch .foo worked after removing cwd"
5850         mkdir .foo && error "mkdir .foo worked after removing cwd"
5851         $TRACE ls . && error "'ls .' worked after removing cwd"
5852         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5853         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5854         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5855         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5856         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5857 }
5858 run_test 48c "Access removed working subdir (should return errors)"
5859
5860 test_48d() { # bug 2350
5861         #lctl set_param debug=-1
5862         #set -vx
5863         rm -rf $DIR/$tdir
5864         test_mkdir -p $DIR/$tdir/dir
5865         cd $DIR/$tdir/dir
5866         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5867         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5868         $TRACE touch foo && error "'touch foo' worked after removing parent"
5869         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5870         touch .foo && error "'touch .foo' worked after removing parent"
5871         mkdir .foo && error "mkdir .foo worked after removing parent"
5872         $TRACE ls . && error "'ls .' worked after removing parent"
5873         $TRACE ls .. && error "'ls ..' worked after removing parent"
5874         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5875         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5876         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5877         true
5878 }
5879 run_test 48d "Access removed parent subdir (should return errors)"
5880
5881 test_48e() { # bug 4134
5882         #lctl set_param debug=-1
5883         #set -vx
5884         rm -rf $DIR/$tdir
5885         test_mkdir -p $DIR/$tdir/dir
5886         cd $DIR/$tdir/dir
5887         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5888         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5889         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5890         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5891         # On a buggy kernel addition of "touch foo" after cd .. will
5892         # produce kernel oops in lookup_hash_it
5893         touch ../foo && error "'cd ..' worked after recreate parent"
5894         cd $DIR
5895         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5896 }
5897 run_test 48e "Access to recreated parent subdir (should return errors)"
5898
5899 test_48f() {
5900         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5901                 skip "need MDS >= 2.13.55"
5902         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5903         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5904                 skip "needs different host for mdt1 mdt2"
5905         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5906
5907         $LFS mkdir -i0 $DIR/$tdir
5908         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5909
5910         for d in sub1 sub2 sub3; do
5911                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5912                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5913                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5914         done
5915
5916         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5917 }
5918 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5919
5920 test_49() { # LU-1030
5921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5922         remote_ost_nodsh && skip "remote OST with nodsh"
5923
5924         # get ost1 size - $FSNAME-OST0000
5925         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5926                 awk '{ print $4 }')
5927         # write 800M at maximum
5928         [[ $ost1_size -lt 2 ]] && ost1_size=2
5929         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5930
5931         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5932         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5933         local dd_pid=$!
5934
5935         # change max_pages_per_rpc while writing the file
5936         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5937         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5938         # loop until dd process exits
5939         while ps ax -opid | grep -wq $dd_pid; do
5940                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5941                 sleep $((RANDOM % 5 + 1))
5942         done
5943         # restore original max_pages_per_rpc
5944         $LCTL set_param $osc1_mppc=$orig_mppc
5945         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5946 }
5947 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5948
5949 test_50() {
5950         # bug 1485
5951         test_mkdir $DIR/$tdir
5952         cd $DIR/$tdir
5953         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5954 }
5955 run_test 50 "special situations: /proc symlinks  ==============="
5956
5957 test_51a() {    # was test_51
5958         # bug 1516 - create an empty entry right after ".." then split dir
5959         test_mkdir -c1 $DIR/$tdir
5960         touch $DIR/$tdir/foo
5961         $MCREATE $DIR/$tdir/bar
5962         rm $DIR/$tdir/foo
5963         createmany -m $DIR/$tdir/longfile 201
5964         FNUM=202
5965         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5966                 $MCREATE $DIR/$tdir/longfile$FNUM
5967                 FNUM=$(($FNUM + 1))
5968                 echo -n "+"
5969         done
5970         echo
5971         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5972 }
5973 run_test 51a "special situations: split htree with empty entry =="
5974
5975 cleanup_print_lfs_df () {
5976         trap 0
5977         $LFS df
5978         $LFS df -i
5979 }
5980
5981 test_51b() {
5982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5983
5984         local dir=$DIR/$tdir
5985         local nrdirs=$((65536 + 100))
5986
5987         # cleanup the directory
5988         rm -fr $dir
5989
5990         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5991
5992         $LFS df
5993         $LFS df -i
5994         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5995         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5996         [[ $numfree -lt $nrdirs ]] &&
5997                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5998
5999         # need to check free space for the directories as well
6000         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6001         numfree=$(( blkfree / $(fs_inode_ksize) ))
6002         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6003
6004         trap cleanup_print_lfs_df EXIT
6005
6006         # create files
6007         createmany -d $dir/d $nrdirs || {
6008                 unlinkmany $dir/d $nrdirs
6009                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6010         }
6011
6012         # really created :
6013         nrdirs=$(ls -U $dir | wc -l)
6014
6015         # unlink all but 100 subdirectories, then check it still works
6016         local left=100
6017         local delete=$((nrdirs - left))
6018
6019         $LFS df
6020         $LFS df -i
6021
6022         # for ldiskfs the nlink count should be 1, but this is OSD specific
6023         # and so this is listed for informational purposes only
6024         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6025         unlinkmany -d $dir/d $delete ||
6026                 error "unlink of first $delete subdirs failed"
6027
6028         echo "nlink between: $(stat -c %h $dir)"
6029         local found=$(ls -U $dir | wc -l)
6030         [ $found -ne $left ] &&
6031                 error "can't find subdirs: found only $found, expected $left"
6032
6033         unlinkmany -d $dir/d $delete $left ||
6034                 error "unlink of second $left subdirs failed"
6035         # regardless of whether the backing filesystem tracks nlink accurately
6036         # or not, the nlink count shouldn't be more than "." and ".." here
6037         local after=$(stat -c %h $dir)
6038         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6039                 echo "nlink after: $after"
6040
6041         cleanup_print_lfs_df
6042 }
6043 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6044
6045 test_51d_sub() {
6046         local stripecount=$1
6047         local nfiles=$2
6048
6049         log "create files with stripecount=$stripecount"
6050         $LFS setstripe -C $stripecount $DIR/$tdir
6051         createmany -o $DIR/$tdir/t- $nfiles
6052         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6053         for ((n = 0; n < $OSTCOUNT; n++)); do
6054                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6055                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6056                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6057                             '($1 == '$n') { objs += 1 } \
6058                             END { printf("%0.0f", objs) }')
6059                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6060         done
6061         unlinkmany $DIR/$tdir/t- $nfiles
6062         rm  -f $TMP/$tfile
6063
6064         local nlast
6065         local min=4
6066         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6067
6068         # For some combinations of stripecount and OSTCOUNT current code
6069         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6070         # than others. Rather than skipping this test entirely, check that
6071         # and keep testing to ensure imbalance does not get worse. LU-15282
6072         (( (OSTCOUNT == 6 && stripecount == 4) ||
6073            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6074            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6075         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6076                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6077                         { $LFS df && $LFS df -i &&
6078                         error "stripecount=$stripecount: " \
6079                               "OST $n has fewer objects vs. OST $nlast " \
6080                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6081                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6082                         { $LFS df && $LFS df -i &&
6083                         error "stripecount=$stripecount: " \
6084                               "OST $n has more objects vs. OST $nlast " \
6085                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6086
6087                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6088                         { $LFS df && $LFS df -i &&
6089                         error "stripecount=$stripecount: " \
6090                               "OST $n has fewer #0 objects vs. OST $nlast " \
6091                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6092                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6093                         { $LFS df && $LFS df -i &&
6094                         error "stripecount=$stripecount: " \
6095                               "OST $n has more #0 objects vs. OST $nlast " \
6096                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6097         done
6098 }
6099
6100 test_51d() {
6101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6102         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6103
6104         local stripecount
6105         local per_ost=100
6106         local nfiles=$((per_ost * OSTCOUNT))
6107         local mdts=$(comma_list $(mdts_nodes))
6108         local param="osp.*.create_count"
6109         local qos_old=$(do_facet mds1 \
6110                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6111
6112         do_nodes $mdts \
6113                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6114         stack_trap "do_nodes $mdts \
6115                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6116
6117         test_mkdir $DIR/$tdir
6118         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6119         (( dirstripes > 0 )) || dirstripes=1
6120
6121         # Ensure enough OST objects precreated for tests to pass without
6122         # running out of objects.  This is an LOV r-r OST algorithm test,
6123         # not an OST object precreation test.
6124         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6125         (( old >= nfiles )) ||
6126         {
6127                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6128
6129                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6130                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6131
6132                 # trigger precreation from all MDTs for all OSTs
6133                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6134                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6135                 done
6136         }
6137
6138         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6139                 sleep 8  # allow object precreation to catch up
6140                 test_51d_sub $stripecount $nfiles
6141         done
6142 }
6143 run_test 51d "check LOV round-robin OST object distribution"
6144
6145 test_51e() {
6146         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6147                 skip_env "ldiskfs only test"
6148         fi
6149
6150         test_mkdir -c1 $DIR/$tdir
6151         test_mkdir -c1 $DIR/$tdir/d0
6152
6153         touch $DIR/$tdir/d0/foo
6154         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6155                 error "file exceed 65000 nlink limit!"
6156         unlinkmany $DIR/$tdir/d0/f- 65001
6157         return 0
6158 }
6159 run_test 51e "check file nlink limit"
6160
6161 test_51f() {
6162         test_mkdir $DIR/$tdir
6163
6164         local max=100000
6165         local ulimit_old=$(ulimit -n)
6166         local spare=20 # number of spare fd's for scripts/libraries, etc.
6167         local mdt=$($LFS getstripe -m $DIR/$tdir)
6168         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6169
6170         echo "MDT$mdt numfree=$numfree, max=$max"
6171         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6172         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6173                 while ! ulimit -n $((numfree + spare)); do
6174                         numfree=$((numfree * 3 / 4))
6175                 done
6176                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6177         else
6178                 echo "left ulimit at $ulimit_old"
6179         fi
6180
6181         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6182                 unlinkmany $DIR/$tdir/f $numfree
6183                 error "create+open $numfree files in $DIR/$tdir failed"
6184         }
6185         ulimit -n $ulimit_old
6186
6187         # if createmany exits at 120s there will be fewer than $numfree files
6188         unlinkmany $DIR/$tdir/f $numfree || true
6189 }
6190 run_test 51f "check many open files limit"
6191
6192 test_52a() {
6193         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6194         test_mkdir $DIR/$tdir
6195         touch $DIR/$tdir/foo
6196         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6197         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6198         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6199         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6200         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6201                                         error "link worked"
6202         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6203         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6204         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6205                                                      error "lsattr"
6206         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6207         cp -r $DIR/$tdir $TMP/
6208         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6209 }
6210 run_test 52a "append-only flag test (should return errors)"
6211
6212 test_52b() {
6213         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6214         test_mkdir $DIR/$tdir
6215         touch $DIR/$tdir/foo
6216         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6217         cat test > $DIR/$tdir/foo && error "cat test worked"
6218         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6219         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6220         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6221                                         error "link worked"
6222         echo foo >> $DIR/$tdir/foo && error "echo worked"
6223         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6224         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6225         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6226         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6227                                                         error "lsattr"
6228         chattr -i $DIR/$tdir/foo || error "chattr failed"
6229
6230         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6231 }
6232 run_test 52b "immutable flag test (should return errors) ======="
6233
6234 test_53() {
6235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6236         remote_mds_nodsh && skip "remote MDS with nodsh"
6237         remote_ost_nodsh && skip "remote OST with nodsh"
6238
6239         local param
6240         local param_seq
6241         local ostname
6242         local mds_last
6243         local mds_last_seq
6244         local ost_last
6245         local ost_last_seq
6246         local ost_last_id
6247         local ostnum
6248         local node
6249         local found=false
6250         local support_last_seq=true
6251
6252         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6253                 support_last_seq=false
6254
6255         # only test MDT0000
6256         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6257         local value
6258         for value in $(do_facet $SINGLEMDS \
6259                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6260                 param=$(echo ${value[0]} | cut -d "=" -f1)
6261                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6262
6263                 if $support_last_seq; then
6264                         param_seq=$(echo $param |
6265                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6266                         mds_last_seq=$(do_facet $SINGLEMDS \
6267                                        $LCTL get_param -n $param_seq)
6268                 fi
6269                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6270
6271                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6272                 node=$(facet_active_host ost$((ostnum+1)))
6273                 param="obdfilter.$ostname.last_id"
6274                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6275                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6276                         ost_last_id=$ost_last
6277
6278                         if $support_last_seq; then
6279                                 ost_last_id=$(echo $ost_last |
6280                                               awk -F':' '{print $2}' |
6281                                               sed -e "s/^0x//g")
6282                                 ost_last_seq=$(echo $ost_last |
6283                                                awk -F':' '{print $1}')
6284                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6285                         fi
6286
6287                         if [[ $ost_last_id != $mds_last ]]; then
6288                                 error "$ost_last_id != $mds_last"
6289                         else
6290                                 found=true
6291                                 break
6292                         fi
6293                 done
6294         done
6295         $found || error "can not match last_seq/last_id for $mdtosc"
6296         return 0
6297 }
6298 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6299
6300 test_54a() {
6301         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6302
6303         LANG=C $SOCKETSERVER $DIR/socket ||
6304                 error "$SOCKETSERVER $DIR/socket failed: $?"
6305         LANG=C $SOCKETCLIENT $DIR/socket ||
6306                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6307         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6308 }
6309 run_test 54a "unix domain socket test =========================="
6310
6311 test_54b() {
6312         f="$DIR/f54b"
6313         mknod $f c 1 3
6314         chmod 0666 $f
6315         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6316 }
6317 run_test 54b "char device works in lustre ======================"
6318
6319 find_loop_dev() {
6320         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6321         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6322         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6323
6324         for i in $(seq 3 7); do
6325                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6326                 LOOPDEV=$LOOPBASE$i
6327                 LOOPNUM=$i
6328                 break
6329         done
6330 }
6331
6332 cleanup_54c() {
6333         local rc=0
6334         loopdev="$DIR/loop54c"
6335
6336         trap 0
6337         $UMOUNT $DIR/$tdir || rc=$?
6338         losetup -d $loopdev || true
6339         losetup -d $LOOPDEV || true
6340         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6341         return $rc
6342 }
6343
6344 test_54c() {
6345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6346
6347         loopdev="$DIR/loop54c"
6348
6349         find_loop_dev
6350         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6351         trap cleanup_54c EXIT
6352         mknod $loopdev b 7 $LOOPNUM
6353         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6354         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6355         losetup $loopdev $DIR/$tfile ||
6356                 error "can't set up $loopdev for $DIR/$tfile"
6357         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6358         test_mkdir $DIR/$tdir
6359         mount -t ext2 $loopdev $DIR/$tdir ||
6360                 error "error mounting $loopdev on $DIR/$tdir"
6361         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6362                 error "dd write"
6363         df $DIR/$tdir
6364         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6365                 error "dd read"
6366         cleanup_54c
6367 }
6368 run_test 54c "block device works in lustre ====================="
6369
6370 test_54d() {
6371         local pipe="$DIR/$tfile.pipe"
6372         local string="aaaaaa"
6373
6374         mknod $pipe p
6375         echo -n "$string" > $pipe &
6376         local result=$(cat $pipe)
6377         [[ "$result" == "$string" ]] || error "$result != $string"
6378 }
6379 run_test 54d "fifo device works in lustre ======================"
6380
6381 test_54e() {
6382         f="$DIR/f54e"
6383         string="aaaaaa"
6384         cp -aL /dev/console $f
6385         echo $string > $f || error "echo $string to $f failed"
6386 }
6387 run_test 54e "console/tty device works in lustre ======================"
6388
6389 test_55a() {
6390         local dev_path="/sys/kernel/debug/lustre/devices"
6391
6392         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6393
6394         # This must be run in iteractive mode, since attach and setup
6395         # are stateful
6396         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6397                 attach obd_test obd_name obd_uuid
6398                 setup obd_test
6399         EOF"
6400
6401         echo "Devices:"
6402         cat "$dev_path" | tail -n 10
6403
6404         $LCTL --device "obd_name" cleanup
6405         $LCTL --device "obd_name" detach
6406
6407         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6408                 error "OBD unit test failed"
6409
6410         rmmod -v obd_test ||
6411                 error "rmmod failed (may trigger a failure in a later test)"
6412 }
6413 run_test 55a "OBD device life cycle unit tests"
6414
6415 test_55b() {
6416         local dev_path="/sys/kernel/debug/lustre/devices"
6417         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6418
6419         # Set up a large number of devices, using the number
6420         # that can be set up in about a minute (based on prior
6421         # testing). We don't want to run this test forever.
6422         local num_dev_to_create="$(( 24000 - $dev_count))"
6423
6424         load_module obdclass/obd_test || error "load_module failed"
6425
6426         local start=$SECONDS
6427
6428         # This must be run in iteractive mode, since attach and setup
6429         # are stateful
6430         for ((i = 1; i <= num_dev_to_create; i++)); do
6431                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6432                 echo "setup obd_test_$i"
6433         done | $LCTL || error "OBD device creation failed"
6434
6435         echo "Load time: $((SECONDS - start))"
6436         echo "Devices:"
6437         cat "$dev_path" | tail -n 10
6438
6439         for ((i = 1; i <= num_dev_to_create; i++)); do
6440                 echo "--device obd_name_$i cleanup"
6441                 echo "--device obd_name_$i detach"
6442         done | $LCTL || error "OBD device cleanup failed"
6443
6444         echo "Unload time: $((SECONDS - start))"
6445
6446         rmmod -v obd_test ||
6447                 error "rmmod failed (may trigger a failure in a later test)"
6448 }
6449 run_test 55b "Load and unload max OBD devices"
6450
6451 test_56a() {
6452         local numfiles=3
6453         local numdirs=2
6454         local dir=$DIR/$tdir
6455
6456         rm -rf $dir
6457         test_mkdir -p $dir/dir
6458         for i in $(seq $numfiles); do
6459                 touch $dir/file$i
6460                 touch $dir/dir/file$i
6461         done
6462
6463         local numcomp=$($LFS getstripe --component-count $dir)
6464
6465         [[ $numcomp == 0 ]] && numcomp=1
6466
6467         # test lfs getstripe with --recursive
6468         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6469
6470         [[ $filenum -eq $((numfiles * 2)) ]] ||
6471                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6472         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6473         [[ $filenum -eq $numfiles ]] ||
6474                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6475         echo "$LFS getstripe showed obdidx or l_ost_idx"
6476
6477         # test lfs getstripe with file instead of dir
6478         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6479         [[ $filenum -eq 1 ]] ||
6480                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6481         echo "$LFS getstripe file1 passed"
6482
6483         #test lfs getstripe with --verbose
6484         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6485         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6486                 error "$LFS getstripe --verbose $dir: "\
6487                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6488         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6489                 error "$LFS getstripe $dir: showed lmm_magic"
6490
6491         #test lfs getstripe with -v prints lmm_fid
6492         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6493         local countfids=$((numdirs + numfiles * numcomp))
6494         [[ $filenum -eq $countfids ]] ||
6495                 error "$LFS getstripe -v $dir: "\
6496                       "got $filenum want $countfids lmm_fid"
6497         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6498                 error "$LFS getstripe $dir: showed lmm_fid by default"
6499         echo "$LFS getstripe --verbose passed"
6500
6501         #check for FID information
6502         local fid1=$($LFS getstripe --fid $dir/file1)
6503         local fid2=$($LFS getstripe --verbose $dir/file1 |
6504                      awk '/lmm_fid: / { print $2; exit; }')
6505         local fid3=$($LFS path2fid $dir/file1)
6506
6507         [ "$fid1" != "$fid2" ] &&
6508                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6509         [ "$fid1" != "$fid3" ] &&
6510                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6511         echo "$LFS getstripe --fid passed"
6512
6513         #test lfs getstripe with --obd
6514         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6515                 error "$LFS getstripe --obd wrong_uuid: should return error"
6516
6517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6518
6519         local ostidx=1
6520         local obduuid=$(ostuuid_from_index $ostidx)
6521         local found=$($LFS getstripe -r --obd $obduuid $dir |
6522                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6523
6524         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6525         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6526                 ((filenum--))
6527         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6528                 ((filenum--))
6529
6530         [[ $found -eq $filenum ]] ||
6531                 error "$LFS getstripe --obd: found $found expect $filenum"
6532         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6533                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6534                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6535                 error "$LFS getstripe --obd: should not show file on other obd"
6536         echo "$LFS getstripe --obd passed"
6537 }
6538 run_test 56a "check $LFS getstripe"
6539
6540 test_56b() {
6541         local dir=$DIR/$tdir
6542         local numdirs=3
6543
6544         test_mkdir $dir
6545         for i in $(seq $numdirs); do
6546                 test_mkdir $dir/dir$i
6547         done
6548
6549         # test lfs getdirstripe default mode is non-recursion, which is
6550         # different from lfs getstripe
6551         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6552
6553         [[ $dircnt -eq 1 ]] ||
6554                 error "$LFS getdirstripe: found $dircnt, not 1"
6555         dircnt=$($LFS getdirstripe --recursive $dir |
6556                 grep -c lmv_stripe_count)
6557         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6558                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6559 }
6560 run_test 56b "check $LFS getdirstripe"
6561
6562 test_56bb() {
6563         verify_yaml_available || skip_env "YAML verification not installed"
6564         local output_file=$DIR/$tfile.out
6565
6566         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6567
6568         cat $output_file
6569         cat $output_file | verify_yaml || error "layout is not valid YAML"
6570 }
6571 run_test 56bb "check $LFS getdirstripe layout is YAML"
6572
6573 test_56c() {
6574         remote_ost_nodsh && skip "remote OST with nodsh"
6575
6576         local ost_idx=0
6577         local ost_name=$(ostname_from_index $ost_idx)
6578         local old_status=$(ost_dev_status $ost_idx)
6579         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6580
6581         [[ -z "$old_status" ]] ||
6582                 skip_env "OST $ost_name is in $old_status status"
6583
6584         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6585         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6586                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6587         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6588                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6589                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6590         fi
6591
6592         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6593                 error "$LFS df -v showing inactive devices"
6594         sleep_maxage
6595
6596         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6597
6598         [[ "$new_status" =~ "D" ]] ||
6599                 error "$ost_name status is '$new_status', missing 'D'"
6600         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6601                 [[ "$new_status" =~ "N" ]] ||
6602                         error "$ost_name status is '$new_status', missing 'N'"
6603         fi
6604         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6605                 [[ "$new_status" =~ "f" ]] ||
6606                         error "$ost_name status is '$new_status', missing 'f'"
6607         fi
6608
6609         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6610         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6611                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6612         [[ -z "$p" ]] && restore_lustre_params < $p || true
6613         sleep_maxage
6614
6615         new_status=$(ost_dev_status $ost_idx)
6616         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6617                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6618         # can't check 'f' as devices may actually be on flash
6619 }
6620 run_test 56c "check 'lfs df' showing device status"
6621
6622 test_56d() {
6623         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6624         local osts=$($LFS df -v $MOUNT | grep -c OST)
6625
6626         $LFS df $MOUNT
6627
6628         (( mdts == MDSCOUNT )) ||
6629                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6630         (( osts == OSTCOUNT )) ||
6631                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6632 }
6633 run_test 56d "'lfs df -v' prints only configured devices"
6634
6635 test_56e() {
6636         err_enoent=2 # No such file or directory
6637         err_eopnotsupp=95 # Operation not supported
6638
6639         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6640         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6641
6642         # Check for handling of path not exists
6643         output=$($LFS df $enoent_mnt 2>&1)
6644         ret=$?
6645
6646         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6647         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6648                 error "expect failure $err_enoent, not $ret"
6649
6650         # Check for handling of non-Lustre FS
6651         output=$($LFS df $notsup_mnt)
6652         ret=$?
6653
6654         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6655         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6656                 error "expect success $err_eopnotsupp, not $ret"
6657
6658         # Check for multiple LustreFS argument
6659         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6660         ret=$?
6661
6662         [[ $output -eq 3 && $ret -eq 0 ]] ||
6663                 error "expect success 3, not $output, rc = $ret"
6664
6665         # Check for correct non-Lustre FS handling among multiple
6666         # LustreFS argument
6667         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6668                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6669         ret=$?
6670
6671         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6672                 error "expect success 2, not $output, rc = $ret"
6673 }
6674 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6675
6676 NUMFILES=3
6677 NUMDIRS=3
6678 setup_56() {
6679         local local_tdir="$1"
6680         local local_numfiles="$2"
6681         local local_numdirs="$3"
6682         local dir_params="$4"
6683         local dir_stripe_params="$5"
6684
6685         if [ ! -d "$local_tdir" ] ; then
6686                 test_mkdir -p $dir_stripe_params $local_tdir
6687                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6688                 for i in $(seq $local_numfiles) ; do
6689                         touch $local_tdir/file$i
6690                 done
6691                 for i in $(seq $local_numdirs) ; do
6692                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6693                         for j in $(seq $local_numfiles) ; do
6694                                 touch $local_tdir/dir$i/file$j
6695                         done
6696                 done
6697         fi
6698 }
6699
6700 setup_56_special() {
6701         local local_tdir=$1
6702         local local_numfiles=$2
6703         local local_numdirs=$3
6704
6705         setup_56 $local_tdir $local_numfiles $local_numdirs
6706
6707         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6708                 for i in $(seq $local_numfiles) ; do
6709                         mknod $local_tdir/loop${i}b b 7 $i
6710                         mknod $local_tdir/null${i}c c 1 3
6711                         ln -s $local_tdir/file1 $local_tdir/link${i}
6712                 done
6713                 for i in $(seq $local_numdirs) ; do
6714                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6715                         mknod $local_tdir/dir$i/null${i}c c 1 3
6716                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6717                 done
6718         fi
6719 }
6720
6721 test_56g() {
6722         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6723         local expected=$(($NUMDIRS + 2))
6724
6725         setup_56 $dir $NUMFILES $NUMDIRS
6726
6727         # test lfs find with -name
6728         for i in $(seq $NUMFILES) ; do
6729                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6730
6731                 [ $nums -eq $expected ] ||
6732                         error "lfs find -name '*$i' $dir wrong: "\
6733                               "found $nums, expected $expected"
6734         done
6735 }
6736 run_test 56g "check lfs find -name"
6737
6738 test_56h() {
6739         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6740         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6741
6742         setup_56 $dir $NUMFILES $NUMDIRS
6743
6744         # test lfs find with ! -name
6745         for i in $(seq $NUMFILES) ; do
6746                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6747
6748                 [ $nums -eq $expected ] ||
6749                         error "lfs find ! -name '*$i' $dir wrong: "\
6750                               "found $nums, expected $expected"
6751         done
6752 }
6753 run_test 56h "check lfs find ! -name"
6754
6755 test_56i() {
6756         local dir=$DIR/$tdir
6757
6758         test_mkdir $dir
6759
6760         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6761         local out=$($cmd)
6762
6763         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6764 }
6765 run_test 56i "check 'lfs find -ost UUID' skips directories"
6766
6767 test_56j() {
6768         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6769
6770         setup_56_special $dir $NUMFILES $NUMDIRS
6771
6772         local expected=$((NUMDIRS + 1))
6773         local cmd="$LFS find -type d $dir"
6774         local nums=$($cmd | wc -l)
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56j "check lfs find -type d"
6780
6781 test_56k() {
6782         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6783
6784         setup_56_special $dir $NUMFILES $NUMDIRS
6785
6786         local expected=$(((NUMDIRS + 1) * NUMFILES))
6787         local cmd="$LFS find -type f $dir"
6788         local nums=$($cmd | wc -l)
6789
6790         [ $nums -eq $expected ] ||
6791                 error "'$cmd' wrong: found $nums, expected $expected"
6792 }
6793 run_test 56k "check lfs find -type f"
6794
6795 test_56l() {
6796         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6797
6798         setup_56_special $dir $NUMFILES $NUMDIRS
6799
6800         local expected=$((NUMDIRS + NUMFILES))
6801         local cmd="$LFS find -type b $dir"
6802         local nums=$($cmd | wc -l)
6803
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806 }
6807 run_test 56l "check lfs find -type b"
6808
6809 test_56m() {
6810         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6811
6812         setup_56_special $dir $NUMFILES $NUMDIRS
6813
6814         local expected=$((NUMDIRS + NUMFILES))
6815         local cmd="$LFS find -type c $dir"
6816         local nums=$($cmd | wc -l)
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819 }
6820 run_test 56m "check lfs find -type c"
6821
6822 test_56n() {
6823         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6824         setup_56_special $dir $NUMFILES $NUMDIRS
6825
6826         local expected=$((NUMDIRS + NUMFILES))
6827         local cmd="$LFS find -type l $dir"
6828         local nums=$($cmd | wc -l)
6829
6830         [ $nums -eq $expected ] ||
6831                 error "'$cmd' wrong: found $nums, expected $expected"
6832 }
6833 run_test 56n "check lfs find -type l"
6834
6835 test_56o() {
6836         local dir=$DIR/$tdir
6837
6838         setup_56 $dir $NUMFILES $NUMDIRS
6839         utime $dir/file1 > /dev/null || error "utime (1)"
6840         utime $dir/file2 > /dev/null || error "utime (2)"
6841         utime $dir/dir1 > /dev/null || error "utime (3)"
6842         utime $dir/dir2 > /dev/null || error "utime (4)"
6843         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6844         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6845
6846         local expected=4
6847         local nums=$($LFS find -mtime +0 $dir | wc -l)
6848
6849         [ $nums -eq $expected ] ||
6850                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6851
6852         expected=12
6853         cmd="$LFS find -mtime 0 $dir"
6854         nums=$($cmd | wc -l)
6855         [ $nums -eq $expected ] ||
6856                 error "'$cmd' wrong: found $nums, expected $expected"
6857 }
6858 run_test 56o "check lfs find -mtime for old files"
6859
6860 test_56ob() {
6861         local dir=$DIR/$tdir
6862         local expected=1
6863         local count=0
6864
6865         # just to make sure there is something that won't be found
6866         test_mkdir $dir
6867         touch $dir/$tfile.now
6868
6869         for age in year week day hour min; do
6870                 count=$((count + 1))
6871
6872                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6873                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6874                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6875
6876                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6877                 local nums=$($cmd | wc -l)
6878                 [ $nums -eq $expected ] ||
6879                         error "'$cmd' wrong: found $nums, expected $expected"
6880
6881                 cmd="$LFS find $dir -atime $count${age:0:1}"
6882                 nums=$($cmd | wc -l)
6883                 [ $nums -eq $expected ] ||
6884                         error "'$cmd' wrong: found $nums, expected $expected"
6885         done
6886
6887         sleep 2
6888         cmd="$LFS find $dir -ctime +1s -type f"
6889         nums=$($cmd | wc -l)
6890         (( $nums == $count * 2 + 1)) ||
6891                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6892 }
6893 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6894
6895 test_newerXY_base() {
6896         local x=$1
6897         local y=$2
6898         local dir=$DIR/$tdir
6899         local ref
6900         local negref
6901
6902         if [ $y == "t" ]; then
6903                 if [ $x == "b" ]; then
6904                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6905                 else
6906                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6907                 fi
6908         else
6909                 ref=$DIR/$tfile.newer.$x$y
6910                 touch $ref || error "touch $ref failed"
6911         fi
6912
6913         echo "before = $ref"
6914         sleep 2
6915         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6916         sleep 2
6917         if [ $y == "t" ]; then
6918                 if [ $x == "b" ]; then
6919                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6920                 else
6921                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6922                 fi
6923         else
6924                 negref=$DIR/$tfile.negnewer.$x$y
6925                 touch $negref || error "touch $negref failed"
6926         fi
6927
6928         echo "after = $negref"
6929         local cmd="$LFS find $dir -newer$x$y $ref"
6930         local nums=$(eval $cmd | wc -l)
6931         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6932
6933         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6934                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6935
6936         cmd="$LFS find $dir ! -newer$x$y $negref"
6937         nums=$(eval $cmd | wc -l)
6938         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6939                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6940
6941         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6942         nums=$(eval $cmd | wc -l)
6943         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6944                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6945
6946         rm -rf $DIR/*
6947 }
6948
6949 test_56oc() {
6950         test_newerXY_base "a" "a"
6951         test_newerXY_base "a" "m"
6952         test_newerXY_base "a" "c"
6953         test_newerXY_base "m" "a"
6954         test_newerXY_base "m" "m"
6955         test_newerXY_base "m" "c"
6956         test_newerXY_base "c" "a"
6957         test_newerXY_base "c" "m"
6958         test_newerXY_base "c" "c"
6959
6960         test_newerXY_base "a" "t"
6961         test_newerXY_base "m" "t"
6962         test_newerXY_base "c" "t"
6963
6964         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6965            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6966                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6967
6968         test_newerXY_base "b" "b"
6969         test_newerXY_base "b" "t"
6970 }
6971 run_test 56oc "check lfs find -newerXY work"
6972
6973 test_56od() {
6974         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6975                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6976
6977         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6978                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6979
6980         local dir=$DIR/$tdir
6981         local ref=$DIR/$tfile.ref
6982         local negref=$DIR/$tfile.negref
6983
6984         mkdir $dir || error "mkdir $dir failed"
6985         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6986         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6987         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6988         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6989         touch $ref || error "touch $ref failed"
6990         # sleep 3 seconds at least
6991         sleep 3
6992
6993         local before=$(do_facet mds1 date +%s)
6994         local skew=$(($(date +%s) - before + 1))
6995
6996         if (( skew < 0 && skew > -5 )); then
6997                 sleep $((0 - skew + 1))
6998                 skew=0
6999         fi
7000
7001         # Set the dir stripe params to limit files all on MDT0,
7002         # otherwise we need to calc the max clock skew between
7003         # the client and MDTs.
7004         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7005         sleep 2
7006         touch $negref || error "touch $negref failed"
7007
7008         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7009         local nums=$($cmd | wc -l)
7010         local expected=$(((NUMFILES + 1) * NUMDIRS))
7011
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014
7015         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7016         nums=$($cmd | wc -l)
7017         expected=$((NUMFILES + 1))
7018         [ $nums -eq $expected ] ||
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020
7021         [ $skew -lt 0 ] && return
7022
7023         local after=$(do_facet mds1 date +%s)
7024         local age=$((after - before + 1 + skew))
7025
7026         cmd="$LFS find $dir -btime -${age}s -type f"
7027         nums=$($cmd | wc -l)
7028         expected=$(((NUMFILES + 1) * NUMDIRS))
7029
7030         echo "Clock skew between client and server: $skew, age:$age"
7031         [ $nums -eq $expected ] ||
7032                 error "'$cmd' wrong: found $nums, expected $expected"
7033
7034         expected=$(($NUMDIRS + 1))
7035         cmd="$LFS find $dir -btime -${age}s -type d"
7036         nums=$($cmd | wc -l)
7037         [ $nums -eq $expected ] ||
7038                 error "'$cmd' wrong: found $nums, expected $expected"
7039         rm -f $ref $negref || error "Failed to remove $ref $negref"
7040 }
7041 run_test 56od "check lfs find -btime with units"
7042
7043 test_56p() {
7044         [ $RUNAS_ID -eq $UID ] &&
7045                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7046
7047         local dir=$DIR/$tdir
7048
7049         setup_56 $dir $NUMFILES $NUMDIRS
7050         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7051
7052         local expected=$NUMFILES
7053         local cmd="$LFS find -uid $RUNAS_ID $dir"
7054         local nums=$($cmd | wc -l)
7055
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058
7059         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7060         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] ||
7063                 error "'$cmd' wrong: found $nums, expected $expected"
7064 }
7065 run_test 56p "check lfs find -uid and ! -uid"
7066
7067 test_56q() {
7068         [ $RUNAS_ID -eq $UID ] &&
7069                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7070
7071         local dir=$DIR/$tdir
7072
7073         setup_56 $dir $NUMFILES $NUMDIRS
7074         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7075
7076         local expected=$NUMFILES
7077         local cmd="$LFS find -gid $RUNAS_GID $dir"
7078         local nums=$($cmd | wc -l)
7079
7080         [ $nums -eq $expected ] ||
7081                 error "'$cmd' wrong: found $nums, expected $expected"
7082
7083         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7084         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] ||
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088 }
7089 run_test 56q "check lfs find -gid and ! -gid"
7090
7091 test_56r() {
7092         local dir=$DIR/$tdir
7093
7094         setup_56 $dir $NUMFILES $NUMDIRS
7095
7096         local expected=12
7097         local cmd="$LFS find -size 0 -type f -lazy $dir"
7098         local nums=$($cmd | wc -l)
7099
7100         [ $nums -eq $expected ] ||
7101                 error "'$cmd' wrong: found $nums, expected $expected"
7102         cmd="$LFS find -size 0 -type f $dir"
7103         nums=$($cmd | wc -l)
7104         [ $nums -eq $expected ] ||
7105                 error "'$cmd' wrong: found $nums, expected $expected"
7106
7107         expected=0
7108         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7109         nums=$($cmd | wc -l)
7110         [ $nums -eq $expected ] ||
7111                 error "'$cmd' wrong: found $nums, expected $expected"
7112         cmd="$LFS find ! -size 0 -type f $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116
7117         echo "test" > $dir/$tfile
7118         echo "test2" > $dir/$tfile.2 && sync
7119         expected=1
7120         cmd="$LFS find -size 5c -type f -lazy $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124         cmd="$LFS find -size 5c -type f $dir"
7125         nums=$($cmd | wc -l)
7126         [ $nums -eq $expected ] ||
7127                 error "'$cmd' wrong: found $nums, expected $expected"
7128
7129         expected=1
7130         cmd="$LFS find -size +5c -type f -lazy $dir"
7131         nums=$($cmd | wc -l)
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134         cmd="$LFS find -size +5c -type f $dir"
7135         nums=$($cmd | wc -l)
7136         [ $nums -eq $expected ] ||
7137                 error "'$cmd' wrong: found $nums, expected $expected"
7138
7139         expected=2
7140         cmd="$LFS find -size +0 -type f -lazy $dir"
7141         nums=$($cmd | wc -l)
7142         [ $nums -eq $expected ] ||
7143                 error "'$cmd' wrong: found $nums, expected $expected"
7144         cmd="$LFS find -size +0 -type f $dir"
7145         nums=$($cmd | wc -l)
7146         [ $nums -eq $expected ] ||
7147                 error "'$cmd' wrong: found $nums, expected $expected"
7148
7149         expected=2
7150         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7151         nums=$($cmd | wc -l)
7152         [ $nums -eq $expected ] ||
7153                 error "'$cmd' wrong: found $nums, expected $expected"
7154         cmd="$LFS find ! -size -5c -type f $dir"
7155         nums=$($cmd | wc -l)
7156         [ $nums -eq $expected ] ||
7157                 error "'$cmd' wrong: found $nums, expected $expected"
7158
7159         expected=12
7160         cmd="$LFS find -size -5c -type f -lazy $dir"
7161         nums=$($cmd | wc -l)
7162         [ $nums -eq $expected ] ||
7163                 error "'$cmd' wrong: found $nums, expected $expected"
7164         cmd="$LFS find -size -5c -type f $dir"
7165         nums=$($cmd | wc -l)
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168 }
7169 run_test 56r "check lfs find -size works"
7170
7171 test_56ra_sub() {
7172         local expected=$1
7173         local glimpses=$2
7174         local cmd="$3"
7175
7176         cancel_lru_locks $OSC
7177
7178         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7179         local nums=$($cmd | wc -l)
7180
7181         [ $nums -eq $expected ] ||
7182                 error "'$cmd' wrong: found $nums, expected $expected"
7183
7184         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7185
7186         if (( rpcs_before + glimpses != rpcs_after )); then
7187                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7188                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7189
7190                 if [[ $glimpses == 0 ]]; then
7191                         error "'$cmd' should not send glimpse RPCs to OST"
7192                 else
7193                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7194                 fi
7195         fi
7196 }
7197
7198 test_56ra() {
7199         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7200                 skip "MDS < 2.12.58 doesn't return LSOM data"
7201         local dir=$DIR/$tdir
7202         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7203
7204         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7205
7206         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7207         $LCTL set_param -n llite.*.statahead_agl=0
7208         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7209
7210         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7211         # open and close all files to ensure LSOM is updated
7212         cancel_lru_locks $OSC
7213         find $dir -type f | xargs cat > /dev/null
7214
7215         #   expect_found  glimpse_rpcs  command_to_run
7216         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7217         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7218         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7219         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7220
7221         echo "test" > $dir/$tfile
7222         echo "test2" > $dir/$tfile.2 && sync
7223         cancel_lru_locks $OSC
7224         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7225
7226         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7227         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7228         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7229         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7230
7231         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7232         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7233         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7234         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7235         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7236         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7237 }
7238 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7239
7240 test_56rb() {
7241         local dir=$DIR/$tdir
7242         local tmp=$TMP/$tfile.log
7243         local mdt_idx;
7244
7245         test_mkdir -p $dir || error "failed to mkdir $dir"
7246         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7247                 error "failed to setstripe $dir/$tfile"
7248         mdt_idx=$($LFS getdirstripe -i $dir)
7249         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7250
7251         stack_trap "rm -f $tmp" EXIT
7252         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7253         ! grep -q obd_uuid $tmp ||
7254                 error "failed to find --size +100K --ost 0 $dir"
7255         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7256         ! grep -q obd_uuid $tmp ||
7257                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7258 }
7259 run_test 56rb "check lfs find --size --ost/--mdt works"
7260
7261 test_56rc() {
7262         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7263         local dir=$DIR/$tdir
7264         local found
7265
7266         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7267         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7268         (( $MDSCOUNT > 2 )) &&
7269                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7270         mkdir $dir/$tdir-{1..10}
7271         touch $dir/$tfile-{1..10}
7272
7273         found=$($LFS find $dir --mdt-count 2 | wc -l)
7274         expect=11
7275         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7276
7277         found=$($LFS find $dir -T +1 | wc -l)
7278         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7279         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7280
7281         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7282         expect=11
7283         (( $found == $expect )) || error "found $found all_char, expect $expect"
7284
7285         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7286         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7287         (( $found == $expect )) || error "found $found all_char, expect $expect"
7288 }
7289 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7290
7291 test_56rd() {
7292         local dir=$DIR/$tdir
7293
7294         test_mkdir $dir
7295         rm -f $dir/*
7296
7297         mkfifo $dir/fifo || error "failed to create fifo file"
7298         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7299                 error "should not fail even cannot get projid from pipe file"
7300         found=$($LFS find $dir -t p --printf "%y")
7301         [[ "p" == $found ]] || error "found $found, expect p"
7302
7303         mknod $dir/chardev c 1 5 ||
7304                 error "failed to create character device file"
7305         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7306                 error "should not fail even cannot get projid from chardev file"
7307         found=$($LFS find $dir -t c --printf "%y")
7308         [[ "c" == $found ]] || error "found $found, expect c"
7309
7310         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7311         (( found == 2 )) || error "unable to list all files"
7312 }
7313 run_test 56rd "check lfs find --printf special files"
7314
7315 test_56s() { # LU-611 #LU-9369
7316         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7317
7318         local dir=$DIR/$tdir
7319         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7320
7321         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7322         for i in $(seq $NUMDIRS); do
7323                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7324         done
7325
7326         local expected=$NUMDIRS
7327         local cmd="$LFS find -c $OSTCOUNT $dir"
7328         local nums=$($cmd | wc -l)
7329
7330         [ $nums -eq $expected ] || {
7331                 $LFS getstripe -R $dir
7332                 error "'$cmd' wrong: found $nums, expected $expected"
7333         }
7334
7335         expected=$((NUMDIRS + onestripe))
7336         cmd="$LFS find -stripe-count +0 -type f $dir"
7337         nums=$($cmd | wc -l)
7338         [ $nums -eq $expected ] || {
7339                 $LFS getstripe -R $dir
7340                 error "'$cmd' wrong: found $nums, expected $expected"
7341         }
7342
7343         expected=$onestripe
7344         cmd="$LFS find -stripe-count 1 -type f $dir"
7345         nums=$($cmd | wc -l)
7346         [ $nums -eq $expected ] || {
7347                 $LFS getstripe -R $dir
7348                 error "'$cmd' wrong: found $nums, expected $expected"
7349         }
7350
7351         cmd="$LFS find -stripe-count -2 -type f $dir"
7352         nums=$($cmd | wc -l)
7353         [ $nums -eq $expected ] || {
7354                 $LFS getstripe -R $dir
7355                 error "'$cmd' wrong: found $nums, expected $expected"
7356         }
7357
7358         expected=0
7359         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7360         nums=$($cmd | wc -l)
7361         [ $nums -eq $expected ] || {
7362                 $LFS getstripe -R $dir
7363                 error "'$cmd' wrong: found $nums, expected $expected"
7364         }
7365 }
7366 run_test 56s "check lfs find -stripe-count works"
7367
7368 test_56t() { # LU-611 #LU-9369
7369         local dir=$DIR/$tdir
7370
7371         setup_56 $dir 0 $NUMDIRS
7372         for i in $(seq $NUMDIRS); do
7373                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7374         done
7375
7376         local expected=$NUMDIRS
7377         local cmd="$LFS find -S 8M $dir"
7378         local nums=$($cmd | wc -l)
7379
7380         [ $nums -eq $expected ] || {
7381                 $LFS getstripe -R $dir
7382                 error "'$cmd' wrong: found $nums, expected $expected"
7383         }
7384         rm -rf $dir
7385
7386         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7387
7388         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7389
7390         expected=$(((NUMDIRS + 1) * NUMFILES))
7391         cmd="$LFS find -stripe-size 512k -type f $dir"
7392         nums=$($cmd | wc -l)
7393         [ $nums -eq $expected ] ||
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395
7396         cmd="$LFS find -stripe-size +320k -type f $dir"
7397         nums=$($cmd | wc -l)
7398         [ $nums -eq $expected ] ||
7399                 error "'$cmd' wrong: found $nums, expected $expected"
7400
7401         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7402         cmd="$LFS find -stripe-size +200k -type f $dir"
7403         nums=$($cmd | wc -l)
7404         [ $nums -eq $expected ] ||
7405                 error "'$cmd' wrong: found $nums, expected $expected"
7406
7407         cmd="$LFS find -stripe-size -640k -type f $dir"
7408         nums=$($cmd | wc -l)
7409         [ $nums -eq $expected ] ||
7410                 error "'$cmd' wrong: found $nums, expected $expected"
7411
7412         expected=4
7413         cmd="$LFS find -stripe-size 256k -type f $dir"
7414         nums=$($cmd | wc -l)
7415         [ $nums -eq $expected ] ||
7416                 error "'$cmd' wrong: found $nums, expected $expected"
7417
7418         cmd="$LFS find -stripe-size -320k -type f $dir"
7419         nums=$($cmd | wc -l)
7420         [ $nums -eq $expected ] ||
7421                 error "'$cmd' wrong: found $nums, expected $expected"
7422
7423         expected=0
7424         cmd="$LFS find -stripe-size 1024k -type f $dir"
7425         nums=$($cmd | wc -l)
7426         [ $nums -eq $expected ] ||
7427                 error "'$cmd' wrong: found $nums, expected $expected"
7428 }
7429 run_test 56t "check lfs find -stripe-size works"
7430
7431 test_56u() { # LU-611
7432         local dir=$DIR/$tdir
7433
7434         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7435
7436         if [[ $OSTCOUNT -gt 1 ]]; then
7437                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7438                 onestripe=4
7439         else
7440                 onestripe=0
7441         fi
7442
7443         local expected=$(((NUMDIRS + 1) * NUMFILES))
7444         local cmd="$LFS find -stripe-index 0 -type f $dir"
7445         local nums=$($cmd | wc -l)
7446
7447         [ $nums -eq $expected ] ||
7448                 error "'$cmd' wrong: found $nums, expected $expected"
7449
7450         expected=$onestripe
7451         cmd="$LFS find -stripe-index 1 -type f $dir"
7452         nums=$($cmd | wc -l)
7453         [ $nums -eq $expected ] ||
7454                 error "'$cmd' wrong: found $nums, expected $expected"
7455
7456         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7457         nums=$($cmd | wc -l)
7458         [ $nums -eq $expected ] ||
7459                 error "'$cmd' wrong: found $nums, expected $expected"
7460
7461         expected=0
7462         # This should produce an error and not return any files
7463         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7464         nums=$($cmd 2>/dev/null | wc -l)
7465         [ $nums -eq $expected ] ||
7466                 error "'$cmd' wrong: found $nums, expected $expected"
7467
7468         if [[ $OSTCOUNT -gt 1 ]]; then
7469                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7470                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7471                 nums=$($cmd | wc -l)
7472                 [ $nums -eq $expected ] ||
7473                         error "'$cmd' wrong: found $nums, expected $expected"
7474         fi
7475 }
7476 run_test 56u "check lfs find -stripe-index works"
7477
7478 test_56v() {
7479         local mdt_idx=0
7480         local dir=$DIR/$tdir
7481
7482         setup_56 $dir $NUMFILES $NUMDIRS
7483
7484         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7485         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7486
7487         for file in $($LFS find -m $UUID $dir); do
7488                 file_midx=$($LFS getstripe -m $file)
7489                 [ $file_midx -eq $mdt_idx ] ||
7490                         error "lfs find -m $UUID != getstripe -m $file_midx"
7491         done
7492 }
7493 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7494
7495 test_56wa() {
7496         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7498
7499         local dir=$DIR/$tdir
7500
7501         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7502         stack_trap "rm -rf $dir"
7503
7504         local stripe_size=$($LFS getstripe -S -d $dir) ||
7505                 error "$LFS getstripe -S -d $dir failed"
7506         stripe_size=${stripe_size%% *}
7507
7508         local file_size=$((stripe_size * OSTCOUNT))
7509         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7510         local required_space=$((file_num * file_size))
7511         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7512                            head -n1)
7513         (( free_space >= required_space / 1024 )) ||
7514                 skip_env "need $required_space, have $free_space kbytes"
7515
7516         local dd_bs=65536
7517         local dd_count=$((file_size / dd_bs))
7518
7519         # write data into the files
7520         local i
7521         local j
7522         local file
7523
7524         for ((i = 1; i <= NUMFILES; i++ )); do
7525                 file=$dir/file$i
7526                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7527                         error "write data into $file failed"
7528         done
7529         for ((i = 1; i <= NUMDIRS; i++ )); do
7530                 for ((j = 1; j <= NUMFILES; j++ )); do
7531                         file=$dir/dir$i/file$j
7532                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7533                                 error "write data into $file failed"
7534                 done
7535         done
7536
7537         # $LFS_MIGRATE will fail if hard link migration is unsupported
7538         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7539                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7540                         error "creating links to $dir/dir1/file1 failed"
7541         fi
7542
7543         local expected=-1
7544
7545         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7546
7547         # lfs_migrate file
7548         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7549
7550         echo "$cmd"
7551         eval $cmd || error "$cmd failed"
7552
7553         check_stripe_count $dir/file1 $expected
7554
7555         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7556                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7557                 # OST 1 if it is on OST 0. This file is small enough to
7558                 # be on only one stripe.
7559                 file=$dir/migr_1_ost
7560                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7561                         error "write data into $file failed"
7562                 local obdidx=$($LFS getstripe -i $file)
7563                 local oldmd5=$(md5sum $file)
7564                 local newobdidx=0
7565
7566                 (( obdidx != 0 )) || newobdidx=1
7567                 cmd="$LFS migrate -i $newobdidx $file"
7568                 echo $cmd
7569                 eval $cmd || error "$cmd failed"
7570
7571                 local realobdix=$($LFS getstripe -i $file)
7572                 local newmd5=$(md5sum $file)
7573
7574                 (( $newobdidx == $realobdix )) ||
7575                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7576                 [[ "$oldmd5" == "$newmd5" ]] ||
7577                         error "md5sum differ: $oldmd5, $newmd5"
7578         fi
7579
7580         # lfs_migrate dir
7581         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7582         echo "$cmd"
7583         eval $cmd || error "$cmd failed"
7584
7585         for (( j = 1; j <= NUMFILES; j++ )); do
7586                 check_stripe_count $dir/dir1/file$j $expected
7587         done
7588
7589         # lfs_migrate works with lfs find
7590         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7591              $LFS_MIGRATE -y -c $expected"
7592         echo "$cmd"
7593         eval $cmd || error "$cmd failed"
7594
7595         for (( i = 2; i <= NUMFILES; i++ )); do
7596                 check_stripe_count $dir/file$i $expected
7597         done
7598         for (( i = 2; i <= NUMDIRS; i++ )); do
7599                 for (( j = 1; j <= NUMFILES; j++ )); do
7600                         check_stripe_count $dir/dir$i/file$j $expected
7601                 done
7602         done
7603 }
7604 run_test 56wa "check lfs_migrate -c stripe_count works"
7605
7606 test_56wb() {
7607         local file1=$DIR/$tdir/file1
7608         local create_pool=false
7609         local initial_pool=$($LFS getstripe -p $DIR)
7610         local pool_list=()
7611         local pool=""
7612
7613         echo -n "Creating test dir..."
7614         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7615         echo "done."
7616
7617         echo -n "Creating test file..."
7618         touch $file1 || error "cannot create file"
7619         echo "done."
7620
7621         echo -n "Detecting existing pools..."
7622         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7623
7624         if [ ${#pool_list[@]} -gt 0 ]; then
7625                 echo "${pool_list[@]}"
7626                 for thispool in "${pool_list[@]}"; do
7627                         if [[ -z "$initial_pool" ||
7628                               "$initial_pool" != "$thispool" ]]; then
7629                                 pool="$thispool"
7630                                 echo "Using existing pool '$pool'"
7631                                 break
7632                         fi
7633                 done
7634         else
7635                 echo "none detected."
7636         fi
7637         if [ -z "$pool" ]; then
7638                 pool=${POOL:-testpool}
7639                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7640                 echo -n "Creating pool '$pool'..."
7641                 create_pool=true
7642                 pool_add $pool &> /dev/null ||
7643                         error "pool_add failed"
7644                 echo "done."
7645
7646                 echo -n "Adding target to pool..."
7647                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7648                         error "pool_add_targets failed"
7649                 echo "done."
7650         fi
7651
7652         echo -n "Setting pool using -p option..."
7653         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7654                 error "migrate failed rc = $?"
7655         echo "done."
7656
7657         echo -n "Verifying test file is in pool after migrating..."
7658         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7659                 error "file was not migrated to pool $pool"
7660         echo "done."
7661
7662         echo -n "Removing test file from pool '$pool'..."
7663         # "lfs migrate $file" won't remove the file from the pool
7664         # until some striping information is changed.
7665         $LFS migrate -c 1 $file1 &> /dev/null ||
7666                 error "cannot remove from pool"
7667         [ "$($LFS getstripe -p $file1)" ] &&
7668                 error "pool still set"
7669         echo "done."
7670
7671         echo -n "Setting pool using --pool option..."
7672         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7673                 error "migrate failed rc = $?"
7674         echo "done."
7675
7676         # Clean up
7677         rm -f $file1
7678         if $create_pool; then
7679                 destroy_test_pools 2> /dev/null ||
7680                         error "destroy test pools failed"
7681         fi
7682 }
7683 run_test 56wb "check lfs_migrate pool support"
7684
7685 test_56wc() {
7686         local file1="$DIR/$tdir/$tfile"
7687         local md5
7688         local parent_ssize
7689         local parent_scount
7690         local cur_ssize
7691         local cur_scount
7692         local orig_ssize
7693         local new_scount
7694         local cur_comp
7695
7696         echo -n "Creating test dir..."
7697         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7698         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7699                 error "cannot set stripe by '-S 1M -c 1'"
7700         echo "done"
7701
7702         echo -n "Setting initial stripe for test file..."
7703         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7704                 error "cannot set stripe"
7705         cur_ssize=$($LFS getstripe -S "$file1")
7706         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7707         echo "done."
7708
7709         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7710         stack_trap "rm -f $file1"
7711         md5="$(md5sum $file1)"
7712
7713         # File currently set to -S 512K -c 1
7714
7715         # Ensure -c and -S options are rejected when -R is set
7716         echo -n "Verifying incompatible options are detected..."
7717         $LFS_MIGRATE -R -c 1 "$file1" &&
7718                 error "incompatible -R and -c options not detected"
7719         $LFS_MIGRATE -R -S 1M "$file1" &&
7720                 error "incompatible -R and -S options not detected"
7721         $LFS_MIGRATE -R -p pool "$file1" &&
7722                 error "incompatible -R and -p options not detected"
7723         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7724                 error "incompatible -R and -E options not detected"
7725         $LFS_MIGRATE -R -A "$file1" &&
7726                 error "incompatible -R and -A options not detected"
7727         $LFS_MIGRATE -A -c 1 "$file1" &&
7728                 error "incompatible -A and -c options not detected"
7729         $LFS_MIGRATE -A -S 1M "$file1" &&
7730                 error "incompatible -A and -S options not detected"
7731         $LFS_MIGRATE -A -p pool "$file1" &&
7732                 error "incompatible -A and -p options not detected"
7733         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7734                 error "incompatible -A and -E options not detected"
7735         echo "done."
7736
7737         # Ensure unrecognized options are passed through to 'lfs migrate'
7738         echo -n "Verifying -S option is passed through to lfs migrate..."
7739         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7740         cur_ssize=$($LFS getstripe -S "$file1")
7741         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7742         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7743         echo "done."
7744
7745         # File currently set to -S 1M -c 1
7746
7747         # Ensure long options are supported
7748         echo -n "Verifying long options supported..."
7749         $LFS_MIGRATE --non-block "$file1" ||
7750                 error "long option without argument not supported"
7751         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7752                 error "long option with argument not supported"
7753         cur_ssize=$($LFS getstripe -S "$file1")
7754         (( cur_ssize == 524288 )) ||
7755                 error "migrate --stripe-size $cur_ssize != 524288"
7756         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7757         echo "done."
7758
7759         # File currently set to -S 512K -c 1
7760
7761         if (( OSTCOUNT > 1 )); then
7762                 echo -n "Verifying explicit stripe count can be set..."
7763                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7764                 cur_scount=$($LFS getstripe -c "$file1")
7765                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7766                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7767                         error "file data has changed (3)"
7768                 echo "done."
7769         fi
7770
7771         # File currently set to -S 512K -c 1 or -S 512K -c 2
7772
7773         # Ensure parent striping is used if -R is set, and no stripe
7774         # count or size is specified
7775         echo -n "Setting stripe for parent directory..."
7776         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7777                 error "cannot set stripe '-S 2M -c 1'"
7778         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7779         echo "done."
7780
7781         echo -n "Verifying restripe option uses parent stripe settings..."
7782         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7783         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7784         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7785         cur_ssize=$($LFS getstripe -S "$file1")
7786         (( cur_ssize == parent_ssize )) ||
7787                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7788         cur_scount=$($LFS getstripe -c "$file1")
7789         (( cur_scount == parent_scount )) ||
7790                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7791         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7792         echo "done."
7793
7794         # File currently set to -S 1M -c 1
7795
7796         # Ensure striping is preserved if -R is not set, and no stripe
7797         # count or size is specified
7798         echo -n "Verifying striping size preserved when not specified..."
7799         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7800         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7801                 error "cannot set stripe on parent directory"
7802         $LFS_MIGRATE "$file1" || error "migrate failed"
7803         cur_ssize=$($LFS getstripe -S "$file1")
7804         (( cur_ssize == orig_ssize )) ||
7805                 error "migrate by default $cur_ssize != $orig_ssize"
7806         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7807         echo "done."
7808
7809         # Ensure file name properly detected when final option has no argument
7810         echo -n "Verifying file name properly detected..."
7811         $LFS_MIGRATE "$file1" ||
7812                 error "file name interpreted as option argument"
7813         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7814         echo "done."
7815
7816         # Ensure PFL arguments are passed through properly
7817         echo -n "Verifying PFL options passed through..."
7818         new_scount=$(((OSTCOUNT + 1) / 2))
7819         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7820                 error "migrate PFL arguments failed"
7821         cur_comp=$($LFS getstripe --comp-count $file1)
7822         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7823         cur_scount=$($LFS getstripe --stripe-count $file1)
7824         (( cur_scount == new_scount)) ||
7825                 error "PFL stripe count $cur_scount != $new_scount"
7826         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7827         echo "done."
7828 }
7829 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7830
7831 test_56wd() {
7832         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7833
7834         local file1=$DIR/$tdir/$tfile
7835
7836         echo -n "Creating test dir..."
7837         test_mkdir $DIR/$tdir || error "cannot create dir"
7838         echo "done."
7839
7840         echo -n "Creating test file..."
7841         echo "$tfile" > $file1
7842         echo "done."
7843
7844         # Ensure 'lfs migrate' will fail by using a non-existent option,
7845         # and make sure rsync is not called to recover
7846         echo -n "Make sure --no-rsync option works..."
7847         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7848                 grep -q 'refusing to fall back to rsync' ||
7849                 error "rsync was called with --no-rsync set"
7850         echo "done."
7851
7852         # Ensure rsync is called without trying 'lfs migrate' first
7853         echo -n "Make sure --rsync option works..."
7854         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7855                 grep -q 'falling back to rsync' &&
7856                 error "lfs migrate was called with --rsync set"
7857         echo "done."
7858 }
7859 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7860
7861 test_56we() {
7862         local td=$DIR/$tdir
7863         local tf=$td/$tfile
7864
7865         test_mkdir $td || error "cannot create $td"
7866         touch $tf || error "cannot touch $tf"
7867
7868         echo -n "Make sure --non-direct|-D works..."
7869         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7870                 grep -q "lfs migrate --non-direct" ||
7871                 error "--non-direct option cannot work correctly"
7872         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7873                 grep -q "lfs migrate -D" ||
7874                 error "-D option cannot work correctly"
7875         echo "done."
7876 }
7877 run_test 56we "check lfs_migrate --non-direct|-D support"
7878
7879 test_56x() {
7880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7881         check_swap_layouts_support
7882
7883         local dir=$DIR/$tdir
7884         local ref1=/etc/passwd
7885         local file1=$dir/file1
7886
7887         test_mkdir $dir || error "creating dir $dir"
7888         $LFS setstripe -c 2 $file1
7889         cp $ref1 $file1
7890         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7891         stripe=$($LFS getstripe -c $file1)
7892         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7893         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7894
7895         # clean up
7896         rm -f $file1
7897 }
7898 run_test 56x "lfs migration support"
7899
7900 test_56xa() {
7901         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7902         check_swap_layouts_support
7903
7904         local dir=$DIR/$tdir/$testnum
7905
7906         test_mkdir -p $dir
7907
7908         local ref1=/etc/passwd
7909         local file1=$dir/file1
7910
7911         $LFS setstripe -c 2 $file1
7912         cp $ref1 $file1
7913         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7914
7915         local stripe=$($LFS getstripe -c $file1)
7916
7917         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7918         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7919
7920         # clean up
7921         rm -f $file1
7922 }
7923 run_test 56xa "lfs migration --block support"
7924
7925 check_migrate_links() {
7926         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7927         local dir="$1"
7928         local file1="$dir/file1"
7929         local begin="$2"
7930         local count="$3"
7931         local runas="$4"
7932         local total_count=$(($begin + $count - 1))
7933         local symlink_count=10
7934         local uniq_count=10
7935
7936         if [ ! -f "$file1" ]; then
7937                 echo -n "creating initial file..."
7938                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7939                         error "cannot setstripe initial file"
7940                 echo "done"
7941
7942                 echo -n "creating symlinks..."
7943                 for s in $(seq 1 $symlink_count); do
7944                         ln -s "$file1" "$dir/slink$s" ||
7945                                 error "cannot create symlinks"
7946                 done
7947                 echo "done"
7948
7949                 echo -n "creating nonlinked files..."
7950                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7951                         error "cannot create nonlinked files"
7952                 echo "done"
7953         fi
7954
7955         # create hard links
7956         if [ ! -f "$dir/file$total_count" ]; then
7957                 echo -n "creating hard links $begin:$total_count..."
7958                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7959                         /dev/null || error "cannot create hard links"
7960                 echo "done"
7961         fi
7962
7963         echo -n "checking number of hard links listed in xattrs..."
7964         local fid=$($LFS getstripe -F "$file1")
7965         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7966
7967         echo "${#paths[*]}"
7968         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7969                         skip "hard link list has unexpected size, skipping test"
7970         fi
7971         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7972                         error "link names should exceed xattrs size"
7973         fi
7974
7975         echo -n "migrating files..."
7976         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7977         local rc=$?
7978         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7979         echo "done"
7980
7981         # make sure all links have been properly migrated
7982         echo -n "verifying files..."
7983         fid=$($LFS getstripe -F "$file1") ||
7984                 error "cannot get fid for file $file1"
7985         for i in $(seq 2 $total_count); do
7986                 local fid2=$($LFS getstripe -F $dir/file$i)
7987
7988                 [ "$fid2" == "$fid" ] ||
7989                         error "migrated hard link has mismatched FID"
7990         done
7991
7992         # make sure hard links were properly detected, and migration was
7993         # performed only once for the entire link set; nonlinked files should
7994         # also be migrated
7995         local actual=$(grep -c 'done' <<< "$migrate_out")
7996         local expected=$(($uniq_count + 1))
7997
7998         [ "$actual" -eq  "$expected" ] ||
7999                 error "hard links individually migrated ($actual != $expected)"
8000
8001         # make sure the correct number of hard links are present
8002         local hardlinks=$(stat -c '%h' "$file1")
8003
8004         [ $hardlinks -eq $total_count ] ||
8005                 error "num hard links $hardlinks != $total_count"
8006         echo "done"
8007
8008         return 0
8009 }
8010
8011 test_56xb() {
8012         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8013                 skip "Need MDS version at least 2.10.55"
8014
8015         local dir="$DIR/$tdir"
8016
8017         test_mkdir "$dir" || error "cannot create dir $dir"
8018
8019         echo "testing lfs migrate mode when all links fit within xattrs"
8020         check_migrate_links "$dir" 2 99
8021
8022         echo "testing rsync mode when all links fit within xattrs"
8023         check_migrate_links --rsync "$dir" 2 99
8024
8025         echo "testing lfs migrate mode when all links do not fit within xattrs"
8026         check_migrate_links "$dir" 101 100
8027
8028         echo "testing rsync mode when all links do not fit within xattrs"
8029         check_migrate_links --rsync "$dir" 101 100
8030
8031         chown -R $RUNAS_ID $dir
8032         echo "testing non-root lfs migrate mode when not all links are in xattr"
8033         check_migrate_links "$dir" 101 100 "$RUNAS"
8034
8035         # clean up
8036         rm -rf $dir
8037 }
8038 run_test 56xb "lfs migration hard link support"
8039
8040 test_56xc() {
8041         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8042
8043         local dir="$DIR/$tdir"
8044
8045         test_mkdir "$dir" || error "cannot create dir $dir"
8046
8047         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8048         echo -n "Setting initial stripe for 20MB test file..."
8049         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8050                 error "cannot setstripe 20MB file"
8051         echo "done"
8052         echo -n "Sizing 20MB test file..."
8053         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8054         echo "done"
8055         echo -n "Verifying small file autostripe count is 1..."
8056         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8057                 error "cannot migrate 20MB file"
8058         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8059                 error "cannot get stripe for $dir/20mb"
8060         [ $stripe_count -eq 1 ] ||
8061                 error "unexpected stripe count $stripe_count for 20MB file"
8062         rm -f "$dir/20mb"
8063         echo "done"
8064
8065         # Test 2: File is small enough to fit within the available space on
8066         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8067         # have at least an additional 1KB for each desired stripe for test 3
8068         echo -n "Setting stripe for 1GB test file..."
8069         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8070         echo "done"
8071         echo -n "Sizing 1GB test file..."
8072         # File size is 1GB + 3KB
8073         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8074         echo "done"
8075
8076         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8077         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8078         if (( avail > 524288 * OSTCOUNT )); then
8079                 echo -n "Migrating 1GB file..."
8080                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8081                         error "cannot migrate 1GB file"
8082                 echo "done"
8083                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8084                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8085                         error "cannot getstripe for 1GB file"
8086                 [ $stripe_count -eq 2 ] ||
8087                         error "unexpected stripe count $stripe_count != 2"
8088                 echo "done"
8089         fi
8090
8091         # Test 3: File is too large to fit within the available space on
8092         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8093         if [ $OSTCOUNT -ge 3 ]; then
8094                 # The required available space is calculated as
8095                 # file size (1GB + 3KB) / OST count (3).
8096                 local kb_per_ost=349526
8097
8098                 echo -n "Migrating 1GB file with limit..."
8099                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8100                         error "cannot migrate 1GB file with limit"
8101                 echo "done"
8102
8103                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8104                 echo -n "Verifying 1GB autostripe count with limited space..."
8105                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8106                         error "unexpected stripe count $stripe_count (min 3)"
8107                 echo "done"
8108         fi
8109
8110         # clean up
8111         rm -rf $dir
8112 }
8113 run_test 56xc "lfs migration autostripe"
8114
8115 test_56xd() {
8116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8117
8118         local dir=$DIR/$tdir
8119         local f_mgrt=$dir/$tfile.mgrt
8120         local f_yaml=$dir/$tfile.yaml
8121         local f_copy=$dir/$tfile.copy
8122         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8123         local layout_copy="-c 2 -S 2M -i 1"
8124         local yamlfile=$dir/yamlfile
8125         local layout_before;
8126         local layout_after;
8127
8128         test_mkdir "$dir" || error "cannot create dir $dir"
8129         stack_trap "rm -rf $dir"
8130         $LFS setstripe $layout_yaml $f_yaml ||
8131                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8132         $LFS getstripe --yaml $f_yaml > $yamlfile
8133         $LFS setstripe $layout_copy $f_copy ||
8134                 error "cannot setstripe $f_copy with layout $layout_copy"
8135         touch $f_mgrt
8136         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8137
8138         # 1. test option --yaml
8139         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8140                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8141         layout_before=$(get_layout_param $f_yaml)
8142         layout_after=$(get_layout_param $f_mgrt)
8143         [ "$layout_after" == "$layout_before" ] ||
8144                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8145
8146         # 2. test option --copy
8147         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8148                 error "cannot migrate $f_mgrt with --copy $f_copy"
8149         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8150         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8151         [ "$layout_after" == "$layout_before" ] ||
8152                 error "lfs_migrate --copy: $layout_after != $layout_before"
8153 }
8154 run_test 56xd "check lfs_migrate --yaml and --copy support"
8155
8156 test_56xe() {
8157         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8158
8159         local dir=$DIR/$tdir
8160         local f_comp=$dir/$tfile
8161         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8162         local layout_before=""
8163         local layout_after=""
8164
8165         test_mkdir "$dir" || error "cannot create dir $dir"
8166         stack_trap "rm -rf $dir"
8167         $LFS setstripe $layout $f_comp ||
8168                 error "cannot setstripe $f_comp with layout $layout"
8169         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8170         dd if=/dev/zero of=$f_comp bs=1M count=4
8171
8172         # 1. migrate a comp layout file by lfs_migrate
8173         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8174         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8175         [ "$layout_before" == "$layout_after" ] ||
8176                 error "lfs_migrate: $layout_before != $layout_after"
8177
8178         # 2. migrate a comp layout file by lfs migrate
8179         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8180         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8181         [ "$layout_before" == "$layout_after" ] ||
8182                 error "lfs migrate: $layout_before != $layout_after"
8183 }
8184 run_test 56xe "migrate a composite layout file"
8185
8186 test_56xf() {
8187         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8188
8189         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8190                 skip "Need server version at least 2.13.53"
8191
8192         local dir=$DIR/$tdir
8193         local f_comp=$dir/$tfile
8194         local layout="-E 1M -c1 -E -1 -c2"
8195         local fid_before=""
8196         local fid_after=""
8197
8198         test_mkdir "$dir" || error "cannot create dir $dir"
8199         stack_trap "rm -rf $dir"
8200         $LFS setstripe $layout $f_comp ||
8201                 error "cannot setstripe $f_comp with layout $layout"
8202         fid_before=$($LFS getstripe --fid $f_comp)
8203         dd if=/dev/zero of=$f_comp bs=1M count=4
8204
8205         # 1. migrate a comp layout file to a comp layout
8206         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8207         fid_after=$($LFS getstripe --fid $f_comp)
8208         [ "$fid_before" == "$fid_after" ] ||
8209                 error "comp-to-comp migrate: $fid_before != $fid_after"
8210
8211         # 2. migrate a comp layout file to a plain layout
8212         $LFS migrate -c2 $f_comp ||
8213                 error "cannot migrate $f_comp by lfs migrate"
8214         fid_after=$($LFS getstripe --fid $f_comp)
8215         [ "$fid_before" == "$fid_after" ] ||
8216                 error "comp-to-plain migrate: $fid_before != $fid_after"
8217
8218         # 3. migrate a plain layout file to a comp layout
8219         $LFS migrate $layout $f_comp ||
8220                 error "cannot migrate $f_comp by lfs migrate"
8221         fid_after=$($LFS getstripe --fid $f_comp)
8222         [ "$fid_before" == "$fid_after" ] ||
8223                 error "plain-to-comp migrate: $fid_before != $fid_after"
8224 }
8225 run_test 56xf "FID is not lost during migration of a composite layout file"
8226
8227 check_file_ost_range() {
8228         local file="$1"
8229         shift
8230         local range="$*"
8231         local -a file_range
8232         local idx
8233
8234         file_range=($($LFS getstripe -y "$file" |
8235                 awk '/l_ost_idx:/ { print $NF }'))
8236
8237         if [[ "${#file_range[@]}" = 0 ]]; then
8238                 echo "No osts found for $file"
8239                 return 1
8240         fi
8241
8242         for idx in "${file_range[@]}"; do
8243                 [[ " $range " =~ " $idx " ]] ||
8244                         return 1
8245         done
8246
8247         return 0
8248 }
8249
8250 sub_test_56xg() {
8251         local stripe_opt="$1"
8252         local pool="$2"
8253         shift 2
8254         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8255
8256         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8257                 error "Fail to migrate $tfile on $pool"
8258         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8259                 error "$tfile is not in pool $pool"
8260         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8261                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8262 }
8263
8264 test_56xg() {
8265         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8266         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8267         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8268                 skip "Need MDS version newer than 2.14.52"
8269
8270         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8271         local -a pool_ranges=("0 0" "1 1" "0 1")
8272
8273         # init pools
8274         for i in "${!pool_names[@]}"; do
8275                 pool_add ${pool_names[$i]} ||
8276                         error "pool_add failed (pool: ${pool_names[$i]})"
8277                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8278                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8279         done
8280
8281         # init the file to migrate
8282         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8283                 error "Unable to create $tfile on OST1"
8284         stack_trap "rm -f $DIR/$tfile"
8285         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8286                 error "Unable to write on $tfile"
8287
8288         echo "1. migrate $tfile on pool ${pool_names[0]}"
8289         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8290
8291         echo "2. migrate $tfile on pool ${pool_names[2]}"
8292         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8293
8294         echo "3. migrate $tfile on pool ${pool_names[1]}"
8295         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8296
8297         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8298         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8299         echo
8300
8301         # Clean pools
8302         destroy_test_pools ||
8303                 error "pool_destroy failed"
8304 }
8305 run_test 56xg "lfs migrate pool support"
8306
8307 test_56xh() {
8308         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8309
8310         local size_mb=25
8311         local file1=$DIR/$tfile
8312         local tmp1=$TMP/$tfile.tmp
8313
8314         $LFS setstripe -c 2 $file1
8315
8316         stack_trap "rm -f $file1 $tmp1"
8317         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8318                         error "error creating $tmp1"
8319         ls -lsh $tmp1
8320         cp $tmp1 $file1
8321
8322         local start=$SECONDS
8323
8324         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8325                 error "migrate failed rc = $?"
8326
8327         local elapsed=$((SECONDS - start))
8328
8329         # with 1MB/s, elapsed should equal size_mb
8330         (( elapsed >= size_mb * 95 / 100 )) ||
8331                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8332
8333         (( elapsed <= size_mb * 120 / 100 )) ||
8334                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8335
8336         (( elapsed <= size_mb * 350 / 100 )) ||
8337                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8338
8339         stripe=$($LFS getstripe -c $file1)
8340         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8341         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8342
8343         # Clean up file (since it is multiple MB)
8344         rm -f $file1 $tmp1
8345 }
8346 run_test 56xh "lfs migrate bandwidth limitation support"
8347
8348 test_56xi() {
8349         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8350         verify_yaml_available || skip_env "YAML verification not installed"
8351
8352         local size_mb=5
8353         local file1=$DIR/$tfile.1
8354         local file2=$DIR/$tfile.2
8355         local file3=$DIR/$tfile.3
8356         local output_file=$DIR/$tfile.out
8357         local tmp1=$TMP/$tfile.tmp
8358
8359         $LFS setstripe -c 2 $file1
8360         $LFS setstripe -c 2 $file2
8361         $LFS setstripe -c 2 $file3
8362
8363         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8364         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8365                         error "error creating $tmp1"
8366         ls -lsh $tmp1
8367         cp $tmp1 $file1
8368         cp $tmp1 $file2
8369         cp $tmp1 $file3
8370
8371         $LFS migrate --stats --stats-interval=1 \
8372                 -c 1 $file1 $file2 $file3 1> $output_file ||
8373                 error "migrate failed rc = $?"
8374
8375         cat $output_file
8376         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8377
8378         # Clean up file (since it is multiple MB)
8379         rm -f $file1 $file2 $file3 $tmp1 $output_file
8380 }
8381 run_test 56xi "lfs migrate stats support"
8382
8383 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8384         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8385
8386         local file=$DIR/$tfile
8387         local linkdir=$DIR/$tdir
8388
8389         test_mkdir $linkdir || error "fail to create $linkdir"
8390         $LFS setstripe -i 0 -c 1 -S1M $file
8391         stack_trap "rm -rf $file $linkdir"
8392         dd if=/dev/urandom of=$file bs=1M count=10 ||
8393                 error "fail to create $file"
8394
8395         # Create file links
8396         local cpts
8397         local threads_max
8398         local nlinks
8399
8400         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8401         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8402         (( nlinks = thread_max * 3 / 2 / cpts))
8403
8404         echo "create $nlinks hard links of $file"
8405         createmany -l $file $linkdir/link $nlinks
8406
8407         # Parallel migrates (should not block)
8408         local i
8409         for ((i = 0; i < nlinks; i++)); do
8410                 echo $linkdir/link$i
8411         done | xargs -n1 -P $nlinks $LFS migrate -c2
8412
8413         local stripe_count
8414         stripe_count=$($LFS getstripe -c $file) ||
8415                 error "fail to get stripe count on $file"
8416
8417         ((stripe_count == 2)) ||
8418                 error "fail to migrate $file (stripe_count = $stripe_count)"
8419 }
8420 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8421
8422 test_56xk() {
8423         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8424
8425         local size_mb=5
8426         local file1=$DIR/$tfile
8427
8428         stack_trap "rm -f $file1"
8429         $LFS setstripe -c 1 $file1
8430         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8431                 error "error creating $file1"
8432         $LFS mirror extend -N $file1 || error "can't mirror"
8433         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8434                 error "can't dd"
8435         $LFS getstripe $file1 | grep stale ||
8436                 error "one component must be stale"
8437
8438         local start=$SECONDS
8439         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8440                 error "migrate failed rc = $?"
8441         local elapsed=$((SECONDS - start))
8442         $LFS getstripe $file1 | grep stale &&
8443                 error "all components must be sync"
8444
8445         # with 1MB/s, elapsed should equal size_mb
8446         (( elapsed >= size_mb * 95 / 100 )) ||
8447                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8448
8449         (( elapsed <= size_mb * 120 / 100 )) ||
8450                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8451
8452         (( elapsed <= size_mb * 350 / 100 )) ||
8453                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8454 }
8455 run_test 56xk "lfs mirror resync bandwidth limitation support"
8456
8457 test_56xl() {
8458         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8459         verify_yaml_available || skip_env "YAML verification not installed"
8460
8461         local size_mb=5
8462         local file1=$DIR/$tfile.1
8463         local output_file=$DIR/$tfile.out
8464
8465         stack_trap "rm -f $file1"
8466         $LFS setstripe -c 1 $file1
8467         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8468                 error "error creating $file1"
8469         $LFS mirror extend -N $file1 || error "can't mirror"
8470         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8471                 error "can't dd"
8472         $LFS getstripe $file1 | grep stale ||
8473                 error "one component must be stale"
8474         $LFS getstripe $file1
8475
8476         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8477                 error "resync failed rc = $?"
8478         $LFS getstripe $file1 | grep stale &&
8479                 error "all components must be sync"
8480
8481         cat $output_file
8482         cat $output_file | verify_yaml || error "stats is not valid YAML"
8483 }
8484 run_test 56xl "lfs mirror resync stats support"
8485
8486 test_56y() {
8487         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8488                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8489
8490         local res=""
8491         local dir=$DIR/$tdir
8492         local f1=$dir/file1
8493         local f2=$dir/file2
8494
8495         test_mkdir -p $dir || error "creating dir $dir"
8496         touch $f1 || error "creating std file $f1"
8497         $MULTIOP $f2 H2c || error "creating released file $f2"
8498
8499         # a directory can be raid0, so ask only for files
8500         res=$($LFS find $dir -L raid0 -type f | wc -l)
8501         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8502
8503         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8504         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8505
8506         # only files can be released, so no need to force file search
8507         res=$($LFS find $dir -L released)
8508         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8509
8510         res=$($LFS find $dir -type f \! -L released)
8511         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8512 }
8513 run_test 56y "lfs find -L raid0|released"
8514
8515 test_56z() { # LU-4824
8516         # This checks to make sure 'lfs find' continues after errors
8517         # There are two classes of errors that should be caught:
8518         # - If multiple paths are provided, all should be searched even if one
8519         #   errors out
8520         # - If errors are encountered during the search, it should not terminate
8521         #   early
8522         local dir=$DIR/$tdir
8523         local i
8524
8525         test_mkdir $dir
8526         for i in d{0..9}; do
8527                 test_mkdir $dir/$i
8528                 touch $dir/$i/$tfile
8529         done
8530         $LFS find $DIR/non_existent_dir $dir &&
8531                 error "$LFS find did not return an error"
8532         # Make a directory unsearchable. This should NOT be the last entry in
8533         # directory order.  Arbitrarily pick the 6th entry
8534         chmod 700 $($LFS find $dir -type d | sed '6!d')
8535
8536         $RUNAS $LFS find $DIR/non_existent $dir
8537         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8538
8539         # The user should be able to see 10 directories and 9 files
8540         (( count == 19 )) ||
8541                 error "$LFS find found $count != 19 entries after error"
8542 }
8543 run_test 56z "lfs find should continue after an error"
8544
8545 test_56aa() { # LU-5937
8546         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8547
8548         local dir=$DIR/$tdir
8549
8550         mkdir $dir
8551         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8552
8553         createmany -o $dir/striped_dir/${tfile}- 1024
8554         local dirs=$($LFS find --size +8k $dir/)
8555
8556         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8557 }
8558 run_test 56aa "lfs find --size under striped dir"
8559
8560 test_56ab() { # LU-10705
8561         test_mkdir $DIR/$tdir
8562         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8563         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8564         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8565         # Flush writes to ensure valid blocks.  Need to be more thorough for
8566         # ZFS, since blocks are not allocated/returned to client immediately.
8567         sync_all_data
8568         wait_zfs_commit ost1 2
8569         cancel_lru_locks osc
8570         ls -ls $DIR/$tdir
8571
8572         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8573
8574         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8575
8576         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8577         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8578
8579         rm -f $DIR/$tdir/$tfile.[123]
8580 }
8581 run_test 56ab "lfs find --blocks"
8582
8583 # LU-11188
8584 test_56aca() {
8585         local dir="$DIR/$tdir"
8586         local perms=(001 002 003 004 005 006 007
8587                      010 020 030 040 050 060 070
8588                      100 200 300 400 500 600 700
8589                      111 222 333 444 555 666 777)
8590         local perm_minus=(8 8 4 8 4 4 2
8591                           8 8 4 8 4 4 2
8592                           8 8 4 8 4 4 2
8593                           4 4 2 4 2 2 1)
8594         local perm_slash=(8  8 12  8 12 12 14
8595                           8  8 12  8 12 12 14
8596                           8  8 12  8 12 12 14
8597                          16 16 24 16 24 24 28)
8598
8599         test_mkdir "$dir"
8600         for perm in ${perms[*]}; do
8601                 touch "$dir/$tfile.$perm"
8602                 chmod $perm "$dir/$tfile.$perm"
8603         done
8604
8605         for ((i = 0; i < ${#perms[*]}; i++)); do
8606                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8607                 (( $num == 1 )) ||
8608                         error "lfs find -perm ${perms[i]}:"\
8609                               "$num != 1"
8610
8611                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8612                 (( $num == ${perm_minus[i]} )) ||
8613                         error "lfs find -perm -${perms[i]}:"\
8614                               "$num != ${perm_minus[i]}"
8615
8616                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8617                 (( $num == ${perm_slash[i]} )) ||
8618                         error "lfs find -perm /${perms[i]}:"\
8619                               "$num != ${perm_slash[i]}"
8620         done
8621 }
8622 run_test 56aca "check lfs find -perm with octal representation"
8623
8624 test_56acb() {
8625         local dir=$DIR/$tdir
8626         # p is the permission of write and execute for user, group and other
8627         # without the umask. It is used to test +wx.
8628         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8629         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8630         local symbolic=(+t  a+t u+t g+t o+t
8631                         g+s u+s o+s +s o+sr
8632                         o=r,ug+o,u+w
8633                         u+ g+ o+ a+ ugo+
8634                         u- g- o- a- ugo-
8635                         u= g= o= a= ugo=
8636                         o=r,ug+o,u+w u=r,a+u,u+w
8637                         g=r,ugo=g,u+w u+x,+X +X
8638                         u+x,u+X u+X u+x,g+X o+r,+X
8639                         u+x,go+X +wx +rwx)
8640
8641         test_mkdir $dir
8642         for perm in ${perms[*]}; do
8643                 touch "$dir/$tfile.$perm"
8644                 chmod $perm "$dir/$tfile.$perm"
8645         done
8646
8647         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8648                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8649
8650                 (( $num == 1 )) ||
8651                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8652         done
8653 }
8654 run_test 56acb "check lfs find -perm with symbolic representation"
8655
8656 test_56acc() {
8657         local dir=$DIR/$tdir
8658         local tests="17777 787 789 abcd
8659                 ug=uu ug=a ug=gu uo=ou urw
8660                 u+xg+x a=r,u+x,"
8661
8662         test_mkdir $dir
8663         for err in $tests; do
8664                 if $LFS find $dir -perm $err 2>/dev/null; then
8665                         error "lfs find -perm $err: parsing should have failed"
8666                 fi
8667         done
8668 }
8669 run_test 56acc "check parsing error for lfs find -perm"
8670
8671 test_56ba() {
8672         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8673                 skip "Need MDS version at least 2.10.50"
8674
8675         # Create composite files with one component
8676         local dir=$DIR/$tdir
8677
8678         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8679         # Create composite files with three components
8680         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8681         # LU-16904 Create plain layout files
8682         lfs setstripe -c 1 $dir/$tfile-{1..10}
8683
8684         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8685
8686         [[ $nfiles == 10 ]] ||
8687                 error "lfs find -E 1M found $nfiles != 10 files"
8688
8689         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8690         [[ $nfiles == 25 ]] ||
8691                 error "lfs find ! -E 1M found $nfiles != 25 files"
8692
8693         # All files have a component that starts at 0
8694         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8695         [[ $nfiles == 35 ]] ||
8696                 error "lfs find --component-start 0 - $nfiles != 35 files"
8697
8698         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8699         [[ $nfiles == 15 ]] ||
8700                 error "lfs find --component-start 2M - $nfiles != 15 files"
8701
8702         # All files created here have a componenet that does not starts at 2M
8703         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8704         [[ $nfiles == 35 ]] ||
8705                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8706
8707         # Find files with a specified number of components
8708         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8709         [[ $nfiles == 15 ]] ||
8710                 error "lfs find --component-count 3 - $nfiles != 15 files"
8711
8712         # Remember non-composite files have a component count of zero
8713         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8714         [[ $nfiles == 10 ]] ||
8715                 error "lfs find --component-count 0 - $nfiles != 10 files"
8716
8717         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8718         [[ $nfiles == 20 ]] ||
8719                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8720
8721         # All files have a flag called "init"
8722         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8723         [[ $nfiles == 35 ]] ||
8724                 error "lfs find --component-flags init - $nfiles != 35 files"
8725
8726         # Multi-component files will have a component not initialized
8727         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8728         [[ $nfiles == 15 ]] ||
8729                 error "lfs find !--component-flags init - $nfiles != 15 files"
8730
8731         rm -rf $dir
8732
8733 }
8734 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8735
8736 test_56ca() {
8737         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8738                 skip "Need MDS version at least 2.10.57"
8739
8740         local td=$DIR/$tdir
8741         local tf=$td/$tfile
8742         local dir
8743         local nfiles
8744         local cmd
8745         local i
8746         local j
8747
8748         # create mirrored directories and mirrored files
8749         mkdir $td || error "mkdir $td failed"
8750         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8751         createmany -o $tf- 10 || error "create $tf- failed"
8752
8753         for i in $(seq 2); do
8754                 dir=$td/dir$i
8755                 mkdir $dir || error "mkdir $dir failed"
8756                 $LFS mirror create -N$((3 + i)) $dir ||
8757                         error "create mirrored dir $dir failed"
8758                 createmany -o $dir/$tfile- 10 ||
8759                         error "create $dir/$tfile- failed"
8760         done
8761
8762         # change the states of some mirrored files
8763         echo foo > $tf-6
8764         for i in $(seq 2); do
8765                 dir=$td/dir$i
8766                 for j in $(seq 4 9); do
8767                         echo foo > $dir/$tfile-$j
8768                 done
8769         done
8770
8771         # find mirrored files with specific mirror count
8772         cmd="$LFS find --mirror-count 3 --type f $td"
8773         nfiles=$($cmd | wc -l)
8774         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8775
8776         cmd="$LFS find ! --mirror-count 3 --type f $td"
8777         nfiles=$($cmd | wc -l)
8778         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8779
8780         cmd="$LFS find --mirror-count +2 --type f $td"
8781         nfiles=$($cmd | wc -l)
8782         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8783
8784         cmd="$LFS find --mirror-count -6 --type f $td"
8785         nfiles=$($cmd | wc -l)
8786         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8787
8788         # find mirrored files with specific file state
8789         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8790         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8791
8792         cmd="$LFS find --mirror-state=ro --type f $td"
8793         nfiles=$($cmd | wc -l)
8794         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8795
8796         cmd="$LFS find ! --mirror-state=ro --type f $td"
8797         nfiles=$($cmd | wc -l)
8798         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8799
8800         cmd="$LFS find --mirror-state=wp --type f $td"
8801         nfiles=$($cmd | wc -l)
8802         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8803
8804         cmd="$LFS find ! --mirror-state=sp --type f $td"
8805         nfiles=$($cmd | wc -l)
8806         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8807 }
8808 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8809
8810 test_56da() { # LU-14179
8811         local path=$DIR/$tdir
8812
8813         test_mkdir $path
8814         cd $path
8815
8816         local longdir=$(str_repeat 'a' 255)
8817
8818         for i in {1..15}; do
8819                 path=$path/$longdir
8820                 test_mkdir $longdir
8821                 cd $longdir
8822         done
8823
8824         local len=${#path}
8825         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8826
8827         test_mkdir $lastdir
8828         cd $lastdir
8829         # PATH_MAX-1
8830         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8831
8832         # NAME_MAX
8833         touch $(str_repeat 'f' 255)
8834
8835         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8836                 error "lfs find reported an error"
8837
8838         rm -rf $DIR/$tdir
8839 }
8840 run_test 56da "test lfs find with long paths"
8841
8842 test_56ea() { #LU-10378
8843         local path=$DIR/$tdir
8844         local pool=$TESTNAME
8845
8846         # Create ost pool
8847         pool_add $pool || error "pool_add $pool failed"
8848         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8849                 error "adding targets to $pool failed"
8850
8851         # Set default pool on directory before creating file
8852         mkdir $path || error "mkdir $path failed"
8853         $LFS setstripe -p $pool $path ||
8854                 error "set OST pool on $pool failed"
8855         touch $path/$tfile || error "touch $path/$tfile failed"
8856
8857         # Compare basic file attributes from -printf and stat
8858         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8859         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8860
8861         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8862                 error "Attrs from lfs find and stat don't match"
8863
8864         # Compare Lustre attributes from lfs find and lfs getstripe
8865         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8866         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8867         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8868         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8869         local fpool=$($LFS getstripe --pool $path/$tfile)
8870         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8871
8872         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8873                 error "Attrs from lfs find and lfs getstripe don't match"
8874
8875         # Verify behavior for unknown escape/format sequences
8876         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8877
8878         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8879                 error "Escape/format codes don't match"
8880 }
8881 run_test 56ea "test lfs find -printf option"
8882
8883 test_56eb() {
8884         local dir=$DIR/$tdir
8885         local subdir_1=$dir/subdir_1
8886
8887         test_mkdir -p $subdir_1
8888         ln -s subdir_1 $dir/link_1
8889
8890         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8891                 error "symlink is not followed"
8892
8893         $LFS getstripe --no-follow $dir |
8894                 grep "^$dir/link_1 has no stripe info$" ||
8895                 error "symlink should not have stripe info"
8896
8897         touch $dir/testfile
8898         ln -s testfile $dir/file_link_2
8899
8900         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8901                 error "symlink is not followed"
8902
8903         $LFS getstripe --no-follow $dir |
8904                 grep "^$dir/file_link_2 has no stripe info$" ||
8905                 error "symlink should not have stripe info"
8906 }
8907 run_test 56eb "check lfs getstripe on symlink"
8908
8909 test_56ec() {
8910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8911         local dir=$DIR/$tdir
8912         local srcfile=$dir/srcfile
8913         local srcyaml=$dir/srcyaml
8914         local destfile=$dir/destfile
8915
8916         test_mkdir -p $dir
8917
8918         $LFS setstripe -i 1 $srcfile
8919         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8920         # if the setstripe yaml parsing fails for any reason, the command can
8921         # randomly assign the correct OST index, leading to an erroneous
8922         # success. but the chance of false success is low enough that a
8923         # regression should still be quickly caught.
8924         $LFS setstripe --yaml=$srcyaml $destfile
8925
8926         local srcindex=$($LFS getstripe -i $srcfile)
8927         local destindex=$($LFS getstripe -i $destfile)
8928
8929         if [[ ! $srcindex -eq $destindex ]]; then
8930                 error "setstripe did not set OST index correctly"
8931         fi
8932 }
8933 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8934
8935 test_56eda() {
8936         local dir=$DIR/$tdir
8937         local subdir=$dir/subdir
8938         local file1=$dir/$tfile
8939         local file2=$dir/$tfile\2
8940         local link=$dir/$tfile-link
8941         local nfiles
8942
8943         test_mkdir -p $dir
8944         $LFS setdirstripe -c1 $subdir
8945         touch $file1
8946         touch $file2
8947         ln $file2 $link
8948
8949         nfiles=$($LFS find --links 1 $dir | wc -l)
8950         (( $nfiles == 1 )) ||
8951                 error "lfs find --links expected 1 file, got $nfiles"
8952
8953         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8954         (( $nfiles == 2 )) ||
8955                 error "lfs find --links expected 2 files, got $nfiles"
8956
8957         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8958         (( $nfiles == 1 )) ||
8959                 error "lfs find --links expected 1 directory, got $nfiles"
8960 }
8961 run_test 56eda "check lfs find --links"
8962
8963 test_56edb() {
8964         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8965
8966         local dir=$DIR/$tdir
8967         local stripedir=$dir/stripedir
8968         local nfiles
8969
8970         test_mkdir -p $dir
8971
8972         $LFS setdirstripe -c2 $stripedir
8973
8974         $LFS getdirstripe $stripedir
8975
8976         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8977         (( $nfiles == 1 )) ||
8978                 error "lfs find --links expected 1 directory, got $nfiles"
8979 }
8980 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8981
8982 test_56ef() {
8983         local dir=$DIR/$tdir
8984         local dir1=$dir/d1
8985         local dir2=$dir/d2
8986         local nfiles
8987         local err_msg
8988
8989         test_mkdir -p $dir
8990
8991         mkdir $dir1
8992         mkdir $dir2
8993
8994         touch $dir1/f
8995         touch $dir2/f
8996
8997         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8998         (( $nfiles == 2 )) ||
8999                 error "(1) lfs find expected 2 files, got $nfiles"
9000
9001         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9002         (( $nfiles == 2 )) ||
9003                 error "(2) lfs find expected 2 files, got $nfiles"
9004
9005         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9006         (( $nfiles == 2 )) ||
9007                 error "(3) lfs find expected 2 files, got $nfiles"
9008
9009         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9010         [[ $err_msg =~ "No such file or directory" ]] ||
9011                 error "expected standard error message, got: '$err_msg'"
9012 }
9013 run_test 56ef "lfs find with multiple paths"
9014
9015 test_57a() {
9016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9017         # note test will not do anything if MDS is not local
9018         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9019                 skip_env "ldiskfs only test"
9020         fi
9021         remote_mds_nodsh && skip "remote MDS with nodsh"
9022
9023         local MNTDEV="osd*.*MDT*.mntdev"
9024         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9025         [ -z "$DEV" ] && error "can't access $MNTDEV"
9026         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9027                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9028                         error "can't access $DEV"
9029                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9030                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9031                 rm $TMP/t57a.dump
9032         done
9033 }
9034 run_test 57a "verify MDS filesystem created with large inodes =="
9035
9036 test_57b() {
9037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9038         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9039                 skip_env "ldiskfs only test"
9040         fi
9041         remote_mds_nodsh && skip "remote MDS with nodsh"
9042
9043         local dir=$DIR/$tdir
9044         local filecount=100
9045         local file1=$dir/f1
9046         local fileN=$dir/f$filecount
9047
9048         rm -rf $dir || error "removing $dir"
9049         test_mkdir -c1 $dir
9050         local mdtidx=$($LFS getstripe -m $dir)
9051         local mdtname=MDT$(printf %04x $mdtidx)
9052         local facet=mds$((mdtidx + 1))
9053
9054         echo "mcreating $filecount files"
9055         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9056
9057         # verify that files do not have EAs yet
9058         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9059                 error "$file1 has an EA"
9060         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9061                 error "$fileN has an EA"
9062
9063         sync
9064         sleep 1
9065         df $dir  #make sure we get new statfs data
9066         local mdsfree=$(do_facet $facet \
9067                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9068         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9069         local file
9070
9071         echo "opening files to create objects/EAs"
9072         for file in $(seq -f $dir/f%g 1 $filecount); do
9073                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9074                         error "opening $file"
9075         done
9076
9077         # verify that files have EAs now
9078         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9079                 error "$file1 missing EA"
9080         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9081                 error "$fileN missing EA"
9082
9083         sleep 1  #make sure we get new statfs data
9084         df $dir
9085         local mdsfree2=$(do_facet $facet \
9086                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9087         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9088
9089         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9090                 if [ "$mdsfree" != "$mdsfree2" ]; then
9091                         error "MDC before $mdcfree != after $mdcfree2"
9092                 else
9093                         echo "MDC before $mdcfree != after $mdcfree2"
9094                         echo "unable to confirm if MDS has large inodes"
9095                 fi
9096         fi
9097         rm -rf $dir
9098 }
9099 run_test 57b "default LOV EAs are stored inside large inodes ==="
9100
9101 test_58() {
9102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9103         [ -z "$(which wiretest 2>/dev/null)" ] &&
9104                         skip_env "could not find wiretest"
9105
9106         wiretest
9107 }
9108 run_test 58 "verify cross-platform wire constants =============="
9109
9110 test_59() {
9111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9112
9113         echo "touch 130 files"
9114         createmany -o $DIR/f59- 130
9115         echo "rm 130 files"
9116         unlinkmany $DIR/f59- 130
9117         sync
9118         # wait for commitment of removal
9119         wait_delete_completed
9120 }
9121 run_test 59 "verify cancellation of llog records async ========="
9122
9123 TEST60_HEAD="test_60 run $RANDOM"
9124 test_60a() {
9125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9126         remote_mgs_nodsh && skip "remote MGS with nodsh"
9127         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9128                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9129                         skip_env "missing subtest run-llog.sh"
9130
9131         log "$TEST60_HEAD - from kernel mode"
9132         do_facet mgs "$LCTL dk > /dev/null"
9133         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9134         do_facet mgs $LCTL dk > $TMP/$tfile
9135
9136         # LU-6388: test llog_reader
9137         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9138         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9139         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9140                         skip_env "missing llog_reader"
9141         local fstype=$(facet_fstype mgs)
9142         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9143                 skip_env "Only for ldiskfs or zfs type mgs"
9144
9145         local mntpt=$(facet_mntpt mgs)
9146         local mgsdev=$(mgsdevname 1)
9147         local fid_list
9148         local fid
9149         local rec_list
9150         local rec
9151         local rec_type
9152         local obj_file
9153         local path
9154         local seq
9155         local oid
9156         local pass=true
9157
9158         #get fid and record list
9159         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9160                 tail -n 4))
9161         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9162                 tail -n 4))
9163         #remount mgs as ldiskfs or zfs type
9164         stop mgs || error "stop mgs failed"
9165         mount_fstype mgs || error "remount mgs failed"
9166         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9167                 fid=${fid_list[i]}
9168                 rec=${rec_list[i]}
9169                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9170                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9171                 oid=$((16#$oid))
9172
9173                 case $fstype in
9174                         ldiskfs )
9175                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9176                         zfs )
9177                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9178                 esac
9179                 echo "obj_file is $obj_file"
9180                 do_facet mgs $llog_reader $obj_file
9181
9182                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9183                         awk '{ print $3 }' | sed -e "s/^type=//g")
9184                 if [ $rec_type != $rec ]; then
9185                         echo "FAILED test_60a wrong record type $rec_type," \
9186                               "should be $rec"
9187                         pass=false
9188                         break
9189                 fi
9190
9191                 #check obj path if record type is LLOG_LOGID_MAGIC
9192                 if [ "$rec" == "1064553b" ]; then
9193                         path=$(do_facet mgs $llog_reader $obj_file |
9194                                 grep "path=" | awk '{ print $NF }' |
9195                                 sed -e "s/^path=//g")
9196                         if [ $obj_file != $mntpt/$path ]; then
9197                                 echo "FAILED test_60a wrong obj path" \
9198                                       "$montpt/$path, should be $obj_file"
9199                                 pass=false
9200                                 break
9201                         fi
9202                 fi
9203         done
9204         rm -f $TMP/$tfile
9205         #restart mgs before "error", otherwise it will block the next test
9206         stop mgs || error "stop mgs failed"
9207         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9208         $pass || error "test failed, see FAILED test_60a messages for specifics"
9209 }
9210 run_test 60a "llog_test run from kernel module and test llog_reader"
9211
9212 test_60b() { # bug 6411
9213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9214
9215         dmesg > $DIR/$tfile
9216         LLOG_COUNT=$(do_facet mgs dmesg |
9217                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9218                           /llog_[a-z]*.c:[0-9]/ {
9219                                 if (marker)
9220                                         from_marker++
9221                                 from_begin++
9222                           }
9223                           END {
9224                                 if (marker)
9225                                         print from_marker
9226                                 else
9227                                         print from_begin
9228                           }")
9229
9230         [[ $LLOG_COUNT -gt 120 ]] &&
9231                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9232 }
9233 run_test 60b "limit repeated messages from CERROR/CWARN"
9234
9235 test_60c() {
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         echo "create 5000 files"
9239         createmany -o $DIR/f60c- 5000
9240 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9241         lctl set_param fail_loc=0x80000137
9242         unlinkmany $DIR/f60c- 5000
9243         lctl set_param fail_loc=0
9244 }
9245 run_test 60c "unlink file when mds full"
9246
9247 test_60d() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249
9250         SAVEPRINTK=$(lctl get_param -n printk)
9251         # verify "lctl mark" is even working"
9252         MESSAGE="test message ID $RANDOM $$"
9253         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9254         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9255
9256         lctl set_param printk=0 || error "set lnet.printk failed"
9257         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9258         MESSAGE="new test message ID $RANDOM $$"
9259         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9260         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9261         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9262
9263         lctl set_param -n printk="$SAVEPRINTK"
9264 }
9265 run_test 60d "test printk console message masking"
9266
9267 test_60e() {
9268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9269         remote_mds_nodsh && skip "remote MDS with nodsh"
9270
9271         touch $DIR/$tfile
9272 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9273         do_facet mds1 lctl set_param fail_loc=0x15b
9274         rm $DIR/$tfile
9275 }
9276 run_test 60e "no space while new llog is being created"
9277
9278 test_60f() {
9279         local old_path=$($LCTL get_param -n debug_path)
9280
9281         stack_trap "$LCTL set_param debug_path=$old_path"
9282         stack_trap "rm -f $TMP/$tfile*"
9283         rm -f $TMP/$tfile* 2> /dev/null
9284         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9285         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9286         test_mkdir $DIR/$tdir
9287         # retry in case the open is cached and not released
9288         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9289                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9290                 sleep 0.1
9291         done
9292         ls $TMP/$tfile*
9293         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9294 }
9295 run_test 60f "change debug_path works"
9296
9297 test_60g() {
9298         local pid
9299         local i
9300
9301         test_mkdir -c $MDSCOUNT $DIR/$tdir
9302
9303         (
9304                 local index=0
9305                 while true; do
9306                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9307                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9308                                 2>/dev/null
9309                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9310                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9311                         index=$((index + 1))
9312                 done
9313         ) &
9314
9315         pid=$!
9316
9317         for i in {0..100}; do
9318                 # define OBD_FAIL_OSD_TXN_START    0x19a
9319                 local index=$((i % MDSCOUNT + 1))
9320
9321                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9322                         > /dev/null
9323                 sleep 0.01
9324         done
9325
9326         kill -9 $pid
9327
9328         for i in $(seq $MDSCOUNT); do
9329                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9330         done
9331
9332         mkdir $DIR/$tdir/new || error "mkdir failed"
9333         rmdir $DIR/$tdir/new || error "rmdir failed"
9334
9335         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9336                 -t namespace
9337         for i in $(seq $MDSCOUNT); do
9338                 wait_update_facet mds$i "$LCTL get_param -n \
9339                         mdd.$(facet_svc mds$i).lfsck_namespace |
9340                         awk '/^status/ { print \\\$2 }'" "completed"
9341         done
9342
9343         ls -R $DIR/$tdir
9344         rm -rf $DIR/$tdir || error "rmdir failed"
9345 }
9346 run_test 60g "transaction abort won't cause MDT hung"
9347
9348 test_60h() {
9349         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9350                 skip "Need MDS version at least 2.12.52"
9351         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9352
9353         local f
9354
9355         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9356         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9357         for fail_loc in 0x80000188 0x80000189; do
9358                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9359                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9360                         error "mkdir $dir-$fail_loc failed"
9361                 for i in {0..10}; do
9362                         # create may fail on missing stripe
9363                         echo $i > $DIR/$tdir-$fail_loc/$i
9364                 done
9365                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9366                         error "getdirstripe $tdir-$fail_loc failed"
9367                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9368                         error "migrate $tdir-$fail_loc failed"
9369                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9370                         error "getdirstripe $tdir-$fail_loc failed"
9371                 pushd $DIR/$tdir-$fail_loc
9372                 for f in *; do
9373                         echo $f | cmp $f - || error "$f data mismatch"
9374                 done
9375                 popd
9376                 rm -rf $DIR/$tdir-$fail_loc
9377         done
9378 }
9379 run_test 60h "striped directory with missing stripes can be accessed"
9380
9381 function t60i_load() {
9382         mkdir $DIR/$tdir
9383         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9384         $LCTL set_param fail_loc=0x131c fail_val=1
9385         for ((i=0; i<5000; i++)); do
9386                 touch $DIR/$tdir/f$i
9387         done
9388 }
9389
9390 test_60i() {
9391         changelog_register || error "changelog_register failed"
9392         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9393         changelog_users $SINGLEMDS | grep -q $cl_user ||
9394                 error "User $cl_user not found in changelog_users"
9395         changelog_chmask "ALL"
9396         t60i_load &
9397         local PID=$!
9398         for((i=0; i<100; i++)); do
9399                 changelog_dump >/dev/null ||
9400                         error "can't read changelog"
9401         done
9402         kill $PID
9403         wait $PID
9404         changelog_deregister || error "changelog_deregister failed"
9405         $LCTL set_param fail_loc=0
9406 }
9407 run_test 60i "llog: new record vs reader race"
9408
9409 test_60j() {
9410         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9411                 skip "need MDS version at least 2.15.50"
9412         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9413         remote_mds_nodsh && skip "remote MDS with nodsh"
9414         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9415
9416         changelog_users $SINGLEMDS | grep "^cl" &&
9417                 skip "active changelog user"
9418
9419         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9420
9421         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9422                 skip_env "missing llog_reader"
9423
9424         mkdir_on_mdt0 $DIR/$tdir
9425
9426         local f=$DIR/$tdir/$tfile
9427         local mdt_dev
9428         local tmpfile
9429         local plain
9430
9431         changelog_register || error "cannot register changelog user"
9432
9433         # set changelog_mask to ALL
9434         changelog_chmask "ALL"
9435         changelog_clear
9436
9437         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9438         unlinkmany ${f}- 100 || error "unlinkmany failed"
9439
9440         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9441         mdt_dev=$(facet_device $SINGLEMDS)
9442
9443         do_facet $SINGLEMDS sync
9444         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9445                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9446                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9447
9448         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9449
9450         # if $tmpfile is not on EXT3 filesystem for some reason
9451         [[ ${plain:0:1} == 'O' ]] ||
9452                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9453
9454         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9455                 $mdt_dev; stat -c %s $tmpfile")
9456         echo "Truncate llog from $size to $((size - size % 8192))"
9457         size=$((size - size % 8192))
9458         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9459         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9460                 grep -c 'in bitmap only')
9461         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9462
9463         size=$((size - 9000))
9464         echo "Corrupt llog in the middle at $size"
9465         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9466                 count=333 conv=notrunc
9467         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9468                 grep -c 'next chunk')
9469         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9470 }
9471 run_test 60j "llog_reader reports corruptions"
9472
9473 test_61a() {
9474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9475
9476         f="$DIR/f61"
9477         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9478         cancel_lru_locks osc
9479         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9480         sync
9481 }
9482 run_test 61a "mmap() writes don't make sync hang ================"
9483
9484 test_61b() {
9485         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9486 }
9487 run_test 61b "mmap() of unstriped file is successful"
9488
9489 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9490 # Though this test is irrelevant anymore, it helped to reveal some
9491 # other grant bugs (LU-4482), let's keep it.
9492 test_63a() {   # was test_63
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494
9495         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9496
9497         for i in `seq 10` ; do
9498                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9499                 sleep 5
9500                 kill $!
9501                 sleep 1
9502         done
9503
9504         rm -f $DIR/f63 || true
9505 }
9506 run_test 63a "Verify oig_wait interruption does not crash ======="
9507
9508 # bug 2248 - async write errors didn't return to application on sync
9509 # bug 3677 - async write errors left page locked
9510 test_63b() {
9511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9512
9513         debugsave
9514         lctl set_param debug=-1
9515
9516         # ensure we have a grant to do async writes
9517         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9518         rm $DIR/$tfile
9519
9520         sync    # sync lest earlier test intercept the fail_loc
9521
9522         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9523         lctl set_param fail_loc=0x80000406
9524         $MULTIOP $DIR/$tfile Owy && \
9525                 error "sync didn't return ENOMEM"
9526         sync; sleep 2; sync     # do a real sync this time to flush page
9527         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9528                 error "locked page left in cache after async error" || true
9529         debugrestore
9530 }
9531 run_test 63b "async write errors should be returned to fsync ==="
9532
9533 test_64a () {
9534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9535
9536         lfs df $DIR
9537         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9538 }
9539 run_test 64a "verify filter grant calculations (in kernel) ====="
9540
9541 test_64b () {
9542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9543
9544         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9545 }
9546 run_test 64b "check out-of-space detection on client"
9547
9548 test_64c() {
9549         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9550 }
9551 run_test 64c "verify grant shrink"
9552
9553 import_param() {
9554         local tgt=$1
9555         local param=$2
9556
9557         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9558 }
9559
9560 # this does exactly what osc_request.c:osc_announce_cached() does in
9561 # order to calculate max amount of grants to ask from server
9562 want_grant() {
9563         local tgt=$1
9564
9565         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9566         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9567
9568         ((rpc_in_flight++));
9569         nrpages=$((nrpages * rpc_in_flight))
9570
9571         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9572
9573         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9574
9575         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9576         local undirty=$((nrpages * PAGE_SIZE))
9577
9578         local max_extent_pages
9579         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9580         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9581         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9582         local grant_extent_tax
9583         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9584
9585         undirty=$((undirty + nrextents * grant_extent_tax))
9586
9587         echo $undirty
9588 }
9589
9590 # this is size of unit for grant allocation. It should be equal to
9591 # what tgt_grant.c:tgt_grant_chunk() calculates
9592 grant_chunk() {
9593         local tgt=$1
9594         local max_brw_size
9595         local grant_extent_tax
9596
9597         max_brw_size=$(import_param $tgt max_brw_size)
9598
9599         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9600
9601         echo $(((max_brw_size + grant_extent_tax) * 2))
9602 }
9603
9604 test_64d() {
9605         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9606                 skip "OST < 2.10.55 doesn't limit grants enough"
9607
9608         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9609
9610         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9611                 skip "no grant_param connect flag"
9612
9613         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9614
9615         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9616         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9617
9618
9619         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9620         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9621
9622         $LFS setstripe $DIR/$tfile -i 0 -c 1
9623         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9624         ddpid=$!
9625
9626         while kill -0 $ddpid; do
9627                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9628
9629                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9630                         kill $ddpid
9631                         error "cur_grant $cur_grant > $max_cur_granted"
9632                 fi
9633
9634                 sleep 1
9635         done
9636 }
9637 run_test 64d "check grant limit exceed"
9638
9639 check_grants() {
9640         local tgt=$1
9641         local expected=$2
9642         local msg=$3
9643         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9644
9645         ((cur_grants == expected)) ||
9646                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9647 }
9648
9649 round_up_p2() {
9650         echo $((($1 + $2 - 1) & ~($2 - 1)))
9651 }
9652
9653 test_64e() {
9654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9655         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9656                 skip "Need OSS version at least 2.11.56"
9657
9658         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9659         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9660         $LCTL set_param debug=+cache
9661
9662         # Remount client to reset grant
9663         remount_client $MOUNT || error "failed to remount client"
9664         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9665
9666         local init_grants=$(import_param $osc_tgt initial_grant)
9667
9668         check_grants $osc_tgt $init_grants "init grants"
9669
9670         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9671         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9672         local gbs=$(import_param $osc_tgt grant_block_size)
9673
9674         # write random number of bytes from max_brw_size / 4 to max_brw_size
9675         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9676         # align for direct io
9677         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9678         # round to grant consumption unit
9679         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9680
9681         local grants=$((wb_round_up + extent_tax))
9682
9683         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9684         stack_trap "rm -f $DIR/$tfile"
9685
9686         # define OBD_FAIL_TGT_NO_GRANT 0x725
9687         # make the server not grant more back
9688         do_facet ost1 $LCTL set_param fail_loc=0x725
9689         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9690
9691         do_facet ost1 $LCTL set_param fail_loc=0
9692
9693         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9694
9695         rm -f $DIR/$tfile || error "rm failed"
9696
9697         # Remount client to reset grant
9698         remount_client $MOUNT || error "failed to remount client"
9699         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9700
9701         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9702
9703         # define OBD_FAIL_TGT_NO_GRANT 0x725
9704         # make the server not grant more back
9705         do_facet ost1 $LCTL set_param fail_loc=0x725
9706         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9707         do_facet ost1 $LCTL set_param fail_loc=0
9708
9709         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9710 }
9711 run_test 64e "check grant consumption (no grant allocation)"
9712
9713 test_64f() {
9714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9715
9716         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9717         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9718         $LCTL set_param debug=+cache
9719
9720         # Remount client to reset grant
9721         remount_client $MOUNT || error "failed to remount client"
9722         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9723
9724         local init_grants=$(import_param $osc_tgt initial_grant)
9725         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9726         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9727         local gbs=$(import_param $osc_tgt grant_block_size)
9728         local chunk=$(grant_chunk $osc_tgt)
9729
9730         # write random number of bytes from max_brw_size / 4 to max_brw_size
9731         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9732         # align for direct io
9733         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9734         # round to grant consumption unit
9735         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9736
9737         local grants=$((wb_round_up + extent_tax))
9738
9739         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9740         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9741                 error "error writing to $DIR/$tfile"
9742
9743         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9744                 "direct io with grant allocation"
9745
9746         rm -f $DIR/$tfile || error "rm failed"
9747
9748         # Remount client to reset grant
9749         remount_client $MOUNT || error "failed to remount client"
9750         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9751
9752         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9753
9754         # Testing that buffered IO consumes grant on the client
9755
9756         # Delay the RPC on the server so it's guaranteed to not complete even
9757         # if the RPC is sent from the client
9758         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9759         $LCTL set_param fail_loc=0x50a fail_val=3
9760         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9761                 error "error writing to $DIR/$tfile with buffered IO"
9762
9763         check_grants $osc_tgt $((init_grants - grants)) \
9764                 "buffered io, not write rpc"
9765
9766         # Clear the fail loc and do a sync on the client
9767         $LCTL set_param fail_loc=0 fail_val=0
9768         sync
9769
9770         # RPC is now known to have sent
9771         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9772                 "buffered io, one RPC"
9773 }
9774 run_test 64f "check grant consumption (with grant allocation)"
9775
9776 test_64g() {
9777         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9778                 skip "Need MDS version at least 2.14.56"
9779
9780         local mdts=$(comma_list $(mdts_nodes))
9781
9782         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9783                         tr '\n' ' ')
9784         stack_trap "$LCTL set_param $old"
9785
9786         # generate dirty pages and increase dirty granted on MDT
9787         stack_trap "rm -f $DIR/$tfile-*"
9788         for (( i = 0; i < 10; i++)); do
9789                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9790                         error "can't set stripe"
9791                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9792                         error "can't dd"
9793                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9794                         $LFS getstripe $DIR/$tfile-$i
9795                         error "not DoM file"
9796                 }
9797         done
9798
9799         # flush dirty pages
9800         sync
9801
9802         # wait until grant shrink reset grant dirty on MDTs
9803         for ((i = 0; i < 120; i++)); do
9804                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9805                         awk '{sum=sum+$1} END {print sum}')
9806                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9807                 echo "$grant_dirty grants, $vm_dirty pages"
9808                 (( grant_dirty + vm_dirty == 0 )) && break
9809                 (( i == 3 )) && sync &&
9810                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9811                 sleep 1
9812         done
9813
9814         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9815                 awk '{sum=sum+$1} END {print sum}')
9816         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9817 }
9818 run_test 64g "grant shrink on MDT"
9819
9820 test_64h() {
9821         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9822                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9823
9824         local instance=$($LFS getname -i $DIR)
9825         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9826         local num_exps=$(do_facet ost1 \
9827             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9828         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9829         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9830         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9831
9832         # 10MiB is for file to be written, max_brw_size * 16 *
9833         # num_exps is space reserve so that tgt_grant_shrink() decided
9834         # to not shrink
9835         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9836         (( avail * 1024 < expect )) &&
9837                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9838
9839         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9840         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9841         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9842         $LCTL set_param osc.*OST0000*.grant_shrink=1
9843         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9844
9845         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9846         stack_trap "rm -f $DIR/$tfile"
9847         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9848
9849         # drop cache so that coming read would do rpc
9850         cancel_lru_locks osc
9851
9852         # shrink interval is set to 10, pause for 7 seconds so that
9853         # grant thread did not wake up yet but coming read entered
9854         # shrink mode for rpc (osc_should_shrink_grant())
9855         sleep 7
9856
9857         declare -a cur_grant_bytes
9858         declare -a tot_granted
9859         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9860         tot_granted[0]=$(do_facet ost1 \
9861             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9862
9863         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9864
9865         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9866         tot_granted[1]=$(do_facet ost1 \
9867             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9868
9869         # grant change should be equal on both sides
9870         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9871                 tot_granted[0] - tot_granted[1])) ||
9872                 error "grant change mismatch, "                                \
9873                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9874                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9875 }
9876 run_test 64h "grant shrink on read"
9877
9878 test_64i() {
9879         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9880                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9881
9882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9883         remote_ost_nodsh && skip "remote OSTs with nodsh"
9884
9885         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9886         stack_trap "rm -f $DIR/$tfile"
9887
9888         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9889
9890         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9891         local instance=$($LFS getname -i $DIR)
9892
9893         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9894         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9895
9896         # shrink grants and simulate rpc loss
9897         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9898         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9899         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9900
9901         fail ost1
9902
9903         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9904
9905         local testid=$(echo $TESTNAME | tr '_' ' ')
9906
9907         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9908                 grep "GRANT, real grant" &&
9909                 error "client has more grants then it owns" || true
9910 }
9911 run_test 64i "shrink on reconnect"
9912
9913 # bug 1414 - set/get directories' stripe info
9914 test_65a() {
9915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9916
9917         test_mkdir $DIR/$tdir
9918         touch $DIR/$tdir/f1
9919         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9920 }
9921 run_test 65a "directory with no stripe info"
9922
9923 test_65b() {
9924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9925
9926         test_mkdir $DIR/$tdir
9927         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9928
9929         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9930                                                 error "setstripe"
9931         touch $DIR/$tdir/f2
9932         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9933 }
9934 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9935
9936 test_65c() {
9937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9938         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9939
9940         test_mkdir $DIR/$tdir
9941         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9942
9943         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9944                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9945         touch $DIR/$tdir/f3
9946         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9947 }
9948 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9949
9950 test_65d() {
9951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9952
9953         test_mkdir $DIR/$tdir
9954         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9955         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9956
9957         if [[ $STRIPECOUNT -le 0 ]]; then
9958                 sc=1
9959         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9960                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9961                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9962         else
9963                 sc=$(($STRIPECOUNT - 1))
9964         fi
9965         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9966         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9967         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9968                 error "lverify failed"
9969 }
9970 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9971
9972 test_65e() {
9973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9974
9975         # LU-16904 delete layout when root is set as PFL layout
9976         save_layout_restore_at_exit $MOUNT
9977         $LFS setstripe -d $MOUNT || error "setstripe failed"
9978
9979         test_mkdir $DIR/$tdir
9980
9981         $LFS setstripe $DIR/$tdir || error "setstripe"
9982         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9983                                         error "no stripe info failed"
9984         touch $DIR/$tdir/f6
9985         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9986 }
9987 run_test 65e "directory setstripe defaults"
9988
9989 test_65f() {
9990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9991
9992         test_mkdir $DIR/${tdir}f
9993         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9994                 error "setstripe succeeded" || true
9995 }
9996 run_test 65f "dir setstripe permission (should return error) ==="
9997
9998 test_65g() {
9999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10000
10001         # LU-16904 delete layout when root is set as PFL layout
10002         save_layout_restore_at_exit $MOUNT
10003         $LFS setstripe -d $MOUNT || error "setstripe failed"
10004
10005         test_mkdir $DIR/$tdir
10006         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10007
10008         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10009                 error "setstripe -S failed"
10010         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10011         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10012                 error "delete default stripe failed"
10013 }
10014 run_test 65g "directory setstripe -d"
10015
10016 test_65h() {
10017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10018
10019         test_mkdir $DIR/$tdir
10020         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10021
10022         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10023                 error "setstripe -S failed"
10024         test_mkdir $DIR/$tdir/dd1
10025         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10026                 error "stripe info inherit failed"
10027 }
10028 run_test 65h "directory stripe info inherit ===================="
10029
10030 test_65i() {
10031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10032
10033         save_layout_restore_at_exit $MOUNT
10034
10035         # bug6367: set non-default striping on root directory
10036         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10037
10038         # bug12836: getstripe on -1 default directory striping
10039         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10040
10041         # bug12836: getstripe -v on -1 default directory striping
10042         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10043
10044         # bug12836: new find on -1 default directory striping
10045         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10046 }
10047 run_test 65i "various tests to set root directory striping"
10048
10049 test_65j() { # bug6367
10050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10051
10052         sync; sleep 1
10053
10054         # if we aren't already remounting for each test, do so for this test
10055         if [ "$I_MOUNTED" = "yes" ]; then
10056                 cleanup || error "failed to unmount"
10057                 setup
10058         fi
10059
10060         save_layout_restore_at_exit $MOUNT
10061
10062         $LFS setstripe -d $MOUNT || error "setstripe failed"
10063 }
10064 run_test 65j "set default striping on root directory (bug 6367)="
10065
10066 cleanup_65k() {
10067         rm -rf $DIR/$tdir
10068         wait_delete_completed
10069         do_facet $SINGLEMDS "lctl set_param -n \
10070                 osp.$ost*MDT0000.max_create_count=$max_count"
10071         do_facet $SINGLEMDS "lctl set_param -n \
10072                 osp.$ost*MDT0000.create_count=$count"
10073         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10074         echo $INACTIVE_OSC "is Activate"
10075
10076         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10077 }
10078
10079 test_65k() { # bug11679
10080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10081         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10082         remote_mds_nodsh && skip "remote MDS with nodsh"
10083
10084         local disable_precreate=true
10085         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10086                 disable_precreate=false
10087
10088         echo "Check OST status: "
10089         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10090                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10091
10092         for OSC in $MDS_OSCS; do
10093                 echo $OSC "is active"
10094                 do_facet $SINGLEMDS lctl --device %$OSC activate
10095         done
10096
10097         for INACTIVE_OSC in $MDS_OSCS; do
10098                 local ost=$(osc_to_ost $INACTIVE_OSC)
10099                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10100                                lov.*md*.target_obd |
10101                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10102
10103                 mkdir -p $DIR/$tdir
10104                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10105                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10106
10107                 echo "Deactivate: " $INACTIVE_OSC
10108                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10109
10110                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10111                               osp.$ost*MDT0000.create_count")
10112                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10113                                   osp.$ost*MDT0000.max_create_count")
10114                 $disable_precreate &&
10115                         do_facet $SINGLEMDS "lctl set_param -n \
10116                                 osp.$ost*MDT0000.max_create_count=0"
10117
10118                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10119                         [ -f $DIR/$tdir/$idx ] && continue
10120                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10121                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10122                                 { cleanup_65k;
10123                                   error "setstripe $idx should succeed"; }
10124                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10125                 done
10126                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10127                 rmdir $DIR/$tdir
10128
10129                 do_facet $SINGLEMDS "lctl set_param -n \
10130                         osp.$ost*MDT0000.max_create_count=$max_count"
10131                 do_facet $SINGLEMDS "lctl set_param -n \
10132                         osp.$ost*MDT0000.create_count=$count"
10133                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10134                 echo $INACTIVE_OSC "is Activate"
10135
10136                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10137         done
10138 }
10139 run_test 65k "validate manual striping works properly with deactivated OSCs"
10140
10141 test_65l() { # bug 12836
10142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10143
10144         test_mkdir -p $DIR/$tdir/test_dir
10145         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10146         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10147 }
10148 run_test 65l "lfs find on -1 stripe dir ========================"
10149
10150 test_65m() {
10151         local layout=$(save_layout $MOUNT)
10152         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10153                 restore_layout $MOUNT $layout
10154                 error "setstripe should fail by non-root users"
10155         }
10156         true
10157 }
10158 run_test 65m "normal user can't set filesystem default stripe"
10159
10160 test_65n() {
10161         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10162         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10163                 skip "Need MDS version at least 2.12.50"
10164         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10165
10166         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10167         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10168         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10169
10170         save_layout_restore_at_exit $MOUNT
10171
10172         # new subdirectory under root directory should not inherit
10173         # the default layout from root
10174         # LU-16904 check if the root is set as PFL layout
10175         local numcomp=$($LFS getstripe --component-count $MOUNT)
10176
10177         if [[ $numcomp -eq 0 ]]; then
10178                 local dir1=$MOUNT/$tdir-1
10179                 mkdir $dir1 || error "mkdir $dir1 failed"
10180                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10181                         error "$dir1 shouldn't have LOV EA"
10182         fi
10183
10184         # delete the default layout on root directory
10185         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10186
10187         local dir2=$MOUNT/$tdir-2
10188         mkdir $dir2 || error "mkdir $dir2 failed"
10189         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10190                 error "$dir2 shouldn't have LOV EA"
10191
10192         # set a new striping pattern on root directory
10193         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10194         local new_def_stripe_size=$((def_stripe_size * 2))
10195         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10196                 error "set stripe size on $MOUNT failed"
10197
10198         # new file created in $dir2 should inherit the new stripe size from
10199         # the filesystem default
10200         local file2=$dir2/$tfile-2
10201         touch $file2 || error "touch $file2 failed"
10202
10203         local file2_stripe_size=$($LFS getstripe -S $file2)
10204         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10205         {
10206                 echo "file2_stripe_size: '$file2_stripe_size'"
10207                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10208                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10209         }
10210
10211         local dir3=$MOUNT/$tdir-3
10212         mkdir $dir3 || error "mkdir $dir3 failed"
10213         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10214         # the root layout, which is the actual default layout that will be used
10215         # when new files are created in $dir3.
10216         local dir3_layout=$(get_layout_param $dir3)
10217         local root_dir_layout=$(get_layout_param $MOUNT)
10218         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10219         {
10220                 echo "dir3_layout: '$dir3_layout'"
10221                 echo "root_dir_layout: '$root_dir_layout'"
10222                 error "$dir3 should show the default layout from $MOUNT"
10223         }
10224
10225         # set OST pool on root directory
10226         local pool=$TESTNAME
10227         pool_add $pool || error "add $pool failed"
10228         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10229                 error "add targets to $pool failed"
10230
10231         $LFS setstripe -p $pool $MOUNT ||
10232                 error "set OST pool on $MOUNT failed"
10233
10234         # new file created in $dir3 should inherit the pool from
10235         # the filesystem default
10236         local file3=$dir3/$tfile-3
10237         touch $file3 || error "touch $file3 failed"
10238
10239         local file3_pool=$($LFS getstripe -p $file3)
10240         [[ "$file3_pool" = "$pool" ]] ||
10241                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10242
10243         local dir4=$MOUNT/$tdir-4
10244         mkdir $dir4 || error "mkdir $dir4 failed"
10245         local dir4_layout=$(get_layout_param $dir4)
10246         root_dir_layout=$(get_layout_param $MOUNT)
10247         echo "$LFS getstripe -d $dir4"
10248         $LFS getstripe -d $dir4
10249         echo "$LFS getstripe -d $MOUNT"
10250         $LFS getstripe -d $MOUNT
10251         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10252         {
10253                 echo "dir4_layout: '$dir4_layout'"
10254                 echo "root_dir_layout: '$root_dir_layout'"
10255                 error "$dir4 should show the default layout from $MOUNT"
10256         }
10257
10258         # new file created in $dir4 should inherit the pool from
10259         # the filesystem default
10260         local file4=$dir4/$tfile-4
10261         touch $file4 || error "touch $file4 failed"
10262
10263         local file4_pool=$($LFS getstripe -p $file4)
10264         [[ "$file4_pool" = "$pool" ]] ||
10265                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10266
10267         # new subdirectory under non-root directory should inherit
10268         # the default layout from its parent directory
10269         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10270                 error "set directory layout on $dir4 failed"
10271
10272         local dir5=$dir4/$tdir-5
10273         mkdir $dir5 || error "mkdir $dir5 failed"
10274
10275         dir4_layout=$(get_layout_param $dir4)
10276         local dir5_layout=$(get_layout_param $dir5)
10277         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10278         {
10279                 echo "dir4_layout: '$dir4_layout'"
10280                 echo "dir5_layout: '$dir5_layout'"
10281                 error "$dir5 should inherit the default layout from $dir4"
10282         }
10283
10284         # though subdir under ROOT doesn't inherit default layout, but
10285         # its sub dir/file should be created with default layout.
10286         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10287         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10288                 skip "Need MDS version at least 2.12.59"
10289
10290         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10291         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10292         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10293
10294         if [ $default_lmv_hash == "none" ]; then
10295                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10296         else
10297                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10298                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10299         fi
10300
10301         $LFS setdirstripe -D -c 2 $MOUNT ||
10302                 error "setdirstripe -D -c 2 failed"
10303         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10304         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10305         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10306
10307         # $dir4 layout includes pool
10308         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10309         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10310                 error "pool lost on setstripe"
10311         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10312         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10313                 error "pool lost on compound layout setstripe"
10314 }
10315 run_test 65n "don't inherit default layout from root for new subdirectories"
10316
10317 test_65o() {
10318         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10319                 skip "need MDS version at least 2.14.57"
10320
10321         # set OST pool on root directory
10322         local pool=$TESTNAME
10323
10324         pool_add $pool || error "add $pool failed"
10325         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10326                 error "add targets to $pool failed"
10327
10328         local dir1=$MOUNT/$tdir
10329
10330         mkdir $dir1 || error "mkdir $dir1 failed"
10331
10332         # set a new striping pattern on root directory
10333         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10334
10335         $LFS setstripe -p $pool $dir1 ||
10336                 error "set directory layout on $dir1 failed"
10337
10338         # $dir1 layout includes pool
10339         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10340         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10341                 error "pool lost on setstripe"
10342         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10343         $LFS getstripe $dir1
10344         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10345                 error "pool lost on compound layout setstripe"
10346
10347         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10348                 error "setdirstripe failed on sub-dir with inherited pool"
10349         $LFS getstripe $dir1/dir2
10350         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10351                 error "pool lost on compound layout setdirstripe"
10352
10353         $LFS setstripe -E -1 -c 1 $dir1
10354         $LFS getstripe -d $dir1
10355         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10356                 error "pool lost on setstripe"
10357 }
10358 run_test 65o "pool inheritance for mdt component"
10359
10360 test_65p () { # LU-16152
10361         local src_dir=$DIR/$tdir/src_dir
10362         local dst_dir=$DIR/$tdir/dst_dir
10363         local yaml_file=$DIR/$tdir/layout.yaml
10364         local border
10365
10366         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10367                 skip "Need at least version 2.15.51"
10368
10369         test_mkdir -p $src_dir
10370         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10371                 error "failed to setstripe"
10372         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10373                 error "failed to getstripe"
10374
10375         test_mkdir -p $dst_dir
10376         $LFS setstripe --yaml $yaml_file $dst_dir ||
10377                 error "failed to setstripe with yaml file"
10378         border=$($LFS getstripe -d $dst_dir |
10379                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10380                 error "failed to getstripe"
10381
10382         # 2048M is 0x80000000, or 2147483648
10383         (( $border == 2147483648 )) ||
10384                 error "failed to handle huge number in yaml layout"
10385 }
10386 run_test 65p "setstripe with yaml file and huge number"
10387
10388 test_65p () { # LU-16194
10389         local src_dir=$DIR/$tdir/src_dir
10390
10391         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10392                 skip "Need at least version 2.15.51"
10393
10394         test_mkdir -p $src_dir
10395         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10396         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10397                 error "should fail if extent start/end >=8E"
10398
10399         # EOF should work as before
10400         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10401                 error "failed to setstripe normally"
10402 }
10403 run_test 65p "setstripe with >=8E offset should fail"
10404
10405 # bug 2543 - update blocks count on client
10406 test_66() {
10407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10408
10409         local COUNT=${COUNT:-8}
10410         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10411         sync; sync_all_data; sync; sync_all_data
10412         cancel_lru_locks osc
10413         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10414         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10415 }
10416 run_test 66 "update inode blocks count on client ==============="
10417
10418 meminfo() {
10419         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10420 }
10421
10422 swap_used() {
10423         swapon -s | awk '($1 == "'$1'") { print $4 }'
10424 }
10425
10426 # bug5265, obdfilter oa2dentry return -ENOENT
10427 # #define OBD_FAIL_SRV_ENOENT 0x217
10428 test_69() {
10429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10430         remote_ost_nodsh && skip "remote OST with nodsh"
10431
10432         f="$DIR/$tfile"
10433         $LFS setstripe -c 1 -i 0 $f
10434         stack_trap "rm -f $f ${f}.2"
10435
10436         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10437
10438         do_facet ost1 lctl set_param fail_loc=0x217
10439         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10440         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10441
10442         do_facet ost1 lctl set_param fail_loc=0
10443         $DIRECTIO write $f 0 2 || error "write error"
10444
10445         cancel_lru_locks osc
10446         $DIRECTIO read $f 0 1 || error "read error"
10447
10448         do_facet ost1 lctl set_param fail_loc=0x217
10449         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10450
10451         do_facet ost1 lctl set_param fail_loc=0
10452 }
10453 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10454
10455 test_70a() {
10456         # Perform a really simple test of health write
10457         # and health check
10458
10459         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10460
10461         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10462
10463         # Test with health write off
10464         do_facet ost1 $LCTL set_param enable_health_write off ||
10465                 error "can't set enable_health_write off"
10466         do_facet ost1 $LCTL get_param enable_health_write ||
10467                 error "can't get enable_health_write"
10468
10469         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10470                 error "not healthy (1)"
10471
10472         # Test with health write on
10473         do_facet ost1 $LCTL set_param enable_health_write on ||
10474                 error "can't set enable_health_write on"
10475         do_facet ost1 $LCTL get_param enable_health_write ||
10476                 error "can't get enable_health_write"
10477
10478         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10479                 error "not healthy (2)"
10480 }
10481 run_test 70a "verify health_check, health_write don't explode (on OST)"
10482
10483 test_71() {
10484         test_mkdir $DIR/$tdir
10485         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10486         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10487 }
10488 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10489
10490 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10492         [ "$RUNAS_ID" = "$UID" ] &&
10493                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10494         # Check that testing environment is properly set up. Skip if not
10495         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10496                 skip_env "User $RUNAS_ID does not exist - skipping"
10497
10498         touch $DIR/$tfile
10499         chmod 777 $DIR/$tfile
10500         chmod ug+s $DIR/$tfile
10501         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10502                 error "$RUNAS dd $DIR/$tfile failed"
10503         # See if we are still setuid/sgid
10504         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10505                 error "S/gid is not dropped on write"
10506         # Now test that MDS is updated too
10507         cancel_lru_locks mdc
10508         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10509                 error "S/gid is not dropped on MDS"
10510         rm -f $DIR/$tfile
10511 }
10512 run_test 72a "Test that remove suid works properly (bug5695) ===="
10513
10514 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10515         local perm
10516
10517         [ "$RUNAS_ID" = "$UID" ] &&
10518                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10519         [ "$RUNAS_ID" -eq 0 ] &&
10520                 skip_env "RUNAS_ID = 0 -- skipping"
10521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10522         # Check that testing environment is properly set up. Skip if not
10523         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10524                 skip_env "User $RUNAS_ID does not exist - skipping"
10525
10526         touch $DIR/${tfile}-f{g,u}
10527         test_mkdir $DIR/${tfile}-dg
10528         test_mkdir $DIR/${tfile}-du
10529         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10530         chmod g+s $DIR/${tfile}-{f,d}g
10531         chmod u+s $DIR/${tfile}-{f,d}u
10532         for perm in 777 2777 4777; do
10533                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10534                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10535                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10536                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10537         done
10538         true
10539 }
10540 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10541
10542 # bug 3462 - multiple simultaneous MDC requests
10543 test_73() {
10544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10545
10546         test_mkdir $DIR/d73-1
10547         test_mkdir $DIR/d73-2
10548         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10549         pid1=$!
10550
10551         lctl set_param fail_loc=0x80000129
10552         $MULTIOP $DIR/d73-1/f73-2 Oc &
10553         sleep 1
10554         lctl set_param fail_loc=0
10555
10556         $MULTIOP $DIR/d73-2/f73-3 Oc &
10557         pid3=$!
10558
10559         kill -USR1 $pid1
10560         wait $pid1 || return 1
10561
10562         sleep 25
10563
10564         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10565         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10566         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10567
10568         rm -rf $DIR/d73-*
10569 }
10570 run_test 73 "multiple MDC requests (should not deadlock)"
10571
10572 test_74a() { # bug 6149, 6184
10573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10574
10575         touch $DIR/f74a
10576         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10577         #
10578         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10579         # will spin in a tight reconnection loop
10580         $LCTL set_param fail_loc=0x8000030e
10581         # get any lock that won't be difficult - lookup works.
10582         ls $DIR/f74a
10583         $LCTL set_param fail_loc=0
10584         rm -f $DIR/f74a
10585         true
10586 }
10587 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10588
10589 test_74b() { # bug 13310
10590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10591
10592         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10593         #
10594         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10595         # will spin in a tight reconnection loop
10596         $LCTL set_param fail_loc=0x8000030e
10597         # get a "difficult" lock
10598         touch $DIR/f74b
10599         $LCTL set_param fail_loc=0
10600         rm -f $DIR/f74b
10601         true
10602 }
10603 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10604
10605 test_74c() {
10606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10607
10608         #define OBD_FAIL_LDLM_NEW_LOCK
10609         $LCTL set_param fail_loc=0x319
10610         touch $DIR/$tfile && error "touch successful"
10611         $LCTL set_param fail_loc=0
10612         true
10613 }
10614 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10615
10616 slab_lic=/sys/kernel/slab/lustre_inode_cache
10617 num_objects() {
10618         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10619         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10620                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10621 }
10622
10623 test_76a() { # Now for b=20433, added originally in b=1443
10624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10625
10626         cancel_lru_locks osc
10627         # there may be some slab objects cached per core
10628         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10629         local before=$(num_objects)
10630         local count=$((512 * cpus))
10631         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10632         local margin=$((count / 10))
10633         if [[ -f $slab_lic/aliases ]]; then
10634                 local aliases=$(cat $slab_lic/aliases)
10635                 (( aliases > 0 )) && margin=$((margin * aliases))
10636         fi
10637
10638         echo "before slab objects: $before"
10639         for i in $(seq $count); do
10640                 touch $DIR/$tfile
10641                 rm -f $DIR/$tfile
10642         done
10643         cancel_lru_locks osc
10644         local after=$(num_objects)
10645         echo "created: $count, after slab objects: $after"
10646         # shared slab counts are not very accurate, allow significant margin
10647         # the main goal is that the cache growth is not permanently > $count
10648         while (( after > before + margin )); do
10649                 sleep 1
10650                 after=$(num_objects)
10651                 wait=$((wait + 1))
10652                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10653                 if (( wait > 60 )); then
10654                         error "inode slab grew from $before+$margin to $after"
10655                 fi
10656         done
10657 }
10658 run_test 76a "confirm clients recycle inodes properly ===="
10659
10660 test_76b() {
10661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10662         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10663
10664         local count=512
10665         local before=$(num_objects)
10666
10667         for i in $(seq $count); do
10668                 mkdir $DIR/$tdir
10669                 rmdir $DIR/$tdir
10670         done
10671
10672         local after=$(num_objects)
10673         local wait=0
10674
10675         while (( after > before )); do
10676                 sleep 1
10677                 after=$(num_objects)
10678                 wait=$((wait + 1))
10679                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10680                 if (( wait > 60 )); then
10681                         error "inode slab grew from $before to $after"
10682                 fi
10683         done
10684
10685         echo "slab objects before: $before, after: $after"
10686 }
10687 run_test 76b "confirm clients recycle directory inodes properly ===="
10688
10689 export ORIG_CSUM=""
10690 set_checksums()
10691 {
10692         # Note: in sptlrpc modes which enable its own bulk checksum, the
10693         # original crc32_le bulk checksum will be automatically disabled,
10694         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10695         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10696         # In this case set_checksums() will not be no-op, because sptlrpc
10697         # bulk checksum will be enabled all through the test.
10698
10699         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10700         lctl set_param -n osc.*.checksums $1
10701         return 0
10702 }
10703
10704 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10705                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10706 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10707                              tr -d [] | head -n1)}
10708 set_checksum_type()
10709 {
10710         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10711         rc=$?
10712         log "set checksum type to $1, rc = $rc"
10713         return $rc
10714 }
10715
10716 get_osc_checksum_type()
10717 {
10718         # arugment 1: OST name, like OST0000
10719         ost=$1
10720         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10721                         sed 's/.*\[\(.*\)\].*/\1/g')
10722         rc=$?
10723         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10724         echo $checksum_type
10725 }
10726
10727 F77_TMP=$TMP/f77-temp
10728 F77SZ=8
10729 setup_f77() {
10730         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10731                 error "error writing to $F77_TMP"
10732 }
10733
10734 test_77a() { # bug 10889
10735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10736         $GSS && skip_env "could not run with gss"
10737
10738         [ ! -f $F77_TMP ] && setup_f77
10739         set_checksums 1
10740         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10741         set_checksums 0
10742         rm -f $DIR/$tfile
10743 }
10744 run_test 77a "normal checksum read/write operation"
10745
10746 test_77b() { # bug 10889
10747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10748         $GSS && skip_env "could not run with gss"
10749
10750         [ ! -f $F77_TMP ] && setup_f77
10751         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10752         $LCTL set_param fail_loc=0x80000409
10753         set_checksums 1
10754
10755         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10756                 error "dd error: $?"
10757         $LCTL set_param fail_loc=0
10758
10759         for algo in $CKSUM_TYPES; do
10760                 cancel_lru_locks osc
10761                 set_checksum_type $algo
10762                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10763                 $LCTL set_param fail_loc=0x80000408
10764                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10765                 $LCTL set_param fail_loc=0
10766         done
10767         set_checksums 0
10768         set_checksum_type $ORIG_CSUM_TYPE
10769         rm -f $DIR/$tfile
10770 }
10771 run_test 77b "checksum error on client write, read"
10772
10773 cleanup_77c() {
10774         trap 0
10775         set_checksums 0
10776         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10777         $check_ost &&
10778                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10779         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10780         $check_ost && [ -n "$ost_file_prefix" ] &&
10781                 do_facet ost1 rm -f ${ost_file_prefix}\*
10782 }
10783
10784 test_77c() {
10785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10786         $GSS && skip_env "could not run with gss"
10787         remote_ost_nodsh && skip "remote OST with nodsh"
10788
10789         local bad1
10790         local osc_file_prefix
10791         local osc_file
10792         local check_ost=false
10793         local ost_file_prefix
10794         local ost_file
10795         local orig_cksum
10796         local dump_cksum
10797         local fid
10798
10799         # ensure corruption will occur on first OSS/OST
10800         $LFS setstripe -i 0 $DIR/$tfile
10801
10802         [ ! -f $F77_TMP ] && setup_f77
10803         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10804                 error "dd write error: $?"
10805         fid=$($LFS path2fid $DIR/$tfile)
10806
10807         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10808         then
10809                 check_ost=true
10810                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10811                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10812         else
10813                 echo "OSS do not support bulk pages dump upon error"
10814         fi
10815
10816         osc_file_prefix=$($LCTL get_param -n debug_path)
10817         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10818
10819         trap cleanup_77c EXIT
10820
10821         set_checksums 1
10822         # enable bulk pages dump upon error on Client
10823         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10824         # enable bulk pages dump upon error on OSS
10825         $check_ost &&
10826                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10827
10828         # flush Client cache to allow next read to reach OSS
10829         cancel_lru_locks osc
10830
10831         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10832         $LCTL set_param fail_loc=0x80000408
10833         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10834         $LCTL set_param fail_loc=0
10835
10836         rm -f $DIR/$tfile
10837
10838         # check cksum dump on Client
10839         osc_file=$(ls ${osc_file_prefix}*)
10840         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10841         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10842         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10843         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10844         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10845                      cksum)
10846         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10847         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10848                 error "dump content does not match on Client"
10849
10850         $check_ost || skip "No need to check cksum dump on OSS"
10851
10852         # check cksum dump on OSS
10853         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10854         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10855         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10856         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10857         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10858                 error "dump content does not match on OSS"
10859
10860         cleanup_77c
10861 }
10862 run_test 77c "checksum error on client read with debug"
10863
10864 test_77d() { # bug 10889
10865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10866         $GSS && skip_env "could not run with gss"
10867
10868         stack_trap "rm -f $DIR/$tfile"
10869         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10870         $LCTL set_param fail_loc=0x80000409
10871         set_checksums 1
10872         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10873                 error "direct write: rc=$?"
10874         $LCTL set_param fail_loc=0
10875         set_checksums 0
10876
10877         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10878         $LCTL set_param fail_loc=0x80000408
10879         set_checksums 1
10880         cancel_lru_locks osc
10881         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10882                 error "direct read: rc=$?"
10883         $LCTL set_param fail_loc=0
10884         set_checksums 0
10885 }
10886 run_test 77d "checksum error on OST direct write, read"
10887
10888 test_77f() { # bug 10889
10889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10890         $GSS && skip_env "could not run with gss"
10891
10892         set_checksums 1
10893         stack_trap "rm -f $DIR/$tfile"
10894         for algo in $CKSUM_TYPES; do
10895                 cancel_lru_locks osc
10896                 set_checksum_type $algo
10897                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10898                 $LCTL set_param fail_loc=0x409
10899                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10900                         error "direct write succeeded"
10901                 $LCTL set_param fail_loc=0
10902         done
10903         set_checksum_type $ORIG_CSUM_TYPE
10904         set_checksums 0
10905 }
10906 run_test 77f "repeat checksum error on write (expect error)"
10907
10908 test_77g() { # bug 10889
10909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10910         $GSS && skip_env "could not run with gss"
10911         remote_ost_nodsh && skip "remote OST with nodsh"
10912
10913         [ ! -f $F77_TMP ] && setup_f77
10914
10915         local file=$DIR/$tfile
10916         stack_trap "rm -f $file" EXIT
10917
10918         $LFS setstripe -c 1 -i 0 $file
10919         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10920         do_facet ost1 lctl set_param fail_loc=0x8000021a
10921         set_checksums 1
10922         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10923                 error "write error: rc=$?"
10924         do_facet ost1 lctl set_param fail_loc=0
10925         set_checksums 0
10926
10927         cancel_lru_locks osc
10928         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10929         do_facet ost1 lctl set_param fail_loc=0x8000021b
10930         set_checksums 1
10931         cmp $F77_TMP $file || error "file compare failed"
10932         do_facet ost1 lctl set_param fail_loc=0
10933         set_checksums 0
10934 }
10935 run_test 77g "checksum error on OST write, read"
10936
10937 test_77k() { # LU-10906
10938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10939         $GSS && skip_env "could not run with gss"
10940
10941         local cksum_param="osc.$FSNAME*.checksums"
10942         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10943         local checksum
10944         local i
10945
10946         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10947         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10948         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10949
10950         for i in 0 1; do
10951                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10952                         error "failed to set checksum=$i on MGS"
10953                 wait_update $HOSTNAME "$get_checksum" $i
10954                 #remount
10955                 echo "remount client, checksum should be $i"
10956                 remount_client $MOUNT || error "failed to remount client"
10957                 checksum=$(eval $get_checksum)
10958                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10959         done
10960         # remove persistent param to avoid races with checksum mountopt below
10961         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10962                 error "failed to delete checksum on MGS"
10963
10964         for opt in "checksum" "nochecksum"; do
10965                 #remount with mount option
10966                 echo "remount client with option $opt, checksum should be $i"
10967                 umount_client $MOUNT || error "failed to umount client"
10968                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10969                         error "failed to mount client with option '$opt'"
10970                 checksum=$(eval $get_checksum)
10971                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10972                 i=$((i - 1))
10973         done
10974
10975         remount_client $MOUNT || error "failed to remount client"
10976 }
10977 run_test 77k "enable/disable checksum correctly"
10978
10979 test_77l() {
10980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10981         $GSS && skip_env "could not run with gss"
10982
10983         set_checksums 1
10984         stack_trap "set_checksums $ORIG_CSUM" EXIT
10985         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10986
10987         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10988
10989         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10990         for algo in $CKSUM_TYPES; do
10991                 set_checksum_type $algo || error "fail to set checksum type $algo"
10992                 osc_algo=$(get_osc_checksum_type OST0000)
10993                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10994
10995                 # no locks, no reqs to let the connection idle
10996                 cancel_lru_locks osc
10997                 lru_resize_disable osc
10998                 wait_osc_import_state client ost1 IDLE
10999
11000                 # ensure ost1 is connected
11001                 stat $DIR/$tfile >/dev/null || error "can't stat"
11002                 wait_osc_import_state client ost1 FULL
11003
11004                 osc_algo=$(get_osc_checksum_type OST0000)
11005                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11006         done
11007         return 0
11008 }
11009 run_test 77l "preferred checksum type is remembered after reconnected"
11010
11011 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11012 rm -f $F77_TMP
11013 unset F77_TMP
11014
11015 test_77m() {
11016         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11017                 skip "Need at least version 2.14.52"
11018         local param=checksum_speed
11019
11020         $LCTL get_param $param || error "reading $param failed"
11021
11022         csum_speeds=$($LCTL get_param -n $param)
11023
11024         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11025                 error "known checksum types are missing"
11026 }
11027 run_test 77m "Verify checksum_speed is correctly read"
11028
11029 check_filefrag_77n() {
11030         local nr_ext=0
11031         local starts=()
11032         local ends=()
11033
11034         while read extidx a b start end rest; do
11035                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11036                         nr_ext=$(( $nr_ext + 1 ))
11037                         starts+=( ${start%..} )
11038                         ends+=( ${end%:} )
11039                 fi
11040         done < <( filefrag -sv $1 )
11041
11042         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11043         return 1
11044 }
11045
11046 test_77n() {
11047         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11048
11049         touch $DIR/$tfile
11050         $TRUNCATE $DIR/$tfile 0
11051         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11052         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11053         check_filefrag_77n $DIR/$tfile ||
11054                 skip "$tfile blocks not contiguous around hole"
11055
11056         set_checksums 1
11057         stack_trap "set_checksums $ORIG_CSUM" EXIT
11058         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11059         stack_trap "rm -f $DIR/$tfile"
11060
11061         for algo in $CKSUM_TYPES; do
11062                 if [[ "$algo" =~ ^t10 ]]; then
11063                         set_checksum_type $algo ||
11064                                 error "fail to set checksum type $algo"
11065                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11066                                 error "fail to read $tfile with $algo"
11067                 fi
11068         done
11069         rm -f $DIR/$tfile
11070         return 0
11071 }
11072 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11073
11074 test_77o() {
11075         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11076                 skip "Need MDS version at least 2.14.55"
11077         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11078                 skip "Need OST version at least 2.14.55"
11079         local ofd=obdfilter
11080         local mdt=mdt
11081
11082         # print OST checksum_type
11083         echo "$ofd.$FSNAME-*.checksum_type:"
11084         do_nodes $(comma_list $(osts_nodes)) \
11085                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11086
11087         # print MDT checksum_type
11088         echo "$mdt.$FSNAME-*.checksum_type:"
11089         do_nodes $(comma_list $(mdts_nodes)) \
11090                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11091
11092         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11093                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11094
11095         (( $o_count == $OSTCOUNT )) ||
11096                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11097
11098         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11099                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11100
11101         (( $m_count == $MDSCOUNT )) ||
11102                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11103 }
11104 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11105
11106 cleanup_test_78() {
11107         trap 0
11108         rm -f $DIR/$tfile
11109 }
11110
11111 test_78() { # bug 10901
11112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11113         remote_ost || skip_env "local OST"
11114
11115         NSEQ=5
11116         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11117         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11118         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11119         echo "MemTotal: $MEMTOTAL"
11120
11121         # reserve 256MB of memory for the kernel and other running processes,
11122         # and then take 1/2 of the remaining memory for the read/write buffers.
11123         if [ $MEMTOTAL -gt 512 ] ;then
11124                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11125         else
11126                 # for those poor memory-starved high-end clusters...
11127                 MEMTOTAL=$((MEMTOTAL / 2))
11128         fi
11129         echo "Mem to use for directio: $MEMTOTAL"
11130
11131         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11132         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11133         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11134         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11135                 head -n1)
11136         echo "Smallest OST: $SMALLESTOST"
11137         [[ $SMALLESTOST -lt 10240 ]] &&
11138                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11139
11140         trap cleanup_test_78 EXIT
11141
11142         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11143                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11144
11145         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11146         echo "File size: $F78SIZE"
11147         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11148         for i in $(seq 1 $NSEQ); do
11149                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11150                 echo directIO rdwr round $i of $NSEQ
11151                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11152         done
11153
11154         cleanup_test_78
11155 }
11156 run_test 78 "handle large O_DIRECT writes correctly ============"
11157
11158 test_79() { # bug 12743
11159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11160
11161         wait_delete_completed
11162
11163         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11164         BKFREE=$(calc_osc_kbytes kbytesfree)
11165         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11166
11167         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11168         DFTOTAL=`echo $STRING | cut -d, -f1`
11169         DFUSED=`echo $STRING  | cut -d, -f2`
11170         DFAVAIL=`echo $STRING | cut -d, -f3`
11171         DFFREE=$(($DFTOTAL - $DFUSED))
11172
11173         ALLOWANCE=$((64 * $OSTCOUNT))
11174
11175         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11176            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11177                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11178         fi
11179         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11180            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11181                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11182         fi
11183         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11184            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11185                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11186         fi
11187 }
11188 run_test 79 "df report consistency check ======================="
11189
11190 test_80() { # bug 10718
11191         remote_ost_nodsh && skip "remote OST with nodsh"
11192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11193
11194         # relax strong synchronous semantics for slow backends like ZFS
11195         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11196                 local soc="obdfilter.*.sync_lock_cancel"
11197                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11198
11199                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11200                 if [ -z "$save" ]; then
11201                         soc="obdfilter.*.sync_on_lock_cancel"
11202                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11203                 fi
11204
11205                 if [ "$save" != "never" ]; then
11206                         local hosts=$(comma_list $(osts_nodes))
11207
11208                         do_nodes $hosts $LCTL set_param $soc=never
11209                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11210                 fi
11211         fi
11212
11213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11214         sync; sleep 1; sync
11215         local before=$(date +%s)
11216         cancel_lru_locks osc
11217         local after=$(date +%s)
11218         local diff=$((after - before))
11219         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11220
11221         rm -f $DIR/$tfile
11222 }
11223 run_test 80 "Page eviction is equally fast at high offsets too"
11224
11225 test_81a() { # LU-456
11226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11227         remote_ost_nodsh && skip "remote OST with nodsh"
11228
11229         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11230         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11231         do_facet ost1 lctl set_param fail_loc=0x80000228
11232
11233         # write should trigger a retry and success
11234         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11235         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11236         RC=$?
11237         if [ $RC -ne 0 ] ; then
11238                 error "write should success, but failed for $RC"
11239         fi
11240 }
11241 run_test 81a "OST should retry write when get -ENOSPC ==============="
11242
11243 test_81b() { # LU-456
11244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11245         remote_ost_nodsh && skip "remote OST with nodsh"
11246
11247         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11248         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11249         do_facet ost1 lctl set_param fail_loc=0x228
11250
11251         # write should retry several times and return -ENOSPC finally
11252         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11253         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11254         RC=$?
11255         ENOSPC=28
11256         if [ $RC -ne $ENOSPC ] ; then
11257                 error "dd should fail for -ENOSPC, but succeed."
11258         fi
11259 }
11260 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11261
11262 test_99() {
11263         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11264
11265         test_mkdir $DIR/$tdir.cvsroot
11266         chown $RUNAS_ID $DIR/$tdir.cvsroot
11267
11268         cd $TMP
11269         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11270
11271         cd /etc/init.d
11272         # some versions of cvs import exit(1) when asked to import links or
11273         # files they can't read.  ignore those files.
11274         local toignore=$(find . -type l -printf '-I %f\n' -o \
11275                          ! -perm /4 -printf '-I %f\n')
11276         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11277                 $tdir.reposname vtag rtag
11278
11279         cd $DIR
11280         test_mkdir $DIR/$tdir.reposname
11281         chown $RUNAS_ID $DIR/$tdir.reposname
11282         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11283
11284         cd $DIR/$tdir.reposname
11285         $RUNAS touch foo99
11286         $RUNAS cvs add -m 'addmsg' foo99
11287         $RUNAS cvs update
11288         $RUNAS cvs commit -m 'nomsg' foo99
11289         rm -fr $DIR/$tdir.cvsroot
11290 }
11291 run_test 99 "cvs strange file/directory operations"
11292
11293 test_100() {
11294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11295         [[ "$NETTYPE" =~ tcp ]] ||
11296                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11297         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11298         remote_ost_nodsh && skip "remote OST with nodsh"
11299         remote_mds_nodsh && skip "remote MDS with nodsh"
11300         remote_servers || skip "useless for local single node setup"
11301
11302         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11303                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11304
11305                 rc=0
11306                 if (( ${LOCAL/*:/} >= 1024 )); then
11307                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11308                         ss -tna
11309                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11310                 fi
11311         done
11312         (( $rc == 0 )) || error "privileged port not found" )
11313 }
11314 run_test 100 "check local port using privileged port"
11315
11316 function get_named_value()
11317 {
11318     local tag=$1
11319
11320     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11321 }
11322
11323 test_101a() {
11324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11325
11326         local s
11327         local discard
11328         local nreads=10000
11329         local cache_limit=32
11330
11331         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11332         $LCTL set_param -n llite.*.read_ahead_stats=0
11333         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11334                               awk '/^max_cached_mb/ { print $2 }')
11335         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11336         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11337
11338         #
11339         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11340         #
11341         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11342         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11343
11344         discard=0
11345         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11346                    get_named_value 'read.but.discarded'); do
11347                         discard=$(($discard + $s))
11348         done
11349
11350         $LCTL get_param osc.*-osc*.rpc_stats
11351         $LCTL get_param llite.*.read_ahead_stats
11352
11353         # Discard is generally zero, but sometimes a few random reads line up
11354         # and trigger larger readahead, which is wasted & leads to discards.
11355         if [[ $(($discard)) -gt $nreads ]]; then
11356                 error "too many ($discard) discarded pages"
11357         fi
11358         rm -f $DIR/$tfile || true
11359 }
11360 run_test 101a "check read-ahead for random reads"
11361
11362 setup_test101bc() {
11363         test_mkdir $DIR/$tdir
11364         local ssize=$1
11365         local FILE_LENGTH=$2
11366         STRIPE_OFFSET=0
11367
11368         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11369
11370         local list=$(comma_list $(osts_nodes))
11371         set_osd_param $list '' read_cache_enable 0
11372         set_osd_param $list '' writethrough_cache_enable 0
11373
11374         trap cleanup_test101bc EXIT
11375         # prepare the read-ahead file
11376         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11377
11378         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11379                                 count=$FILE_SIZE_MB 2> /dev/null
11380
11381 }
11382
11383 cleanup_test101bc() {
11384         trap 0
11385         rm -rf $DIR/$tdir
11386         rm -f $DIR/$tfile
11387
11388         local list=$(comma_list $(osts_nodes))
11389         set_osd_param $list '' read_cache_enable 1
11390         set_osd_param $list '' writethrough_cache_enable 1
11391 }
11392
11393 ra_check_101() {
11394         local read_size=$1
11395         local stripe_size=$2
11396         local stride_length=$((stripe_size / read_size))
11397         local stride_width=$((stride_length * OSTCOUNT))
11398         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11399                                 (stride_width - stride_length) ))
11400         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11401                   get_named_value 'read.but.discarded' | calc_sum)
11402
11403         if [[ $discard -gt $discard_limit ]]; then
11404                 $LCTL get_param llite.*.read_ahead_stats
11405                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11406         else
11407                 echo "Read-ahead success for size ${read_size}"
11408         fi
11409 }
11410
11411 test_101b() {
11412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11413         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11414
11415         local STRIPE_SIZE=1048576
11416         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11417
11418         if [ $SLOW == "yes" ]; then
11419                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11420         else
11421                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11422         fi
11423
11424         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11425
11426         # prepare the read-ahead file
11427         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11428         cancel_lru_locks osc
11429         for BIDX in 2 4 8 16 32 64 128 256
11430         do
11431                 local BSIZE=$((BIDX*4096))
11432                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11433                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11434                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11435                 $LCTL set_param -n llite.*.read_ahead_stats=0
11436                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11437                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11438                 cancel_lru_locks osc
11439                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11440         done
11441         cleanup_test101bc
11442         true
11443 }
11444 run_test 101b "check stride-io mode read-ahead ================="
11445
11446 test_101c() {
11447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11448
11449         local STRIPE_SIZE=1048576
11450         local FILE_LENGTH=$((STRIPE_SIZE*100))
11451         local nreads=10000
11452         local rsize=65536
11453         local osc_rpc_stats
11454
11455         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11456
11457         cancel_lru_locks osc
11458         $LCTL set_param osc.*.rpc_stats=0
11459         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11460         $LCTL get_param osc.*.rpc_stats
11461         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11462                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11463                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11464                 local size
11465
11466                 if [ $lines -le 20 ]; then
11467                         echo "continue debug"
11468                         continue
11469                 fi
11470                 for size in 1 2 4 8; do
11471                         local rpc=$(echo "$stats" |
11472                                     awk '($1 == "'$size':") {print $2; exit; }')
11473                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11474                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11475                 done
11476                 echo "$osc_rpc_stats check passed!"
11477         done
11478         cleanup_test101bc
11479         true
11480 }
11481 run_test 101c "check stripe_size aligned read-ahead"
11482
11483 test_101d() {
11484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11485
11486         local file=$DIR/$tfile
11487         local sz_MB=${FILESIZE_101d:-80}
11488         local ra_MB=${READAHEAD_MB:-40}
11489
11490         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11491         [ $free_MB -lt $sz_MB ] &&
11492                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11493
11494         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11495         $LFS setstripe -c -1 $file || error "setstripe failed"
11496
11497         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11498         echo Cancel LRU locks on lustre client to flush the client cache
11499         cancel_lru_locks osc
11500
11501         echo Disable read-ahead
11502         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11503         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11504         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11505         $LCTL get_param -n llite.*.max_read_ahead_mb
11506
11507         echo "Reading the test file $file with read-ahead disabled"
11508         local sz_KB=$((sz_MB * 1024 / 4))
11509         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11510         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11511         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11512         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11513                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11514
11515         echo "Cancel LRU locks on lustre client to flush the client cache"
11516         cancel_lru_locks osc
11517         echo Enable read-ahead with ${ra_MB}MB
11518         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11519
11520         echo "Reading the test file $file with read-ahead enabled"
11521         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11522                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11523
11524         echo "read-ahead disabled time read '$raOFF'"
11525         echo "read-ahead enabled time read '$raON'"
11526
11527         rm -f $file
11528         wait_delete_completed
11529
11530         # use awk for this check instead of bash because it handles decimals
11531         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11532                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11533 }
11534 run_test 101d "file read with and without read-ahead enabled"
11535
11536 test_101e() {
11537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11538
11539         local file=$DIR/$tfile
11540         local size_KB=500  #KB
11541         local count=100
11542         local bsize=1024
11543
11544         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11545         local need_KB=$((count * size_KB))
11546         [[ $free_KB -le $need_KB ]] &&
11547                 skip_env "Need free space $need_KB, have $free_KB"
11548
11549         echo "Creating $count ${size_KB}K test files"
11550         for ((i = 0; i < $count; i++)); do
11551                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11552         done
11553
11554         echo "Cancel LRU locks on lustre client to flush the client cache"
11555         cancel_lru_locks $OSC
11556
11557         echo "Reset readahead stats"
11558         $LCTL set_param -n llite.*.read_ahead_stats=0
11559
11560         for ((i = 0; i < $count; i++)); do
11561                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11562         done
11563
11564         $LCTL get_param llite.*.max_cached_mb
11565         $LCTL get_param llite.*.read_ahead_stats
11566         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11567                      get_named_value 'misses' | calc_sum)
11568
11569         for ((i = 0; i < $count; i++)); do
11570                 rm -rf $file.$i 2>/dev/null
11571         done
11572
11573         #10000 means 20% reads are missing in readahead
11574         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11575 }
11576 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11577
11578 test_101f() {
11579         which iozone || skip_env "no iozone installed"
11580
11581         local old_debug=$($LCTL get_param debug)
11582         old_debug=${old_debug#*=}
11583         $LCTL set_param debug="reada mmap"
11584
11585         # create a test file
11586         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11587
11588         echo Cancel LRU locks on lustre client to flush the client cache
11589         cancel_lru_locks osc
11590
11591         echo Reset readahead stats
11592         $LCTL set_param -n llite.*.read_ahead_stats=0
11593
11594         echo mmap read the file with small block size
11595         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11596                 > /dev/null 2>&1
11597
11598         echo checking missing pages
11599         $LCTL get_param llite.*.read_ahead_stats
11600         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11601                         get_named_value 'misses' | calc_sum)
11602
11603         $LCTL set_param debug="$old_debug"
11604         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11605         rm -f $DIR/$tfile
11606 }
11607 run_test 101f "check mmap read performance"
11608
11609 test_101g_brw_size_test() {
11610         local mb=$1
11611         local pages=$((mb * 1048576 / PAGE_SIZE))
11612         local file=$DIR/$tfile
11613
11614         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11615                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11616         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11617                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11618                         return 2
11619         done
11620
11621         stack_trap "rm -f $file" EXIT
11622         $LCTL set_param -n osc.*.rpc_stats=0
11623
11624         # 10 RPCs should be enough for the test
11625         local count=10
11626         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11627                 { error "dd write ${mb} MB blocks failed"; return 3; }
11628         cancel_lru_locks osc
11629         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11630                 { error "dd write ${mb} MB blocks failed"; return 4; }
11631
11632         # calculate number of full-sized read and write RPCs
11633         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11634                 sed -n '/pages per rpc/,/^$/p' |
11635                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11636                 END { print reads,writes }'))
11637         # allow one extra full-sized read RPC for async readahead
11638         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11639                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11640         [[ ${rpcs[1]} == $count ]] ||
11641                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11642 }
11643
11644 test_101g() {
11645         remote_ost_nodsh && skip "remote OST with nodsh"
11646
11647         local rpcs
11648         local osts=$(get_facets OST)
11649         local list=$(comma_list $(osts_nodes))
11650         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11651         local brw_size="obdfilter.*.brw_size"
11652
11653         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11654
11655         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11656
11657         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11658                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11659                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11660            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11661                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11662                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11663
11664                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11665                         suffix="M"
11666
11667                 if [[ $orig_mb -lt 16 ]]; then
11668                         save_lustre_params $osts "$brw_size" > $p
11669                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11670                                 error "set 16MB RPC size failed"
11671
11672                         echo "remount client to enable new RPC size"
11673                         remount_client $MOUNT || error "remount_client failed"
11674                 fi
11675
11676                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11677                 # should be able to set brw_size=12, but no rpc_stats for that
11678                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11679         fi
11680
11681         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11682
11683         if [[ $orig_mb -lt 16 ]]; then
11684                 restore_lustre_params < $p
11685                 remount_client $MOUNT || error "remount_client restore failed"
11686         fi
11687
11688         rm -f $p $DIR/$tfile
11689 }
11690 run_test 101g "Big bulk(4/16 MiB) readahead"
11691
11692 test_101h() {
11693         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11694
11695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11696                 error "dd 70M file failed"
11697         echo Cancel LRU locks on lustre client to flush the client cache
11698         cancel_lru_locks osc
11699
11700         echo "Reset readahead stats"
11701         $LCTL set_param -n llite.*.read_ahead_stats 0
11702
11703         echo "Read 10M of data but cross 64M bundary"
11704         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11705         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11706                      get_named_value 'misses' | calc_sum)
11707         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11708         rm -f $p $DIR/$tfile
11709 }
11710 run_test 101h "Readahead should cover current read window"
11711
11712 test_101i() {
11713         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11714                 error "dd 10M file failed"
11715
11716         local max_per_file_mb=$($LCTL get_param -n \
11717                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11718         cancel_lru_locks osc
11719         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11720         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11721                 error "set max_read_ahead_per_file_mb to 1 failed"
11722
11723         echo "Reset readahead stats"
11724         $LCTL set_param llite.*.read_ahead_stats=0
11725
11726         dd if=$DIR/$tfile of=/dev/null bs=2M
11727
11728         $LCTL get_param llite.*.read_ahead_stats
11729         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11730                      awk '/misses/ { print $2 }')
11731         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11732         rm -f $DIR/$tfile
11733 }
11734 run_test 101i "allow current readahead to exceed reservation"
11735
11736 test_101j() {
11737         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11738                 error "setstripe $DIR/$tfile failed"
11739         local file_size=$((1048576 * 16))
11740         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11741         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11742
11743         echo Disable read-ahead
11744         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11745
11746         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11747         for blk in $PAGE_SIZE 1048576 $file_size; do
11748                 cancel_lru_locks osc
11749                 echo "Reset readahead stats"
11750                 $LCTL set_param -n llite.*.read_ahead_stats=0
11751                 local count=$(($file_size / $blk))
11752                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11753                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11754                              get_named_value 'failed.to.fast.read' | calc_sum)
11755                 $LCTL get_param -n llite.*.read_ahead_stats
11756                 [ $miss -eq $count ] || error "expected $count got $miss"
11757         done
11758
11759         rm -f $p $DIR/$tfile
11760 }
11761 run_test 101j "A complete read block should be submitted when no RA"
11762
11763 test_readahead_base() {
11764         local file=$DIR/$tfile
11765         local size=$1
11766         local iosz
11767         local ramax
11768         local ranum
11769
11770         $LCTL set_param -n llite.*.read_ahead_stats=0
11771         # The first page is not accounted into readahead
11772         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11773         iosz=$(((size + 1048575) / 1048576 * 1048576))
11774         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11775
11776         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11777         fallocate -l $size $file || error "failed to fallocate $file"
11778         cancel_lru_locks osc
11779         $MULTIOP $file or${iosz}c || error "failed to read $file"
11780         $LCTL get_param -n llite.*.read_ahead_stats
11781         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11782                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11783         (( $ranum <= $ramax )) ||
11784                 error "read-ahead pages is $ranum more than $ramax"
11785         rm -rf $file || error "failed to remove $file"
11786 }
11787
11788 test_101m()
11789 {
11790         local file=$DIR/$tfile
11791         local ramax
11792         local ranum
11793         local size
11794         local iosz
11795
11796         check_set_fallocate_or_skip
11797         stack_trap "rm -f $file" EXIT
11798
11799         test_readahead_base 4096
11800
11801         # file size: 16K = 16384
11802         test_readahead_base 16384
11803         test_readahead_base 16385
11804         test_readahead_base 16383
11805
11806         # file size: 1M + 1 = 1048576 + 1
11807         test_readahead_base 1048577
11808         # file size: 1M + 16K
11809         test_readahead_base $((1048576 + 16384))
11810
11811         # file size: stripe_size * (stripe_count - 1) + 16K
11812         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11813         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11814         # file size: stripe_size * stripe_count + 16K
11815         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11816         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11817         # file size: 2 * stripe_size * stripe_count + 16K
11818         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11819         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11820 }
11821 run_test 101m "read ahead for small file and last stripe of the file"
11822
11823 setup_test102() {
11824         test_mkdir $DIR/$tdir
11825         chown $RUNAS_ID $DIR/$tdir
11826         STRIPE_SIZE=65536
11827         STRIPE_OFFSET=1
11828         STRIPE_COUNT=$OSTCOUNT
11829         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11830
11831         trap cleanup_test102 EXIT
11832         cd $DIR
11833         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11834         cd $DIR/$tdir
11835         for num in 1 2 3 4; do
11836                 for count in $(seq 1 $STRIPE_COUNT); do
11837                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11838                                 local size=`expr $STRIPE_SIZE \* $num`
11839                                 local file=file"$num-$idx-$count"
11840                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11841                         done
11842                 done
11843         done
11844
11845         cd $DIR
11846         $1 tar cf $TMP/f102.tar $tdir --xattrs
11847 }
11848
11849 cleanup_test102() {
11850         trap 0
11851         rm -f $TMP/f102.tar
11852         rm -rf $DIR/d0.sanity/d102
11853 }
11854
11855 test_102a() {
11856         [ "$UID" != 0 ] && skip "must run as root"
11857         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11858                 skip_env "must have user_xattr"
11859
11860         [ -z "$(which setfattr 2>/dev/null)" ] &&
11861                 skip_env "could not find setfattr"
11862
11863         local testfile=$DIR/$tfile
11864
11865         touch $testfile
11866         echo "set/get xattr..."
11867         setfattr -n trusted.name1 -v value1 $testfile ||
11868                 error "setfattr -n trusted.name1=value1 $testfile failed"
11869         getfattr -n trusted.name1 $testfile 2> /dev/null |
11870           grep "trusted.name1=.value1" ||
11871                 error "$testfile missing trusted.name1=value1"
11872
11873         setfattr -n user.author1 -v author1 $testfile ||
11874                 error "setfattr -n user.author1=author1 $testfile failed"
11875         getfattr -n user.author1 $testfile 2> /dev/null |
11876           grep "user.author1=.author1" ||
11877                 error "$testfile missing trusted.author1=author1"
11878
11879         echo "listxattr..."
11880         setfattr -n trusted.name2 -v value2 $testfile ||
11881                 error "$testfile unable to set trusted.name2"
11882         setfattr -n trusted.name3 -v value3 $testfile ||
11883                 error "$testfile unable to set trusted.name3"
11884         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11885             grep "trusted.name" | wc -l) -eq 3 ] ||
11886                 error "$testfile missing 3 trusted.name xattrs"
11887
11888         setfattr -n user.author2 -v author2 $testfile ||
11889                 error "$testfile unable to set user.author2"
11890         setfattr -n user.author3 -v author3 $testfile ||
11891                 error "$testfile unable to set user.author3"
11892         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11893             grep "user.author" | wc -l) -eq 3 ] ||
11894                 error "$testfile missing 3 user.author xattrs"
11895
11896         echo "remove xattr..."
11897         setfattr -x trusted.name1 $testfile ||
11898                 error "$testfile error deleting trusted.name1"
11899         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11900                 error "$testfile did not delete trusted.name1 xattr"
11901
11902         setfattr -x user.author1 $testfile ||
11903                 error "$testfile error deleting user.author1"
11904         echo "set lustre special xattr ..."
11905         $LFS setstripe -c1 $testfile
11906         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11907                 awk -F "=" '/trusted.lov/ { print $2 }' )
11908         setfattr -n "trusted.lov" -v $lovea $testfile ||
11909                 error "$testfile doesn't ignore setting trusted.lov again"
11910         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11911                 error "$testfile allow setting invalid trusted.lov"
11912         rm -f $testfile
11913 }
11914 run_test 102a "user xattr test =================================="
11915
11916 check_102b_layout() {
11917         local layout="$*"
11918         local testfile=$DIR/$tfile
11919
11920         echo "test layout '$layout'"
11921         $LFS setstripe $layout $testfile || error "setstripe failed"
11922         $LFS getstripe -y $testfile
11923
11924         echo "get/set/list trusted.lov xattr ..." # b=10930
11925         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11926         [[ "$value" =~ "trusted.lov" ]] ||
11927                 error "can't get trusted.lov from $testfile"
11928         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11929                 error "getstripe failed"
11930
11931         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11932
11933         value=$(cut -d= -f2 <<<$value)
11934         # LU-13168: truncated xattr should fail if short lov_user_md header
11935         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11936                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11937         for len in $lens; do
11938                 echo "setfattr $len $testfile.2"
11939                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11940                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11941         done
11942         local stripe_size=$($LFS getstripe -S $testfile.2)
11943         local stripe_count=$($LFS getstripe -c $testfile.2)
11944         [[ $stripe_size -eq 65536 ]] ||
11945                 error "stripe size $stripe_size != 65536"
11946         [[ $stripe_count -eq $stripe_count_orig ]] ||
11947                 error "stripe count $stripe_count != $stripe_count_orig"
11948         rm $testfile $testfile.2
11949 }
11950
11951 test_102b() {
11952         [ -z "$(which setfattr 2>/dev/null)" ] &&
11953                 skip_env "could not find setfattr"
11954         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11955
11956         # check plain layout
11957         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11958
11959         # and also check composite layout
11960         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11961
11962 }
11963 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11964
11965 test_102c() {
11966         [ -z "$(which setfattr 2>/dev/null)" ] &&
11967                 skip_env "could not find setfattr"
11968         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11969
11970         # b10930: get/set/list lustre.lov xattr
11971         echo "get/set/list lustre.lov xattr ..."
11972         test_mkdir $DIR/$tdir
11973         chown $RUNAS_ID $DIR/$tdir
11974         local testfile=$DIR/$tdir/$tfile
11975         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11976                 error "setstripe failed"
11977         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11978                 error "getstripe failed"
11979         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11980         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11981
11982         local testfile2=${testfile}2
11983         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11984                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11985
11986         $RUNAS $MCREATE $testfile2
11987         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11988         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11989         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11990         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11991         [ $stripe_count -eq $STRIPECOUNT ] ||
11992                 error "stripe count $stripe_count != $STRIPECOUNT"
11993 }
11994 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11995
11996 compare_stripe_info1() {
11997         local stripe_index_all_zero=true
11998
11999         for num in 1 2 3 4; do
12000                 for count in $(seq 1 $STRIPE_COUNT); do
12001                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12002                                 local size=$((STRIPE_SIZE * num))
12003                                 local file=file"$num-$offset-$count"
12004                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12005                                 [[ $stripe_size -ne $size ]] &&
12006                                     error "$file: size $stripe_size != $size"
12007                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12008                                 # allow fewer stripes to be created, ORI-601
12009                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12010                                     error "$file: count $stripe_count != $count"
12011                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12012                                 [[ $stripe_index -ne 0 ]] &&
12013                                         stripe_index_all_zero=false
12014                         done
12015                 done
12016         done
12017         $stripe_index_all_zero &&
12018                 error "all files are being extracted starting from OST index 0"
12019         return 0
12020 }
12021
12022 have_xattrs_include() {
12023         tar --help | grep -q xattrs-include &&
12024                 echo --xattrs-include="lustre.*"
12025 }
12026
12027 test_102d() {
12028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12030
12031         XINC=$(have_xattrs_include)
12032         setup_test102
12033         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12034         cd $DIR/$tdir/$tdir
12035         compare_stripe_info1
12036 }
12037 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12038
12039 test_102f() {
12040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12041         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12042
12043         XINC=$(have_xattrs_include)
12044         setup_test102
12045         test_mkdir $DIR/$tdir.restore
12046         cd $DIR
12047         tar cf - --xattrs $tdir | tar xf - \
12048                 -C $DIR/$tdir.restore --xattrs $XINC
12049         cd $DIR/$tdir.restore/$tdir
12050         compare_stripe_info1
12051 }
12052 run_test 102f "tar copy files, not keep osts"
12053
12054 grow_xattr() {
12055         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12056                 skip "must have user_xattr"
12057         [ -z "$(which setfattr 2>/dev/null)" ] &&
12058                 skip_env "could not find setfattr"
12059         [ -z "$(which getfattr 2>/dev/null)" ] &&
12060                 skip_env "could not find getfattr"
12061
12062         local xsize=${1:-1024}  # in bytes
12063         local file=$DIR/$tfile
12064         local value="$(generate_string $xsize)"
12065         local xbig=trusted.big
12066         local toobig=$2
12067
12068         touch $file
12069         log "save $xbig on $file"
12070         if [ -z "$toobig" ]
12071         then
12072                 setfattr -n $xbig -v $value $file ||
12073                         error "saving $xbig on $file failed"
12074         else
12075                 setfattr -n $xbig -v $value $file &&
12076                         error "saving $xbig on $file succeeded"
12077                 return 0
12078         fi
12079
12080         local orig=$(get_xattr_value $xbig $file)
12081         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12082
12083         local xsml=trusted.sml
12084         log "save $xsml on $file"
12085         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12086
12087         local new=$(get_xattr_value $xbig $file)
12088         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12089
12090         log "grow $xsml on $file"
12091         setfattr -n $xsml -v "$value" $file ||
12092                 error "growing $xsml on $file failed"
12093
12094         new=$(get_xattr_value $xbig $file)
12095         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12096         log "$xbig still valid after growing $xsml"
12097
12098         rm -f $file
12099 }
12100
12101 test_102h() { # bug 15777
12102         grow_xattr 1024
12103 }
12104 run_test 102h "grow xattr from inside inode to external block"
12105
12106 test_102ha() {
12107         large_xattr_enabled || skip_env "ea_inode feature disabled"
12108
12109         echo "setting xattr of max xattr size: $(max_xattr_size)"
12110         grow_xattr $(max_xattr_size)
12111
12112         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12113         echo "This should fail:"
12114         grow_xattr $(($(max_xattr_size) + 10)) 1
12115 }
12116 run_test 102ha "grow xattr from inside inode to external inode"
12117
12118 test_102i() { # bug 17038
12119         [ -z "$(which getfattr 2>/dev/null)" ] &&
12120                 skip "could not find getfattr"
12121
12122         touch $DIR/$tfile
12123         ln -s $DIR/$tfile $DIR/${tfile}link
12124         getfattr -n trusted.lov $DIR/$tfile ||
12125                 error "lgetxattr on $DIR/$tfile failed"
12126         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12127                 grep -i "no such attr" ||
12128                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12129         rm -f $DIR/$tfile $DIR/${tfile}link
12130 }
12131 run_test 102i "lgetxattr test on symbolic link ============"
12132
12133 test_102j() {
12134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12135         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12136
12137         XINC=$(have_xattrs_include)
12138         setup_test102 "$RUNAS"
12139         chown $RUNAS_ID $DIR/$tdir
12140         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12141         cd $DIR/$tdir/$tdir
12142         compare_stripe_info1 "$RUNAS"
12143 }
12144 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12145
12146 test_102k() {
12147         [ -z "$(which setfattr 2>/dev/null)" ] &&
12148                 skip "could not find setfattr"
12149
12150         touch $DIR/$tfile
12151         # b22187 just check that does not crash for regular file.
12152         setfattr -n trusted.lov $DIR/$tfile
12153         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12154         local test_kdir=$DIR/$tdir
12155         test_mkdir $test_kdir
12156         local default_size=$($LFS getstripe -S $test_kdir)
12157         local default_count=$($LFS getstripe -c $test_kdir)
12158         local default_offset=$($LFS getstripe -i $test_kdir)
12159         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12160                 error 'dir setstripe failed'
12161         setfattr -n trusted.lov $test_kdir
12162         local stripe_size=$($LFS getstripe -S $test_kdir)
12163         local stripe_count=$($LFS getstripe -c $test_kdir)
12164         local stripe_offset=$($LFS getstripe -i $test_kdir)
12165         [ $stripe_size -eq $default_size ] ||
12166                 error "stripe size $stripe_size != $default_size"
12167         [ $stripe_count -eq $default_count ] ||
12168                 error "stripe count $stripe_count != $default_count"
12169         [ $stripe_offset -eq $default_offset ] ||
12170                 error "stripe offset $stripe_offset != $default_offset"
12171         rm -rf $DIR/$tfile $test_kdir
12172 }
12173 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12174
12175 test_102l() {
12176         [ -z "$(which getfattr 2>/dev/null)" ] &&
12177                 skip "could not find getfattr"
12178
12179         # LU-532 trusted. xattr is invisible to non-root
12180         local testfile=$DIR/$tfile
12181
12182         touch $testfile
12183
12184         echo "listxattr as user..."
12185         chown $RUNAS_ID $testfile
12186         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12187             grep -q "trusted" &&
12188                 error "$testfile trusted xattrs are user visible"
12189
12190         return 0;
12191 }
12192 run_test 102l "listxattr size test =================================="
12193
12194 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12195         local path=$DIR/$tfile
12196         touch $path
12197
12198         listxattr_size_check $path || error "listattr_size_check $path failed"
12199 }
12200 run_test 102m "Ensure listxattr fails on small bufffer ========"
12201
12202 cleanup_test102
12203
12204 getxattr() { # getxattr path name
12205         # Return the base64 encoding of the value of xattr name on path.
12206         local path=$1
12207         local name=$2
12208
12209         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12210         # file: $path
12211         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12212         #
12213         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12214
12215         getfattr --absolute-names --encoding=base64 --name=$name $path |
12216                 awk -F= -v name=$name '$1 == name {
12217                         print substr($0, index($0, "=") + 1);
12218         }'
12219 }
12220
12221 test_102n() { # LU-4101 mdt: protect internal xattrs
12222         [ -z "$(which setfattr 2>/dev/null)" ] &&
12223                 skip "could not find setfattr"
12224         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12225         then
12226                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12227         fi
12228
12229         local file0=$DIR/$tfile.0
12230         local file1=$DIR/$tfile.1
12231         local xattr0=$TMP/$tfile.0
12232         local xattr1=$TMP/$tfile.1
12233         local namelist="lov lma lmv link fid version som hsm"
12234         local name
12235         local value
12236
12237         rm -rf $file0 $file1 $xattr0 $xattr1
12238         touch $file0 $file1
12239
12240         # Get 'before' xattrs of $file1.
12241         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12242
12243         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12244                 namelist+=" lfsck_namespace"
12245         for name in $namelist; do
12246                 # Try to copy xattr from $file0 to $file1.
12247                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12248
12249                 setfattr --name=trusted.$name --value="$value" $file1 ||
12250                         error "setxattr 'trusted.$name' failed"
12251
12252                 # Try to set a garbage xattr.
12253                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12254
12255                 if [[ x$name == "xlov" ]]; then
12256                         setfattr --name=trusted.lov --value="$value" $file1 &&
12257                         error "setxattr invalid 'trusted.lov' success"
12258                 else
12259                         setfattr --name=trusted.$name --value="$value" $file1 ||
12260                                 error "setxattr invalid 'trusted.$name' failed"
12261                 fi
12262
12263                 # Try to remove the xattr from $file1. We don't care if this
12264                 # appears to succeed or fail, we just don't want there to be
12265                 # any changes or crashes.
12266                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12267         done
12268
12269         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12270         then
12271                 name="lfsck_ns"
12272                 # Try to copy xattr from $file0 to $file1.
12273                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12274
12275                 setfattr --name=trusted.$name --value="$value" $file1 ||
12276                         error "setxattr 'trusted.$name' failed"
12277
12278                 # Try to set a garbage xattr.
12279                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12280
12281                 setfattr --name=trusted.$name --value="$value" $file1 ||
12282                         error "setxattr 'trusted.$name' failed"
12283
12284                 # Try to remove the xattr from $file1. We don't care if this
12285                 # appears to succeed or fail, we just don't want there to be
12286                 # any changes or crashes.
12287                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12288         fi
12289
12290         # Get 'after' xattrs of file1.
12291         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12292
12293         if ! diff $xattr0 $xattr1; then
12294                 error "before and after xattrs of '$file1' differ"
12295         fi
12296
12297         rm -rf $file0 $file1 $xattr0 $xattr1
12298
12299         return 0
12300 }
12301 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12302
12303 test_102p() { # LU-4703 setxattr did not check ownership
12304         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12305                 skip "MDS needs to be at least 2.5.56"
12306
12307         local testfile=$DIR/$tfile
12308
12309         touch $testfile
12310
12311         echo "setfacl as user..."
12312         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12313         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12314
12315         echo "setfattr as user..."
12316         setfacl -m "u:$RUNAS_ID:---" $testfile
12317         $RUNAS setfattr -x system.posix_acl_access $testfile
12318         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12319 }
12320 run_test 102p "check setxattr(2) correctly fails without permission"
12321
12322 test_102q() {
12323         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12324                 skip "MDS needs to be at least 2.6.92"
12325
12326         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12327 }
12328 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12329
12330 test_102r() {
12331         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12332                 skip "MDS needs to be at least 2.6.93"
12333
12334         touch $DIR/$tfile || error "touch"
12335         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12336         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12337         rm $DIR/$tfile || error "rm"
12338
12339         #normal directory
12340         mkdir -p $DIR/$tdir || error "mkdir"
12341         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12342         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12343         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12344                 error "$testfile error deleting user.author1"
12345         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12346                 grep "user.$(basename $tdir)" &&
12347                 error "$tdir did not delete user.$(basename $tdir)"
12348         rmdir $DIR/$tdir || error "rmdir"
12349
12350         #striped directory
12351         test_mkdir $DIR/$tdir
12352         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12353         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12354         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12355                 error "$testfile error deleting user.author1"
12356         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12357                 grep "user.$(basename $tdir)" &&
12358                 error "$tdir did not delete user.$(basename $tdir)"
12359         rmdir $DIR/$tdir || error "rm striped dir"
12360 }
12361 run_test 102r "set EAs with empty values"
12362
12363 test_102s() {
12364         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12365                 skip "MDS needs to be at least 2.11.52"
12366
12367         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12368
12369         save_lustre_params client "llite.*.xattr_cache" > $save
12370
12371         for cache in 0 1; do
12372                 lctl set_param llite.*.xattr_cache=$cache
12373
12374                 rm -f $DIR/$tfile
12375                 touch $DIR/$tfile || error "touch"
12376                 for prefix in lustre security system trusted user; do
12377                         # Note getxattr() may fail with 'Operation not
12378                         # supported' or 'No such attribute' depending
12379                         # on prefix and cache.
12380                         getfattr -n $prefix.n102s $DIR/$tfile &&
12381                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12382                 done
12383         done
12384
12385         restore_lustre_params < $save
12386 }
12387 run_test 102s "getting nonexistent xattrs should fail"
12388
12389 test_102t() {
12390         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12391                 skip "MDS needs to be at least 2.11.52"
12392
12393         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12394
12395         save_lustre_params client "llite.*.xattr_cache" > $save
12396
12397         for cache in 0 1; do
12398                 lctl set_param llite.*.xattr_cache=$cache
12399
12400                 for buf_size in 0 256; do
12401                         rm -f $DIR/$tfile
12402                         touch $DIR/$tfile || error "touch"
12403                         setfattr -n user.multiop $DIR/$tfile
12404                         $MULTIOP $DIR/$tfile oa$buf_size ||
12405                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12406                 done
12407         done
12408
12409         restore_lustre_params < $save
12410 }
12411 run_test 102t "zero length xattr values handled correctly"
12412
12413 run_acl_subtest()
12414 {
12415         local test=$LUSTRE/tests/acl/$1.test
12416         local tmp=$(mktemp -t $1-XXXXXX).test
12417         local bin=$2
12418         local dmn=$3
12419         local grp=$4
12420         local nbd=$5
12421         export LANG=C
12422
12423
12424         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12425         local sedgroups="-e s/:users/:$grp/g"
12426         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12427
12428         sed $sedusers $sedgroups < $test > $tmp
12429         stack_trap "rm -f $tmp"
12430         [[ -s $tmp ]] || error "sed failed to create test script"
12431
12432         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12433         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12434 }
12435
12436 test_103a() {
12437         [ "$UID" != 0 ] && skip "must run as root"
12438         $GSS && skip_env "could not run under gss"
12439         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12440                 skip_env "must have acl enabled"
12441         which setfacl || skip_env "could not find setfacl"
12442         remote_mds_nodsh && skip "remote MDS with nodsh"
12443
12444         local mdts=$(comma_list $(mdts_nodes))
12445         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12446
12447         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12448         stack_trap "[[ -z \"$saved\" ]] || \
12449                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12450
12451         ACLBIN=${ACLBIN:-"bin"}
12452         ACLDMN=${ACLDMN:-"daemon"}
12453         ACLGRP=${ACLGRP:-"users"}
12454         ACLNBD=${ACLNBD:-"nobody"}
12455
12456         if ! id $ACLBIN ||
12457            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12458                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12459                 ACLBIN=$USER0
12460                 if ! id $ACLBIN ; then
12461                         cat /etc/passwd
12462                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12463                 fi
12464         fi
12465         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12466            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12467                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12468                 ACLDMN=$USER1
12469                 if ! id $ACLDMN ; then
12470                         cat /etc/passwd
12471                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12472                 fi
12473         fi
12474         if ! getent group $ACLGRP; then
12475                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12476                 ACLGRP="$TSTUSR"
12477                 if ! getent group $ACLGRP; then
12478                         echo "cannot find group '$ACLGRP', adding it"
12479                         cat /etc/group
12480                         add_group 60000 $ACLGRP
12481                 fi
12482         fi
12483
12484         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12485         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12486         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12487
12488         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12489                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12490                 ACLGRP="$TSTUSR"
12491                 if ! getent group $ACLGRP; then
12492                         echo "cannot find group '$ACLGRP', adding it"
12493                         cat /etc/group
12494                         add_group 60000 $ACLGRP
12495                 fi
12496                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12497                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12498                         cat /etc/group
12499                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12500                 fi
12501         fi
12502
12503         gpasswd -a $ACLDMN $ACLBIN ||
12504                 error "setting client group failed"             # LU-5641
12505         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12506                 error "setting MDS group failed"                # LU-5641
12507
12508         declare -a identity_old
12509
12510         for ((num = 1; num <= $MDSCOUNT; num++)); do
12511                 switch_identity $num true || identity_old[$num]=$?
12512         done
12513
12514         SAVE_UMASK=$(umask)
12515         umask 0022
12516         mkdir -p $DIR/$tdir
12517         cd $DIR/$tdir
12518
12519         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12520         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12521         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12522         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12523         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12524         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12525         if ! id -u $ACLNBD ||
12526            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12527                 ACLNBD="nfsnobody"
12528                 if ! id -u $ACLNBD; then
12529                         ACLNBD=""
12530                 fi
12531         fi
12532         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12533                 add_group $(id -u $ACLNBD) $ACLNBD
12534                 if ! getent group $ACLNBD; then
12535                         ACLNBD=""
12536                 fi
12537         fi
12538         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12539            [[ -n "$ACLNBD" ]] && which setfattr; then
12540                 run_acl_subtest permissions_xattr \
12541                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12542         elif [[ -z "$ACLNBD" ]]; then
12543                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12544         else
12545                 echo "skip 'permission_xattr' test - missing setfattr command"
12546         fi
12547         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12548
12549         # inheritance test got from HP
12550         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12551         chmod +x make-tree || error "chmod +x failed"
12552         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12553         rm -f make-tree
12554
12555         echo "LU-974 ignore umask when acl is enabled..."
12556         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12557         if [ $MDSCOUNT -ge 2 ]; then
12558                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12559         fi
12560
12561         echo "LU-2561 newly created file is same size as directory..."
12562         if [ "$mds1_FSTYPE" != "zfs" ]; then
12563                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12564         else
12565                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12566         fi
12567
12568         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12569
12570         cd $SAVE_PWD
12571         umask $SAVE_UMASK
12572
12573         for ((num = 1; num <= $MDSCOUNT; num++)); do
12574                 if [[ "${identity_old[$num]}" == 1 ]]; then
12575                         switch_identity $num false || identity_old[$num]=$?
12576                 fi
12577         done
12578 }
12579 run_test 103a "acl test"
12580
12581 test_103b() {
12582         declare -a pids
12583         local U
12584
12585         stack_trap "rm -f $DIR/$tfile.*"
12586         for U in {0..511}; do
12587                 {
12588                 local O=$(printf "%04o" $U)
12589
12590                 umask $(printf "%04o" $((511 ^ $O)))
12591                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12592                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12593
12594                 (( $S == ($O & 0666) )) ||
12595                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12596
12597                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12598                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12599                 (( $S == ($O & 0666) )) ||
12600                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12601
12602                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12603                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12604                 (( $S == ($O & 0666) )) ||
12605                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12606                 rm -f $DIR/$tfile.[smp]$0
12607                 } &
12608                 local pid=$!
12609
12610                 # limit the concurrently running threads to 64. LU-11878
12611                 local idx=$((U % 64))
12612                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12613                 pids[idx]=$pid
12614         done
12615         wait
12616 }
12617 run_test 103b "umask lfs setstripe"
12618
12619 test_103c() {
12620         mkdir -p $DIR/$tdir
12621         cp -rp $DIR/$tdir $DIR/$tdir.bak
12622
12623         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12624                 error "$DIR/$tdir shouldn't contain default ACL"
12625         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12626                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12627         true
12628 }
12629 run_test 103c "'cp -rp' won't set empty acl"
12630
12631 test_103e() {
12632         local numacl
12633         local fileacl
12634         local saved_debug=$($LCTL get_param -n debug)
12635
12636         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12637                 skip "MDS needs to be at least 2.14.52"
12638
12639         large_xattr_enabled || skip_env "ea_inode feature disabled"
12640
12641         mkdir -p $DIR/$tdir
12642         # add big LOV EA to cause reply buffer overflow earlier
12643         $LFS setstripe -C 1000 $DIR/$tdir
12644         lctl set_param mdc.*-mdc*.stats=clear
12645
12646         $LCTL set_param debug=0
12647         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12648         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12649
12650         # add a large number of default ACLs (expect 8000+ for 2.13+)
12651         for U in {2..7000}; do
12652                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12653                         error "Able to add just $U default ACLs"
12654         done
12655         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12656         echo "$numacl default ACLs created"
12657
12658         stat $DIR/$tdir || error "Cannot stat directory"
12659         # check file creation
12660         touch $DIR/$tdir/$tfile ||
12661                 error "failed to create $tfile with $numacl default ACLs"
12662         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12663         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12664         echo "$fileacl ACLs were inherited"
12665         (( $fileacl == $numacl )) ||
12666                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12667         # check that new ACLs creation adds new ACLs to inherited ACLs
12668         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12669                 error "Cannot set new ACL"
12670         numacl=$((numacl + 1))
12671         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12672         (( $fileacl == $numacl )) ||
12673                 error "failed to add new ACL: $fileacl != $numacl as expected"
12674         # adds more ACLs to a file to reach their maximum at 8000+
12675         numacl=0
12676         for U in {20000..25000}; do
12677                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12678                 numacl=$((numacl + 1))
12679         done
12680         echo "Added $numacl more ACLs to the file"
12681         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12682         echo "Total $fileacl ACLs in file"
12683         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12684         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12685         rmdir $DIR/$tdir || error "Cannot remove directory"
12686 }
12687 run_test 103e "inheritance of big amount of default ACLs"
12688
12689 test_103f() {
12690         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12691                 skip "MDS needs to be at least 2.14.51"
12692
12693         large_xattr_enabled || skip_env "ea_inode feature disabled"
12694
12695         # enable changelog to consume more internal MDD buffers
12696         changelog_register
12697
12698         mkdir -p $DIR/$tdir
12699         # add big LOV EA
12700         $LFS setstripe -C 1000 $DIR/$tdir
12701         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12702         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12703         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12704         rmdir $DIR/$tdir || error "Cannot remove directory"
12705 }
12706 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12707
12708 test_104a() {
12709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12710
12711         touch $DIR/$tfile
12712         lfs df || error "lfs df failed"
12713         lfs df -ih || error "lfs df -ih failed"
12714         lfs df -h $DIR || error "lfs df -h $DIR failed"
12715         lfs df -i $DIR || error "lfs df -i $DIR failed"
12716         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12717         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12718
12719         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12720         lctl --device %$OSC deactivate
12721         lfs df || error "lfs df with deactivated OSC failed"
12722         lctl --device %$OSC activate
12723         # wait the osc back to normal
12724         wait_osc_import_ready client ost
12725
12726         lfs df || error "lfs df with reactivated OSC failed"
12727         rm -f $DIR/$tfile
12728 }
12729 run_test 104a "lfs df [-ih] [path] test ========================="
12730
12731 test_104b() {
12732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12733         [ $RUNAS_ID -eq $UID ] &&
12734                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12735
12736         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12737                         grep "Permission denied" | wc -l)))
12738         if [ $denied_cnt -ne 0 ]; then
12739                 error "lfs check servers test failed"
12740         fi
12741 }
12742 run_test 104b "$RUNAS lfs check servers test ===================="
12743
12744 #
12745 # Verify $1 is within range of $2.
12746 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12747 # $1 is <= 2% of $2. Else Fail.
12748 #
12749 value_in_range() {
12750         # Strip all units (M, G, T)
12751         actual=$(echo $1 | tr -d A-Z)
12752         expect=$(echo $2 | tr -d A-Z)
12753
12754         expect_lo=$(($expect * 98 / 100)) # 2% below
12755         expect_hi=$(($expect * 102 / 100)) # 2% above
12756
12757         # permit 2% drift above and below
12758         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12759 }
12760
12761 test_104c() {
12762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12763         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12764
12765         local ost_param="osd-zfs.$FSNAME-OST0000."
12766         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12767         local ofacets=$(get_facets OST)
12768         local mfacets=$(get_facets MDS)
12769         local saved_ost_blocks=
12770         local saved_mdt_blocks=
12771
12772         echo "Before recordsize change"
12773         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12774         df=($(df -h | grep "$MOUNT"$))
12775
12776         # For checking.
12777         echo "lfs output : ${lfs_df[*]}"
12778         echo "df  output : ${df[*]}"
12779
12780         for facet in ${ofacets//,/ }; do
12781                 if [ -z $saved_ost_blocks ]; then
12782                         saved_ost_blocks=$(do_facet $facet \
12783                                 lctl get_param -n $ost_param.blocksize)
12784                         echo "OST Blocksize: $saved_ost_blocks"
12785                 fi
12786                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12787                 do_facet $facet zfs set recordsize=32768 $ost
12788         done
12789
12790         # BS too small. Sufficient for functional testing.
12791         for facet in ${mfacets//,/ }; do
12792                 if [ -z $saved_mdt_blocks ]; then
12793                         saved_mdt_blocks=$(do_facet $facet \
12794                                 lctl get_param -n $mdt_param.blocksize)
12795                         echo "MDT Blocksize: $saved_mdt_blocks"
12796                 fi
12797                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12798                 do_facet $facet zfs set recordsize=32768 $mdt
12799         done
12800
12801         # Give new values chance to reflect change
12802         sleep 2
12803
12804         echo "After recordsize change"
12805         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12806         df_after=($(df -h | grep "$MOUNT"$))
12807
12808         # For checking.
12809         echo "lfs output : ${lfs_df_after[*]}"
12810         echo "df  output : ${df_after[*]}"
12811
12812         # Verify lfs df
12813         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12814                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12815         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12816                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12817         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12818                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12819
12820         # Verify df
12821         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12822                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12823         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12824                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12825         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12826                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12827
12828         # Restore MDT recordize back to original
12829         for facet in ${mfacets//,/ }; do
12830                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12831                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12832         done
12833
12834         # Restore OST recordize back to original
12835         for facet in ${ofacets//,/ }; do
12836                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12837                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12838         done
12839
12840         return 0
12841 }
12842 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12843
12844 test_104d() {
12845         (( $RUNAS_ID != $UID )) ||
12846                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12847
12848         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12849                 skip "lustre version doesn't support lctl dl with non-root"
12850
12851         # debugfs only allows root users to access files, so the
12852         # previous move of the "devices" file to debugfs broke
12853         # "lctl dl" for non-root users. The LU-9680 Netlink
12854         # interface again allows non-root users to list devices.
12855         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12856                 error "lctl dl doesn't work for non root"
12857
12858         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12859         [ "$ost_count" -eq $OSTCOUNT ]  ||
12860                 error "lctl dl reports wrong number of OST devices"
12861
12862         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12863         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12864                 error "lctl dl reports wrong number of MDT devices"
12865 }
12866 run_test 104d "$RUNAS lctl dl test"
12867
12868 test_105a() {
12869         # doesn't work on 2.4 kernels
12870         touch $DIR/$tfile
12871         if $(flock_is_enabled); then
12872                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12873         else
12874                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12875         fi
12876         rm -f $DIR/$tfile
12877 }
12878 run_test 105a "flock when mounted without -o flock test ========"
12879
12880 test_105b() {
12881         touch $DIR/$tfile
12882         if $(flock_is_enabled); then
12883                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12884         else
12885                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12886         fi
12887         rm -f $DIR/$tfile
12888 }
12889 run_test 105b "fcntl when mounted without -o flock test ========"
12890
12891 test_105c() {
12892         touch $DIR/$tfile
12893         if $(flock_is_enabled); then
12894                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12895         else
12896                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12897         fi
12898         rm -f $DIR/$tfile
12899 }
12900 run_test 105c "lockf when mounted without -o flock test"
12901
12902 test_105d() { # bug 15924
12903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12904
12905         test_mkdir $DIR/$tdir
12906         flock_is_enabled || skip_env "mount w/o flock enabled"
12907         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12908         $LCTL set_param fail_loc=0x80000315
12909         flocks_test 2 $DIR/$tdir
12910 }
12911 run_test 105d "flock race (should not freeze) ========"
12912
12913 test_105e() { # bug 22660 && 22040
12914         flock_is_enabled || skip_env "mount w/o flock enabled"
12915
12916         touch $DIR/$tfile
12917         flocks_test 3 $DIR/$tfile
12918 }
12919 run_test 105e "Two conflicting flocks from same process"
12920
12921 test_106() { #bug 10921
12922         test_mkdir $DIR/$tdir
12923         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12924         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12925 }
12926 run_test 106 "attempt exec of dir followed by chown of that dir"
12927
12928 test_107() {
12929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12930
12931         CDIR=`pwd`
12932         local file=core
12933
12934         cd $DIR
12935         rm -f $file
12936
12937         local save_pattern=$(sysctl -n kernel.core_pattern)
12938         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12939         sysctl -w kernel.core_pattern=$file
12940         sysctl -w kernel.core_uses_pid=0
12941
12942         ulimit -c unlimited
12943         sleep 60 &
12944         SLEEPPID=$!
12945
12946         sleep 1
12947
12948         kill -s 11 $SLEEPPID
12949         wait $SLEEPPID
12950         if [ -e $file ]; then
12951                 size=`stat -c%s $file`
12952                 [ $size -eq 0 ] && error "Fail to create core file $file"
12953         else
12954                 error "Fail to create core file $file"
12955         fi
12956         rm -f $file
12957         sysctl -w kernel.core_pattern=$save_pattern
12958         sysctl -w kernel.core_uses_pid=$save_uses_pid
12959         cd $CDIR
12960 }
12961 run_test 107 "Coredump on SIG"
12962
12963 test_110() {
12964         test_mkdir $DIR/$tdir
12965         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12966         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12967                 error "mkdir with 256 char should fail, but did not"
12968         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12969                 error "create with 255 char failed"
12970         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12971                 error "create with 256 char should fail, but did not"
12972
12973         ls -l $DIR/$tdir
12974         rm -rf $DIR/$tdir
12975 }
12976 run_test 110 "filename length checking"
12977
12978 test_116a() { # was previously test_116()
12979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12980         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12981         remote_mds_nodsh && skip "remote MDS with nodsh"
12982
12983         echo -n "Free space priority "
12984         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12985                 head -n1
12986         declare -a AVAIL
12987         free_min_max
12988
12989         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12990         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12991         stack_trap simple_cleanup_common
12992
12993         # Check if we need to generate uneven OSTs
12994         test_mkdir -p $DIR/$tdir/OST${MINI}
12995         local FILL=$((MINV / 4))
12996         local DIFF=$((MAXV - MINV))
12997         local DIFF2=$((DIFF * 100 / MINV))
12998
12999         local threshold=$(do_facet $SINGLEMDS \
13000                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13001         threshold=${threshold%%%}
13002         echo -n "Check for uneven OSTs: "
13003         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13004
13005         if [[ $DIFF2 -gt $threshold ]]; then
13006                 echo "ok"
13007                 echo "Don't need to fill OST$MINI"
13008         else
13009                 # generate uneven OSTs. Write 2% over the QOS threshold value
13010                 echo "no"
13011                 DIFF=$((threshold - DIFF2 + 2))
13012                 DIFF2=$((MINV * DIFF / 100))
13013                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13014                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13015                         error "setstripe failed"
13016                 DIFF=$((DIFF2 / 2048))
13017                 i=0
13018                 while [ $i -lt $DIFF ]; do
13019                         i=$((i + 1))
13020                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13021                                 bs=2M count=1 2>/dev/null
13022                         echo -n .
13023                 done
13024                 echo .
13025                 sync
13026                 sleep_maxage
13027                 free_min_max
13028         fi
13029
13030         DIFF=$((MAXV - MINV))
13031         DIFF2=$((DIFF * 100 / MINV))
13032         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13033         if [ $DIFF2 -gt $threshold ]; then
13034                 echo "ok"
13035         else
13036                 skip "QOS imbalance criteria not met"
13037         fi
13038
13039         MINI1=$MINI
13040         MINV1=$MINV
13041         MAXI1=$MAXI
13042         MAXV1=$MAXV
13043
13044         # now fill using QOS
13045         $LFS setstripe -c 1 $DIR/$tdir
13046         FILL=$((FILL / 200))
13047         if [ $FILL -gt 600 ]; then
13048                 FILL=600
13049         fi
13050         echo "writing $FILL files to QOS-assigned OSTs"
13051         i=0
13052         while [ $i -lt $FILL ]; do
13053                 i=$((i + 1))
13054                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13055                         count=1 2>/dev/null
13056                 echo -n .
13057         done
13058         echo "wrote $i 200k files"
13059         sync
13060         sleep_maxage
13061
13062         echo "Note: free space may not be updated, so measurements might be off"
13063         free_min_max
13064         DIFF2=$((MAXV - MINV))
13065         echo "free space delta: orig $DIFF final $DIFF2"
13066         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13067         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13068         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13069         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13070         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13071         if [[ $DIFF -gt 0 ]]; then
13072                 FILL=$((DIFF2 * 100 / DIFF - 100))
13073                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13074         fi
13075
13076         # Figure out which files were written where
13077         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13078                awk '/'$MINI1': / {print $2; exit}')
13079         echo $UUID
13080         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13081         echo "$MINC files created on smaller OST $MINI1"
13082         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13083                awk '/'$MAXI1': / {print $2; exit}')
13084         echo $UUID
13085         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13086         echo "$MAXC files created on larger OST $MAXI1"
13087         if [[ $MINC -gt 0 ]]; then
13088                 FILL=$((MAXC * 100 / MINC - 100))
13089                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13090         fi
13091         [[ $MAXC -gt $MINC ]] ||
13092                 error_ignore LU-9 "stripe QOS didn't balance free space"
13093 }
13094 run_test 116a "stripe QOS: free space balance ==================="
13095
13096 test_116b() { # LU-2093
13097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13098         remote_mds_nodsh && skip "remote MDS with nodsh"
13099
13100 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13101         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13102                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13103         [ -z "$old_rr" ] && skip "no QOS"
13104         do_facet $SINGLEMDS lctl set_param \
13105                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13106         mkdir -p $DIR/$tdir
13107         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13108         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13109         do_facet $SINGLEMDS lctl set_param fail_loc=0
13110         rm -rf $DIR/$tdir
13111         do_facet $SINGLEMDS lctl set_param \
13112                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13113 }
13114 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13115
13116 test_117() # bug 10891
13117 {
13118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13119
13120         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13121         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13122         lctl set_param fail_loc=0x21e
13123         > $DIR/$tfile || error "truncate failed"
13124         lctl set_param fail_loc=0
13125         echo "Truncate succeeded."
13126         rm -f $DIR/$tfile
13127 }
13128 run_test 117 "verify osd extend =========="
13129
13130 NO_SLOW_RESENDCOUNT=4
13131 export OLD_RESENDCOUNT=""
13132 set_resend_count () {
13133         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13134         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13135         lctl set_param -n $PROC_RESENDCOUNT $1
13136         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13137 }
13138
13139 # for reduce test_118* time (b=14842)
13140 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13141
13142 # Reset async IO behavior after error case
13143 reset_async() {
13144         FILE=$DIR/reset_async
13145
13146         # Ensure all OSCs are cleared
13147         $LFS setstripe -c -1 $FILE
13148         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13149         sync
13150         rm $FILE
13151 }
13152
13153 test_118a() #bug 11710
13154 {
13155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13156
13157         reset_async
13158
13159         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13160         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13161         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13162
13163         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13164                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13165                 return 1;
13166         fi
13167         rm -f $DIR/$tfile
13168 }
13169 run_test 118a "verify O_SYNC works =========="
13170
13171 test_118b()
13172 {
13173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13174         remote_ost_nodsh && skip "remote OST with nodsh"
13175
13176         reset_async
13177
13178         #define OBD_FAIL_SRV_ENOENT 0x217
13179         set_nodes_failloc "$(osts_nodes)" 0x217
13180         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13181         RC=$?
13182         set_nodes_failloc "$(osts_nodes)" 0
13183         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13184         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13185                     grep -c writeback)
13186
13187         if [[ $RC -eq 0 ]]; then
13188                 error "Must return error due to dropped pages, rc=$RC"
13189                 return 1;
13190         fi
13191
13192         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13193                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13194                 return 1;
13195         fi
13196
13197         echo "Dirty pages not leaked on ENOENT"
13198
13199         # Due to the above error the OSC will issue all RPCs syncronously
13200         # until a subsequent RPC completes successfully without error.
13201         $MULTIOP $DIR/$tfile Ow4096yc
13202         rm -f $DIR/$tfile
13203
13204         return 0
13205 }
13206 run_test 118b "Reclaim dirty pages on fatal error =========="
13207
13208 test_118c()
13209 {
13210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13211
13212         # for 118c, restore the original resend count, LU-1940
13213         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13214                                 set_resend_count $OLD_RESENDCOUNT
13215         remote_ost_nodsh && skip "remote OST with nodsh"
13216
13217         reset_async
13218
13219         #define OBD_FAIL_OST_EROFS               0x216
13220         set_nodes_failloc "$(osts_nodes)" 0x216
13221
13222         # multiop should block due to fsync until pages are written
13223         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13224         MULTIPID=$!
13225         sleep 1
13226
13227         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13228                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13229         fi
13230
13231         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13232                     grep -c writeback)
13233         if [[ $WRITEBACK -eq 0 ]]; then
13234                 error "No page in writeback, writeback=$WRITEBACK"
13235         fi
13236
13237         set_nodes_failloc "$(osts_nodes)" 0
13238         wait $MULTIPID
13239         RC=$?
13240         if [[ $RC -ne 0 ]]; then
13241                 error "Multiop fsync failed, rc=$RC"
13242         fi
13243
13244         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13245         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13246                     grep -c writeback)
13247         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13248                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13249         fi
13250
13251         rm -f $DIR/$tfile
13252         echo "Dirty pages flushed via fsync on EROFS"
13253         return 0
13254 }
13255 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13256
13257 # continue to use small resend count to reduce test_118* time (b=14842)
13258 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13259
13260 test_118d()
13261 {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263         remote_ost_nodsh && skip "remote OST with nodsh"
13264
13265         reset_async
13266
13267         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13268         set_nodes_failloc "$(osts_nodes)" 0x214
13269         # multiop should block due to fsync until pages are written
13270         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13271         MULTIPID=$!
13272         sleep 1
13273
13274         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13275                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13276         fi
13277
13278         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13279                     grep -c writeback)
13280         if [[ $WRITEBACK -eq 0 ]]; then
13281                 error "No page in writeback, writeback=$WRITEBACK"
13282         fi
13283
13284         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13285         set_nodes_failloc "$(osts_nodes)" 0
13286
13287         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13288         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13289                     grep -c writeback)
13290         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13291                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13292         fi
13293
13294         rm -f $DIR/$tfile
13295         echo "Dirty pages gaurenteed flushed via fsync"
13296         return 0
13297 }
13298 run_test 118d "Fsync validation inject a delay of the bulk =========="
13299
13300 test_118f() {
13301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13302
13303         reset_async
13304
13305         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13306         lctl set_param fail_loc=0x8000040a
13307
13308         # Should simulate EINVAL error which is fatal
13309         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13310         RC=$?
13311         if [[ $RC -eq 0 ]]; then
13312                 error "Must return error due to dropped pages, rc=$RC"
13313         fi
13314
13315         lctl set_param fail_loc=0x0
13316
13317         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13318         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13319         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13320                     grep -c writeback)
13321         if [[ $LOCKED -ne 0 ]]; then
13322                 error "Locked pages remain in cache, locked=$LOCKED"
13323         fi
13324
13325         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13326                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13327         fi
13328
13329         rm -f $DIR/$tfile
13330         echo "No pages locked after fsync"
13331
13332         reset_async
13333         return 0
13334 }
13335 run_test 118f "Simulate unrecoverable OSC side error =========="
13336
13337 test_118g() {
13338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13339
13340         reset_async
13341
13342         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13343         lctl set_param fail_loc=0x406
13344
13345         # simulate local -ENOMEM
13346         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13347         RC=$?
13348
13349         lctl set_param fail_loc=0
13350         if [[ $RC -eq 0 ]]; then
13351                 error "Must return error due to dropped pages, rc=$RC"
13352         fi
13353
13354         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13355         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13356         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13357                         grep -c writeback)
13358         if [[ $LOCKED -ne 0 ]]; then
13359                 error "Locked pages remain in cache, locked=$LOCKED"
13360         fi
13361
13362         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13363                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13364         fi
13365
13366         rm -f $DIR/$tfile
13367         echo "No pages locked after fsync"
13368
13369         reset_async
13370         return 0
13371 }
13372 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13373
13374 test_118h() {
13375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13376         remote_ost_nodsh && skip "remote OST with nodsh"
13377
13378         reset_async
13379
13380         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13381         set_nodes_failloc "$(osts_nodes)" 0x20e
13382         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13383         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13384         RC=$?
13385
13386         set_nodes_failloc "$(osts_nodes)" 0
13387         if [[ $RC -eq 0 ]]; then
13388                 error "Must return error due to dropped pages, rc=$RC"
13389         fi
13390
13391         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13392         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13393         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13394                     grep -c writeback)
13395         if [[ $LOCKED -ne 0 ]]; then
13396                 error "Locked pages remain in cache, locked=$LOCKED"
13397         fi
13398
13399         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13400                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13401         fi
13402
13403         rm -f $DIR/$tfile
13404         echo "No pages locked after fsync"
13405
13406         return 0
13407 }
13408 run_test 118h "Verify timeout in handling recoverables errors  =========="
13409
13410 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13411
13412 test_118i() {
13413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13414         remote_ost_nodsh && skip "remote OST with nodsh"
13415
13416         reset_async
13417
13418         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13419         set_nodes_failloc "$(osts_nodes)" 0x20e
13420
13421         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13422         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13423         PID=$!
13424         sleep 5
13425         set_nodes_failloc "$(osts_nodes)" 0
13426
13427         wait $PID
13428         RC=$?
13429         if [[ $RC -ne 0 ]]; then
13430                 error "got error, but should be not, rc=$RC"
13431         fi
13432
13433         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13434         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13435         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13436         if [[ $LOCKED -ne 0 ]]; then
13437                 error "Locked pages remain in cache, locked=$LOCKED"
13438         fi
13439
13440         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13441                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13442         fi
13443
13444         rm -f $DIR/$tfile
13445         echo "No pages locked after fsync"
13446
13447         return 0
13448 }
13449 run_test 118i "Fix error before timeout in recoverable error  =========="
13450
13451 [ "$SLOW" = "no" ] && set_resend_count 4
13452
13453 test_118j() {
13454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13455         remote_ost_nodsh && skip "remote OST with nodsh"
13456
13457         reset_async
13458
13459         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13460         set_nodes_failloc "$(osts_nodes)" 0x220
13461
13462         # return -EIO from OST
13463         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13464         RC=$?
13465         set_nodes_failloc "$(osts_nodes)" 0x0
13466         if [[ $RC -eq 0 ]]; then
13467                 error "Must return error due to dropped pages, rc=$RC"
13468         fi
13469
13470         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13471         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13472         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13473         if [[ $LOCKED -ne 0 ]]; then
13474                 error "Locked pages remain in cache, locked=$LOCKED"
13475         fi
13476
13477         # in recoverable error on OST we want resend and stay until it finished
13478         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13479                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13480         fi
13481
13482         rm -f $DIR/$tfile
13483         echo "No pages locked after fsync"
13484
13485         return 0
13486 }
13487 run_test 118j "Simulate unrecoverable OST side error =========="
13488
13489 test_118k()
13490 {
13491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13492         remote_ost_nodsh && skip "remote OSTs with nodsh"
13493
13494         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13495         set_nodes_failloc "$(osts_nodes)" 0x20e
13496         test_mkdir $DIR/$tdir
13497
13498         for ((i=0;i<10;i++)); do
13499                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13500                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13501                 SLEEPPID=$!
13502                 sleep 0.500s
13503                 kill $SLEEPPID
13504                 wait $SLEEPPID
13505         done
13506
13507         set_nodes_failloc "$(osts_nodes)" 0
13508         rm -rf $DIR/$tdir
13509 }
13510 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13511
13512 test_118l() # LU-646
13513 {
13514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13515
13516         test_mkdir $DIR/$tdir
13517         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13518         rm -rf $DIR/$tdir
13519 }
13520 run_test 118l "fsync dir"
13521
13522 test_118m() # LU-3066
13523 {
13524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13525
13526         test_mkdir $DIR/$tdir
13527         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13528         rm -rf $DIR/$tdir
13529 }
13530 run_test 118m "fdatasync dir ========="
13531
13532 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13533
13534 test_118n()
13535 {
13536         local begin
13537         local end
13538
13539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13540         remote_ost_nodsh && skip "remote OSTs with nodsh"
13541
13542         # Sleep to avoid a cached response.
13543         #define OBD_STATFS_CACHE_SECONDS 1
13544         sleep 2
13545
13546         # Inject a 10 second delay in the OST_STATFS handler.
13547         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13548         set_nodes_failloc "$(osts_nodes)" 0x242
13549
13550         begin=$SECONDS
13551         stat --file-system $MOUNT > /dev/null
13552         end=$SECONDS
13553
13554         set_nodes_failloc "$(osts_nodes)" 0
13555
13556         if ((end - begin > 20)); then
13557             error "statfs took $((end - begin)) seconds, expected 10"
13558         fi
13559 }
13560 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13561
13562 test_119a() # bug 11737
13563 {
13564         BSIZE=$((512 * 1024))
13565         directio write $DIR/$tfile 0 1 $BSIZE
13566         # We ask to read two blocks, which is more than a file size.
13567         # directio will indicate an error when requested and actual
13568         # sizes aren't equeal (a normal situation in this case) and
13569         # print actual read amount.
13570         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13571         if [ "$NOB" != "$BSIZE" ]; then
13572                 error "read $NOB bytes instead of $BSIZE"
13573         fi
13574         rm -f $DIR/$tfile
13575 }
13576 run_test 119a "Short directIO read must return actual read amount"
13577
13578 test_119b() # bug 11737
13579 {
13580         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13581
13582         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13583         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13584         sync
13585         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13586                 error "direct read failed"
13587         rm -f $DIR/$tfile
13588 }
13589 run_test 119b "Sparse directIO read must return actual read amount"
13590
13591 test_119c() # bug 13099
13592 {
13593         BSIZE=1048576
13594         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13595         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13596         rm -f $DIR/$tfile
13597 }
13598 run_test 119c "Testing for direct read hitting hole"
13599
13600 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13601 # Maloo test history
13602
13603 test_119e()
13604 {
13605         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13606                 skip "Need server version at least 2.15.58"
13607         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13608
13609         local stripe_size=$((1024 * 1024)) #1 MiB
13610         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13611         local file_size=$((25 * stripe_size))
13612         local bsizes
13613
13614         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13615         stack_trap "rm -f $DIR/$tfile*"
13616
13617         # Just a bit bigger than the largest size in the test set below
13618         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13619                 error "buffered i/o to create file failed"
13620
13621         # trivial test of unaligned DIO
13622         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13623                 iflag=direct oflag=direct ||
13624                 error "trivial unaligned dio failed"
13625
13626         # Test of disabling unaligned DIO support
13627         $LCTL set_param llite.*.unaligned_dio=0
13628         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13629         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13630         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13631                 iflag=direct oflag=direct &&
13632                 error "unaligned dio succeeded when disabled"
13633         $LCTL set_param llite.*.unaligned_dio=1
13634
13635         # Clean up before next part of test
13636         rm -f $DIR/$tfile.2
13637
13638         if zfs_or_rotational; then
13639                 # DIO on ZFS can take up to 2 seconds per IO
13640                 # rotational is better, but still slow.
13641                 # Limit testing on those media to larger sizes
13642                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13643                         $((stripe_size + 1024))"
13644         else
13645                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13646                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13647                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13648                         $((stripe_size - 1)) $stripe_size \
13649                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13650                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13651         fi
13652
13653         for bs in $bsizes; do
13654                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13655                 echo "Read/write with DIO at size $bs"
13656                 # Read and write with DIO from source to dest
13657                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13658                         iflag=direct oflag=direct ||
13659                         error "dio failed"
13660
13661                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13662                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13663                         error "size incorrect, file copy read/write bsize: $bs"
13664                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13665                         error "files differ, bsize $bs"
13666                 rm -f $DIR/$tfile.2
13667         done
13668 }
13669 run_test 119e "Basic tests of dio read and write at various sizes"
13670
13671 test_119f()
13672 {
13673         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13674
13675         local stripe_size=$((1024 * 1024)) #1 MiB
13676         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13677         local file_size=$((25 * stripe_size))
13678         local bsizes
13679
13680         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13681         stack_trap "rm -f $DIR/$tfile*"
13682
13683         # Just a bit bigger than the largest size in the test set below
13684         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13685                 error "buffered i/o to create file failed"
13686
13687         if zfs_or_rotational; then
13688                 # DIO on ZFS can take up to 2 seconds per IO
13689                 # rotational is better, but still slow.
13690                 # Limit testing on those media to larger sizes
13691                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13692                         $((stripe_size + 1024))"
13693         else
13694                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13695                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13696                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13697                         $((stripe_size - 1)) $stripe_size \
13698                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13699                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13700         fi
13701
13702         for bs in $bsizes; do
13703                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13704                 # Read and write with DIO from source to dest in two
13705                 # threads - should give correct copy of file
13706
13707                 echo "bs: $bs"
13708                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13709                         oflag=direct conv=notrunc &
13710                 pid_dio1=$!
13711                 # Note block size is different here for a more interesting race
13712                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13713                         iflag=direct oflag=direct conv=notrunc &
13714                 pid_dio2=$!
13715                 wait $pid_dio1
13716                 rc1=$?
13717                 wait $pid_dio2
13718                 rc2=$?
13719                 if (( rc1 != 0 )); then
13720                         error "dio copy 1 w/bsize $bs failed: $rc1"
13721                 fi
13722                 if (( rc2 != 0 )); then
13723                         error "dio copy 2 w/bsize $bs failed: $rc2"
13724                 fi
13725
13726
13727                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13728                         error "size incorrect, file copy read/write bsize: $bs"
13729                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13730                         error "files differ, bsize $bs"
13731                 rm -f $DIR/$tfile.2
13732         done
13733 }
13734 run_test 119f "dio vs dio race"
13735
13736 test_119g()
13737 {
13738         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13739
13740         local stripe_size=$((1024 * 1024)) #1 MiB
13741         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13742         local file_size=$((25 * stripe_size))
13743         local bsizes
13744
13745         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13746         stack_trap "rm -f $DIR/$tfile*"
13747
13748         # Just a bit bigger than the largest size in the test set below
13749         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13750                 error "buffered i/o to create file failed"
13751
13752         if zfs_or_rotational; then
13753                 # DIO on ZFS can take up to 2 seconds per IO
13754                 # rotational is better, but still slow.
13755                 # Limit testing on those media to larger sizes
13756                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13757                         $((stripe_size + 1024))"
13758         else
13759                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13760                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13761                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13762                         $((stripe_size - 1)) $stripe_size \
13763                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13764                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13765         fi
13766
13767         for bs in $bsizes; do
13768                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13769                 echo "bs: $bs"
13770                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13771                         oflag=direct conv=notrunc &
13772                 pid_dio1=$!
13773                 # Buffered I/O with similar but not the same block size
13774                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13775                 pid_bio2=$!
13776                 wait $pid_dio1
13777                 rc1=$?
13778                 wait $pid_bio2
13779                 rc2=$?
13780                 if (( rc1 != 0 )); then
13781                         error "dio copy 1 w/bsize $bs failed: $rc1"
13782                 fi
13783                 if (( rc2 != 0 )); then
13784                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13785                 fi
13786
13787                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13788                         error "size incorrect"
13789                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13790                         error "files differ, bsize $bs"
13791                 rm -f $DIR/$tfile.2
13792         done
13793 }
13794 run_test 119g "dio vs buffered I/O race"
13795
13796 test_119h()
13797 {
13798         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13799
13800         local stripe_size=$((1024 * 1024)) #1 MiB
13801         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13802         local file_size=$((25 * stripe_size))
13803         local bsizes
13804
13805         stack_trap "rm -f $DIR/$tfile.*"
13806
13807         if zfs_or_rotational; then
13808                 # DIO on ZFS can take up to 2 seconds per IO
13809                 # rotational is better, but still slow.
13810                 # Limit testing on those media to larger sizes
13811                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13812                         $((stripe_size + 1024))"
13813         else
13814                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13815                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13816                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13817                         $((stripe_size - 1)) $stripe_size \
13818                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13819                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13820         fi
13821
13822         for bs in $bsizes; do
13823                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13824                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13825                 echo "unaligned writes of blocksize: $bs"
13826                 # Write a file with unaligned DIO and regular DIO, and compare
13827                 # them
13828                 # with 'u', multiop randomly unaligns the io from the buffer
13829                 $MULTIOP $DIR/$tfile.1 \
13830                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13831                         error "multiop memory unaligned write failed, $bs"
13832                 $MULTIOP $DIR/$tfile.2 \
13833                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13834                         error "multiop memory aligned write failed, $bs"
13835
13836                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13837                         error "files differ, bsize $bs"
13838                 rm -f $DIR/$tfile.*
13839         done
13840
13841         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13842         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13843                 error "dd to create source file for read failed"
13844
13845         # Just a few quick tests to make sure unaligned DIO reads don't crash
13846         for bs in $bsizes; do
13847
13848                 echo "unaligned reads of blocksize: $bs"
13849                 # with 'u', multiop randomly unaligns the io from the buffer
13850                 $MULTIOP $DIR/$tfile.1 \
13851                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13852                         error "multiop memory unaligned read failed, $bs"
13853
13854         done
13855         rm -f $DIR/$tfile*
13856 }
13857 run_test 119h "basic tests of memory unaligned dio"
13858
13859 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13860 test_119i()
13861 {
13862         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13863         which aiocp || skip_env "no aiocp installed"
13864
13865         local stripe_size=$((1024 * 1024)) #1 MiB
13866         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13867         local file_size=$((25 * stripe_size))
13868         local bsizes
13869
13870         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13871         stack_trap "rm -f $DIR/$tfile.*"
13872
13873         # Just a bit bigger than the largest size in the test set below
13874         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13875                 error "buffered i/o to create file failed"
13876
13877         if zfs_or_rotational; then
13878                 # DIO on ZFS can take up to 2 seconds per IO
13879                 # rotational is better, but still slow.
13880                 # Limit testing on those media to larger sizes
13881                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13882                         $((stripe_size + 1024))"
13883         else
13884                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13885                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13886                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13887                         $((stripe_size - 1)) $stripe_size \
13888                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13889                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13890         fi
13891
13892         # Do page aligned and NOT page aligned AIO
13893         for align in 8 512 $((PAGE_SIZE)); do
13894         # Deliberately includes a few aligned sizes
13895         for bs in $bsizes; do
13896                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13897
13898                 echo "bs: $bs, align: $align, file_size $file_size"
13899                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13900                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13901                         error "unaligned aio failed, bs: $bs, align: $align"
13902
13903                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13904                         error "size incorrect"
13905                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13906                         error "files differ"
13907                 rm -f $DIR/$tfile.2
13908         done
13909         done
13910 }
13911 run_test 119i "test unaligned aio at varying sizes"
13912
13913 test_120a() {
13914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13915         remote_mds_nodsh && skip "remote MDS with nodsh"
13916         test_mkdir -i0 -c1 $DIR/$tdir
13917         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13918                 skip_env "no early lock cancel on server"
13919
13920         lru_resize_disable mdc
13921         lru_resize_disable osc
13922         cancel_lru_locks mdc
13923         # asynchronous object destroy at MDT could cause bl ast to client
13924         cancel_lru_locks osc
13925
13926         stat $DIR/$tdir > /dev/null
13927         can1=$(do_facet mds1 \
13928                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13929                awk '/ldlm_cancel/ {print $2}')
13930         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13931                awk '/ldlm_bl_callback/ {print $2}')
13932         test_mkdir -i0 -c1 $DIR/$tdir/d1
13933         can2=$(do_facet mds1 \
13934                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13935                awk '/ldlm_cancel/ {print $2}')
13936         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13937                awk '/ldlm_bl_callback/ {print $2}')
13938         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13939         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13940         lru_resize_enable mdc
13941         lru_resize_enable osc
13942 }
13943 run_test 120a "Early Lock Cancel: mkdir test"
13944
13945 test_120b() {
13946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13947         remote_mds_nodsh && skip "remote MDS with nodsh"
13948         test_mkdir $DIR/$tdir
13949         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13950                 skip_env "no early lock cancel on server"
13951
13952         lru_resize_disable mdc
13953         lru_resize_disable osc
13954         cancel_lru_locks mdc
13955         stat $DIR/$tdir > /dev/null
13956         can1=$(do_facet $SINGLEMDS \
13957                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13958                awk '/ldlm_cancel/ {print $2}')
13959         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13960                awk '/ldlm_bl_callback/ {print $2}')
13961         touch $DIR/$tdir/f1
13962         can2=$(do_facet $SINGLEMDS \
13963                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13964                awk '/ldlm_cancel/ {print $2}')
13965         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13966                awk '/ldlm_bl_callback/ {print $2}')
13967         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13968         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13969         lru_resize_enable mdc
13970         lru_resize_enable osc
13971 }
13972 run_test 120b "Early Lock Cancel: create test"
13973
13974 test_120c() {
13975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13976         remote_mds_nodsh && skip "remote MDS with nodsh"
13977         test_mkdir -i0 -c1 $DIR/$tdir
13978         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13979                 skip "no early lock cancel on server"
13980
13981         lru_resize_disable mdc
13982         lru_resize_disable osc
13983         test_mkdir -i0 -c1 $DIR/$tdir/d1
13984         test_mkdir -i0 -c1 $DIR/$tdir/d2
13985         touch $DIR/$tdir/d1/f1
13986         cancel_lru_locks mdc
13987         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13988         can1=$(do_facet mds1 \
13989                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13990                awk '/ldlm_cancel/ {print $2}')
13991         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13992                awk '/ldlm_bl_callback/ {print $2}')
13993         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13994         can2=$(do_facet mds1 \
13995                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13996                awk '/ldlm_cancel/ {print $2}')
13997         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13998                awk '/ldlm_bl_callback/ {print $2}')
13999         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14000         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14001         lru_resize_enable mdc
14002         lru_resize_enable osc
14003 }
14004 run_test 120c "Early Lock Cancel: link test"
14005
14006 test_120d() {
14007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14008         remote_mds_nodsh && skip "remote MDS with nodsh"
14009         test_mkdir -i0 -c1 $DIR/$tdir
14010         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14011                 skip_env "no early lock cancel on server"
14012
14013         lru_resize_disable mdc
14014         lru_resize_disable osc
14015         touch $DIR/$tdir
14016         cancel_lru_locks mdc
14017         stat $DIR/$tdir > /dev/null
14018         can1=$(do_facet mds1 \
14019                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14020                awk '/ldlm_cancel/ {print $2}')
14021         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14022                awk '/ldlm_bl_callback/ {print $2}')
14023         chmod a+x $DIR/$tdir
14024         can2=$(do_facet mds1 \
14025                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14026                awk '/ldlm_cancel/ {print $2}')
14027         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14028                awk '/ldlm_bl_callback/ {print $2}')
14029         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14030         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14031         lru_resize_enable mdc
14032         lru_resize_enable osc
14033 }
14034 run_test 120d "Early Lock Cancel: setattr test"
14035
14036 test_120e() {
14037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14038         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14039                 skip_env "no early lock cancel on server"
14040         remote_mds_nodsh && skip "remote MDS with nodsh"
14041
14042         local dlmtrace_set=false
14043
14044         test_mkdir -i0 -c1 $DIR/$tdir
14045         lru_resize_disable mdc
14046         lru_resize_disable osc
14047         ! $LCTL get_param debug | grep -q dlmtrace &&
14048                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14049         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14050         cancel_lru_locks mdc
14051         cancel_lru_locks osc
14052         dd if=$DIR/$tdir/f1 of=/dev/null
14053         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14054         # XXX client can not do early lock cancel of OST lock
14055         # during unlink (LU-4206), so cancel osc lock now.
14056         sleep 2
14057         cancel_lru_locks osc
14058         can1=$(do_facet mds1 \
14059                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14060                awk '/ldlm_cancel/ {print $2}')
14061         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14062                awk '/ldlm_bl_callback/ {print $2}')
14063         unlink $DIR/$tdir/f1
14064         sleep 5
14065         can2=$(do_facet mds1 \
14066                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14067                awk '/ldlm_cancel/ {print $2}')
14068         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14069                awk '/ldlm_bl_callback/ {print $2}')
14070         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14071                 $LCTL dk $TMP/cancel.debug.txt
14072         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14073                 $LCTL dk $TMP/blocking.debug.txt
14074         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14075         lru_resize_enable mdc
14076         lru_resize_enable osc
14077 }
14078 run_test 120e "Early Lock Cancel: unlink test"
14079
14080 test_120f() {
14081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14082         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14083                 skip_env "no early lock cancel on server"
14084         remote_mds_nodsh && skip "remote MDS with nodsh"
14085
14086         test_mkdir -i0 -c1 $DIR/$tdir
14087         lru_resize_disable mdc
14088         lru_resize_disable osc
14089         test_mkdir -i0 -c1 $DIR/$tdir/d1
14090         test_mkdir -i0 -c1 $DIR/$tdir/d2
14091         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14092         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14093         cancel_lru_locks mdc
14094         cancel_lru_locks osc
14095         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14096         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14097         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14098         # XXX client can not do early lock cancel of OST lock
14099         # during rename (LU-4206), so cancel osc lock now.
14100         sleep 2
14101         cancel_lru_locks osc
14102         can1=$(do_facet mds1 \
14103                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14104                awk '/ldlm_cancel/ {print $2}')
14105         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14106                awk '/ldlm_bl_callback/ {print $2}')
14107         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14108         sleep 5
14109         can2=$(do_facet mds1 \
14110                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14111                awk '/ldlm_cancel/ {print $2}')
14112         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14113                awk '/ldlm_bl_callback/ {print $2}')
14114         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14115         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14116         lru_resize_enable mdc
14117         lru_resize_enable osc
14118 }
14119 run_test 120f "Early Lock Cancel: rename test"
14120
14121 test_120g() {
14122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14123         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14124                 skip_env "no early lock cancel on server"
14125         remote_mds_nodsh && skip "remote MDS with nodsh"
14126
14127         lru_resize_disable mdc
14128         lru_resize_disable osc
14129         count=10000
14130         echo create $count files
14131         test_mkdir $DIR/$tdir
14132         cancel_lru_locks mdc
14133         cancel_lru_locks osc
14134         t0=$(date +%s)
14135
14136         can0=$(do_facet $SINGLEMDS \
14137                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14138                awk '/ldlm_cancel/ {print $2}')
14139         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14140                awk '/ldlm_bl_callback/ {print $2}')
14141         createmany -o $DIR/$tdir/f $count
14142         sync
14143         can1=$(do_facet $SINGLEMDS \
14144                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14145                awk '/ldlm_cancel/ {print $2}')
14146         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14147                awk '/ldlm_bl_callback/ {print $2}')
14148         t1=$(date +%s)
14149         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14150         echo rm $count files
14151         rm -r $DIR/$tdir
14152         sync
14153         can2=$(do_facet $SINGLEMDS \
14154                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14155                awk '/ldlm_cancel/ {print $2}')
14156         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14157                awk '/ldlm_bl_callback/ {print $2}')
14158         t2=$(date +%s)
14159         echo total: $count removes in $((t2-t1))
14160         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14161         sleep 2
14162         # wait for commitment of removal
14163         lru_resize_enable mdc
14164         lru_resize_enable osc
14165 }
14166 run_test 120g "Early Lock Cancel: performance test"
14167
14168 test_121() { #bug #10589
14169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14170
14171         rm -rf $DIR/$tfile
14172         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14173 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14174         lctl set_param fail_loc=0x310
14175         cancel_lru_locks osc > /dev/null
14176         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14177         lctl set_param fail_loc=0
14178         [[ $reads -eq $writes ]] ||
14179                 error "read $reads blocks, must be $writes blocks"
14180 }
14181 run_test 121 "read cancel race ========="
14182
14183 test_123a_base() { # was test 123, statahead(bug 11401)
14184         local lsx="$1"
14185
14186         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14187
14188         SLOWOK=0
14189         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14190                 log "testing UP system. Performance may be lower than expected."
14191                 SLOWOK=1
14192         fi
14193         running_in_vm && SLOWOK=1
14194
14195         $LCTL set_param mdc.*.batch_stats=0
14196
14197         rm -rf $DIR/$tdir
14198         test_mkdir $DIR/$tdir
14199         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14200         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14201         MULT=10
14202         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14203                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14204
14205                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14206                 lctl set_param -n llite.*.statahead_max 0
14207                 lctl get_param llite.*.statahead_max
14208                 cancel_lru_locks mdc
14209                 cancel_lru_locks osc
14210                 stime=$(date +%s)
14211                 time $lsx $DIR/$tdir | wc -l
14212                 etime=$(date +%s)
14213                 delta=$((etime - stime))
14214                 log "$lsx $i files without statahead: $delta sec"
14215                 lctl set_param llite.*.statahead_max=$max
14216
14217                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14218                          awk '/statahead.wrong:/ { print $NF }')
14219                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14220                 cancel_lru_locks mdc
14221                 cancel_lru_locks osc
14222                 stime=$(date +%s)
14223                 time $lsx $DIR/$tdir | wc -l
14224                 etime=$(date +%s)
14225                 delta_sa=$((etime - stime))
14226                 log "$lsx $i files with statahead: $delta_sa sec"
14227                 lctl get_param -n llite.*.statahead_stats
14228                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14229                          awk '/statahead.wrong:/ { print $NF }')
14230
14231                 [[ $swrong -lt $ewrong ]] &&
14232                         log "statahead was stopped, maybe too many locks held!"
14233                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14234
14235                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14236                         max=$(lctl get_param -n llite.*.statahead_max |
14237                                 head -n 1)
14238                         lctl set_param -n llite.*.statahead_max 0
14239                         lctl get_param llite.*.statahead_max
14240                         cancel_lru_locks mdc
14241                         cancel_lru_locks osc
14242                         stime=$(date +%s)
14243                         time $lsx $DIR/$tdir | wc -l
14244                         etime=$(date +%s)
14245                         delta=$((etime - stime))
14246                         log "$lsx $i files again without statahead: $delta sec"
14247                         lctl set_param llite.*.statahead_max=$max
14248                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14249                                 if [ $SLOWOK -eq 0 ]; then
14250                                         error "$lsx $i files is slower with statahead!"
14251                                 else
14252                                         log "$lsx $i files is slower with statahead!"
14253                                 fi
14254                                 break
14255                         fi
14256                 fi
14257
14258                 [ $delta -gt 20 ] && break
14259                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14260                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14261         done
14262         log "$lsx done"
14263
14264         stime=$(date +%s)
14265         rm -r $DIR/$tdir
14266         sync
14267         etime=$(date +%s)
14268         delta=$((etime - stime))
14269         log "rm -r $DIR/$tdir/: $delta seconds"
14270         log "rm done"
14271         lctl get_param -n llite.*.statahead_stats
14272         $LCTL get_param mdc.*.batch_stats
14273 }
14274
14275 test_123aa() {
14276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14277
14278         test_123a_base "ls -l"
14279 }
14280 run_test 123aa "verify statahead work"
14281
14282 test_123ab() {
14283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14284
14285         statx_supported || skip_env "Test must be statx() syscall supported"
14286
14287         test_123a_base "$STATX -l"
14288 }
14289 run_test 123ab "verify statahead work by using statx"
14290
14291 test_123ac() {
14292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14293
14294         statx_supported || skip_env "Test must be statx() syscall supported"
14295
14296         local rpcs_before
14297         local rpcs_after
14298         local agl_before
14299         local agl_after
14300
14301         cancel_lru_locks $OSC
14302         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14303         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14304                      awk '/agl.total:/ { print $NF }')
14305         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14306         test_123a_base "$STATX --cached=always -D"
14307         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14308                     awk '/agl.total:/ { print $NF }')
14309         [ $agl_before -eq $agl_after ] ||
14310                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14311         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14312         [ $rpcs_after -eq $rpcs_before ] ||
14313                 error "$STATX should not send glimpse RPCs to $OSC"
14314 }
14315 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14316
14317 test_batch_statahead() {
14318         local max=$1
14319         local batch_max=$2
14320         local num=10000
14321         local batch_rpcs
14322         local unbatch_rpcs
14323         local hit_total
14324
14325         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14326         $LCTL set_param mdc.*.batch_stats=0
14327         $LCTL set_param llite.*.statahead_max=$max
14328         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14329         # Verify that batched statahead is faster than one without statahead
14330         test_123a_base "ls -l"
14331
14332         stack_trap "rm -rf $DIR/$tdir" EXIT
14333         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14334         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14335
14336         # unbatched statahead
14337         $LCTL set_param llite.*.statahead_batch_max=0
14338         $LCTL set_param llite.*.statahead_stats=clear
14339         $LCTL set_param mdc.*.stats=clear
14340         cancel_lru_locks mdc
14341         cancel_lru_locks osc
14342         time ls -l $DIR/$tdir | wc -l
14343         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14344         wait_update_facet client "pgrep ll_sa" "" 35 ||
14345                 error "ll_sa thread is still running"
14346         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14347                     awk '/hit.total:/ { print $NF }')
14348         # hit ratio should be larger than 75% (7500).
14349         (( $hit_total > 7500 )) ||
14350                 error "unbatched statahead hit count ($hit_total) is too low"
14351
14352         # batched statahead
14353         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14354         $LCTL set_param llite.*.statahead_stats=clear
14355         $LCTL set_param mdc.*.batch_stats=clear
14356         $LCTL set_param mdc.*.stats=clear
14357         cancel_lru_locks mdc
14358         cancel_lru_locks osc
14359         time ls -l $DIR/$tdir | wc -l
14360         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14361         # wait for statahead thread to quit and update statahead stats
14362         wait_update_facet client "pgrep ll_sa" "" 35 ||
14363                 error "ll_sa thread is still running"
14364         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14365                     awk '/hit.total:/ { print $NF }')
14366         # hit ratio should be larger than 75% (7500).
14367         (( $hit_total > 7500 )) ||
14368                 error "batched statahead hit count ($hit_total) is too low"
14369
14370         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14371         (( $unbatch_rpcs > $batch_rpcs )) ||
14372                 error "batched statahead does not reduce RPC count"
14373         $LCTL get_param mdc.*.batch_stats
14374 }
14375
14376 test_123ad() {
14377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14378
14379         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14380                 skip "Need server version at least 2.15.53"
14381
14382         local max
14383         local batch_max
14384
14385         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14386         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14387
14388         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14389         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14390
14391         test_batch_statahead 32 32
14392         test_batch_statahead 2048 256
14393 }
14394 run_test 123ad "Verify batching statahead works correctly"
14395
14396 test_123b () { # statahead(bug 15027)
14397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14398
14399         test_mkdir $DIR/$tdir
14400         createmany -o $DIR/$tdir/$tfile-%d 1000
14401
14402         cancel_lru_locks mdc
14403         cancel_lru_locks osc
14404
14405 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14406         lctl set_param fail_loc=0x80000803
14407         ls -lR $DIR/$tdir > /dev/null
14408         log "ls done"
14409         lctl set_param fail_loc=0x0
14410         lctl get_param -n llite.*.statahead_stats
14411         rm -r $DIR/$tdir
14412         sync
14413
14414 }
14415 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14416
14417 test_123c() {
14418         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14419
14420         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14421         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14422         touch $DIR/$tdir.1/{1..3}
14423         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14424
14425         remount_client $MOUNT
14426
14427         $MULTIOP $DIR/$tdir.0 Q
14428
14429         # let statahead to complete
14430         ls -l $DIR/$tdir.0 > /dev/null
14431
14432         testid=$(echo $TESTNAME | tr '_' ' ')
14433         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14434                 error "statahead warning" || true
14435 }
14436 run_test 123c "Can not initialize inode warning on DNE statahead"
14437
14438 test_123d() {
14439         local num=100
14440         local swrong
14441         local ewrong
14442
14443         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14444         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14445                 error "setdirstripe $DIR/$tdir failed"
14446         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14447         remount_client $MOUNT
14448         $LCTL get_param llite.*.statahead_max
14449         $LCTL set_param llite.*.statahead_stats=0 ||
14450                 error "clear statahead_stats failed"
14451         swrong=$(lctl get_param -n llite.*.statahead_stats |
14452                  awk '/statahead.wrong:/ { print $NF }')
14453         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14454         # wait for statahead thread finished to update hit/miss stats.
14455         sleep 1
14456         $LCTL get_param -n llite.*.statahead_stats
14457         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14458                  awk '/statahead.wrong:/ { print $NF }')
14459         (( $swrong == $ewrong )) ||
14460                 log "statahead was stopped, maybe too many locks held!"
14461 }
14462 run_test 123d "Statahead on striped directories works correctly"
14463
14464 test_123e() {
14465         local max
14466         local batch_max
14467         local dir=$DIR/$tdir
14468
14469         mkdir $dir || error "mkdir $dir failed"
14470         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14471         stack_trap "rm -rf $dir"
14472
14473         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14474
14475         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14476         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14477         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14478         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14479
14480         $LCTL set_param llite.*.statahead_max=2048
14481         $LCTL set_param llite.*.statahead_batch_max=1024
14482
14483         ls -l $dir
14484         $LCTL get_param mdc.*.batch_stats
14485         $LCTL get_param llite.*.statahead_*
14486 }
14487 run_test 123e "statahead with large wide striping"
14488
14489 test_123f() {
14490         local max
14491         local batch_max
14492         local dir=$DIR/$tdir
14493
14494         mkdir $dir || error "mkdir $dir failed"
14495         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14496         stack_trap "rm -rf $dir"
14497
14498         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14499
14500         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14501         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14502
14503         $LCTL set_param llite.*.statahead_max=64
14504         $LCTL set_param llite.*.statahead_batch_max=64
14505
14506         ls -l $dir
14507         lctl get_param mdc.*.batch_stats
14508         lctl get_param llite.*.statahead_*
14509
14510         $LCTL set_param llite.*.statahead_max=$max
14511         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14512 }
14513 run_test 123f "Retry mechanism with large wide striping files"
14514
14515 test_123g() {
14516         local dir=$DIR/$tdir
14517         local num=1000
14518
14519         mkdir $dir || error "failed to mkdir $dir"
14520         createmany -o $dir/$tfile $num || error "failed creatmany files"
14521         cancel_lru_locks mdc
14522         cancel_lru_locks osc
14523
14524         $LCTL set_param llite.*.statahead_stats=clear
14525         $LCTL set_param mdc.*.batch_stats=clear
14526         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14527                 error "aheadmany $dir with $tfile failed"
14528         wait_update_facet client "pgrep ll_sa" "" 35 ||
14529                 error "ll_sa thread is still running"
14530         $LCTL get_param -n llite.*.statahead_stats
14531         $LCTL get_param -n mdc.*.batch_stats
14532
14533         local count
14534
14535         count=$($LCTL get_param -n llite.*.statahead_stats |
14536                 awk '/hit.total:/ {print $2}')
14537         echo "Hit total: $count"
14538         # Hit ratio should be >= 75%
14539         (( $count > num * 75 / 100 )) ||
14540                 error "hit total $count is be > 75% of $num"
14541 }
14542 run_test 123g "Test for stat-ahead advise"
14543
14544 test_123h_base() {
14545         local dir=$DIR/$tdir
14546         local cmd="touch $dir/$tfile.{$1}"
14547         local fcnt=$2
14548
14549         stack_trap "rm -rf $dir"
14550         mkdir -p $dir || error "failed to mkdir $dir"
14551         eval $cmd
14552
14553         cancel_lru_locks mdc
14554         $LCTL set_param llite.*.statahead_stats=clear
14555         $LCTL set_param mdc.*.batch_stats=0
14556         $LCTL set_param llite.*.statahead_max=1024
14557         $LCTL set_param llite.*.statahead_batch_max=1024
14558         lctl get_param -n llite.*.statahead_stats
14559         du -a $dir > /dev/null
14560         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14561         wait_update_facet client "pgrep ll_sa" "" 35 ||
14562                 error "ll_sa statahead thread does not quit in 35s"
14563         $LCTL get_param -n llite.*.statahead_stats
14564         $LCTL get_param -n mdc.*.batch_stats
14565
14566         local count=$($LCTL get_param -n llite.*.statahead_stats |
14567                         awk '/fname.total:/ {print $2}')
14568
14569         [ $count == 1 ] || error "File name pattern statahead not trigger"
14570         count=$($LCTL get_param -n llite.*.statahead_stats |
14571                 awk '/hit.total:/ {print $2}')
14572         # Hit ratio should be >= 75%
14573         (( $count > fcnt * 75 / 100 )) ||
14574                 error "hit total is too low: $count"
14575         rm -rf $dir || error "rm -rf $dir failed"
14576 }
14577
14578 test_123h() {
14579         local max
14580         local batch_max
14581         local enabled
14582
14583         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14584         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14585         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14586         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14587         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14588         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14589
14590         $LCTL set_param llite.*.enable_statahead_fname=1
14591
14592         echo "Scan a directory with number regularized fname"
14593         test_123h_base "0..10000" 10000
14594
14595         echo "Scan a directory with zeroed padding number regularized fname"
14596         test_123h_base "000000..010000" 10000
14597 }
14598 run_test 123h "Verify statahead work with the fname pattern via du"
14599
14600 test_123i() {
14601         local dir=$DIR/$tdir
14602         local cmd="createmany -m $dir/$tfile.%06d 1000"
14603
14604         stack_trap "unlinkmany $dir/$tfile.%06d 1000"
14605         mkdir -p $dir || error "failed to mkdir $dir"
14606         eval $cmd
14607
14608         cancel_lru_locks mdc
14609         $LCTL set_param llite.*.statahead_stats=clear
14610         $LCTL set_param mdc.*.batch_stats=0
14611
14612         local max
14613         local batch_max
14614         local enabled
14615
14616         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14617         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14618         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14619         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14620         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14621         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14622
14623         $LCTL set_param llite.*.statahead_max=1024
14624         $LCTL set_param llite.*.statahead_batch_max=32
14625         $LCTL set_param llite.*.enable_statahead_fname=1
14626         echo "statahead_stats (Pre):"
14627         lctl get_param -n llite.*.statahead_stats
14628         ls $dir/* > /dev/null
14629         echo "statahead_stats (Post):"
14630         $LCTL get_param -n llite.*.statahead_stats
14631         $LCTL get_param -n mdc.*.batch_stats
14632
14633         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14634         wait_update_facet client "pgrep ll_sa" "" 35 ||
14635                 error "ll_sa statahead thread does not quit in 35s"
14636         $LCTL get_param -n llite.*.statahead_stats
14637         $LCTL get_param -n mdc.*.batch_stats
14638
14639         local count=$($LCTL get_param -n llite.*.statahead_stats |
14640                         awk '/fname.total:/ {print $2}')
14641
14642         [ $count == 1 ] || error "File name pattern statahead not trigger"
14643         count=$($LCTL get_param -n llite.*.statahead_stats |
14644                 awk '/hit.total:/ {print $2}')
14645         # Hit ratio should be >= 75%
14646         (( $count > 75 )) || error "hit total is too low: $count"
14647 }
14648 run_test 123i "Verify statahead work with the fname pattern via ls dir/*"
14649
14650 test_124a() {
14651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14652         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14653                 skip_env "no lru resize on server"
14654
14655         local NR=2000
14656
14657         test_mkdir $DIR/$tdir
14658
14659         log "create $NR files at $DIR/$tdir"
14660         createmany -o $DIR/$tdir/f $NR ||
14661                 error "failed to create $NR files in $DIR/$tdir"
14662
14663         cancel_lru_locks mdc
14664         ls -l $DIR/$tdir > /dev/null
14665
14666         local NSDIR=""
14667         local LRU_SIZE=0
14668         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14669                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14670                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14671                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14672                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14673                         log "NSDIR=$NSDIR"
14674                         log "NS=$(basename $NSDIR)"
14675                         break
14676                 fi
14677         done
14678
14679         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14680                 skip "Not enough cached locks created!"
14681         fi
14682         log "LRU=$LRU_SIZE"
14683
14684         local SLEEP=30
14685
14686         # We know that lru resize allows one client to hold $LIMIT locks
14687         # for 10h. After that locks begin to be killed by client.
14688         local MAX_HRS=10
14689         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14690         log "LIMIT=$LIMIT"
14691         if [ $LIMIT -lt $LRU_SIZE ]; then
14692                 skip "Limit is too small $LIMIT"
14693         fi
14694
14695         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14696         # killing locks. Some time was spent for creating locks. This means
14697         # that up to the moment of sleep finish we must have killed some of
14698         # them (10-100 locks). This depends on how fast ther were created.
14699         # Many of them were touched in almost the same moment and thus will
14700         # be killed in groups.
14701         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14702
14703         # Use $LRU_SIZE_B here to take into account real number of locks
14704         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14705         local LRU_SIZE_B=$LRU_SIZE
14706         log "LVF=$LVF"
14707         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14708         log "OLD_LVF=$OLD_LVF"
14709         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14710
14711         # Let's make sure that we really have some margin. Client checks
14712         # cached locks every 10 sec.
14713         SLEEP=$((SLEEP+20))
14714         log "Sleep ${SLEEP} sec"
14715         local SEC=0
14716         while ((SEC<$SLEEP)); do
14717                 echo -n "..."
14718                 sleep 5
14719                 SEC=$((SEC+5))
14720                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14721                 echo -n "$LRU_SIZE"
14722         done
14723         echo ""
14724         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14725         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14726
14727         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14728                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14729                 unlinkmany $DIR/$tdir/f $NR
14730                 return
14731         }
14732
14733         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14734         log "unlink $NR files at $DIR/$tdir"
14735         unlinkmany $DIR/$tdir/f $NR
14736 }
14737 run_test 124a "lru resize ======================================="
14738
14739 get_max_pool_limit()
14740 {
14741         local limit=$($LCTL get_param \
14742                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14743         local max=0
14744         for l in $limit; do
14745                 if [[ $l -gt $max ]]; then
14746                         max=$l
14747                 fi
14748         done
14749         echo $max
14750 }
14751
14752 test_124b() {
14753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14754         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14755                 skip_env "no lru resize on server"
14756
14757         LIMIT=$(get_max_pool_limit)
14758
14759         NR=$(($(default_lru_size)*20))
14760         if [[ $NR -gt $LIMIT ]]; then
14761                 log "Limit lock number by $LIMIT locks"
14762                 NR=$LIMIT
14763         fi
14764
14765         IFree=$(mdsrate_inodes_available)
14766         if [ $IFree -lt $NR ]; then
14767                 log "Limit lock number by $IFree inodes"
14768                 NR=$IFree
14769         fi
14770
14771         lru_resize_disable mdc
14772         test_mkdir -p $DIR/$tdir/disable_lru_resize
14773
14774         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14775         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14776         cancel_lru_locks mdc
14777         stime=`date +%s`
14778         PID=""
14779         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14780         PID="$PID $!"
14781         sleep 2
14782         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14783         PID="$PID $!"
14784         sleep 2
14785         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14786         PID="$PID $!"
14787         wait $PID
14788         etime=`date +%s`
14789         nolruresize_delta=$((etime-stime))
14790         log "ls -la time: $nolruresize_delta seconds"
14791         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14792         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14793
14794         lru_resize_enable mdc
14795         test_mkdir -p $DIR/$tdir/enable_lru_resize
14796
14797         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14798         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14799         cancel_lru_locks mdc
14800         stime=`date +%s`
14801         PID=""
14802         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14803         PID="$PID $!"
14804         sleep 2
14805         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14806         PID="$PID $!"
14807         sleep 2
14808         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14809         PID="$PID $!"
14810         wait $PID
14811         etime=`date +%s`
14812         lruresize_delta=$((etime-stime))
14813         log "ls -la time: $lruresize_delta seconds"
14814         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14815
14816         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14817                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14818         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14819                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14820         else
14821                 log "lru resize performs the same with no lru resize"
14822         fi
14823         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14824 }
14825 run_test 124b "lru resize (performance test) ======================="
14826
14827 test_124c() {
14828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14829         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14830                 skip_env "no lru resize on server"
14831
14832         # cache ununsed locks on client
14833         local nr=100
14834         cancel_lru_locks mdc
14835         test_mkdir $DIR/$tdir
14836         createmany -o $DIR/$tdir/f $nr ||
14837                 error "failed to create $nr files in $DIR/$tdir"
14838         ls -l $DIR/$tdir > /dev/null
14839
14840         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14841         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14842         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14843         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14844         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14845
14846         # set lru_max_age to 1 sec
14847         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14848         echo "sleep $((recalc_p * 2)) seconds..."
14849         sleep $((recalc_p * 2))
14850
14851         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14852         # restore lru_max_age
14853         $LCTL set_param -n $nsdir.lru_max_age $max_age
14854         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14855         unlinkmany $DIR/$tdir/f $nr
14856 }
14857 run_test 124c "LRUR cancel very aged locks"
14858
14859 test_124d() {
14860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14861         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14862                 skip_env "no lru resize on server"
14863
14864         # cache ununsed locks on client
14865         local nr=100
14866
14867         lru_resize_disable mdc
14868         stack_trap "lru_resize_enable mdc" EXIT
14869
14870         cancel_lru_locks mdc
14871
14872         # asynchronous object destroy at MDT could cause bl ast to client
14873         test_mkdir $DIR/$tdir
14874         createmany -o $DIR/$tdir/f $nr ||
14875                 error "failed to create $nr files in $DIR/$tdir"
14876         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14877
14878         ls -l $DIR/$tdir > /dev/null
14879
14880         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14881         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14882         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14883         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14884
14885         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14886
14887         # set lru_max_age to 1 sec
14888         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14889         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14890
14891         echo "sleep $((recalc_p * 2)) seconds..."
14892         sleep $((recalc_p * 2))
14893
14894         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14895
14896         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14897 }
14898 run_test 124d "cancel very aged locks if lru-resize disabled"
14899
14900 test_125() { # 13358
14901         $LCTL get_param -n llite.*.client_type | grep -q local ||
14902                 skip "must run as local client"
14903         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14904                 skip_env "must have acl enabled"
14905         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14906         id $USER0 || skip_env "missing user $USER0"
14907
14908         test_mkdir $DIR/$tdir
14909         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14910         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14911                 error "setfacl $DIR/$tdir failed"
14912         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14913 }
14914 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14915
14916 test_126() { # bug 12829/13455
14917         $GSS && skip_env "must run as gss disabled"
14918         $LCTL get_param -n llite.*.client_type | grep -q local ||
14919                 skip "must run as local client"
14920         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14921
14922         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14923         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14924         rm -f $DIR/$tfile
14925         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14926 }
14927 run_test 126 "check that the fsgid provided by the client is taken into account"
14928
14929 test_127a() { # bug 15521
14930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14931         local name count samp unit min max sum sumsq
14932         local tmpfile=$TMP/$tfile.tmp
14933
14934         # enable stats header if it is disabled
14935         $LCTL set_param enable_stats_header=1
14936
14937         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14938         echo "stats before reset"
14939         stack_trap "rm -f $tmpfile"
14940         local now=$(date +%s)
14941
14942         $LCTL get_param osc.*.stats | tee $tmpfile
14943
14944         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14945         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14946         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14947         local uptime=$(awk '{ print $1 }' /proc/uptime)
14948
14949         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14950         (( ${snapshot_time%\.*} >= $now - 5 &&
14951            ${snapshot_time%\.*} <= $now + 5 )) ||
14952                 error "snapshot_time=$snapshot_time != now=$now"
14953         # elapsed _should_ be from mount, but at least less than uptime
14954         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14955                 error "elapsed=$elapsed > uptime=$uptime"
14956         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14957            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14958                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14959
14960         $LCTL set_param osc.*.stats=0
14961         local reset=$(date +%s)
14962         local fsize=$((2048 * 1024))
14963
14964         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14965         cancel_lru_locks osc
14966         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14967
14968         now=$(date +%s)
14969         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14970         while read name count samp unit min max sum sumsq; do
14971                 [[ "$samp" == "samples" ]] || continue
14972
14973                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14974                 [ ! $min ] && error "Missing min value for $name proc entry"
14975                 eval $name=$count || error "Wrong proc format"
14976
14977                 case $name in
14978                 read_bytes|write_bytes)
14979                         [[ "$unit" =~ "bytes" ]] ||
14980                                 error "unit is not 'bytes': $unit"
14981                         (( $min >= 4096 )) || error "min is too small: $min"
14982                         (( $min <= $fsize )) || error "min is too big: $min"
14983                         (( $max >= 4096 )) || error "max is too small: $max"
14984                         (( $max <= $fsize )) || error "max is too big: $max"
14985                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14986                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14987                                 error "sumsquare is too small: $sumsq"
14988                         (( $sumsq <= $fsize * $fsize )) ||
14989                                 error "sumsquare is too big: $sumsq"
14990                         ;;
14991                 ost_read|ost_write)
14992                         [[ "$unit" =~ "usec" ]] ||
14993                                 error "unit is not 'usec': $unit"
14994                         ;;
14995                 *)      ;;
14996                 esac
14997         done < $tmpfile
14998
14999         #check that we actually got some stats
15000         [ "$read_bytes" ] || error "Missing read_bytes stats"
15001         [ "$write_bytes" ] || error "Missing write_bytes stats"
15002         [ "$read_bytes" != 0 ] || error "no read done"
15003         [ "$write_bytes" != 0 ] || error "no write done"
15004
15005         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15006         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15007         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15008
15009         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15010         (( ${snapshot_time%\.*} >= $now - 5 &&
15011            ${snapshot_time%\.*} <= $now + 5 )) ||
15012                 error "reset snapshot_time=$snapshot_time != now=$now"
15013         # elapsed should be from time of stats reset
15014         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15015            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15016                 error "reset elapsed=$elapsed > $now - $reset"
15017         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15018            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15019                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15020 }
15021 run_test 127a "verify the client stats are sane"
15022
15023 test_127b() { # bug LU-333
15024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15025         local name count samp unit min max sum sumsq
15026
15027         echo "stats before reset"
15028         $LCTL get_param llite.*.stats
15029         $LCTL set_param llite.*.stats=0
15030
15031         # perform 2 reads and writes so MAX is different from SUM.
15032         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15033         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15034         cancel_lru_locks osc
15035         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15036         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15037
15038         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15039         stack_trap "rm -f $TMP/$tfile.tmp"
15040         while read name count samp unit min max sum sumsq; do
15041                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15042                 eval $name=$count || error "Wrong proc format"
15043
15044                 case $name in
15045                 read_bytes|write_bytes)
15046                         [[ "$unit" =~ "bytes" ]] ||
15047                                 error "unit is not 'bytes': $unit"
15048                         (( $count == 2 )) || error "count is not 2: $count"
15049                         (( $min == $PAGE_SIZE )) ||
15050                                 error "min is not $PAGE_SIZE: $min"
15051                         (( $max == $PAGE_SIZE )) ||
15052                                 error "max is not $PAGE_SIZE: $max"
15053                         (( $sum == $PAGE_SIZE * 2 )) ||
15054                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15055                         ;;
15056                 read|write)
15057                         [[ "$unit" =~ "usec" ]] ||
15058                                 error "unit is not 'usec': $unit"
15059                         ;;
15060                 *)      ;;
15061                 esac
15062         done < $TMP/$tfile.tmp
15063
15064         #check that we actually got some stats
15065         [ "$read_bytes" ] || error "Missing read_bytes stats"
15066         [ "$write_bytes" ] || error "Missing write_bytes stats"
15067         [ "$read_bytes" != 0 ] || error "no read done"
15068         [ "$write_bytes" != 0 ] || error "no write done"
15069 }
15070 run_test 127b "verify the llite client stats are sane"
15071
15072 test_127c() { # LU-12394
15073         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15074         local size
15075         local bsize
15076         local reads
15077         local writes
15078         local count
15079
15080         $LCTL set_param llite.*.extents_stats=1
15081         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15082
15083         # Use two stripes so there is enough space in default config
15084         $LFS setstripe -c 2 $DIR/$tfile
15085
15086         # Extent stats start at 0-4K and go in power of two buckets
15087         # LL_HIST_START = 12 --> 2^12 = 4K
15088         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15089         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15090         # small configs
15091         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15092                 do
15093                 # Write and read, 2x each, second time at a non-zero offset
15094                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15095                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15096                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15097                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15098                 rm -f $DIR/$tfile
15099         done
15100
15101         $LCTL get_param llite.*.extents_stats
15102
15103         count=2
15104         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15105                 do
15106                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15107                                 grep -m 1 $bsize)
15108                 reads=$(echo $bucket | awk '{print $5}')
15109                 writes=$(echo $bucket | awk '{print $9}')
15110                 [ "$reads" -eq $count ] ||
15111                         error "$reads reads in < $bsize bucket, expect $count"
15112                 [ "$writes" -eq $count ] ||
15113                         error "$writes writes in < $bsize bucket, expect $count"
15114         done
15115
15116         # Test mmap write and read
15117         $LCTL set_param llite.*.extents_stats=c
15118         size=512
15119         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15120         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15121         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15122
15123         $LCTL get_param llite.*.extents_stats
15124
15125         count=$(((size*1024) / PAGE_SIZE))
15126
15127         bsize=$((2 * PAGE_SIZE / 1024))K
15128
15129         bucket=$($LCTL get_param -n llite.*.extents_stats |
15130                         grep -m 1 $bsize)
15131         reads=$(echo $bucket | awk '{print $5}')
15132         writes=$(echo $bucket | awk '{print $9}')
15133         # mmap writes fault in the page first, creating an additonal read
15134         [ "$reads" -eq $((2 * count)) ] ||
15135                 error "$reads reads in < $bsize bucket, expect $count"
15136         [ "$writes" -eq $count ] ||
15137                 error "$writes writes in < $bsize bucket, expect $count"
15138 }
15139 run_test 127c "test llite extent stats with regular & mmap i/o"
15140
15141 test_128() { # bug 15212
15142         touch $DIR/$tfile
15143         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15144                 find $DIR/$tfile
15145                 find $DIR/$tfile
15146         EOF
15147
15148         result=$(grep error $TMP/$tfile.log)
15149         rm -f $DIR/$tfile $TMP/$tfile.log
15150         [ -z "$result" ] ||
15151                 error "consecutive find's under interactive lfs failed"
15152 }
15153 run_test 128 "interactive lfs for 2 consecutive find's"
15154
15155 set_dir_limits () {
15156         local mntdev
15157         local canondev
15158         local node
15159
15160         local ldproc=/proc/fs/ldiskfs
15161         local facets=$(get_facets MDS)
15162
15163         for facet in ${facets//,/ }; do
15164                 canondev=$(ldiskfs_canon \
15165                            *.$(convert_facet2label $facet).mntdev $facet)
15166                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15167                         ldproc=/sys/fs/ldiskfs
15168                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15169                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15170         done
15171 }
15172
15173 check_mds_dmesg() {
15174         local facets=$(get_facets MDS)
15175         for facet in ${facets//,/ }; do
15176                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15177         done
15178         return 1
15179 }
15180
15181 test_129() {
15182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15183         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15184                 skip "Need MDS version with at least 2.5.56"
15185         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15186                 skip_env "ldiskfs only test"
15187         fi
15188         remote_mds_nodsh && skip "remote MDS with nodsh"
15189
15190         local ENOSPC=28
15191         local has_warning=false
15192
15193         rm -rf $DIR/$tdir
15194         mkdir -p $DIR/$tdir
15195
15196         # block size of mds1
15197         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15198         set_dir_limits $maxsize $((maxsize * 6 / 8))
15199         stack_trap "set_dir_limits 0 0"
15200         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15201         local dirsize=$(stat -c%s "$DIR/$tdir")
15202         local nfiles=0
15203         while (( $dirsize <= $maxsize )); do
15204                 $MCREATE $DIR/$tdir/file_base_$nfiles
15205                 rc=$?
15206                 # check two errors:
15207                 # ENOSPC for ext4 max_dir_size, which has been used since
15208                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15209                 if (( rc == ENOSPC )); then
15210                         set_dir_limits 0 0
15211                         echo "rc=$rc returned as expected after $nfiles files"
15212
15213                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15214                                 error "create failed w/o dir size limit"
15215
15216                         # messages may be rate limited if test is run repeatedly
15217                         check_mds_dmesg '"is approaching max"' ||
15218                                 echo "warning message should be output"
15219                         check_mds_dmesg '"has reached max"' ||
15220                                 echo "reached message should be output"
15221
15222                         dirsize=$(stat -c%s "$DIR/$tdir")
15223
15224                         [[ $dirsize -ge $maxsize ]] && return 0
15225                         error "dirsize $dirsize < $maxsize after $nfiles files"
15226                 elif (( rc != 0 )); then
15227                         break
15228                 fi
15229                 nfiles=$((nfiles + 1))
15230                 dirsize=$(stat -c%s "$DIR/$tdir")
15231         done
15232
15233         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15234 }
15235 run_test 129 "test directory size limit ========================"
15236
15237 OLDIFS="$IFS"
15238 cleanup_130() {
15239         trap 0
15240         IFS="$OLDIFS"
15241         rm -f $DIR/$tfile
15242 }
15243
15244 test_130a() {
15245         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15246         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15247
15248         trap cleanup_130 EXIT RETURN
15249
15250         local fm_file=$DIR/$tfile
15251         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15252         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15253                 error "dd failed for $fm_file"
15254
15255         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15256         filefrag -ves $fm_file
15257         local rc=$?
15258         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15259                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15260         (( $rc == 0 )) || error "filefrag $fm_file failed"
15261
15262         filefrag_op=$(filefrag -ve -k $fm_file |
15263                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15264         local lun=$($LFS getstripe -i $fm_file)
15265
15266         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15267         IFS=$'\n'
15268         local tot_len=0
15269         for line in $filefrag_op; do
15270                 local frag_lun=$(echo $line | cut -d: -f5)
15271                 local ext_len=$(echo $line | cut -d: -f4)
15272
15273                 if (( $frag_lun != $lun )); then
15274                         error "FIEMAP on 1-stripe file($fm_file) failed"
15275                         return
15276                 fi
15277                 (( tot_len += ext_len ))
15278         done
15279
15280         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15281                 error "FIEMAP on 1-stripe file($fm_file) failed"
15282                 return
15283         fi
15284
15285         echo "FIEMAP on single striped file succeeded"
15286 }
15287 run_test 130a "FIEMAP (1-stripe file)"
15288
15289 test_130b() {
15290         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15291
15292         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15293         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15294         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15295                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15296
15297         trap cleanup_130 EXIT RETURN
15298
15299         local fm_file=$DIR/$tfile
15300         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15301                 error "setstripe on $fm_file"
15302
15303         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15304                 error "dd failed on $fm_file"
15305
15306         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15307         filefrag_op=$(filefrag -ve -k $fm_file |
15308                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15309
15310         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15311                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15312
15313         IFS=$'\n'
15314         local tot_len=0
15315         local num_luns=1
15316
15317         for line in $filefrag_op; do
15318                 local frag_lun=$(echo $line | cut -d: -f5 |
15319                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15320                 local ext_len=$(echo $line | cut -d: -f4)
15321                 if (( $frag_lun != $last_lun )); then
15322                         if (( tot_len != 1024 )); then
15323                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15324                                 return
15325                         else
15326                                 (( num_luns += 1 ))
15327                                 tot_len=0
15328                         fi
15329                 fi
15330                 (( tot_len += ext_len ))
15331                 last_lun=$frag_lun
15332         done
15333         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15334                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15335                 return
15336         fi
15337
15338         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15339 }
15340 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15341
15342 test_130c() {
15343         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15344
15345         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15346         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15347         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15348                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15349
15350         trap cleanup_130 EXIT RETURN
15351
15352         local fm_file=$DIR/$tfile
15353         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15354
15355         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15356                 error "dd failed on $fm_file"
15357
15358         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15359         filefrag_op=$(filefrag -ve -k $fm_file |
15360                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15361
15362         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15363                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15364
15365         IFS=$'\n'
15366         local tot_len=0
15367         local num_luns=1
15368         for line in $filefrag_op; do
15369                 local frag_lun=$(echo $line | cut -d: -f5 |
15370                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15371                 local ext_len=$(echo $line | cut -d: -f4)
15372                 if (( $frag_lun != $last_lun )); then
15373                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15374                         if (( logical != 512 )); then
15375                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15376                                 return
15377                         fi
15378                         if (( tot_len != 512 )); then
15379                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15380                                 return
15381                         else
15382                                 (( num_luns += 1 ))
15383                                 tot_len=0
15384                         fi
15385                 fi
15386                 (( tot_len += ext_len ))
15387                 last_lun=$frag_lun
15388         done
15389         if (( num_luns != 2 || tot_len != 512 )); then
15390                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15391                 return
15392         fi
15393
15394         echo "FIEMAP on 2-stripe file with hole succeeded"
15395 }
15396 run_test 130c "FIEMAP (2-stripe file with hole)"
15397
15398 test_130d() {
15399         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15400
15401         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15402         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15403         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15404                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15405
15406         trap cleanup_130 EXIT RETURN
15407
15408         local fm_file=$DIR/$tfile
15409         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15410                         error "setstripe on $fm_file"
15411
15412         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15413         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15414                 error "dd failed on $fm_file"
15415
15416         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15417         filefrag_op=$(filefrag -ve -k $fm_file |
15418                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15419
15420         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15421                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15422
15423         IFS=$'\n'
15424         local tot_len=0
15425         local num_luns=1
15426         for line in $filefrag_op; do
15427                 local frag_lun=$(echo $line | cut -d: -f5 |
15428                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15429                 local ext_len=$(echo $line | cut -d: -f4)
15430                 if (( $frag_lun != $last_lun )); then
15431                         if (( tot_len != 1024 )); then
15432                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15433                                 return
15434                         else
15435                                 (( num_luns += 1 ))
15436                                 local tot_len=0
15437                         fi
15438                 fi
15439                 (( tot_len += ext_len ))
15440                 last_lun=$frag_lun
15441         done
15442         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15443                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15444                 return
15445         fi
15446
15447         echo "FIEMAP on N-stripe file succeeded"
15448 }
15449 run_test 130d "FIEMAP (N-stripe file)"
15450
15451 test_130e() {
15452         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15453
15454         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15455         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15456         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15457                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15458
15459         trap cleanup_130 EXIT RETURN
15460
15461         local fm_file=$DIR/$tfile
15462         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15463         stack_trap "rm -f $fm_file"
15464
15465         local num_blks=512
15466         local expected_len=$(( (num_blks / 2) * 64 ))
15467         for ((i = 0; i < $num_blks; i++)); do
15468                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15469                         conv=notrunc > /dev/null 2>&1
15470         done
15471
15472         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15473         filefrag_op=$(filefrag -ve -k $fm_file |
15474                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15475
15476         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15477
15478         IFS=$'\n'
15479         local tot_len=0
15480         local num_luns=1
15481         for line in $filefrag_op; do
15482                 local frag_lun=$(echo $line | cut -d: -f5)
15483                 local ext_len=$(echo $line | cut -d: -f4)
15484                 if (( $frag_lun != $last_lun )); then
15485                         if (( tot_len != $expected_len )); then
15486                                 error "OST$last_lun $tot_len != $expected_len"
15487                         else
15488                                 (( num_luns += 1 ))
15489                                 tot_len=0
15490                         fi
15491                 fi
15492                 (( tot_len += ext_len ))
15493                 last_lun=$frag_lun
15494         done
15495         if (( num_luns != 2 || tot_len != $expected_len )); then
15496                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15497         fi
15498
15499         echo "FIEMAP with continuation calls succeeded"
15500 }
15501 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15502
15503 test_130f() {
15504         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15505         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15506         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15507                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15508
15509         local fm_file=$DIR/$tfile
15510         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15511                 error "multiop create with lov_delay_create on $fm_file"
15512
15513         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15514         filefrag_extents=$(filefrag -vek $fm_file |
15515                            awk '/extents? found/ { print $2 }')
15516         if (( $filefrag_extents != 0 )); then
15517                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15518         fi
15519
15520         rm -f $fm_file
15521 }
15522 run_test 130f "FIEMAP (unstriped file)"
15523
15524 test_130g() {
15525         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15526                 skip "Need MDS version with at least 2.12.53 for overstriping"
15527         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15528         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15529         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15530                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15531
15532         local file=$DIR/$tfile
15533         local nr=$((OSTCOUNT * 100))
15534
15535         $LFS setstripe -C $nr -S1M $file ||
15536                 error "failed to setstripe -C $nr $file"
15537
15538         stack_trap "rm -f $file"
15539         dd if=/dev/zero of=$file count=$nr bs=1M
15540         sync
15541         nr=$($LFS getstripe -c $file)
15542
15543         local extents=$(filefrag -v $file |
15544                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15545
15546         echo "filefrag list $extents extents in file with stripecount $nr"
15547         if (( extents < nr )); then
15548                 $LFS getstripe $file
15549                 filefrag -v $file
15550                 error "filefrag printed $extents < $nr extents"
15551         fi
15552 }
15553 run_test 130g "FIEMAP (overstripe file)"
15554
15555 # Test for writev/readv
15556 test_131a() {
15557         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15558                 error "writev test failed"
15559         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15560                 error "readv failed"
15561         rm -f $DIR/$tfile
15562 }
15563 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15564
15565 test_131b() {
15566         local fsize=$((524288 + 1048576 + 1572864))
15567         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15568                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15569                         error "append writev test failed"
15570
15571         ((fsize += 1572864 + 1048576))
15572         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15573                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15574                         error "append writev test failed"
15575         rm -f $DIR/$tfile
15576 }
15577 run_test 131b "test append writev"
15578
15579 test_131c() {
15580         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15581         error "NOT PASS"
15582 }
15583 run_test 131c "test read/write on file w/o objects"
15584
15585 test_131d() {
15586         rwv -f $DIR/$tfile -w -n 1 1572864
15587         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15588         if [ "$NOB" != 1572864 ]; then
15589                 error "Short read filed: read $NOB bytes instead of 1572864"
15590         fi
15591         rm -f $DIR/$tfile
15592 }
15593 run_test 131d "test short read"
15594
15595 test_131e() {
15596         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15597         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15598         error "read hitting hole failed"
15599         rm -f $DIR/$tfile
15600 }
15601 run_test 131e "test read hitting hole"
15602
15603 check_stats() {
15604         local facet=$1
15605         local op=$2
15606         local want=${3:-0}
15607         local res
15608
15609         # open             11 samples [usecs] 468 4793 13658 35791898
15610         case $facet in
15611         mds*) res=($(do_facet $facet \
15612                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15613                  ;;
15614         ost*) res=($(do_facet $facet \
15615                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15616                  ;;
15617         *) error "Wrong facet '$facet'" ;;
15618         esac
15619         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15620         # if $want is zero, it means any stat increment is ok.
15621         if (( $want > 0 )); then
15622                 local count=${res[1]}
15623
15624                 if (( $count != $want )); then
15625                         if [[ $facet =~ "mds" ]]; then
15626                                 do_nodes $(comma_list $(mdts_nodes)) \
15627                                         $LCTL get_param mdt.*.md_stats
15628                         else
15629                                 do_nodes $(comma_list $(osts-nodes)) \
15630                                         $LCTL get_param obdfilter.*.stats
15631                         fi
15632                         error "The $op counter on $facet is $count, not $want"
15633                 fi
15634         fi
15635 }
15636
15637 test_133a() {
15638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15639         remote_ost_nodsh && skip "remote OST with nodsh"
15640         remote_mds_nodsh && skip "remote MDS with nodsh"
15641         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15642                 skip_env "MDS doesn't support rename stats"
15643
15644         local testdir=$DIR/${tdir}/stats_testdir
15645
15646         mkdir -p $DIR/${tdir}
15647
15648         # clear stats.
15649         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15650         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15651
15652         # verify mdt stats first.
15653         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15654         check_stats $SINGLEMDS "mkdir" 1
15655
15656         # clear "open" from "lfs mkdir" above
15657         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15658         touch ${testdir}/${tfile} || error "touch failed"
15659         check_stats $SINGLEMDS "open" 1
15660         check_stats $SINGLEMDS "close" 1
15661         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15662                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15663                 check_stats $SINGLEMDS "mknod" 2
15664         }
15665         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15666         check_stats $SINGLEMDS "unlink" 1
15667         rm -f ${testdir}/${tfile} || error "file remove failed"
15668         check_stats $SINGLEMDS "unlink" 2
15669
15670         # remove working dir and check mdt stats again.
15671         rmdir ${testdir} || error "rmdir failed"
15672         check_stats $SINGLEMDS "rmdir" 1
15673
15674         local testdir1=$DIR/${tdir}/stats_testdir1
15675         mkdir_on_mdt0 -p ${testdir}
15676         mkdir_on_mdt0 -p ${testdir1}
15677         touch ${testdir1}/test1
15678         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15679         check_stats $SINGLEMDS "crossdir_rename" 1
15680
15681         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15682         check_stats $SINGLEMDS "samedir_rename" 1
15683
15684         rm -rf $DIR/${tdir}
15685 }
15686 run_test 133a "Verifying MDT stats ========================================"
15687
15688 test_133b() {
15689         local res
15690
15691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15692         remote_ost_nodsh && skip "remote OST with nodsh"
15693         remote_mds_nodsh && skip "remote MDS with nodsh"
15694
15695         local testdir=$DIR/${tdir}/stats_testdir
15696
15697         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15698         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15699         touch ${testdir}/${tfile} || error "touch failed"
15700         cancel_lru_locks mdc
15701
15702         # clear stats.
15703         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15704         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15705
15706         # extra mdt stats verification.
15707         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15708         check_stats $SINGLEMDS "setattr" 1
15709         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15710         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15711         then            # LU-1740
15712                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15713                 check_stats $SINGLEMDS "getattr" 1
15714         fi
15715         rm -rf $DIR/${tdir}
15716
15717         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15718         # so the check below is not reliable
15719         [ $MDSCOUNT -eq 1 ] || return 0
15720
15721         # Sleep to avoid a cached response.
15722         #define OBD_STATFS_CACHE_SECONDS 1
15723         sleep 2
15724         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15725         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15726         $LFS df || error "lfs failed"
15727         check_stats $SINGLEMDS "statfs" 1
15728
15729         # check aggregated statfs (LU-10018)
15730         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15731                 return 0
15732         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15733                 return 0
15734         sleep 2
15735         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15736         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15737         df $DIR
15738         check_stats $SINGLEMDS "statfs" 1
15739
15740         # We want to check that the client didn't send OST_STATFS to
15741         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15742         # extra care is needed here.
15743         if remote_mds; then
15744                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15745                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15746
15747                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15748                 [ "$res" ] && error "OST got STATFS"
15749         fi
15750
15751         return 0
15752 }
15753 run_test 133b "Verifying extra MDT stats =================================="
15754
15755 test_133c() {
15756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15757         remote_ost_nodsh && skip "remote OST with nodsh"
15758         remote_mds_nodsh && skip "remote MDS with nodsh"
15759
15760         local testdir=$DIR/$tdir/stats_testdir
15761
15762         test_mkdir -p $testdir
15763
15764         # verify obdfilter stats.
15765         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15766         sync
15767         cancel_lru_locks osc
15768         wait_delete_completed
15769
15770         # clear stats.
15771         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15772         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15773
15774         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15775                 error "dd failed"
15776         sync
15777         cancel_lru_locks osc
15778         check_stats ost1 "write" 1
15779
15780         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15781         check_stats ost1 "read" 1
15782
15783         > $testdir/$tfile || error "truncate failed"
15784         check_stats ost1 "punch" 1
15785
15786         rm -f $testdir/$tfile || error "file remove failed"
15787         wait_delete_completed
15788         check_stats ost1 "destroy" 1
15789
15790         rm -rf $DIR/$tdir
15791 }
15792 run_test 133c "Verifying OST stats ========================================"
15793
15794 order_2() {
15795         local value=$1
15796         local orig=$value
15797         local order=1
15798
15799         while [ $value -ge 2 ]; do
15800                 order=$((order*2))
15801                 value=$((value/2))
15802         done
15803
15804         if [ $orig -gt $order ]; then
15805                 order=$((order*2))
15806         fi
15807         echo $order
15808 }
15809
15810 size_in_KMGT() {
15811     local value=$1
15812     local size=('K' 'M' 'G' 'T');
15813     local i=0
15814     local size_string=$value
15815
15816     while [ $value -ge 1024 ]; do
15817         if [ $i -gt 3 ]; then
15818             #T is the biggest unit we get here, if that is bigger,
15819             #just return XXXT
15820             size_string=${value}T
15821             break
15822         fi
15823         value=$((value >> 10))
15824         if [ $value -lt 1024 ]; then
15825             size_string=${value}${size[$i]}
15826             break
15827         fi
15828         i=$((i + 1))
15829     done
15830
15831     echo $size_string
15832 }
15833
15834 get_rename_size() {
15835         local size=$1
15836         local context=${2:-.}
15837         local sample=$(do_facet $SINGLEMDS $LCTL \
15838                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15839                 grep -A1 $context |
15840                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15841         echo $sample
15842 }
15843
15844 test_133d() {
15845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15846         remote_ost_nodsh && skip "remote OST with nodsh"
15847         remote_mds_nodsh && skip "remote MDS with nodsh"
15848         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15849                 skip_env "MDS doesn't support rename stats"
15850
15851         local testdir1=$DIR/${tdir}/stats_testdir1
15852         local testdir2=$DIR/${tdir}/stats_testdir2
15853         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15854
15855         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15856
15857         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15858         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15859
15860         createmany -o $testdir1/test 512 || error "createmany failed"
15861
15862         # check samedir rename size
15863         mv ${testdir1}/test0 ${testdir1}/test_0
15864
15865         local testdir1_size=$(ls -l $DIR/${tdir} |
15866                 awk '/stats_testdir1/ {print $5}')
15867         local testdir2_size=$(ls -l $DIR/${tdir} |
15868                 awk '/stats_testdir2/ {print $5}')
15869
15870         testdir1_size=$(order_2 $testdir1_size)
15871         testdir2_size=$(order_2 $testdir2_size)
15872
15873         testdir1_size=$(size_in_KMGT $testdir1_size)
15874         testdir2_size=$(size_in_KMGT $testdir2_size)
15875
15876         echo "source rename dir size: ${testdir1_size}"
15877         echo "target rename dir size: ${testdir2_size}"
15878
15879         local cmd="do_facet $SINGLEMDS $LCTL "
15880         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15881
15882         eval $cmd || error "$cmd failed"
15883         local samedir=$($cmd | grep 'same_dir')
15884         local same_sample=$(get_rename_size $testdir1_size)
15885         [ -z "$samedir" ] && error "samedir_rename_size count error"
15886         [[ $same_sample -eq 1 ]] ||
15887                 error "samedir_rename_size error $same_sample"
15888         echo "Check same dir rename stats success"
15889
15890         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15891
15892         # check crossdir rename size
15893         mv ${testdir1}/test_0 ${testdir2}/test_0
15894
15895         testdir1_size=$(ls -l $DIR/${tdir} |
15896                 awk '/stats_testdir1/ {print $5}')
15897         testdir2_size=$(ls -l $DIR/${tdir} |
15898                 awk '/stats_testdir2/ {print $5}')
15899
15900         testdir1_size=$(order_2 $testdir1_size)
15901         testdir2_size=$(order_2 $testdir2_size)
15902
15903         testdir1_size=$(size_in_KMGT $testdir1_size)
15904         testdir2_size=$(size_in_KMGT $testdir2_size)
15905
15906         echo "source rename dir size: ${testdir1_size}"
15907         echo "target rename dir size: ${testdir2_size}"
15908
15909         eval $cmd || error "$cmd failed"
15910         local crossdir=$($cmd | grep 'crossdir')
15911         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15912         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15913         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15914         [[ $src_sample -eq 1 ]] ||
15915                 error "crossdir_rename_size error $src_sample"
15916         [[ $tgt_sample -eq 1 ]] ||
15917                 error "crossdir_rename_size error $tgt_sample"
15918         echo "Check cross dir rename stats success"
15919         rm -rf $DIR/${tdir}
15920 }
15921 run_test 133d "Verifying rename_stats ========================================"
15922
15923 test_133e() {
15924         remote_mds_nodsh && skip "remote MDS with nodsh"
15925         remote_ost_nodsh && skip "remote OST with nodsh"
15926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15927
15928         local testdir=$DIR/${tdir}/stats_testdir
15929         local ctr f0 f1 bs=32768 count=42 sum
15930
15931         mkdir -p ${testdir} || error "mkdir failed"
15932
15933         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15934
15935         for ctr in {write,read}_bytes; do
15936                 sync
15937                 cancel_lru_locks osc
15938
15939                 do_facet ost1 $LCTL set_param -n \
15940                         "obdfilter.*.exports.clear=clear"
15941
15942                 if [ $ctr = write_bytes ]; then
15943                         f0=/dev/zero
15944                         f1=${testdir}/${tfile}
15945                 else
15946                         f0=${testdir}/${tfile}
15947                         f1=/dev/null
15948                 fi
15949
15950                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15951                         error "dd failed"
15952                 sync
15953                 cancel_lru_locks osc
15954
15955                 sum=$(do_facet ost1 $LCTL get_param \
15956                         "obdfilter.*.exports.*.stats" |
15957                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15958                                 $1 == ctr { sum += $7 }
15959                                 END { printf("%0.0f", sum) }')
15960
15961                 if ((sum != bs * count)); then
15962                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15963                 fi
15964         done
15965
15966         rm -rf $DIR/${tdir}
15967 }
15968 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15969
15970 test_133f() {
15971         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15972                 skip "too old lustre for get_param -R ($facet_ver)"
15973
15974         # verifying readability.
15975         $LCTL get_param -R '*' &> /dev/null
15976
15977         # Verifing writability with badarea_io.
15978         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15979         local skipped_params='force_lbug|changelog_mask|daemon_file'
15980         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15981                 egrep -v "$skipped_params" |
15982                 xargs -n 1 find $proc_dirs -name |
15983                 xargs -n 1 badarea_io ||
15984                 error "client badarea_io failed"
15985
15986         # remount the FS in case writes/reads /proc break the FS
15987         cleanup || error "failed to unmount"
15988         setup || error "failed to setup"
15989 }
15990 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15991
15992 test_133g() {
15993         remote_mds_nodsh && skip "remote MDS with nodsh"
15994         remote_ost_nodsh && skip "remote OST with nodsh"
15995
15996         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15997         local proc_dirs_str=$(eval echo $proc_dirs)
15998         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15999         local facet
16000         for facet in mds1 ost1; do
16001                 local facet_ver=$(lustre_version_code $facet)
16002                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16003                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16004                 else
16005                         log "$facet: too old lustre for get_param -R"
16006                 fi
16007                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16008                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16009                                 tr -d = | egrep -v $skipped_params |
16010                                 xargs -n 1 find $proc_dirs_str -name |
16011                                 xargs -n 1 badarea_io" ||
16012                                         error "$facet badarea_io failed"
16013                 else
16014                         skip_noexit "$facet: too old lustre for get_param -R"
16015                 fi
16016         done
16017
16018         # remount the FS in case writes/reads /proc break the FS
16019         cleanup || error "failed to unmount"
16020         setup || error "failed to setup"
16021 }
16022 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16023
16024 test_133h() {
16025         remote_mds_nodsh && skip "remote MDS with nodsh"
16026         remote_ost_nodsh && skip "remote OST with nodsh"
16027         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16028                 skip "Need MDS version at least 2.9.54"
16029
16030         local facet
16031         for facet in client mds1 ost1; do
16032                 # Get the list of files that are missing the terminating newline
16033                 local plist=$(do_facet $facet
16034                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16035                 local ent
16036                 for ent in $plist; do
16037                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16038                                 awk -v FS='\v' -v RS='\v\v' \
16039                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16040                                         print FILENAME}'" 2>/dev/null)
16041                         [ -z $missing ] || {
16042                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16043                                 error "file does not end with newline: $facet-$ent"
16044                         }
16045                 done
16046         done
16047 }
16048 run_test 133h "Proc files should end with newlines"
16049
16050 test_134a() {
16051         remote_mds_nodsh && skip "remote MDS with nodsh"
16052         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16053                 skip "Need MDS version at least 2.7.54"
16054
16055         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16056         cancel_lru_locks mdc
16057
16058         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16059         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16060         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16061
16062         local nr=1000
16063         createmany -o $DIR/$tdir/f $nr ||
16064                 error "failed to create $nr files in $DIR/$tdir"
16065         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16066
16067         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16068         do_facet mds1 $LCTL set_param fail_loc=0x327
16069         do_facet mds1 $LCTL set_param fail_val=500
16070         touch $DIR/$tdir/m
16071
16072         echo "sleep 10 seconds ..."
16073         sleep 10
16074         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16075
16076         do_facet mds1 $LCTL set_param fail_loc=0
16077         do_facet mds1 $LCTL set_param fail_val=0
16078         [ $lck_cnt -lt $unused ] ||
16079                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16080
16081         rm $DIR/$tdir/m
16082         unlinkmany $DIR/$tdir/f $nr
16083 }
16084 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16085
16086 test_134b() {
16087         remote_mds_nodsh && skip "remote MDS with nodsh"
16088         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16089                 skip "Need MDS version at least 2.7.54"
16090
16091         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16092         cancel_lru_locks mdc
16093
16094         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16095                         ldlm.lock_reclaim_threshold_mb)
16096         # disable reclaim temporarily
16097         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16098
16099         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16100         do_facet mds1 $LCTL set_param fail_loc=0x328
16101         do_facet mds1 $LCTL set_param fail_val=500
16102
16103         $LCTL set_param debug=+trace
16104
16105         local nr=600
16106         createmany -o $DIR/$tdir/f $nr &
16107         local create_pid=$!
16108
16109         echo "Sleep $TIMEOUT seconds ..."
16110         sleep $TIMEOUT
16111         if ! ps -p $create_pid  > /dev/null 2>&1; then
16112                 do_facet mds1 $LCTL set_param fail_loc=0
16113                 do_facet mds1 $LCTL set_param fail_val=0
16114                 do_facet mds1 $LCTL set_param \
16115                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16116                 error "createmany finished incorrectly!"
16117         fi
16118         do_facet mds1 $LCTL set_param fail_loc=0
16119         do_facet mds1 $LCTL set_param fail_val=0
16120         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16121         wait $create_pid || return 1
16122
16123         unlinkmany $DIR/$tdir/f $nr
16124 }
16125 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16126
16127 test_135() {
16128         remote_mds_nodsh && skip "remote MDS with nodsh"
16129         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16130                 skip "Need MDS version at least 2.13.50"
16131         local fname
16132
16133         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16134
16135 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16136         #set only one record at plain llog
16137         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16138
16139         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16140
16141         #fill already existed plain llog each 64767
16142         #wrapping whole catalog
16143         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16144
16145         createmany -o $DIR/$tdir/$tfile_ 64700
16146         for (( i = 0; i < 64700; i = i + 2 ))
16147         do
16148                 rm $DIR/$tdir/$tfile_$i &
16149                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16150                 local pid=$!
16151                 wait $pid
16152         done
16153
16154         #waiting osp synchronization
16155         wait_delete_completed
16156 }
16157 run_test 135 "Race catalog processing"
16158
16159 test_136() {
16160         remote_mds_nodsh && skip "remote MDS with nodsh"
16161         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16162                 skip "Need MDS version at least 2.13.50"
16163         local fname
16164
16165         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16166         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16167         #set only one record at plain llog
16168 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16169         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16170
16171         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16172
16173         #fill already existed 2 plain llogs each 64767
16174         #wrapping whole catalog
16175         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16176         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16177         wait_delete_completed
16178
16179         createmany -o $DIR/$tdir/$tfile_ 10
16180         sleep 25
16181
16182         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16183         for (( i = 0; i < 10; i = i + 3 ))
16184         do
16185                 rm $DIR/$tdir/$tfile_$i &
16186                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16187                 local pid=$!
16188                 wait $pid
16189                 sleep 7
16190                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16191         done
16192
16193         #waiting osp synchronization
16194         wait_delete_completed
16195 }
16196 run_test 136 "Race catalog processing 2"
16197
16198 test_140() { #bug-17379
16199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16200
16201         test_mkdir $DIR/$tdir
16202         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16203         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16204
16205         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16206         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16207         local i=0
16208         while i=$((i + 1)); do
16209                 test_mkdir $i
16210                 cd $i || error "Changing to $i"
16211                 ln -s ../stat stat || error "Creating stat symlink"
16212                 # Read the symlink until ELOOP present,
16213                 # not LBUGing the system is considered success,
16214                 # we didn't overrun the stack.
16215                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16216                 if [ $ret -ne 0 ]; then
16217                         if [ $ret -eq 40 ]; then
16218                                 break  # -ELOOP
16219                         else
16220                                 error "Open stat symlink"
16221                                         return
16222                         fi
16223                 fi
16224         done
16225         i=$((i - 1))
16226         echo "The symlink depth = $i"
16227         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16228                 error "Invalid symlink depth"
16229
16230         # Test recursive symlink
16231         ln -s symlink_self symlink_self
16232         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16233         echo "open symlink_self returns $ret"
16234         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16235 }
16236 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16237
16238 test_150a() {
16239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16240
16241         local TF="$TMP/$tfile"
16242
16243         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16244         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16245         cp $TF $DIR/$tfile
16246         cancel_lru_locks $OSC
16247         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16248         remount_client $MOUNT
16249         df -P $MOUNT
16250         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16251
16252         $TRUNCATE $TF 6000
16253         $TRUNCATE $DIR/$tfile 6000
16254         cancel_lru_locks $OSC
16255         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16256
16257         echo "12345" >>$TF
16258         echo "12345" >>$DIR/$tfile
16259         cancel_lru_locks $OSC
16260         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16261
16262         echo "12345" >>$TF
16263         echo "12345" >>$DIR/$tfile
16264         cancel_lru_locks $OSC
16265         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16266 }
16267 run_test 150a "truncate/append tests"
16268
16269 test_150b() {
16270         check_set_fallocate_or_skip
16271         local out
16272
16273         touch $DIR/$tfile
16274         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16275         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16276                 skip_eopnotsupp "$out|check_fallocate failed"
16277 }
16278 run_test 150b "Verify fallocate (prealloc) functionality"
16279
16280 test_150bb() {
16281         check_set_fallocate_or_skip
16282
16283         touch $DIR/$tfile
16284         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16285         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16286         > $DIR/$tfile
16287         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16288         # precomputed md5sum for 20MB of zeroes
16289         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16290         local sum=($(md5sum $DIR/$tfile))
16291
16292         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16293
16294         check_set_fallocate 1
16295
16296         > $DIR/$tfile
16297         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16298         sum=($(md5sum $DIR/$tfile))
16299
16300         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16301 }
16302 run_test 150bb "Verify fallocate modes both zero space"
16303
16304 test_150c() {
16305         check_set_fallocate_or_skip
16306         local striping="-c2"
16307
16308         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16309         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16310         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16311         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16312         local want=$((OSTCOUNT * 1048576))
16313
16314         # Must allocate all requested space, not more than 5% extra
16315         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16316                 error "bytes $bytes is not $want"
16317
16318         rm -f $DIR/$tfile
16319
16320         echo "verify fallocate on PFL file"
16321
16322         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16323
16324         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16325                 error "Create $DIR/$tfile failed"
16326         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16327         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16328         want=$((512 * 1048576))
16329
16330         # Must allocate all requested space, not more than 5% extra
16331         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16332                 error "bytes $bytes is not $want"
16333 }
16334 run_test 150c "Verify fallocate Size and Blocks"
16335
16336 test_150d() {
16337         check_set_fallocate_or_skip
16338         local striping="-c2"
16339
16340         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16341
16342         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16343         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16344                 error "setstripe failed"
16345         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16346         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16347         local want=$((OSTCOUNT * 1048576))
16348
16349         # Must allocate all requested space, not more than 5% extra
16350         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16351                 error "bytes $bytes is not $want"
16352 }
16353 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16354
16355 test_150e() {
16356         check_set_fallocate_or_skip
16357
16358         echo "df before:"
16359         $LFS df
16360         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16361         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16362                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16363
16364         # Find OST with Minimum Size
16365         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16366                        sort -un | head -1)
16367
16368         # Get 100MB per OST of the available space to reduce run time
16369         # else 60% of the available space if we are running SLOW tests
16370         if [ $SLOW == "no" ]; then
16371                 local space=$((1024 * 100 * OSTCOUNT))
16372         else
16373                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16374         fi
16375
16376         fallocate -l${space}k $DIR/$tfile ||
16377                 error "fallocate ${space}k $DIR/$tfile failed"
16378         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16379
16380         # get size immediately after fallocate. This should be correctly
16381         # updated
16382         local size=$(stat -c '%s' $DIR/$tfile)
16383         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16384
16385         # Sleep for a while for statfs to get updated. And not pull from cache.
16386         sleep 2
16387
16388         echo "df after fallocate:"
16389         $LFS df
16390
16391         (( size / 1024 == space )) || error "size $size != requested $space"
16392         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16393                 error "used $used < space $space"
16394
16395         rm $DIR/$tfile || error "rm failed"
16396         sync
16397         wait_delete_completed
16398
16399         echo "df after unlink:"
16400         $LFS df
16401 }
16402 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16403
16404 test_150f() {
16405         local size
16406         local blocks
16407         local want_size_before=20480 # in bytes
16408         local want_blocks_before=40 # 512 sized blocks
16409         local want_blocks_after=24  # 512 sized blocks
16410         local length=$(((want_blocks_before - want_blocks_after) * 512))
16411
16412         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16413                 skip "need at least 2.14.0 for fallocate punch"
16414
16415         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16416                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16417         fi
16418
16419         check_set_fallocate_or_skip
16420         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16421
16422         [[ "x$DOM" == "xyes" ]] &&
16423                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16424
16425         echo "Verify fallocate punch: Range within the file range"
16426         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16427                 error "dd failed for bs 4096 and count 5"
16428
16429         # Call fallocate with punch range which is within the file range
16430         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16431                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16432         # client must see changes immediately after fallocate
16433         size=$(stat -c '%s' $DIR/$tfile)
16434         blocks=$(stat -c '%b' $DIR/$tfile)
16435
16436         # Verify punch worked.
16437         (( blocks == want_blocks_after )) ||
16438                 error "punch failed: blocks $blocks != $want_blocks_after"
16439
16440         (( size == want_size_before )) ||
16441                 error "punch failed: size $size != $want_size_before"
16442
16443         # Verify there is hole in file
16444         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16445         # precomputed md5sum
16446         local expect="4a9a834a2db02452929c0a348273b4aa"
16447
16448         cksum=($(md5sum $DIR/$tfile))
16449         [[ "${cksum[0]}" == "$expect" ]] ||
16450                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16451
16452         # Start second sub-case for fallocate punch.
16453         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16454         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16455                 error "dd failed for bs 4096 and count 5"
16456
16457         # Punch range less than block size will have no change in block count
16458         want_blocks_after=40  # 512 sized blocks
16459
16460         # Punch overlaps two blocks and less than blocksize
16461         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16462                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16463         size=$(stat -c '%s' $DIR/$tfile)
16464         blocks=$(stat -c '%b' $DIR/$tfile)
16465
16466         # Verify punch worked.
16467         (( blocks == want_blocks_after )) ||
16468                 error "punch failed: blocks $blocks != $want_blocks_after"
16469
16470         (( size == want_size_before )) ||
16471                 error "punch failed: size $size != $want_size_before"
16472
16473         # Verify if range is really zero'ed out. We expect Zeros.
16474         # precomputed md5sum
16475         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16476         cksum=($(md5sum $DIR/$tfile))
16477         [[ "${cksum[0]}" == "$expect" ]] ||
16478                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16479 }
16480 run_test 150f "Verify fallocate punch functionality"
16481
16482 test_150g() {
16483         local space
16484         local size
16485         local blocks
16486         local blocks_after
16487         local size_after
16488         local BS=4096 # Block size in bytes
16489
16490         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16491                 skip "need at least 2.14.0 for fallocate punch"
16492
16493         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16494                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16495         fi
16496
16497         check_set_fallocate_or_skip
16498         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16499
16500         if [[ "x$DOM" == "xyes" ]]; then
16501                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16502                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16503         else
16504                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16505                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16506         fi
16507
16508         # Get 100MB per OST of the available space to reduce run time
16509         # else 60% of the available space if we are running SLOW tests
16510         if [ $SLOW == "no" ]; then
16511                 space=$((1024 * 100 * OSTCOUNT))
16512         else
16513                 # Find OST with Minimum Size
16514                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16515                         sort -un | head -1)
16516                 echo "min size OST: $space"
16517                 space=$(((space * 60)/100 * OSTCOUNT))
16518         fi
16519         # space in 1k units, round to 4k blocks
16520         local blkcount=$((space * 1024 / $BS))
16521
16522         echo "Verify fallocate punch: Very large Range"
16523         fallocate -l${space}k $DIR/$tfile ||
16524                 error "fallocate ${space}k $DIR/$tfile failed"
16525         # write 1M at the end, start and in the middle
16526         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16527                 error "dd failed: bs $BS count 256"
16528         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16529                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16530         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16531                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16532
16533         # Gather stats.
16534         size=$(stat -c '%s' $DIR/$tfile)
16535
16536         # gather punch length.
16537         local punch_size=$((size - (BS * 2)))
16538
16539         echo "punch_size = $punch_size"
16540         echo "size - punch_size: $((size - punch_size))"
16541         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16542
16543         # Call fallocate to punch all except 2 blocks. We leave the
16544         # first and the last block
16545         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16546         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16547                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16548
16549         size_after=$(stat -c '%s' $DIR/$tfile)
16550         blocks_after=$(stat -c '%b' $DIR/$tfile)
16551
16552         # Verify punch worked.
16553         # Size should be kept
16554         (( size == size_after )) ||
16555                 error "punch failed: size $size != $size_after"
16556
16557         # two 4k data blocks to remain plus possible 1 extra extent block
16558         (( blocks_after <= ((BS / 512) * 3) )) ||
16559                 error "too many blocks remains: $blocks_after"
16560
16561         # Verify that file has hole between the first and the last blocks
16562         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16563         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16564
16565         echo "Hole at [$hole_start, $hole_end)"
16566         (( hole_start == BS )) ||
16567                 error "no hole at offset $BS after punch"
16568
16569         (( hole_end == BS + punch_size )) ||
16570                 error "data at offset $hole_end < $((BS + punch_size))"
16571 }
16572 run_test 150g "Verify fallocate punch on large range"
16573
16574 test_150h() {
16575         local file=$DIR/$tfile
16576         local size
16577
16578         check_set_fallocate_or_skip
16579         statx_supported || skip_env "Test must be statx() syscall supported"
16580
16581         # fallocate() does not update the size information on the MDT
16582         fallocate -l 16K $file || error "failed to fallocate $file"
16583         cancel_lru_locks $OSC
16584         # STATX with cached-always mode will not send glimpse RPCs to OST,
16585         # it uses the caching attrs on the client side as much as possible.
16586         size=$($STATX --cached=always -c %s $file)
16587         [ $size == 16384 ] ||
16588                 error "size after fallocate() is $size, expected 16384"
16589 }
16590 run_test 150h "Verify extend fallocate updates the file size"
16591
16592 #LU-2902 roc_hit was not able to read all values from lproc
16593 function roc_hit_init() {
16594         local list=$(comma_list $(osts_nodes))
16595         local dir=$DIR/$tdir-check
16596         local file=$dir/$tfile
16597         local BEFORE
16598         local AFTER
16599         local idx
16600
16601         test_mkdir $dir
16602         #use setstripe to do a write to every ost
16603         for i in $(seq 0 $((OSTCOUNT-1))); do
16604                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16605                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16606                 idx=$(printf %04x $i)
16607                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16608                         awk '$1 == "cache_access" {sum += $7}
16609                                 END { printf("%0.0f", sum) }')
16610
16611                 cancel_lru_locks osc
16612                 cat $file >/dev/null
16613
16614                 AFTER=$(get_osd_param $list *OST*$idx stats |
16615                         awk '$1 == "cache_access" {sum += $7}
16616                                 END { printf("%0.0f", sum) }')
16617
16618                 echo BEFORE:$BEFORE AFTER:$AFTER
16619                 if ! let "AFTER - BEFORE == 4"; then
16620                         rm -rf $dir
16621                         error "roc_hit is not safe to use"
16622                 fi
16623                 rm $file
16624         done
16625
16626         rm -rf $dir
16627 }
16628
16629 function roc_hit() {
16630         local list=$(comma_list $(osts_nodes))
16631         echo $(get_osd_param $list '' stats |
16632                 awk '$1 == "cache_hit" {sum += $7}
16633                         END { printf("%0.0f", sum) }')
16634 }
16635
16636 function set_cache() {
16637         local on=1
16638
16639         if [ "$2" == "off" ]; then
16640                 on=0;
16641         fi
16642         local list=$(comma_list $(osts_nodes))
16643         set_osd_param $list '' $1_cache_enable $on
16644
16645         cancel_lru_locks osc
16646 }
16647
16648 test_151() {
16649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16650         remote_ost_nodsh && skip "remote OST with nodsh"
16651         (( CLIENT_VERSION == OST1_VERSION )) ||
16652                 skip "LU-13081: no interop testing for OSS cache"
16653
16654         local CPAGES=3
16655         local list=$(comma_list $(osts_nodes))
16656
16657         # check whether obdfilter is cache capable at all
16658         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16659                 skip "not cache-capable obdfilter"
16660         fi
16661
16662         # check cache is enabled on all obdfilters
16663         if get_osd_param $list '' read_cache_enable | grep 0; then
16664                 skip "oss cache is disabled"
16665         fi
16666
16667         set_osd_param $list '' writethrough_cache_enable 1
16668
16669         # check write cache is enabled on all obdfilters
16670         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16671                 skip "oss write cache is NOT enabled"
16672         fi
16673
16674         roc_hit_init
16675
16676         #define OBD_FAIL_OBD_NO_LRU  0x609
16677         do_nodes $list $LCTL set_param fail_loc=0x609
16678
16679         # pages should be in the case right after write
16680         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16681                 error "dd failed"
16682
16683         local BEFORE=$(roc_hit)
16684         cancel_lru_locks osc
16685         cat $DIR/$tfile >/dev/null
16686         local AFTER=$(roc_hit)
16687
16688         do_nodes $list $LCTL set_param fail_loc=0
16689
16690         if ! let "AFTER - BEFORE == CPAGES"; then
16691                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16692         fi
16693
16694         cancel_lru_locks osc
16695         # invalidates OST cache
16696         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16697         set_osd_param $list '' read_cache_enable 0
16698         cat $DIR/$tfile >/dev/null
16699
16700         # now data shouldn't be found in the cache
16701         BEFORE=$(roc_hit)
16702         cancel_lru_locks osc
16703         cat $DIR/$tfile >/dev/null
16704         AFTER=$(roc_hit)
16705         if let "AFTER - BEFORE != 0"; then
16706                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16707         fi
16708
16709         set_osd_param $list '' read_cache_enable 1
16710         rm -f $DIR/$tfile
16711 }
16712 run_test 151 "test cache on oss and controls ==============================="
16713
16714 test_152() {
16715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16716
16717         local TF="$TMP/$tfile"
16718
16719         # simulate ENOMEM during write
16720 #define OBD_FAIL_OST_NOMEM      0x226
16721         lctl set_param fail_loc=0x80000226
16722         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16723         cp $TF $DIR/$tfile
16724         sync || error "sync failed"
16725         lctl set_param fail_loc=0
16726
16727         # discard client's cache
16728         cancel_lru_locks osc
16729
16730         # simulate ENOMEM during read
16731         lctl set_param fail_loc=0x80000226
16732         cmp $TF $DIR/$tfile || error "cmp failed"
16733         lctl set_param fail_loc=0
16734
16735         rm -f $TF
16736 }
16737 run_test 152 "test read/write with enomem ============================"
16738
16739 test_153() {
16740         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16741 }
16742 run_test 153 "test if fdatasync does not crash ======================="
16743
16744 dot_lustre_fid_permission_check() {
16745         local fid=$1
16746         local ffid=$MOUNT/.lustre/fid/$fid
16747         local test_dir=$2
16748
16749         echo "stat fid $fid"
16750         stat $ffid || error "stat $ffid failed."
16751         echo "touch fid $fid"
16752         touch $ffid || error "touch $ffid failed."
16753         echo "write to fid $fid"
16754         cat /etc/hosts > $ffid || error "write $ffid failed."
16755         echo "read fid $fid"
16756         diff /etc/hosts $ffid || error "read $ffid failed."
16757         echo "append write to fid $fid"
16758         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16759         echo "rename fid $fid"
16760         mv $ffid $test_dir/$tfile.1 &&
16761                 error "rename $ffid to $tfile.1 should fail."
16762         touch $test_dir/$tfile.1
16763         mv $test_dir/$tfile.1 $ffid &&
16764                 error "rename $tfile.1 to $ffid should fail."
16765         rm -f $test_dir/$tfile.1
16766         echo "truncate fid $fid"
16767         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16768         echo "link fid $fid"
16769         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16770         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16771                 id $USER0 || skip_env "missing user $USER0"
16772                 echo "setfacl fid $fid"
16773                 setfacl -R -m u:$USER0:rwx $ffid ||
16774                         error "setfacl $ffid failed"
16775                 echo "getfacl fid $fid"
16776                 getfacl $ffid || error "getfacl $ffid failed."
16777         fi
16778         echo "unlink fid $fid"
16779         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16780         echo "mknod fid $fid"
16781         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16782
16783         fid=[0xf00000400:0x1:0x0]
16784         ffid=$MOUNT/.lustre/fid/$fid
16785
16786         echo "stat non-exist fid $fid"
16787         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16788         echo "write to non-exist fid $fid"
16789         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16790         echo "link new fid $fid"
16791         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16792
16793         mkdir -p $test_dir/$tdir
16794         touch $test_dir/$tdir/$tfile
16795         fid=$($LFS path2fid $test_dir/$tdir)
16796         rc=$?
16797         [ $rc -ne 0 ] &&
16798                 error "error: could not get fid for $test_dir/$dir/$tfile."
16799
16800         ffid=$MOUNT/.lustre/fid/$fid
16801
16802         echo "ls $fid"
16803         ls $ffid || error "ls $ffid failed."
16804         echo "touch $fid/$tfile.1"
16805         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16806
16807         echo "touch $MOUNT/.lustre/fid/$tfile"
16808         touch $MOUNT/.lustre/fid/$tfile && \
16809                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16810
16811         echo "setxattr to $MOUNT/.lustre/fid"
16812         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16813
16814         echo "listxattr for $MOUNT/.lustre/fid"
16815         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16816
16817         echo "delxattr from $MOUNT/.lustre/fid"
16818         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16819
16820         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16821         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16822                 error "touch invalid fid should fail."
16823
16824         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16825         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16826                 error "touch non-normal fid should fail."
16827
16828         echo "rename $tdir to $MOUNT/.lustre/fid"
16829         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16830                 error "rename to $MOUNT/.lustre/fid should fail."
16831
16832         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16833         then            # LU-3547
16834                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16835                 local new_obf_mode=777
16836
16837                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16838                 chmod $new_obf_mode $DIR/.lustre/fid ||
16839                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16840
16841                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16842                 [ $obf_mode -eq $new_obf_mode ] ||
16843                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16844
16845                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16846                 chmod $old_obf_mode $DIR/.lustre/fid ||
16847                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16848         fi
16849
16850         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16851         fid=$($LFS path2fid $test_dir/$tfile-2)
16852
16853         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16854         then # LU-5424
16855                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16856                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16857                         error "create lov data thru .lustre failed"
16858         fi
16859         echo "cp /etc/passwd $test_dir/$tfile-2"
16860         cp /etc/passwd $test_dir/$tfile-2 ||
16861                 error "copy to $test_dir/$tfile-2 failed."
16862         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16863         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16864                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16865
16866         rm -rf $test_dir/tfile.lnk
16867         rm -rf $test_dir/$tfile-2
16868 }
16869
16870 test_154A() {
16871         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16872                 skip "Need MDS version at least 2.4.1"
16873
16874         local tf=$DIR/$tfile
16875         touch $tf
16876
16877         local fid=$($LFS path2fid $tf)
16878         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16879
16880         # check that we get the same pathname back
16881         local rootpath
16882         local found
16883         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16884                 echo "$rootpath $fid"
16885                 found=$($LFS fid2path $rootpath "$fid")
16886                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16887                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16888         done
16889
16890         # check wrong root path format
16891         rootpath=$MOUNT"_wrong"
16892         found=$($LFS fid2path $rootpath "$fid")
16893         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16894 }
16895 run_test 154A "lfs path2fid and fid2path basic checks"
16896
16897 test_154B() {
16898         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16899                 skip "Need MDS version at least 2.4.1"
16900
16901         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16902         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16903         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16904         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16905
16906         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16907         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16908
16909         # check that we get the same pathname
16910         echo "PFID: $PFID, name: $name"
16911         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16912         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16913         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16914                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16915
16916         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16917 }
16918 run_test 154B "verify the ll_decode_linkea tool"
16919
16920 test_154a() {
16921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16922         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16923         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16924                 skip "Need MDS version at least 2.2.51"
16925         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16926
16927         cp /etc/hosts $DIR/$tfile
16928
16929         fid=$($LFS path2fid $DIR/$tfile)
16930         rc=$?
16931         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16932
16933         dot_lustre_fid_permission_check "$fid" $DIR ||
16934                 error "dot lustre permission check $fid failed"
16935
16936         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16937
16938         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16939
16940         touch $MOUNT/.lustre/file &&
16941                 error "creation is not allowed under .lustre"
16942
16943         mkdir $MOUNT/.lustre/dir &&
16944                 error "mkdir is not allowed under .lustre"
16945
16946         rm -rf $DIR/$tfile
16947 }
16948 run_test 154a "Open-by-FID"
16949
16950 test_154b() {
16951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16952         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16954         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16955                 skip "Need MDS version at least 2.2.51"
16956
16957         local remote_dir=$DIR/$tdir/remote_dir
16958         local MDTIDX=1
16959         local rc=0
16960
16961         mkdir -p $DIR/$tdir
16962         $LFS mkdir -i $MDTIDX $remote_dir ||
16963                 error "create remote directory failed"
16964
16965         cp /etc/hosts $remote_dir/$tfile
16966
16967         fid=$($LFS path2fid $remote_dir/$tfile)
16968         rc=$?
16969         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16970
16971         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16972                 error "dot lustre permission check $fid failed"
16973         rm -rf $DIR/$tdir
16974 }
16975 run_test 154b "Open-by-FID for remote directory"
16976
16977 test_154c() {
16978         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16979                 skip "Need MDS version at least 2.4.1"
16980
16981         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16982         local FID1=$($LFS path2fid $DIR/$tfile.1)
16983         local FID2=$($LFS path2fid $DIR/$tfile.2)
16984         local FID3=$($LFS path2fid $DIR/$tfile.3)
16985
16986         local N=1
16987         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16988                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16989                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16990                 local want=FID$N
16991                 [ "$FID" = "${!want}" ] ||
16992                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16993                 N=$((N + 1))
16994         done
16995
16996         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16997         do
16998                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16999                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17000                 N=$((N + 1))
17001         done
17002 }
17003 run_test 154c "lfs path2fid and fid2path multiple arguments"
17004
17005 test_154d() {
17006         remote_mds_nodsh && skip "remote MDS with nodsh"
17007         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17008                 skip "Need MDS version at least 2.5.53"
17009
17010         if remote_mds; then
17011                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17012         else
17013                 nid="0@lo"
17014         fi
17015         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17016         local fd
17017         local cmd
17018
17019         rm -f $DIR/$tfile
17020         touch $DIR/$tfile
17021
17022         local fid=$($LFS path2fid $DIR/$tfile)
17023         # Open the file
17024         fd=$(free_fd)
17025         cmd="exec $fd<$DIR/$tfile"
17026         eval $cmd
17027         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17028         echo "$fid_list" | grep "$fid"
17029         rc=$?
17030
17031         cmd="exec $fd>/dev/null"
17032         eval $cmd
17033         if [ $rc -ne 0 ]; then
17034                 error "FID $fid not found in open files list $fid_list"
17035         fi
17036 }
17037 run_test 154d "Verify open file fid"
17038
17039 test_154e()
17040 {
17041         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17042                 skip "Need MDS version at least 2.6.50"
17043
17044         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17045                 error ".lustre returned by readdir"
17046         fi
17047 }
17048 run_test 154e ".lustre is not returned by readdir"
17049
17050 test_154f() {
17051         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17052
17053         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17054         mkdir_on_mdt0 $DIR/$tdir
17055         # test dirs inherit from its stripe
17056         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17057         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17058         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17059         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17060         touch $DIR/f
17061
17062         # get fid of parents
17063         local FID0=$($LFS path2fid $DIR/$tdir)
17064         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17065         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17066         local FID3=$($LFS path2fid $DIR)
17067
17068         # check that path2fid --parents returns expected <parent_fid>/name
17069         # 1) test for a directory (single parent)
17070         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17071         [ "$parent" == "$FID0/foo1" ] ||
17072                 error "expected parent: $FID0/foo1, got: $parent"
17073
17074         # 2) test for a file with nlink > 1 (multiple parents)
17075         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17076         echo "$parent" | grep -F "$FID1/$tfile" ||
17077                 error "$FID1/$tfile not returned in parent list"
17078         echo "$parent" | grep -F "$FID2/link" ||
17079                 error "$FID2/link not returned in parent list"
17080
17081         # 3) get parent by fid
17082         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17083         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17084         echo "$parent" | grep -F "$FID1/$tfile" ||
17085                 error "$FID1/$tfile not returned in parent list (by fid)"
17086         echo "$parent" | grep -F "$FID2/link" ||
17087                 error "$FID2/link not returned in parent list (by fid)"
17088
17089         # 4) test for entry in root directory
17090         parent=$($LFS path2fid --parents $DIR/f)
17091         echo "$parent" | grep -F "$FID3/f" ||
17092                 error "$FID3/f not returned in parent list"
17093
17094         # 5) test it on root directory
17095         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17096                 error "$MOUNT should not have parents"
17097
17098         # enable xattr caching and check that linkea is correctly updated
17099         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17100         save_lustre_params client "llite.*.xattr_cache" > $save
17101         lctl set_param llite.*.xattr_cache 1
17102
17103         # 6.1) linkea update on rename
17104         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17105
17106         # get parents by fid
17107         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17108         # foo1 should no longer be returned in parent list
17109         echo "$parent" | grep -F "$FID1" &&
17110                 error "$FID1 should no longer be in parent list"
17111         # the new path should appear
17112         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17113                 error "$FID2/$tfile.moved is not in parent list"
17114
17115         # 6.2) linkea update on unlink
17116         rm -f $DIR/$tdir/foo2/link
17117         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17118         # foo2/link should no longer be returned in parent list
17119         echo "$parent" | grep -F "$FID2/link" &&
17120                 error "$FID2/link should no longer be in parent list"
17121         true
17122
17123         rm -f $DIR/f
17124         restore_lustre_params < $save
17125         rm -f $save
17126 }
17127 run_test 154f "get parent fids by reading link ea"
17128
17129 test_154g()
17130 {
17131         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17132            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17133                 skip "Need MDS version at least 2.6.92"
17134
17135         mkdir_on_mdt0 $DIR/$tdir
17136         llapi_fid_test -d $DIR/$tdir
17137 }
17138 run_test 154g "various llapi FID tests"
17139
17140 test_154h()
17141 {
17142         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17143                 skip "Need client at least version 2.15.55.1"
17144
17145         # Create an empty file
17146         touch $DIR/$tfile
17147
17148         # Get FID (interactive mode) and save under $TMP/$tfile.log
17149         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17150                 path2fid $DIR/$tfile
17151         EOF
17152
17153         fid=$(cat $TMP/$tfile.log)
17154         # $fid should not be empty
17155         [[ ! -z $fid ]] || error "FID is empty"
17156         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17157 }
17158 run_test 154h "Verify interactive path2fid"
17159
17160 test_155_small_load() {
17161     local temp=$TMP/$tfile
17162     local file=$DIR/$tfile
17163
17164     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17165         error "dd of=$temp bs=6096 count=1 failed"
17166     cp $temp $file
17167     cancel_lru_locks $OSC
17168     cmp $temp $file || error "$temp $file differ"
17169
17170     $TRUNCATE $temp 6000
17171     $TRUNCATE $file 6000
17172     cmp $temp $file || error "$temp $file differ (truncate1)"
17173
17174     echo "12345" >>$temp
17175     echo "12345" >>$file
17176     cmp $temp $file || error "$temp $file differ (append1)"
17177
17178     echo "12345" >>$temp
17179     echo "12345" >>$file
17180     cmp $temp $file || error "$temp $file differ (append2)"
17181
17182     rm -f $temp $file
17183     true
17184 }
17185
17186 test_155_big_load() {
17187         remote_ost_nodsh && skip "remote OST with nodsh"
17188
17189         local temp=$TMP/$tfile
17190         local file=$DIR/$tfile
17191
17192         free_min_max
17193         local cache_size=$(do_facet ost$((MAXI+1)) \
17194                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17195
17196         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17197         # pre-set value
17198         if [ -z "$cache_size" ]; then
17199                 cache_size=256
17200         fi
17201         local large_file_size=$((cache_size * 2))
17202
17203         echo "OSS cache size: $cache_size KB"
17204         echo "Large file size: $large_file_size KB"
17205
17206         [ $MAXV -le $large_file_size ] &&
17207                 skip_env "max available OST size needs > $large_file_size KB"
17208
17209         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17210
17211         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17212                 error "dd of=$temp bs=$large_file_size count=1k failed"
17213         cp $temp $file
17214         ls -lh $temp $file
17215         cancel_lru_locks osc
17216         cmp $temp $file || error "$temp $file differ"
17217
17218         rm -f $temp $file
17219         true
17220 }
17221
17222 save_writethrough() {
17223         local facets=$(get_facets OST)
17224
17225         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17226 }
17227
17228 test_155a() {
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230
17231         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17232
17233         save_writethrough $p
17234
17235         set_cache read on
17236         set_cache writethrough on
17237         test_155_small_load
17238         restore_lustre_params < $p
17239         rm -f $p
17240 }
17241 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17242
17243 test_155b() {
17244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17245
17246         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17247
17248         save_writethrough $p
17249
17250         set_cache read on
17251         set_cache writethrough off
17252         test_155_small_load
17253         restore_lustre_params < $p
17254         rm -f $p
17255 }
17256 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17257
17258 test_155c() {
17259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17260
17261         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17262
17263         save_writethrough $p
17264
17265         set_cache read off
17266         set_cache writethrough on
17267         test_155_small_load
17268         restore_lustre_params < $p
17269         rm -f $p
17270 }
17271 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17272
17273 test_155d() {
17274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17275
17276         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17277
17278         save_writethrough $p
17279
17280         set_cache read off
17281         set_cache writethrough off
17282         test_155_small_load
17283         restore_lustre_params < $p
17284         rm -f $p
17285 }
17286 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17287
17288 test_155e() {
17289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17290
17291         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17292
17293         save_writethrough $p
17294
17295         set_cache read on
17296         set_cache writethrough on
17297         test_155_big_load
17298         restore_lustre_params < $p
17299         rm -f $p
17300 }
17301 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17302
17303 test_155f() {
17304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17305
17306         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17307
17308         save_writethrough $p
17309
17310         set_cache read on
17311         set_cache writethrough off
17312         test_155_big_load
17313         restore_lustre_params < $p
17314         rm -f $p
17315 }
17316 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17317
17318 test_155g() {
17319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17320
17321         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17322
17323         save_writethrough $p
17324
17325         set_cache read off
17326         set_cache writethrough on
17327         test_155_big_load
17328         restore_lustre_params < $p
17329         rm -f $p
17330 }
17331 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17332
17333 test_155h() {
17334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17335
17336         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17337
17338         save_writethrough $p
17339
17340         set_cache read off
17341         set_cache writethrough off
17342         test_155_big_load
17343         restore_lustre_params < $p
17344         rm -f $p
17345 }
17346 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17347
17348 test_156() {
17349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17350         remote_ost_nodsh && skip "remote OST with nodsh"
17351         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17352                 skip "stats not implemented on old servers"
17353         [ "$ost1_FSTYPE" = "zfs" ] &&
17354                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17355         (( CLIENT_VERSION == OST1_VERSION )) ||
17356                 skip "LU-13081: no interop testing for OSS cache"
17357
17358         local CPAGES=3
17359         local BEFORE
17360         local AFTER
17361         local file="$DIR/$tfile"
17362         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17363
17364         save_writethrough $p
17365         roc_hit_init
17366
17367         log "Turn on read and write cache"
17368         set_cache read on
17369         set_cache writethrough on
17370
17371         log "Write data and read it back."
17372         log "Read should be satisfied from the cache."
17373         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17374         BEFORE=$(roc_hit)
17375         cancel_lru_locks osc
17376         cat $file >/dev/null
17377         AFTER=$(roc_hit)
17378         if ! let "AFTER - BEFORE == CPAGES"; then
17379                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17380         else
17381                 log "cache hits: before: $BEFORE, after: $AFTER"
17382         fi
17383
17384         log "Read again; it should be satisfied from the cache."
17385         BEFORE=$AFTER
17386         cancel_lru_locks osc
17387         cat $file >/dev/null
17388         AFTER=$(roc_hit)
17389         if ! let "AFTER - BEFORE == CPAGES"; then
17390                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17391         else
17392                 log "cache hits:: before: $BEFORE, after: $AFTER"
17393         fi
17394
17395         log "Turn off the read cache and turn on the write cache"
17396         set_cache read off
17397         set_cache writethrough on
17398
17399         log "Read again; it should be satisfied from the cache."
17400         BEFORE=$(roc_hit)
17401         cancel_lru_locks osc
17402         cat $file >/dev/null
17403         AFTER=$(roc_hit)
17404         if ! let "AFTER - BEFORE == CPAGES"; then
17405                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17406         else
17407                 log "cache hits:: before: $BEFORE, after: $AFTER"
17408         fi
17409
17410         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17411                 # > 2.12.56 uses pagecache if cached
17412                 log "Read again; it should not be satisfied from the cache."
17413                 BEFORE=$AFTER
17414                 cancel_lru_locks osc
17415                 cat $file >/dev/null
17416                 AFTER=$(roc_hit)
17417                 if ! let "AFTER - BEFORE == 0"; then
17418                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17419                 else
17420                         log "cache hits:: before: $BEFORE, after: $AFTER"
17421                 fi
17422         fi
17423
17424         log "Write data and read it back."
17425         log "Read should be satisfied from the cache."
17426         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17427         BEFORE=$(roc_hit)
17428         cancel_lru_locks osc
17429         cat $file >/dev/null
17430         AFTER=$(roc_hit)
17431         if ! let "AFTER - BEFORE == CPAGES"; then
17432                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17433         else
17434                 log "cache hits:: before: $BEFORE, after: $AFTER"
17435         fi
17436
17437         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17438                 # > 2.12.56 uses pagecache if cached
17439                 log "Read again; it should not be satisfied from the cache."
17440                 BEFORE=$AFTER
17441                 cancel_lru_locks osc
17442                 cat $file >/dev/null
17443                 AFTER=$(roc_hit)
17444                 if ! let "AFTER - BEFORE == 0"; then
17445                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17446                 else
17447                         log "cache hits:: before: $BEFORE, after: $AFTER"
17448                 fi
17449         fi
17450
17451         log "Turn off read and write cache"
17452         set_cache read off
17453         set_cache writethrough off
17454
17455         log "Write data and read it back"
17456         log "It should not be satisfied from the cache."
17457         rm -f $file
17458         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17459         cancel_lru_locks osc
17460         BEFORE=$(roc_hit)
17461         cat $file >/dev/null
17462         AFTER=$(roc_hit)
17463         if ! let "AFTER - BEFORE == 0"; then
17464                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17465         else
17466                 log "cache hits:: before: $BEFORE, after: $AFTER"
17467         fi
17468
17469         log "Turn on the read cache and turn off the write cache"
17470         set_cache read on
17471         set_cache writethrough off
17472
17473         log "Write data and read it back"
17474         log "It should not be satisfied from the cache."
17475         rm -f $file
17476         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17477         BEFORE=$(roc_hit)
17478         cancel_lru_locks osc
17479         cat $file >/dev/null
17480         AFTER=$(roc_hit)
17481         if ! let "AFTER - BEFORE == 0"; then
17482                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17483         else
17484                 log "cache hits:: before: $BEFORE, after: $AFTER"
17485         fi
17486
17487         log "Read again; it should be satisfied from the cache."
17488         BEFORE=$(roc_hit)
17489         cancel_lru_locks osc
17490         cat $file >/dev/null
17491         AFTER=$(roc_hit)
17492         if ! let "AFTER - BEFORE == CPAGES"; then
17493                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17494         else
17495                 log "cache hits:: before: $BEFORE, after: $AFTER"
17496         fi
17497
17498         restore_lustre_params < $p
17499         rm -f $p $file
17500 }
17501 run_test 156 "Verification of tunables"
17502
17503 test_160a() {
17504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17505         remote_mds_nodsh && skip "remote MDS with nodsh"
17506         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17507                 skip "Need MDS version at least 2.2.0"
17508
17509         changelog_register || error "changelog_register failed"
17510         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17511         changelog_users $SINGLEMDS | grep -q $cl_user ||
17512                 error "User $cl_user not found in changelog_users"
17513
17514         mkdir_on_mdt0 $DIR/$tdir
17515
17516         # change something
17517         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17518         changelog_clear 0 || error "changelog_clear failed"
17519         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17520         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17521         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17522         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17523         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17524         rm $DIR/$tdir/pics/desktop.jpg
17525
17526         echo "verifying changelog mask"
17527         changelog_chmask "-MKDIR"
17528         changelog_chmask "-CLOSE"
17529
17530         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17531         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17532
17533         changelog_chmask "+MKDIR"
17534         changelog_chmask "+CLOSE"
17535
17536         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17537         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17538
17539         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17540         CLOSES=$(changelog_dump | grep -c "CLOSE")
17541         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17542         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17543
17544         # verify contents
17545         echo "verifying target fid"
17546         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17547         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17548         [ "$fidc" == "$fidf" ] ||
17549                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17550         echo "verifying parent fid"
17551         # The FID returned from the Changelog may be the directory shard on
17552         # a different MDT, and not the FID returned by path2fid on the parent.
17553         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17554         # since this is what will matter when recreating this file in the tree.
17555         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17556         local pathp=$($LFS fid2path $MOUNT "$fidp")
17557         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17558                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17559
17560         echo "getting records for $cl_user"
17561         changelog_users $SINGLEMDS
17562         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17563         local nclr=3
17564         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17565                 error "changelog_clear failed"
17566         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17567         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17568         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17569                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17570
17571         local min0_rec=$(changelog_users $SINGLEMDS |
17572                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17573         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17574                           awk '{ print $1; exit; }')
17575
17576         changelog_dump | tail -n 5
17577         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17578         [ $first_rec == $((min0_rec + 1)) ] ||
17579                 error "first index should be $min0_rec + 1 not $first_rec"
17580
17581         # LU-3446 changelog index reset on MDT restart
17582         local cur_rec1=$(changelog_users $SINGLEMDS |
17583                          awk '/^current.index:/ { print $NF }')
17584         changelog_clear 0 ||
17585                 error "clear all changelog records for $cl_user failed"
17586         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17587         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17588                 error "Fail to start $SINGLEMDS"
17589         local cur_rec2=$(changelog_users $SINGLEMDS |
17590                          awk '/^current.index:/ { print $NF }')
17591         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17592         [ $cur_rec1 == $cur_rec2 ] ||
17593                 error "current index should be $cur_rec1 not $cur_rec2"
17594
17595         echo "verifying users from this test are deregistered"
17596         changelog_deregister || error "changelog_deregister failed"
17597         changelog_users $SINGLEMDS | grep -q $cl_user &&
17598                 error "User '$cl_user' still in changelog_users"
17599
17600         # lctl get_param -n mdd.*.changelog_users
17601         # current_index: 144
17602         # ID    index (idle seconds)
17603         # cl3   144   (2) mask=<list>
17604         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17605                 # this is the normal case where all users were deregistered
17606                 # make sure no new records are added when no users are present
17607                 local last_rec1=$(changelog_users $SINGLEMDS |
17608                                   awk '/^current.index:/ { print $NF }')
17609                 touch $DIR/$tdir/chloe
17610                 local last_rec2=$(changelog_users $SINGLEMDS |
17611                                   awk '/^current.index:/ { print $NF }')
17612                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17613                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17614         else
17615                 # any changelog users must be leftovers from a previous test
17616                 changelog_users $SINGLEMDS
17617                 echo "other changelog users; can't verify off"
17618         fi
17619 }
17620 run_test 160a "changelog sanity"
17621
17622 test_160b() { # LU-3587
17623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17624         remote_mds_nodsh && skip "remote MDS with nodsh"
17625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17626                 skip "Need MDS version at least 2.2.0"
17627
17628         changelog_register || error "changelog_register failed"
17629         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17630         changelog_users $SINGLEMDS | grep -q $cl_user ||
17631                 error "User '$cl_user' not found in changelog_users"
17632
17633         local longname1=$(str_repeat a 255)
17634         local longname2=$(str_repeat b 255)
17635
17636         cd $DIR
17637         echo "creating very long named file"
17638         touch $longname1 || error "create of '$longname1' failed"
17639         echo "renaming very long named file"
17640         mv $longname1 $longname2
17641
17642         changelog_dump | grep RENME | tail -n 5
17643         rm -f $longname2
17644 }
17645 run_test 160b "Verify that very long rename doesn't crash in changelog"
17646
17647 test_160c() {
17648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17649         remote_mds_nodsh && skip "remote MDS with nodsh"
17650
17651         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17652                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17653                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17654                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17655
17656         local rc=0
17657
17658         # Registration step
17659         changelog_register || error "changelog_register failed"
17660
17661         rm -rf $DIR/$tdir
17662         mkdir -p $DIR/$tdir
17663         $MCREATE $DIR/$tdir/foo_160c
17664         changelog_chmask "-TRUNC"
17665         $TRUNCATE $DIR/$tdir/foo_160c 200
17666         changelog_chmask "+TRUNC"
17667         $TRUNCATE $DIR/$tdir/foo_160c 199
17668         changelog_dump | tail -n 5
17669         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17670         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17671 }
17672 run_test 160c "verify that changelog log catch the truncate event"
17673
17674 test_160d() {
17675         remote_mds_nodsh && skip "remote MDS with nodsh"
17676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17678         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17679                 skip "Need MDS version at least 2.7.60"
17680
17681         # Registration step
17682         changelog_register || error "changelog_register failed"
17683
17684         mkdir -p $DIR/$tdir/migrate_dir
17685         changelog_clear 0 || error "changelog_clear failed"
17686
17687         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17688         changelog_dump | tail -n 5
17689         local migrates=$(changelog_dump | grep -c "MIGRT")
17690         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17691 }
17692 run_test 160d "verify that changelog log catch the migrate event"
17693
17694 test_160e() {
17695         remote_mds_nodsh && skip "remote MDS with nodsh"
17696
17697         # Create a user
17698         changelog_register || error "changelog_register failed"
17699
17700         local MDT0=$(facet_svc $SINGLEMDS)
17701         local rc
17702
17703         # No user (expect fail)
17704         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17705         rc=$?
17706         if [ $rc -eq 0 ]; then
17707                 error "Should fail without user"
17708         elif [ $rc -ne 4 ]; then
17709                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17710         fi
17711
17712         # Delete a future user (expect fail)
17713         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17714         rc=$?
17715         if [ $rc -eq 0 ]; then
17716                 error "Deleted non-existant user cl77"
17717         elif [ $rc -ne 2 ]; then
17718                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17719         fi
17720
17721         # Clear to a bad index (1 billion should be safe)
17722         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17723         rc=$?
17724
17725         if [ $rc -eq 0 ]; then
17726                 error "Successfully cleared to invalid CL index"
17727         elif [ $rc -ne 22 ]; then
17728                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17729         fi
17730 }
17731 run_test 160e "changelog negative testing (should return errors)"
17732
17733 test_160f() {
17734         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17735         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17736                 skip "Need MDS version at least 2.10.56"
17737
17738         local mdts=$(comma_list $(mdts_nodes))
17739
17740         # Create a user
17741         changelog_register || error "first changelog_register failed"
17742         changelog_register || error "second changelog_register failed"
17743         local cl_users
17744         declare -A cl_user1
17745         declare -A cl_user2
17746         local user_rec1
17747         local user_rec2
17748         local i
17749
17750         # generate some changelog records to accumulate on each MDT
17751         # use all_char because created files should be evenly distributed
17752         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17753                 error "test_mkdir $tdir failed"
17754         log "$(date +%s): creating first files"
17755         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17756                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17757                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17758         done
17759
17760         # check changelogs have been generated
17761         local start=$SECONDS
17762         local idle_time=$((MDSCOUNT * 5 + 5))
17763         local nbcl=$(changelog_dump | wc -l)
17764         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17765
17766         for param in "changelog_max_idle_time=$idle_time" \
17767                      "changelog_gc=1" \
17768                      "changelog_min_gc_interval=2" \
17769                      "changelog_min_free_cat_entries=3"; do
17770                 local MDT0=$(facet_svc $SINGLEMDS)
17771                 local var="${param%=*}"
17772                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17773
17774                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17775                 do_nodes $mdts $LCTL set_param mdd.*.$param
17776         done
17777
17778         # force cl_user2 to be idle (1st part), but also cancel the
17779         # cl_user1 records so that it is not evicted later in the test.
17780         local sleep1=$((idle_time / 2))
17781         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17782         sleep $sleep1
17783
17784         # simulate changelog catalog almost full
17785         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17786         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17787
17788         for i in $(seq $MDSCOUNT); do
17789                 cl_users=(${CL_USERS[mds$i]})
17790                 cl_user1[mds$i]="${cl_users[0]}"
17791                 cl_user2[mds$i]="${cl_users[1]}"
17792
17793                 [ -n "${cl_user1[mds$i]}" ] ||
17794                         error "mds$i: no user registered"
17795                 [ -n "${cl_user2[mds$i]}" ] ||
17796                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17797
17798                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17799                 [ -n "$user_rec1" ] ||
17800                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17801                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17802                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17803                 [ -n "$user_rec2" ] ||
17804                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17805                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17806                      "$user_rec1 + 2 == $user_rec2"
17807                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17808                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17809                               "$user_rec1 + 2, but is $user_rec2"
17810                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17811                 [ -n "$user_rec2" ] ||
17812                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17813                 [ $user_rec1 == $user_rec2 ] ||
17814                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17815                               "$user_rec1, but is $user_rec2"
17816         done
17817
17818         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17819         local sleep2=$((idle_time - (SECONDS - start) + 1))
17820         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17821         sleep $sleep2
17822
17823         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17824         # cl_user1 should be OK because it recently processed records.
17825         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17826         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17827                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17828                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17829         done
17830
17831         # ensure gc thread is done
17832         for i in $(mdts_nodes); do
17833                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17834                         error "$i: GC-thread not done"
17835         done
17836
17837         local first_rec
17838         for (( i = 1; i <= MDSCOUNT; i++ )); do
17839                 # check cl_user1 still registered
17840                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17842                 # check cl_user2 unregistered
17843                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17844                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17845
17846                 # check changelogs are present and starting at $user_rec1 + 1
17847                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17848                 [ -n "$user_rec1" ] ||
17849                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17850                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17851                             awk '{ print $1; exit; }')
17852
17853                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17854                 [ $((user_rec1 + 1)) == $first_rec ] ||
17855                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17856         done
17857 }
17858 run_test 160f "changelog garbage collect (timestamped users)"
17859
17860 test_160g() {
17861         remote_mds_nodsh && skip "remote MDS with nodsh"
17862         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17863                 skip "Need MDS version at least 2.14.55"
17864
17865         local mdts=$(comma_list $(mdts_nodes))
17866
17867         # Create a user
17868         changelog_register || error "first changelog_register failed"
17869         changelog_register || error "second changelog_register failed"
17870         local cl_users
17871         declare -A cl_user1
17872         declare -A cl_user2
17873         local user_rec1
17874         local user_rec2
17875         local i
17876
17877         # generate some changelog records to accumulate on each MDT
17878         # use all_char because created files should be evenly distributed
17879         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17880                 error "test_mkdir $tdir failed"
17881         for ((i = 0; i < MDSCOUNT; i++)); do
17882                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17883                         error "create $DIR/$tdir/d$i.1 failed"
17884         done
17885
17886         # check changelogs have been generated
17887         local nbcl=$(changelog_dump | wc -l)
17888         (( $nbcl > 0 )) || error "no changelogs found"
17889
17890         # reduce the max_idle_indexes value to make sure we exceed it
17891         for param in "changelog_max_idle_indexes=2" \
17892                      "changelog_gc=1" \
17893                      "changelog_min_gc_interval=2"; do
17894                 local MDT0=$(facet_svc $SINGLEMDS)
17895                 local var="${param%=*}"
17896                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17897
17898                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17899                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17900                         error "unable to set mdd.*.$param"
17901         done
17902
17903         local start=$SECONDS
17904         for i in $(seq $MDSCOUNT); do
17905                 cl_users=(${CL_USERS[mds$i]})
17906                 cl_user1[mds$i]="${cl_users[0]}"
17907                 cl_user2[mds$i]="${cl_users[1]}"
17908
17909                 [ -n "${cl_user1[mds$i]}" ] ||
17910                         error "mds$i: user1 is not registered"
17911                 [ -n "${cl_user2[mds$i]}" ] ||
17912                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17913
17914                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17915                 [ -n "$user_rec1" ] ||
17916                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17917                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17918                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17919                 [ -n "$user_rec2" ] ||
17920                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17921                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17922                      "$user_rec1 + 2 == $user_rec2"
17923                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17924                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17925                               "expected $user_rec1 + 2, but is $user_rec2"
17926                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17927                 [ -n "$user_rec2" ] ||
17928                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17929                 [ $user_rec1 == $user_rec2 ] ||
17930                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17931                               "expected $user_rec1, but is $user_rec2"
17932         done
17933
17934         # ensure we are past the previous changelog_min_gc_interval set above
17935         local sleep2=$((start + 2 - SECONDS))
17936         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17937         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17938         # cl_user1 should be OK because it recently processed records.
17939         for ((i = 0; i < MDSCOUNT; i++)); do
17940                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17941                         error "create $DIR/$tdir/d$i.3 failed"
17942         done
17943
17944         # ensure gc thread is done
17945         for i in $(mdts_nodes); do
17946                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17947                         error "$i: GC-thread not done"
17948         done
17949
17950         local first_rec
17951         for (( i = 1; i <= MDSCOUNT; i++ )); do
17952                 # check cl_user1 still registered
17953                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17954                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17955                 # check cl_user2 unregistered
17956                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17957                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17958
17959                 # check changelogs are present and starting at $user_rec1 + 1
17960                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17961                 [ -n "$user_rec1" ] ||
17962                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17963                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17964                             awk '{ print $1; exit; }')
17965
17966                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17967                 [ $((user_rec1 + 1)) == $first_rec ] ||
17968                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17969         done
17970 }
17971 run_test 160g "changelog garbage collect on idle records"
17972
17973 test_160h() {
17974         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17975         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17976                 skip "Need MDS version at least 2.10.56"
17977
17978         local mdts=$(comma_list $(mdts_nodes))
17979
17980         # Create a user
17981         changelog_register || error "first changelog_register failed"
17982         changelog_register || error "second changelog_register failed"
17983         local cl_users
17984         declare -A cl_user1
17985         declare -A cl_user2
17986         local user_rec1
17987         local user_rec2
17988         local i
17989
17990         # generate some changelog records to accumulate on each MDT
17991         # use all_char because created files should be evenly distributed
17992         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17993                 error "test_mkdir $tdir failed"
17994         for ((i = 0; i < MDSCOUNT; i++)); do
17995                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17996                         error "create $DIR/$tdir/d$i.1 failed"
17997         done
17998
17999         # check changelogs have been generated
18000         local nbcl=$(changelog_dump | wc -l)
18001         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18002
18003         for param in "changelog_max_idle_time=10" \
18004                      "changelog_gc=1" \
18005                      "changelog_min_gc_interval=2"; do
18006                 local MDT0=$(facet_svc $SINGLEMDS)
18007                 local var="${param%=*}"
18008                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18009
18010                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18011                 do_nodes $mdts $LCTL set_param mdd.*.$param
18012         done
18013
18014         # force cl_user2 to be idle (1st part)
18015         sleep 9
18016
18017         for i in $(seq $MDSCOUNT); do
18018                 cl_users=(${CL_USERS[mds$i]})
18019                 cl_user1[mds$i]="${cl_users[0]}"
18020                 cl_user2[mds$i]="${cl_users[1]}"
18021
18022                 [ -n "${cl_user1[mds$i]}" ] ||
18023                         error "mds$i: no user registered"
18024                 [ -n "${cl_user2[mds$i]}" ] ||
18025                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18026
18027                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18028                 [ -n "$user_rec1" ] ||
18029                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18030                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18031                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18032                 [ -n "$user_rec2" ] ||
18033                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18034                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18035                      "$user_rec1 + 2 == $user_rec2"
18036                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18037                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18038                               "$user_rec1 + 2, but is $user_rec2"
18039                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18040                 [ -n "$user_rec2" ] ||
18041                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18042                 [ $user_rec1 == $user_rec2 ] ||
18043                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18044                               "$user_rec1, but is $user_rec2"
18045         done
18046
18047         # force cl_user2 to be idle (2nd part) and to reach
18048         # changelog_max_idle_time
18049         sleep 2
18050
18051         # force each GC-thread start and block then
18052         # one per MDT/MDD, set fail_val accordingly
18053         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18054         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18055
18056         # generate more changelogs to trigger fail_loc
18057         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18058                 error "create $DIR/$tdir/${tfile}bis failed"
18059
18060         # stop MDT to stop GC-thread, should be done in back-ground as it will
18061         # block waiting for the thread to be released and exit
18062         declare -A stop_pids
18063         for i in $(seq $MDSCOUNT); do
18064                 stop mds$i &
18065                 stop_pids[mds$i]=$!
18066         done
18067
18068         for i in $(mdts_nodes); do
18069                 local facet
18070                 local nb=0
18071                 local facets=$(facets_up_on_host $i)
18072
18073                 for facet in ${facets//,/ }; do
18074                         if [[ $facet == mds* ]]; then
18075                                 nb=$((nb + 1))
18076                         fi
18077                 done
18078                 # ensure each MDS's gc threads are still present and all in "R"
18079                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18080                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18081                         error "$i: expected $nb GC-thread"
18082                 wait_update $i \
18083                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18084                         "R" 20 ||
18085                         error "$i: GC-thread not found in R-state"
18086                 # check umounts of each MDT on MDS have reached kthread_stop()
18087                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18088                         error "$i: expected $nb umount"
18089                 wait_update $i \
18090                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18091                         error "$i: umount not found in D-state"
18092         done
18093
18094         # release all GC-threads
18095         do_nodes $mdts $LCTL set_param fail_loc=0
18096
18097         # wait for MDT stop to complete
18098         for i in $(seq $MDSCOUNT); do
18099                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18100         done
18101
18102         # XXX
18103         # may try to check if any orphan changelog records are present
18104         # via ldiskfs/zfs and llog_reader...
18105
18106         # re-start/mount MDTs
18107         for i in $(seq $MDSCOUNT); do
18108                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18109                         error "Fail to start mds$i"
18110         done
18111
18112         local first_rec
18113         for i in $(seq $MDSCOUNT); do
18114                 # check cl_user1 still registered
18115                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18116                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18117                 # check cl_user2 unregistered
18118                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18119                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18120
18121                 # check changelogs are present and starting at $user_rec1 + 1
18122                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18123                 [ -n "$user_rec1" ] ||
18124                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18125                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18126                             awk '{ print $1; exit; }')
18127
18128                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18129                 [ $((user_rec1 + 1)) == $first_rec ] ||
18130                         error "mds$i: first index should be $user_rec1 + 1, " \
18131                               "but is $first_rec"
18132         done
18133 }
18134 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18135               "during mount"
18136
18137 test_160i() {
18138
18139         local mdts=$(comma_list $(mdts_nodes))
18140
18141         changelog_register || error "first changelog_register failed"
18142
18143         # generate some changelog records to accumulate on each MDT
18144         # use all_char because created files should be evenly distributed
18145         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18146                 error "test_mkdir $tdir failed"
18147         for ((i = 0; i < MDSCOUNT; i++)); do
18148                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18149                         error "create $DIR/$tdir/d$i.1 failed"
18150         done
18151
18152         # check changelogs have been generated
18153         local nbcl=$(changelog_dump | wc -l)
18154         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18155
18156         # simulate race between register and unregister
18157         # XXX as fail_loc is set per-MDS, with DNE configs the race
18158         # simulation will only occur for one MDT per MDS and for the
18159         # others the normal race scenario will take place
18160         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18161         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18162         do_nodes $mdts $LCTL set_param fail_val=1
18163
18164         # unregister 1st user
18165         changelog_deregister &
18166         local pid1=$!
18167         # wait some time for deregister work to reach race rdv
18168         sleep 2
18169         # register 2nd user
18170         changelog_register || error "2nd user register failed"
18171
18172         wait $pid1 || error "1st user deregister failed"
18173
18174         local i
18175         local last_rec
18176         declare -A LAST_REC
18177         for i in $(seq $MDSCOUNT); do
18178                 if changelog_users mds$i | grep "^cl"; then
18179                         # make sure new records are added with one user present
18180                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18181                                           awk '/^current.index:/ { print $NF }')
18182                 else
18183                         error "mds$i has no user registered"
18184                 fi
18185         done
18186
18187         # generate more changelog records to accumulate on each MDT
18188         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18189                 error "create $DIR/$tdir/${tfile}bis failed"
18190
18191         for i in $(seq $MDSCOUNT); do
18192                 last_rec=$(changelog_users $SINGLEMDS |
18193                            awk '/^current.index:/ { print $NF }')
18194                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18195                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18196                         error "changelogs are off on mds$i"
18197         done
18198 }
18199 run_test 160i "changelog user register/unregister race"
18200
18201 test_160j() {
18202         remote_mds_nodsh && skip "remote MDS with nodsh"
18203         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18204                 skip "Need MDS version at least 2.12.56"
18205
18206         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18207         stack_trap "umount $MOUNT2" EXIT
18208
18209         changelog_register || error "first changelog_register failed"
18210         stack_trap "changelog_deregister" EXIT
18211
18212         # generate some changelog
18213         # use all_char because created files should be evenly distributed
18214         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18215                 error "mkdir $tdir failed"
18216         for ((i = 0; i < MDSCOUNT; i++)); do
18217                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18218                         error "create $DIR/$tdir/d$i.1 failed"
18219         done
18220
18221         # open the changelog device
18222         exec 3>/dev/changelog-$FSNAME-MDT0000
18223         stack_trap "exec 3>&-" EXIT
18224         exec 4</dev/changelog-$FSNAME-MDT0000
18225         stack_trap "exec 4<&-" EXIT
18226
18227         # umount the first lustre mount
18228         umount $MOUNT
18229         stack_trap "mount_client $MOUNT" EXIT
18230
18231         # read changelog, which may or may not fail, but should not crash
18232         cat <&4 >/dev/null
18233
18234         # clear changelog
18235         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18236         changelog_users $SINGLEMDS | grep -q $cl_user ||
18237                 error "User $cl_user not found in changelog_users"
18238
18239         printf 'clear:'$cl_user':0' >&3
18240 }
18241 run_test 160j "client can be umounted while its chanangelog is being used"
18242
18243 test_160k() {
18244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18245         remote_mds_nodsh && skip "remote MDS with nodsh"
18246
18247         mkdir -p $DIR/$tdir/1/1
18248
18249         changelog_register || error "changelog_register failed"
18250         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18251
18252         changelog_users $SINGLEMDS | grep -q $cl_user ||
18253                 error "User '$cl_user' not found in changelog_users"
18254 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18255         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18256         rmdir $DIR/$tdir/1/1 & sleep 1
18257         mkdir $DIR/$tdir/2
18258         touch $DIR/$tdir/2/2
18259         rm -rf $DIR/$tdir/2
18260
18261         wait
18262         sleep 4
18263
18264         changelog_dump | grep rmdir || error "rmdir not recorded"
18265 }
18266 run_test 160k "Verify that changelog records are not lost"
18267
18268 # Verifies that a file passed as a parameter has recently had an operation
18269 # performed on it that has generated an MTIME changelog which contains the
18270 # correct parent FID. As files might reside on a different MDT from the
18271 # parent directory in DNE configurations, the FIDs are translated to paths
18272 # before being compared, which should be identical
18273 compare_mtime_changelog() {
18274         local file="${1}"
18275         local mdtidx
18276         local mtime
18277         local cl_fid
18278         local pdir
18279         local dir
18280
18281         mdtidx=$($LFS getstripe --mdt-index $file)
18282         mdtidx=$(printf "%04x" $mdtidx)
18283
18284         # Obtain the parent FID from the MTIME changelog
18285         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18286         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18287
18288         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18289         [ -z "$cl_fid" ] && error "parent FID not present"
18290
18291         # Verify that the path for the parent FID is the same as the path for
18292         # the test directory
18293         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18294
18295         dir=$(dirname $1)
18296
18297         [[ "${pdir%/}" == "$dir" ]] ||
18298                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18299 }
18300
18301 test_160l() {
18302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18303
18304         remote_mds_nodsh && skip "remote MDS with nodsh"
18305         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18306                 skip "Need MDS version at least 2.13.55"
18307
18308         local cl_user
18309
18310         changelog_register || error "changelog_register failed"
18311         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18312
18313         changelog_users $SINGLEMDS | grep -q $cl_user ||
18314                 error "User '$cl_user' not found in changelog_users"
18315
18316         # Clear some types so that MTIME changelogs are generated
18317         changelog_chmask "-CREAT"
18318         changelog_chmask "-CLOSE"
18319
18320         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18321
18322         # Test CL_MTIME during setattr
18323         touch $DIR/$tdir/$tfile
18324         compare_mtime_changelog $DIR/$tdir/$tfile
18325
18326         # Test CL_MTIME during close
18327         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18328         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18329 }
18330 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18331
18332 test_160m() {
18333         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18334         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18335                 skip "Need MDS version at least 2.14.51"
18336         local cl_users
18337         local cl_user1
18338         local cl_user2
18339         local pid1
18340
18341         # Create a user
18342         changelog_register || error "first changelog_register failed"
18343         changelog_register || error "second changelog_register failed"
18344
18345         cl_users=(${CL_USERS[mds1]})
18346         cl_user1="${cl_users[0]}"
18347         cl_user2="${cl_users[1]}"
18348         # generate some changelog records to accumulate on MDT0
18349         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18350         createmany -m $DIR/$tdir/$tfile 50 ||
18351                 error "create $DIR/$tdir/$tfile failed"
18352         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18353         rm -f $DIR/$tdir
18354
18355         # check changelogs have been generated
18356         local nbcl=$(changelog_dump | wc -l)
18357         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18358
18359 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18360         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18361
18362         __changelog_clear mds1 $cl_user1 +10
18363         __changelog_clear mds1 $cl_user2 0 &
18364         pid1=$!
18365         sleep 2
18366         __changelog_clear mds1 $cl_user1 0 ||
18367                 error "fail to cancel record for $cl_user1"
18368         wait $pid1
18369         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18370 }
18371 run_test 160m "Changelog clear race"
18372
18373 test_160n() {
18374         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18375         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18376                 skip "Need MDS version at least 2.14.51"
18377         local cl_users
18378         local cl_user1
18379         local cl_user2
18380         local pid1
18381         local first_rec
18382         local last_rec=0
18383
18384         # Create a user
18385         changelog_register || error "first changelog_register failed"
18386
18387         cl_users=(${CL_USERS[mds1]})
18388         cl_user1="${cl_users[0]}"
18389
18390         # generate some changelog records to accumulate on MDT0
18391         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18392         first_rec=$(changelog_users $SINGLEMDS |
18393                         awk '/^current.index:/ { print $NF }')
18394         while (( last_rec < (( first_rec + 65000)) )); do
18395                 createmany -m $DIR/$tdir/$tfile 10000 ||
18396                         error "create $DIR/$tdir/$tfile failed"
18397
18398                 for i in $(seq 0 10000); do
18399                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18400                                 > /dev/null
18401                 done
18402
18403                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18404                         error "unlinkmany failed unlink"
18405                 last_rec=$(changelog_users $SINGLEMDS |
18406                         awk '/^current.index:/ { print $NF }')
18407                 echo last record $last_rec
18408                 (( last_rec == 0 )) && error "no changelog found"
18409         done
18410
18411 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18412         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18413
18414         __changelog_clear mds1 $cl_user1 0 &
18415         pid1=$!
18416         sleep 2
18417         __changelog_clear mds1 $cl_user1 0 ||
18418                 error "fail to cancel record for $cl_user1"
18419         wait $pid1
18420         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18421 }
18422 run_test 160n "Changelog destroy race"
18423
18424 test_160o() {
18425         local mdt="$(facet_svc $SINGLEMDS)"
18426
18427         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18428         remote_mds_nodsh && skip "remote MDS with nodsh"
18429         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18430                 skip "Need MDS version at least 2.14.52"
18431
18432         changelog_register --user test_160o -m unlnk+close+open ||
18433                 error "changelog_register failed"
18434
18435         do_facet $SINGLEMDS $LCTL --device $mdt \
18436                                 changelog_register -u "Tt3_-#" &&
18437                 error "bad symbols in name should fail"
18438
18439         do_facet $SINGLEMDS $LCTL --device $mdt \
18440                                 changelog_register -u test_160o &&
18441                 error "the same name registration should fail"
18442
18443         do_facet $SINGLEMDS $LCTL --device $mdt \
18444                         changelog_register -u test_160toolongname &&
18445                 error "too long name registration should fail"
18446
18447         changelog_chmask "MARK+HSM"
18448         lctl get_param mdd.*.changelog*mask
18449         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18450         changelog_users $SINGLEMDS | grep -q $cl_user ||
18451                 error "User $cl_user not found in changelog_users"
18452         #verify username
18453         echo $cl_user | grep -q test_160o ||
18454                 error "User $cl_user has no specific name 'test160o'"
18455
18456         # change something
18457         changelog_clear 0 || error "changelog_clear failed"
18458         # generate some changelog records to accumulate on MDT0
18459         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18460         touch $DIR/$tdir/$tfile                 # open 1
18461
18462         OPENS=$(changelog_dump | grep -c "OPEN")
18463         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18464
18465         # must be no MKDIR it wasn't set as user mask
18466         MKDIR=$(changelog_dump | grep -c "MKDIR")
18467         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18468
18469         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18470                                 mdd.$mdt.changelog_current_mask -n)
18471         # register maskless user
18472         changelog_register || error "changelog_register failed"
18473         # effective mask should be not changed because it is not minimal
18474         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18475                                 mdd.$mdt.changelog_current_mask -n)
18476         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18477         # set server mask to minimal value
18478         changelog_chmask "MARK"
18479         # check effective mask again, should be treated as DEFMASK now
18480         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18481                                 mdd.$mdt.changelog_current_mask -n)
18482         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18483
18484         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18485                 # set server mask back to some value
18486                 changelog_chmask "CLOSE,UNLNK"
18487                 # check effective mask again, should not remain as DEFMASK
18488                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18489                                 mdd.$mdt.changelog_current_mask -n)
18490                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18491         fi
18492
18493         do_facet $SINGLEMDS $LCTL --device $mdt \
18494                                 changelog_deregister -u test_160o ||
18495                 error "cannot deregister by name"
18496 }
18497 run_test 160o "changelog user name and mask"
18498
18499 test_160p() {
18500         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18501         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18502                 skip "Need MDS version at least 2.14.51"
18503         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18504         local cl_users
18505         local cl_user1
18506         local entry_count
18507
18508         # Create a user
18509         changelog_register || error "first changelog_register failed"
18510
18511         cl_users=(${CL_USERS[mds1]})
18512         cl_user1="${cl_users[0]}"
18513
18514         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18515         createmany -m $DIR/$tdir/$tfile 50 ||
18516                 error "create $DIR/$tdir/$tfile failed"
18517         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18518         rm -rf $DIR/$tdir
18519
18520         # check changelogs have been generated
18521         entry_count=$(changelog_dump | wc -l)
18522         ((entry_count != 0)) || error "no changelog entries found"
18523
18524         # remove changelog_users and check that orphan entries are removed
18525         stop mds1
18526         local dev=$(mdsdevname 1)
18527         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18528         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18529         entry_count=$(changelog_dump | wc -l)
18530         ((entry_count == 0)) ||
18531                 error "found $entry_count changelog entries, expected none"
18532 }
18533 run_test 160p "Changelog orphan cleanup with no users"
18534
18535 test_160q() {
18536         local mdt="$(facet_svc $SINGLEMDS)"
18537         local clu
18538
18539         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18540         remote_mds_nodsh && skip "remote MDS with nodsh"
18541         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18542                 skip "Need MDS version at least 2.14.54"
18543
18544         # set server mask to minimal value like server init does
18545         changelog_chmask "MARK"
18546         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18547                 error "changelog_register failed"
18548         # check effective mask again, should be treated as DEFMASK now
18549         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18550                                 mdd.$mdt.changelog_current_mask -n)
18551         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18552                 error "changelog_deregister failed"
18553         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18554 }
18555 run_test 160q "changelog effective mask is DEFMASK if not set"
18556
18557 test_160s() {
18558         remote_mds_nodsh && skip "remote MDS with nodsh"
18559         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18560                 skip "Need MDS version at least 2.14.55"
18561
18562         local mdts=$(comma_list $(mdts_nodes))
18563
18564         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18565         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18566                                        fail_val=$((24 * 3600 * 10))
18567
18568         # Create a user which is 10 days old
18569         changelog_register || error "first changelog_register failed"
18570         local cl_users
18571         declare -A cl_user1
18572         local i
18573
18574         # generate some changelog records to accumulate on each MDT
18575         # use all_char because created files should be evenly distributed
18576         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18577                 error "test_mkdir $tdir failed"
18578         for ((i = 0; i < MDSCOUNT; i++)); do
18579                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18580                         error "create $DIR/$tdir/d$i.1 failed"
18581         done
18582
18583         # check changelogs have been generated
18584         local nbcl=$(changelog_dump | wc -l)
18585         (( nbcl > 0 )) || error "no changelogs found"
18586
18587         # reduce the max_idle_indexes value to make sure we exceed it
18588         for param in "changelog_max_idle_indexes=2097446912" \
18589                      "changelog_max_idle_time=2592000" \
18590                      "changelog_gc=1" \
18591                      "changelog_min_gc_interval=2"; do
18592                 local MDT0=$(facet_svc $SINGLEMDS)
18593                 local var="${param%=*}"
18594                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18595
18596                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18597                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18598                         error "unable to set mdd.*.$param"
18599         done
18600
18601         local start=$SECONDS
18602         for i in $(seq $MDSCOUNT); do
18603                 cl_users=(${CL_USERS[mds$i]})
18604                 cl_user1[mds$i]="${cl_users[0]}"
18605
18606                 [[ -n "${cl_user1[mds$i]}" ]] ||
18607                         error "mds$i: no user registered"
18608         done
18609
18610         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18611         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18612
18613         # ensure we are past the previous changelog_min_gc_interval set above
18614         local sleep2=$((start + 2 - SECONDS))
18615         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18616
18617         # Generate one more changelog to trigger GC
18618         for ((i = 0; i < MDSCOUNT; i++)); do
18619                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18620                         error "create $DIR/$tdir/d$i.3 failed"
18621         done
18622
18623         # ensure gc thread is done
18624         for node in $(mdts_nodes); do
18625                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18626                         error "$node: GC-thread not done"
18627         done
18628
18629         do_nodes $mdts $LCTL set_param fail_loc=0
18630
18631         for (( i = 1; i <= MDSCOUNT; i++ )); do
18632                 # check cl_user1 is purged
18633                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18634                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18635         done
18636         return 0
18637 }
18638 run_test 160s "changelog garbage collect on idle records * time"
18639
18640 test_160t() {
18641         remote_mds_nodsh && skip "remote MDS with nodsh"
18642         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18643                 skip "Need MDS version at least 2.15.50"
18644
18645         local MDT0=$(facet_svc $SINGLEMDS)
18646         local cl_users
18647         local cl_user1
18648         local cl_user2
18649         local start
18650
18651         changelog_register --user user1 -m all ||
18652                 error "user1 failed to register"
18653
18654         mkdir_on_mdt0 $DIR/$tdir
18655         # create default overstripe to maximize changelog size
18656         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18657         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18658         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18659
18660         # user2 consumes less records so less space
18661         changelog_register --user user2 || error "user2 failed to register"
18662         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18663         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18664
18665         # check changelogs have been generated
18666         local nbcl=$(changelog_dump | wc -l)
18667         (( nbcl > 0 )) || error "no changelogs found"
18668
18669         # reduce the changelog_min_gc_interval to force check
18670         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18671                 local var="${param%=*}"
18672                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18673
18674                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18675                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18676                         error "unable to set mdd.*.$param"
18677         done
18678
18679         start=$SECONDS
18680         cl_users=(${CL_USERS[mds1]})
18681         cl_user1="${cl_users[0]}"
18682         cl_user2="${cl_users[1]}"
18683
18684         [[ -n $cl_user1 ]] ||
18685                 error "mds1: user #1 isn't registered"
18686         [[ -n $cl_user2 ]] ||
18687                 error "mds1: user #2 isn't registered"
18688
18689         # ensure we are past the previous changelog_min_gc_interval set above
18690         local sleep2=$((start + 2 - SECONDS))
18691         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18692
18693         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18694         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18695                         fail_val=$(((llog_size1 + llog_size2) / 2))
18696
18697         # Generate more changelog to trigger GC
18698         createmany -o $DIR/$tdir/u3_ 4 ||
18699                 error "create failed for more files"
18700
18701         # ensure gc thread is done
18702         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18703                 error "mds1: GC-thread not done"
18704
18705         do_facet mds1 $LCTL set_param fail_loc=0
18706
18707         # check cl_user1 is purged
18708         changelog_users mds1 | grep -q "$cl_user1" &&
18709                 error "User $cl_user1 is registered"
18710         # check cl_user2 is not purged
18711         changelog_users mds1 | grep -q "$cl_user2" ||
18712                 error "User $cl_user2 is not registered"
18713 }
18714 run_test 160t "changelog garbage collect on lack of space"
18715
18716 test_161a() {
18717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18718
18719         test_mkdir -c1 $DIR/$tdir
18720         cp /etc/hosts $DIR/$tdir/$tfile
18721         test_mkdir -c1 $DIR/$tdir/foo1
18722         test_mkdir -c1 $DIR/$tdir/foo2
18723         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18724         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18725         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18726         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18727         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18728         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18729                 $LFS fid2path $DIR $FID
18730                 error "bad link ea"
18731         fi
18732         # middle
18733         rm $DIR/$tdir/foo2/zachary
18734         # last
18735         rm $DIR/$tdir/foo2/thor
18736         # first
18737         rm $DIR/$tdir/$tfile
18738         # rename
18739         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18740         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18741                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18742         rm $DIR/$tdir/foo2/maggie
18743
18744         # overflow the EA
18745         local longname=$tfile.avg_len_is_thirty_two_
18746         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18747                 error_noexit 'failed to unlink many hardlinks'" EXIT
18748         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18749                 error "failed to hardlink many files"
18750         links=$($LFS fid2path $DIR $FID | wc -l)
18751         echo -n "${links}/1000 links in link EA"
18752         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18753 }
18754 run_test 161a "link ea sanity"
18755
18756 test_161b() {
18757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18758         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18759
18760         local MDTIDX=1
18761         local remote_dir=$DIR/$tdir/remote_dir
18762
18763         mkdir -p $DIR/$tdir
18764         $LFS mkdir -i $MDTIDX $remote_dir ||
18765                 error "create remote directory failed"
18766
18767         cp /etc/hosts $remote_dir/$tfile
18768         mkdir -p $remote_dir/foo1
18769         mkdir -p $remote_dir/foo2
18770         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18771         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18772         ln $remote_dir/$tfile $remote_dir/foo1/luna
18773         ln $remote_dir/$tfile $remote_dir/foo2/thor
18774
18775         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18776                      tr -d ']')
18777         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18778                 $LFS fid2path $DIR $FID
18779                 error "bad link ea"
18780         fi
18781         # middle
18782         rm $remote_dir/foo2/zachary
18783         # last
18784         rm $remote_dir/foo2/thor
18785         # first
18786         rm $remote_dir/$tfile
18787         # rename
18788         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18789         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18790         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18791                 $LFS fid2path $DIR $FID
18792                 error "bad link rename"
18793         fi
18794         rm $remote_dir/foo2/maggie
18795
18796         # overflow the EA
18797         local longname=filename_avg_len_is_thirty_two_
18798         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18799                 error "failed to hardlink many files"
18800         links=$($LFS fid2path $DIR $FID | wc -l)
18801         echo -n "${links}/1000 links in link EA"
18802         [[ ${links} -gt 60 ]] ||
18803                 error "expected at least 60 links in link EA"
18804         unlinkmany $remote_dir/foo2/$longname 1000 ||
18805         error "failed to unlink many hardlinks"
18806 }
18807 run_test 161b "link ea sanity under remote directory"
18808
18809 test_161c() {
18810         remote_mds_nodsh && skip "remote MDS with nodsh"
18811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18812         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18813                 skip "Need MDS version at least 2.1.5"
18814
18815         # define CLF_RENAME_LAST 0x0001
18816         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18817         changelog_register || error "changelog_register failed"
18818
18819         rm -rf $DIR/$tdir
18820         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18821         touch $DIR/$tdir/foo_161c
18822         touch $DIR/$tdir/bar_161c
18823         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18824         changelog_dump | grep RENME | tail -n 5
18825         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18826         changelog_clear 0 || error "changelog_clear failed"
18827         if [ x$flags != "x0x1" ]; then
18828                 error "flag $flags is not 0x1"
18829         fi
18830
18831         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18832         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18833         touch $DIR/$tdir/foo_161c
18834         touch $DIR/$tdir/bar_161c
18835         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18836         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18837         changelog_dump | grep RENME | tail -n 5
18838         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18839         changelog_clear 0 || error "changelog_clear failed"
18840         if [ x$flags != "x0x0" ]; then
18841                 error "flag $flags is not 0x0"
18842         fi
18843         echo "rename overwrite a target having nlink > 1," \
18844                 "changelog record has flags of $flags"
18845
18846         # rename doesn't overwrite a target (changelog flag 0x0)
18847         touch $DIR/$tdir/foo_161c
18848         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18849         changelog_dump | grep RENME | tail -n 5
18850         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18851         changelog_clear 0 || error "changelog_clear failed"
18852         if [ x$flags != "x0x0" ]; then
18853                 error "flag $flags is not 0x0"
18854         fi
18855         echo "rename doesn't overwrite a target," \
18856                 "changelog record has flags of $flags"
18857
18858         # define CLF_UNLINK_LAST 0x0001
18859         # unlink a file having nlink = 1 (changelog flag 0x1)
18860         rm -f $DIR/$tdir/foo2_161c
18861         changelog_dump | grep UNLNK | tail -n 5
18862         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18863         changelog_clear 0 || error "changelog_clear failed"
18864         if [ x$flags != "x0x1" ]; then
18865                 error "flag $flags is not 0x1"
18866         fi
18867         echo "unlink a file having nlink = 1," \
18868                 "changelog record has flags of $flags"
18869
18870         # unlink a file having nlink > 1 (changelog flag 0x0)
18871         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18872         rm -f $DIR/$tdir/foobar_161c
18873         changelog_dump | grep UNLNK | tail -n 5
18874         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18875         changelog_clear 0 || error "changelog_clear failed"
18876         if [ x$flags != "x0x0" ]; then
18877                 error "flag $flags is not 0x0"
18878         fi
18879         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18880 }
18881 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18882
18883 test_161d() {
18884         remote_mds_nodsh && skip "remote MDS with nodsh"
18885         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18886
18887         local pid
18888         local fid
18889
18890         changelog_register || error "changelog_register failed"
18891
18892         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18893         # interfer with $MOUNT/.lustre/fid/ access
18894         mkdir $DIR/$tdir
18895         [[ $? -eq 0 ]] || error "mkdir failed"
18896
18897         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18898         $LCTL set_param fail_loc=0x8000140c
18899         # 5s pause
18900         $LCTL set_param fail_val=5
18901
18902         # create file
18903         echo foofoo > $DIR/$tdir/$tfile &
18904         pid=$!
18905
18906         # wait for create to be delayed
18907         sleep 2
18908
18909         ps -p $pid
18910         [[ $? -eq 0 ]] || error "create should be blocked"
18911
18912         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18913         stack_trap "rm -f $tempfile"
18914         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18915         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18916         # some delay may occur during ChangeLog publishing and file read just
18917         # above, that could allow file write to happen finally
18918         [[ -s $tempfile ]] && echo "file should be empty"
18919
18920         $LCTL set_param fail_loc=0
18921
18922         wait $pid
18923         [[ $? -eq 0 ]] || error "create failed"
18924 }
18925 run_test 161d "create with concurrent .lustre/fid access"
18926
18927 check_path() {
18928         local expected="$1"
18929         shift
18930         local fid="$2"
18931
18932         local path
18933         path=$($LFS fid2path "$@")
18934         local rc=$?
18935
18936         if [ $rc -ne 0 ]; then
18937                 error "path looked up of '$expected' failed: rc=$rc"
18938         elif [ "$path" != "$expected" ]; then
18939                 error "path looked up '$path' instead of '$expected'"
18940         else
18941                 echo "FID '$fid' resolves to path '$path' as expected"
18942         fi
18943 }
18944
18945 test_162a() { # was test_162
18946         test_mkdir -p -c1 $DIR/$tdir/d2
18947         touch $DIR/$tdir/d2/$tfile
18948         touch $DIR/$tdir/d2/x1
18949         touch $DIR/$tdir/d2/x2
18950         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18951         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18952         # regular file
18953         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18954         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18955
18956         # softlink
18957         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18958         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18959         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18960
18961         # softlink to wrong file
18962         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18963         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18964         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18965
18966         # hardlink
18967         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18968         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18969         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18970         # fid2path dir/fsname should both work
18971         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18972         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18973
18974         # hardlink count: check that there are 2 links
18975         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18976         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18977
18978         # hardlink indexing: remove the first link
18979         rm $DIR/$tdir/d2/p/q/r/hlink
18980         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18981 }
18982 run_test 162a "path lookup sanity"
18983
18984 test_162b() {
18985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18987
18988         mkdir $DIR/$tdir
18989         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18990                                 error "create striped dir failed"
18991
18992         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18993                                         tail -n 1 | awk '{print $2}')
18994         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18995
18996         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18997         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18998
18999         # regular file
19000         for ((i=0;i<5;i++)); do
19001                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19002                         error "get fid for f$i failed"
19003                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19004
19005                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19006                         error "get fid for d$i failed"
19007                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19008         done
19009
19010         return 0
19011 }
19012 run_test 162b "striped directory path lookup sanity"
19013
19014 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19015 test_162c() {
19016         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19017                 skip "Need MDS version at least 2.7.51"
19018
19019         local lpath=$tdir.local
19020         local rpath=$tdir.remote
19021
19022         test_mkdir $DIR/$lpath
19023         test_mkdir $DIR/$rpath
19024
19025         for ((i = 0; i <= 101; i++)); do
19026                 lpath="$lpath/$i"
19027                 mkdir $DIR/$lpath
19028                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19029                         error "get fid for local directory $DIR/$lpath failed"
19030                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19031
19032                 rpath="$rpath/$i"
19033                 test_mkdir $DIR/$rpath
19034                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19035                         error "get fid for remote directory $DIR/$rpath failed"
19036                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19037         done
19038
19039         return 0
19040 }
19041 run_test 162c "fid2path works with paths 100 or more directories deep"
19042
19043 oalr_event_count() {
19044         local event="${1}"
19045         local trace="${2}"
19046
19047         awk -v name="${FSNAME}-OST0000" \
19048             -v event="${event}" \
19049             '$1 == "TRACE" && $2 == event && $3 == name' \
19050             "${trace}" |
19051         wc -l
19052 }
19053
19054 oalr_expect_event_count() {
19055         local event="${1}"
19056         local trace="${2}"
19057         local expect="${3}"
19058         local count
19059
19060         count=$(oalr_event_count "${event}" "${trace}")
19061         if ((count == expect)); then
19062                 return 0
19063         fi
19064
19065         error_noexit "${event} event count was '${count}', expected ${expect}"
19066         cat "${trace}" >&2
19067         exit 1
19068 }
19069
19070 cleanup_165() {
19071         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19072         stop ost1
19073         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19074 }
19075
19076 setup_165() {
19077         sync # Flush previous IOs so we can count log entries.
19078         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19079         stack_trap cleanup_165 EXIT
19080 }
19081
19082 test_165a() {
19083         local trace="/tmp/${tfile}.trace"
19084         local rc
19085         local count
19086
19087         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19088                 skip "OFD access log unsupported"
19089
19090         setup_165
19091         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19092         sleep 5
19093
19094         do_facet ost1 ofd_access_log_reader --list
19095         stop ost1
19096
19097         do_facet ost1 killall -TERM ofd_access_log_reader
19098         wait
19099         rc=$?
19100
19101         if ((rc != 0)); then
19102                 error "ofd_access_log_reader exited with rc = '${rc}'"
19103         fi
19104
19105         # Parse trace file for discovery events:
19106         oalr_expect_event_count alr_log_add "${trace}" 1
19107         oalr_expect_event_count alr_log_eof "${trace}" 1
19108         oalr_expect_event_count alr_log_free "${trace}" 1
19109 }
19110 run_test 165a "ofd access log discovery"
19111
19112 test_165b() {
19113         local trace="/tmp/${tfile}.trace"
19114         local file="${DIR}/${tfile}"
19115         local pfid1
19116         local pfid2
19117         local -a entry
19118         local rc
19119         local count
19120         local size
19121         local flags
19122
19123         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19124                 skip "OFD access log unsupported"
19125
19126         setup_165
19127         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19128         sleep 5
19129
19130         do_facet ost1 ofd_access_log_reader --list
19131
19132         lfs setstripe -c 1 -i 0 "${file}"
19133         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19134                 error "cannot create '${file}'"
19135
19136         sleep 5
19137         do_facet ost1 killall -TERM ofd_access_log_reader
19138         wait
19139         rc=$?
19140
19141         if ((rc != 0)); then
19142                 error "ofd_access_log_reader exited with rc = '${rc}'"
19143         fi
19144
19145         oalr_expect_event_count alr_log_entry "${trace}" 1
19146
19147         pfid1=$($LFS path2fid "${file}")
19148
19149         # 1     2             3   4    5     6   7    8    9     10
19150         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19151         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19152
19153         echo "entry = '${entry[*]}'" >&2
19154
19155         pfid2=${entry[4]}
19156         if [[ "${pfid1}" != "${pfid2}" ]]; then
19157                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19158         fi
19159
19160         size=${entry[8]}
19161         if ((size != 1048576)); then
19162                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19163         fi
19164
19165         flags=${entry[10]}
19166         if [[ "${flags}" != "w" ]]; then
19167                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19168         fi
19169
19170         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19171         sleep 5
19172
19173         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19174                 error "cannot read '${file}'"
19175         sleep 5
19176
19177         do_facet ost1 killall -TERM ofd_access_log_reader
19178         wait
19179         rc=$?
19180
19181         if ((rc != 0)); then
19182                 error "ofd_access_log_reader exited with rc = '${rc}'"
19183         fi
19184
19185         oalr_expect_event_count alr_log_entry "${trace}" 1
19186
19187         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19188         echo "entry = '${entry[*]}'" >&2
19189
19190         pfid2=${entry[4]}
19191         if [[ "${pfid1}" != "${pfid2}" ]]; then
19192                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19193         fi
19194
19195         size=${entry[8]}
19196         if ((size != 524288)); then
19197                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19198         fi
19199
19200         flags=${entry[10]}
19201         if [[ "${flags}" != "r" ]]; then
19202                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19203         fi
19204 }
19205 run_test 165b "ofd access log entries are produced and consumed"
19206
19207 test_165c() {
19208         local trace="/tmp/${tfile}.trace"
19209         local file="${DIR}/${tdir}/${tfile}"
19210
19211         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19212                 skip "OFD access log unsupported"
19213
19214         test_mkdir "${DIR}/${tdir}"
19215
19216         setup_165
19217         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19218         sleep 5
19219
19220         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19221
19222         # 4096 / 64 = 64. Create twice as many entries.
19223         for ((i = 0; i < 128; i++)); do
19224                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19225                         error "cannot create file"
19226         done
19227
19228         sync
19229
19230         do_facet ost1 killall -TERM ofd_access_log_reader
19231         wait
19232         rc=$?
19233         if ((rc != 0)); then
19234                 error "ofd_access_log_reader exited with rc = '${rc}'"
19235         fi
19236
19237         unlinkmany  "${file}-%d" 128
19238 }
19239 run_test 165c "full ofd access logs do not block IOs"
19240
19241 oal_get_read_count() {
19242         local stats="$1"
19243
19244         # STATS lustre-OST0001 alr_read_count 1
19245
19246         do_facet ost1 cat "${stats}" |
19247         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19248              END { print count; }'
19249 }
19250
19251 oal_expect_read_count() {
19252         local stats="$1"
19253         local count
19254         local expect="$2"
19255
19256         # Ask ofd_access_log_reader to write stats.
19257         do_facet ost1 killall -USR1 ofd_access_log_reader
19258
19259         # Allow some time for things to happen.
19260         sleep 1
19261
19262         count=$(oal_get_read_count "${stats}")
19263         if ((count == expect)); then
19264                 return 0
19265         fi
19266
19267         error_noexit "bad read count, got ${count}, expected ${expect}"
19268         do_facet ost1 cat "${stats}" >&2
19269         exit 1
19270 }
19271
19272 test_165d() {
19273         local stats="/tmp/${tfile}.stats"
19274         local file="${DIR}/${tdir}/${tfile}"
19275         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19276
19277         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19278                 skip "OFD access log unsupported"
19279
19280         test_mkdir "${DIR}/${tdir}"
19281
19282         setup_165
19283         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19284         sleep 5
19285
19286         lfs setstripe -c 1 -i 0 "${file}"
19287
19288         do_facet ost1 lctl set_param "${param}=rw"
19289         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19290                 error "cannot create '${file}'"
19291         oal_expect_read_count "${stats}" 1
19292
19293         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19294                 error "cannot read '${file}'"
19295         oal_expect_read_count "${stats}" 2
19296
19297         do_facet ost1 lctl set_param "${param}=r"
19298         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19299                 error "cannot create '${file}'"
19300         oal_expect_read_count "${stats}" 2
19301
19302         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19303                 error "cannot read '${file}'"
19304         oal_expect_read_count "${stats}" 3
19305
19306         do_facet ost1 lctl set_param "${param}=w"
19307         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19308                 error "cannot create '${file}'"
19309         oal_expect_read_count "${stats}" 4
19310
19311         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19312                 error "cannot read '${file}'"
19313         oal_expect_read_count "${stats}" 4
19314
19315         do_facet ost1 lctl set_param "${param}=0"
19316         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19317                 error "cannot create '${file}'"
19318         oal_expect_read_count "${stats}" 4
19319
19320         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19321                 error "cannot read '${file}'"
19322         oal_expect_read_count "${stats}" 4
19323
19324         do_facet ost1 killall -TERM ofd_access_log_reader
19325         wait
19326         rc=$?
19327         if ((rc != 0)); then
19328                 error "ofd_access_log_reader exited with rc = '${rc}'"
19329         fi
19330 }
19331 run_test 165d "ofd_access_log mask works"
19332
19333 test_165e() {
19334         local stats="/tmp/${tfile}.stats"
19335         local file0="${DIR}/${tdir}-0/${tfile}"
19336         local file1="${DIR}/${tdir}-1/${tfile}"
19337
19338         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19339                 skip "OFD access log unsupported"
19340
19341         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19342
19343         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19344         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19345
19346         lfs setstripe -c 1 -i 0 "${file0}"
19347         lfs setstripe -c 1 -i 0 "${file1}"
19348
19349         setup_165
19350         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19351         sleep 5
19352
19353         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19354                 error "cannot create '${file0}'"
19355         sync
19356         oal_expect_read_count "${stats}" 0
19357
19358         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19359                 error "cannot create '${file1}'"
19360         sync
19361         oal_expect_read_count "${stats}" 1
19362
19363         do_facet ost1 killall -TERM ofd_access_log_reader
19364         wait
19365         rc=$?
19366         if ((rc != 0)); then
19367                 error "ofd_access_log_reader exited with rc = '${rc}'"
19368         fi
19369 }
19370 run_test 165e "ofd_access_log MDT index filter works"
19371
19372 test_165f() {
19373         local trace="/tmp/${tfile}.trace"
19374         local rc
19375         local count
19376
19377         setup_165
19378         do_facet ost1 timeout 60 ofd_access_log_reader \
19379                 --exit-on-close --debug=- --trace=- > "${trace}" &
19380         sleep 5
19381         stop ost1
19382
19383         wait
19384         rc=$?
19385
19386         if ((rc != 0)); then
19387                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19388                 cat "${trace}"
19389                 exit 1
19390         fi
19391 }
19392 run_test 165f "ofd_access_log_reader --exit-on-close works"
19393
19394 test_169() {
19395         # do directio so as not to populate the page cache
19396         log "creating a 10 Mb file"
19397         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19398                 error "multiop failed while creating a file"
19399         log "starting reads"
19400         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19401         log "truncating the file"
19402         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19403                 error "multiop failed while truncating the file"
19404         log "killing dd"
19405         kill %+ || true # reads might have finished
19406         echo "wait until dd is finished"
19407         wait
19408         log "removing the temporary file"
19409         rm -rf $DIR/$tfile || error "tmp file removal failed"
19410 }
19411 run_test 169 "parallel read and truncate should not deadlock"
19412
19413 test_170() {
19414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19415
19416         $LCTL clear     # bug 18514
19417         $LCTL debug_daemon start $TMP/${tfile}_log_good
19418         touch $DIR/$tfile
19419         $LCTL debug_daemon stop
19420         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19421                 error "sed failed to read log_good"
19422
19423         $LCTL debug_daemon start $TMP/${tfile}_log_good
19424         rm -rf $DIR/$tfile
19425         $LCTL debug_daemon stop
19426
19427         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19428                error "lctl df log_bad failed"
19429
19430         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19431         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19432
19433         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19434         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19435
19436         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19437                 error "bad_line good_line1 good_line2 are empty"
19438
19439         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19440         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19441         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19442
19443         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19444         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19445         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19446
19447         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19448                 error "bad_line_new good_line_new are empty"
19449
19450         local expected_good=$((good_line1 + good_line2*2))
19451
19452         rm -f $TMP/${tfile}*
19453         # LU-231, short malformed line may not be counted into bad lines
19454         if [ $bad_line -ne $bad_line_new ] &&
19455                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19456                 error "expected $bad_line bad lines, but got $bad_line_new"
19457                 return 1
19458         fi
19459
19460         if [ $expected_good -ne $good_line_new ]; then
19461                 error "expected $expected_good good lines, but got $good_line_new"
19462                 return 2
19463         fi
19464         true
19465 }
19466 run_test 170 "test lctl df to handle corrupted log ====================="
19467
19468 test_171() { # bug20592
19469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19470
19471         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19472         $LCTL set_param fail_loc=0x50e
19473         $LCTL set_param fail_val=3000
19474         multiop_bg_pause $DIR/$tfile O_s || true
19475         local MULTIPID=$!
19476         kill -USR1 $MULTIPID
19477         # cause log dump
19478         sleep 3
19479         wait $MULTIPID
19480         if dmesg | grep "recursive fault"; then
19481                 error "caught a recursive fault"
19482         fi
19483         $LCTL set_param fail_loc=0
19484         true
19485 }
19486 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19487
19488 test_172() {
19489
19490         #define OBD_FAIL_OBD_CLEANUP  0x60e
19491         $LCTL set_param fail_loc=0x60e
19492         umount $MOUNT || error "umount $MOUNT failed"
19493         stack_trap "mount_client $MOUNT"
19494
19495         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19496                 error "no client OBDs are remained"
19497
19498         $LCTL dl | while read devno state type name foo; do
19499                 case $type in
19500                 lov|osc|lmv|mdc)
19501                         $LCTL --device $name cleanup
19502                         $LCTL --device $name detach
19503                         ;;
19504                 *)
19505                         # skip server devices
19506                         ;;
19507                 esac
19508         done
19509
19510         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19511                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19512                 error "some client OBDs are still remained"
19513         fi
19514
19515 }
19516 run_test 172 "manual device removal with lctl cleanup/detach ======"
19517
19518 # it would be good to share it with obdfilter-survey/iokit-libecho code
19519 setup_obdecho_osc () {
19520         local rc=0
19521         local ost_nid=$1
19522         local obdfilter_name=$2
19523         echo "Creating new osc for $obdfilter_name on $ost_nid"
19524         # make sure we can find loopback nid
19525         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19526
19527         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19528                            ${obdfilter_name}_osc_UUID || rc=2; }
19529         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19530                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19531         return $rc
19532 }
19533
19534 cleanup_obdecho_osc () {
19535         local obdfilter_name=$1
19536         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19537         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19538         return 0
19539 }
19540
19541 obdecho_test() {
19542         local OBD=$1
19543         local node=$2
19544         local pages=${3:-64}
19545         local rc=0
19546         local id
19547
19548         local count=10
19549         local obd_size=$(get_obd_size $node $OBD)
19550         local page_size=$(get_page_size $node)
19551         if [[ -n "$obd_size" ]]; then
19552                 local new_count=$((obd_size / (pages * page_size / 1024)))
19553                 [[ $new_count -ge $count ]] || count=$new_count
19554         fi
19555
19556         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19557         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19558                            rc=2; }
19559         if [ $rc -eq 0 ]; then
19560             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19561             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19562         fi
19563         echo "New object id is $id"
19564         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19565                            rc=4; }
19566         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19567                            "test_brw $count w v $pages $id" || rc=4; }
19568         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19569                            rc=4; }
19570         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19571                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19572         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19573                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19574         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19575         return $rc
19576 }
19577
19578 test_180a() {
19579         skip "obdecho on osc is no longer supported"
19580 }
19581 run_test 180a "test obdecho on osc"
19582
19583 test_180b() {
19584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19585         remote_ost_nodsh && skip "remote OST with nodsh"
19586
19587         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19588                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19589                 error "failed to load module obdecho"
19590
19591         local target=$(do_facet ost1 $LCTL dl |
19592                        awk '/obdfilter/ { print $4; exit; }')
19593
19594         if [ -n "$target" ]; then
19595                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19596         else
19597                 do_facet ost1 $LCTL dl
19598                 error "there is no obdfilter target on ost1"
19599         fi
19600 }
19601 run_test 180b "test obdecho directly on obdfilter"
19602
19603 test_180c() { # LU-2598
19604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19605         remote_ost_nodsh && skip "remote OST with nodsh"
19606         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19607                 skip "Need MDS version at least 2.4.0"
19608
19609         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19610                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19611                 error "failed to load module obdecho"
19612
19613         local target=$(do_facet ost1 $LCTL dl |
19614                        awk '/obdfilter/ { print $4; exit; }')
19615
19616         if [ -n "$target" ]; then
19617                 local pages=16384 # 64MB bulk I/O RPC size
19618
19619                 obdecho_test "$target" ost1 "$pages" ||
19620                         error "obdecho_test with pages=$pages failed with $?"
19621         else
19622                 do_facet ost1 $LCTL dl
19623                 error "there is no obdfilter target on ost1"
19624         fi
19625 }
19626 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19627
19628 test_181() { # bug 22177
19629         test_mkdir $DIR/$tdir
19630         # create enough files to index the directory
19631         createmany -o $DIR/$tdir/foobar 4000
19632         # print attributes for debug purpose
19633         lsattr -d .
19634         # open dir
19635         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19636         MULTIPID=$!
19637         # remove the files & current working dir
19638         unlinkmany $DIR/$tdir/foobar 4000
19639         rmdir $DIR/$tdir
19640         kill -USR1 $MULTIPID
19641         wait $MULTIPID
19642         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19643         return 0
19644 }
19645 run_test 181 "Test open-unlinked dir ========================"
19646
19647 test_182a() {
19648         local fcount=1000
19649         local tcount=10
19650
19651         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19652
19653         $LCTL set_param mdc.*.rpc_stats=clear
19654
19655         for (( i = 0; i < $tcount; i++ )) ; do
19656                 mkdir $DIR/$tdir/$i
19657         done
19658
19659         for (( i = 0; i < $tcount; i++ )) ; do
19660                 createmany -o $DIR/$tdir/$i/f- $fcount &
19661         done
19662         wait
19663
19664         for (( i = 0; i < $tcount; i++ )) ; do
19665                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19666         done
19667         wait
19668
19669         $LCTL get_param mdc.*.rpc_stats
19670
19671         rm -rf $DIR/$tdir
19672 }
19673 run_test 182a "Test parallel modify metadata operations from mdc"
19674
19675 test_182b() {
19676         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19677         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19678         local dcount=1000
19679         local tcount=10
19680         local stime
19681         local etime
19682         local delta
19683
19684         do_facet mds1 $LCTL list_param \
19685                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19686                 skip "MDS lacks parallel RPC handling"
19687
19688         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19689
19690         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19691                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19692
19693         stime=$(date +%s)
19694         createmany -i 0 -d $DIR/$tdir/t- $tcount
19695
19696         for (( i = 0; i < $tcount; i++ )) ; do
19697                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19698         done
19699         wait
19700         etime=$(date +%s)
19701         delta=$((etime - stime))
19702         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19703
19704         stime=$(date +%s)
19705         for (( i = 0; i < $tcount; i++ )) ; do
19706                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19707         done
19708         wait
19709         etime=$(date +%s)
19710         delta=$((etime - stime))
19711         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19712
19713         rm -rf $DIR/$tdir
19714
19715         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19716
19717         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19718
19719         stime=$(date +%s)
19720         createmany -i 0 -d $DIR/$tdir/t- $tcount
19721
19722         for (( i = 0; i < $tcount; i++ )) ; do
19723                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19724         done
19725         wait
19726         etime=$(date +%s)
19727         delta=$((etime - stime))
19728         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19729
19730         stime=$(date +%s)
19731         for (( i = 0; i < $tcount; i++ )) ; do
19732                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19733         done
19734         wait
19735         etime=$(date +%s)
19736         delta=$((etime - stime))
19737         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19738
19739         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19740 }
19741 run_test 182b "Test parallel modify metadata operations from osp"
19742
19743 test_183() { # LU-2275
19744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19745         remote_mds_nodsh && skip "remote MDS with nodsh"
19746         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19747                 skip "Need MDS version at least 2.3.56"
19748
19749         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19750         echo aaa > $DIR/$tdir/$tfile
19751
19752 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19753         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19754
19755         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19756         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19757
19758         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19759
19760         # Flush negative dentry cache
19761         touch $DIR/$tdir/$tfile
19762
19763         # We are not checking for any leaked references here, they'll
19764         # become evident next time we do cleanup with module unload.
19765         rm -rf $DIR/$tdir
19766 }
19767 run_test 183 "No crash or request leak in case of strange dispositions ========"
19768
19769 # test suite 184 is for LU-2016, LU-2017
19770 test_184a() {
19771         check_swap_layouts_support
19772
19773         dir0=$DIR/$tdir/$testnum
19774         test_mkdir -p -c1 $dir0
19775         ref1=/etc/passwd
19776         ref2=/etc/group
19777         file1=$dir0/f1
19778         file2=$dir0/f2
19779         $LFS setstripe -c1 $file1
19780         cp $ref1 $file1
19781         $LFS setstripe -c2 $file2
19782         cp $ref2 $file2
19783         gen1=$($LFS getstripe -g $file1)
19784         gen2=$($LFS getstripe -g $file2)
19785
19786         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19787         gen=$($LFS getstripe -g $file1)
19788         [[ $gen1 != $gen ]] ||
19789                 error "Layout generation on $file1 does not change"
19790         gen=$($LFS getstripe -g $file2)
19791         [[ $gen2 != $gen ]] ||
19792                 error "Layout generation on $file2 does not change"
19793
19794         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19795         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19796
19797         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19798 }
19799 run_test 184a "Basic layout swap"
19800
19801 test_184b() {
19802         check_swap_layouts_support
19803
19804         dir0=$DIR/$tdir/$testnum
19805         mkdir -p $dir0 || error "creating dir $dir0"
19806         file1=$dir0/f1
19807         file2=$dir0/f2
19808         file3=$dir0/f3
19809         dir1=$dir0/d1
19810         dir2=$dir0/d2
19811         mkdir $dir1 $dir2
19812         $LFS setstripe -c1 $file1
19813         $LFS setstripe -c2 $file2
19814         $LFS setstripe -c1 $file3
19815         chown $RUNAS_ID $file3
19816         gen1=$($LFS getstripe -g $file1)
19817         gen2=$($LFS getstripe -g $file2)
19818
19819         $LFS swap_layouts $dir1 $dir2 &&
19820                 error "swap of directories layouts should fail"
19821         $LFS swap_layouts $dir1 $file1 &&
19822                 error "swap of directory and file layouts should fail"
19823         $RUNAS $LFS swap_layouts $file1 $file2 &&
19824                 error "swap of file we cannot write should fail"
19825         $LFS swap_layouts $file1 $file3 &&
19826                 error "swap of file with different owner should fail"
19827         /bin/true # to clear error code
19828 }
19829 run_test 184b "Forbidden layout swap (will generate errors)"
19830
19831 test_184c() {
19832         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19833         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19834         check_swap_layouts_support
19835         check_swap_layout_no_dom $DIR
19836
19837         local dir0=$DIR/$tdir/$testnum
19838         mkdir -p $dir0 || error "creating dir $dir0"
19839
19840         local ref1=$dir0/ref1
19841         local ref2=$dir0/ref2
19842         local file1=$dir0/file1
19843         local file2=$dir0/file2
19844         # create a file large enough for the concurrent test
19845         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19846         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19847         echo "ref file size: ref1($(stat -c %s $ref1))," \
19848              "ref2($(stat -c %s $ref2))"
19849
19850         cp $ref2 $file2
19851         dd if=$ref1 of=$file1 bs=16k &
19852         local DD_PID=$!
19853
19854         # Make sure dd starts to copy file, but wait at most 5 seconds
19855         local loops=0
19856         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19857
19858         $LFS swap_layouts $file1 $file2
19859         local rc=$?
19860         wait $DD_PID
19861         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19862         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19863
19864         # how many bytes copied before swapping layout
19865         local copied=$(stat -c %s $file2)
19866         local remaining=$(stat -c %s $ref1)
19867         remaining=$((remaining - copied))
19868         echo "Copied $copied bytes before swapping layout..."
19869
19870         cmp -n $copied $file1 $ref2 | grep differ &&
19871                 error "Content mismatch [0, $copied) of ref2 and file1"
19872         cmp -n $copied $file2 $ref1 ||
19873                 error "Content mismatch [0, $copied) of ref1 and file2"
19874         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19875                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19876
19877         # clean up
19878         rm -f $ref1 $ref2 $file1 $file2
19879 }
19880 run_test 184c "Concurrent write and layout swap"
19881
19882 test_184d() {
19883         check_swap_layouts_support
19884         check_swap_layout_no_dom $DIR
19885         [ -z "$(which getfattr 2>/dev/null)" ] &&
19886                 skip_env "no getfattr command"
19887
19888         local file1=$DIR/$tdir/$tfile-1
19889         local file2=$DIR/$tdir/$tfile-2
19890         local file3=$DIR/$tdir/$tfile-3
19891         local lovea1
19892         local lovea2
19893
19894         mkdir -p $DIR/$tdir
19895         touch $file1 || error "create $file1 failed"
19896         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19897                 error "create $file2 failed"
19898         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19899                 error "create $file3 failed"
19900         lovea1=$(get_layout_param $file1)
19901
19902         $LFS swap_layouts $file2 $file3 ||
19903                 error "swap $file2 $file3 layouts failed"
19904         $LFS swap_layouts $file1 $file2 ||
19905                 error "swap $file1 $file2 layouts failed"
19906
19907         lovea2=$(get_layout_param $file2)
19908         echo "$lovea1"
19909         echo "$lovea2"
19910         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19911
19912         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19913         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19914 }
19915 run_test 184d "allow stripeless layouts swap"
19916
19917 test_184e() {
19918         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19919                 skip "Need MDS version at least 2.6.94"
19920         check_swap_layouts_support
19921         check_swap_layout_no_dom $DIR
19922         [ -z "$(which getfattr 2>/dev/null)" ] &&
19923                 skip_env "no getfattr command"
19924
19925         local file1=$DIR/$tdir/$tfile-1
19926         local file2=$DIR/$tdir/$tfile-2
19927         local file3=$DIR/$tdir/$tfile-3
19928         local lovea
19929
19930         mkdir -p $DIR/$tdir
19931         touch $file1 || error "create $file1 failed"
19932         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19933                 error "create $file2 failed"
19934         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19935                 error "create $file3 failed"
19936
19937         $LFS swap_layouts $file1 $file2 ||
19938                 error "swap $file1 $file2 layouts failed"
19939
19940         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19941         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19942
19943         echo 123 > $file1 || error "Should be able to write into $file1"
19944
19945         $LFS swap_layouts $file1 $file3 ||
19946                 error "swap $file1 $file3 layouts failed"
19947
19948         echo 123 > $file1 || error "Should be able to write into $file1"
19949
19950         rm -rf $file1 $file2 $file3
19951 }
19952 run_test 184e "Recreate layout after stripeless layout swaps"
19953
19954 test_184f() {
19955         # Create a file with name longer than sizeof(struct stat) ==
19956         # 144 to see if we can get chars from the file name to appear
19957         # in the returned striping. Note that 'f' == 0x66.
19958         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19959
19960         mkdir -p $DIR/$tdir
19961         mcreate $DIR/$tdir/$file
19962         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19963                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19964         fi
19965 }
19966 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19967
19968 test_185() { # LU-2441
19969         # LU-3553 - no volatile file support in old servers
19970         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19971                 skip "Need MDS version at least 2.3.60"
19972
19973         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19974         touch $DIR/$tdir/spoo
19975         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19976         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19977                 error "cannot create/write a volatile file"
19978         [ "$FILESET" == "" ] &&
19979         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19980                 error "FID is still valid after close"
19981
19982         multiop_bg_pause $DIR/$tdir Vw4096_c
19983         local multi_pid=$!
19984
19985         local OLD_IFS=$IFS
19986         IFS=":"
19987         local fidv=($fid)
19988         IFS=$OLD_IFS
19989         # assume that the next FID for this client is sequential, since stdout
19990         # is unfortunately eaten by multiop_bg_pause
19991         local n=$((${fidv[1]} + 1))
19992         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19993         if [ "$FILESET" == "" ]; then
19994                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19995                         error "FID is missing before close"
19996         fi
19997         kill -USR1 $multi_pid
19998         # 1 second delay, so if mtime change we will see it
19999         sleep 1
20000         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20001         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20002 }
20003 run_test 185 "Volatile file support"
20004
20005 function create_check_volatile() {
20006         local idx=$1
20007         local tgt
20008
20009         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20010         local PID=$!
20011         sleep 1
20012         local FID=$(cat /tmp/${tfile}.fid)
20013         [ "$FID" == "" ] && error "can't get FID for volatile"
20014         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20015         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20016         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20017         kill -USR1 $PID
20018         wait
20019         sleep 1
20020         cancel_lru_locks mdc # flush opencache
20021         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20022         return 0
20023 }
20024
20025 test_185a(){
20026         # LU-12516 - volatile creation via .lustre
20027         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20028                 skip "Need MDS version at least 2.3.55"
20029
20030         create_check_volatile 0
20031         [ $MDSCOUNT -lt 2 ] && return 0
20032
20033         # DNE case
20034         create_check_volatile 1
20035
20036         return 0
20037 }
20038 run_test 185a "Volatile file creation in .lustre/fid/"
20039
20040 test_187a() {
20041         remote_mds_nodsh && skip "remote MDS with nodsh"
20042         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20043                 skip "Need MDS version at least 2.3.0"
20044
20045         local dir0=$DIR/$tdir/$testnum
20046         mkdir -p $dir0 || error "creating dir $dir0"
20047
20048         local file=$dir0/file1
20049         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20050         stack_trap "rm -f $file"
20051         local dv1=$($LFS data_version $file)
20052         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20053         local dv2=$($LFS data_version $file)
20054         [[ $dv1 != $dv2 ]] ||
20055                 error "data version did not change on write $dv1 == $dv2"
20056 }
20057 run_test 187a "Test data version change"
20058
20059 test_187b() {
20060         remote_mds_nodsh && skip "remote MDS with nodsh"
20061         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20062                 skip "Need MDS version at least 2.3.0"
20063
20064         local dir0=$DIR/$tdir/$testnum
20065         mkdir -p $dir0 || error "creating dir $dir0"
20066
20067         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20068         [[ ${DV[0]} != ${DV[1]} ]] ||
20069                 error "data version did not change on write"\
20070                       " ${DV[0]} == ${DV[1]}"
20071
20072         # clean up
20073         rm -f $file1
20074 }
20075 run_test 187b "Test data version change on volatile file"
20076
20077 test_200() {
20078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20079         remote_mgs_nodsh && skip "remote MGS with nodsh"
20080         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20081
20082         local POOL=${POOL:-cea1}
20083         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20084         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20085         # Pool OST targets
20086         local first_ost=0
20087         local last_ost=$(($OSTCOUNT - 1))
20088         local ost_step=2
20089         local ost_list=$(seq $first_ost $ost_step $last_ost)
20090         local ost_range="$first_ost $last_ost $ost_step"
20091         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20092         local file_dir=$POOL_ROOT/file_tst
20093         local subdir=$test_path/subdir
20094         local rc=0
20095
20096         while : ; do
20097                 # former test_200a test_200b
20098                 pool_add $POOL                          || { rc=$? ; break; }
20099                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20100                 # former test_200c test_200d
20101                 mkdir -p $test_path
20102                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20103                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20104                 mkdir -p $subdir
20105                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20106                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20107                                                         || { rc=$? ; break; }
20108                 # former test_200e test_200f
20109                 local files=$((OSTCOUNT*3))
20110                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20111                                                         || { rc=$? ; break; }
20112                 pool_create_files $POOL $file_dir $files "$ost_list" \
20113                                                         || { rc=$? ; break; }
20114                 # former test_200g test_200h
20115                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20116                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20117
20118                 # former test_201a test_201b test_201c
20119                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20120
20121                 local f=$test_path/$tfile
20122                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20123                 pool_remove $POOL $f                    || { rc=$? ; break; }
20124                 break
20125         done
20126
20127         destroy_test_pools
20128
20129         return $rc
20130 }
20131 run_test 200 "OST pools"
20132
20133 # usage: default_attr <count | size | offset>
20134 default_attr() {
20135         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20136 }
20137
20138 # usage: check_default_stripe_attr
20139 check_default_stripe_attr() {
20140         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20141         case $1 in
20142         --stripe-count|-c)
20143                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20144         --stripe-size|-S)
20145                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20146         --stripe-index|-i)
20147                 EXPECTED=-1;;
20148         *)
20149                 error "unknown getstripe attr '$1'"
20150         esac
20151
20152         [ $ACTUAL == $EXPECTED ] ||
20153                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20154 }
20155
20156 test_204a() {
20157         test_mkdir $DIR/$tdir
20158         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20159
20160         check_default_stripe_attr --stripe-count
20161         check_default_stripe_attr --stripe-size
20162         check_default_stripe_attr --stripe-index
20163 }
20164 run_test 204a "Print default stripe attributes"
20165
20166 test_204b() {
20167         test_mkdir $DIR/$tdir
20168         $LFS setstripe --stripe-count 1 $DIR/$tdir
20169
20170         check_default_stripe_attr --stripe-size
20171         check_default_stripe_attr --stripe-index
20172 }
20173 run_test 204b "Print default stripe size and offset"
20174
20175 test_204c() {
20176         test_mkdir $DIR/$tdir
20177         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20178
20179         check_default_stripe_attr --stripe-count
20180         check_default_stripe_attr --stripe-index
20181 }
20182 run_test 204c "Print default stripe count and offset"
20183
20184 test_204d() {
20185         test_mkdir $DIR/$tdir
20186         $LFS setstripe --stripe-index 0 $DIR/$tdir
20187
20188         check_default_stripe_attr --stripe-count
20189         check_default_stripe_attr --stripe-size
20190 }
20191 run_test 204d "Print default stripe count and size"
20192
20193 test_204e() {
20194         test_mkdir $DIR/$tdir
20195         $LFS setstripe -d $DIR/$tdir
20196
20197         # LU-16904 check if root is set as PFL layout
20198         local numcomp=$($LFS getstripe --component-count $MOUNT)
20199
20200         if [[ $numcomp -gt 0 ]]; then
20201                 check_default_stripe_attr --stripe-count
20202         else
20203                 check_default_stripe_attr --stripe-count --raw
20204         fi
20205         check_default_stripe_attr --stripe-size --raw
20206         check_default_stripe_attr --stripe-index --raw
20207 }
20208 run_test 204e "Print raw stripe attributes"
20209
20210 test_204f() {
20211         test_mkdir $DIR/$tdir
20212         $LFS setstripe --stripe-count 1 $DIR/$tdir
20213
20214         check_default_stripe_attr --stripe-size --raw
20215         check_default_stripe_attr --stripe-index --raw
20216 }
20217 run_test 204f "Print raw stripe size and offset"
20218
20219 test_204g() {
20220         test_mkdir $DIR/$tdir
20221         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20222
20223         check_default_stripe_attr --stripe-count --raw
20224         check_default_stripe_attr --stripe-index --raw
20225 }
20226 run_test 204g "Print raw stripe count and offset"
20227
20228 test_204h() {
20229         test_mkdir $DIR/$tdir
20230         $LFS setstripe --stripe-index 0 $DIR/$tdir
20231
20232         check_default_stripe_attr --stripe-count --raw
20233         check_default_stripe_attr --stripe-size --raw
20234 }
20235 run_test 204h "Print raw stripe count and size"
20236
20237 # Figure out which job scheduler is being used, if any,
20238 # or use a fake one
20239 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20240         JOBENV=SLURM_JOB_ID
20241 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20242         JOBENV=LSB_JOBID
20243 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20244         JOBENV=PBS_JOBID
20245 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20246         JOBENV=LOADL_STEP_ID
20247 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20248         JOBENV=JOB_ID
20249 else
20250         $LCTL list_param jobid_name > /dev/null 2>&1
20251         if [ $? -eq 0 ]; then
20252                 JOBENV=nodelocal
20253         else
20254                 JOBENV=FAKE_JOBID
20255         fi
20256 fi
20257 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20258
20259 verify_jobstats() {
20260         local cmd=($1)
20261         shift
20262         local facets="$@"
20263
20264 # we don't really need to clear the stats for this test to work, since each
20265 # command has a unique jobid, but it makes debugging easier if needed.
20266 #       for facet in $facets; do
20267 #               local dev=$(convert_facet2label $facet)
20268 #               # clear old jobstats
20269 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20270 #       done
20271
20272         # use a new JobID for each test, or we might see an old one
20273         [ "$JOBENV" = "FAKE_JOBID" ] &&
20274                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20275
20276         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20277
20278         [ "$JOBENV" = "nodelocal" ] && {
20279                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20280                 $LCTL set_param jobid_name=$FAKE_JOBID
20281                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20282         }
20283
20284         log "Test: ${cmd[*]}"
20285         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20286
20287         if [ $JOBENV = "FAKE_JOBID" ]; then
20288                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20289         else
20290                 ${cmd[*]}
20291         fi
20292
20293         # all files are created on OST0000
20294         for facet in $facets; do
20295                 local stats="*.$(convert_facet2label $facet).job_stats"
20296
20297                 # strip out libtool wrappers for in-tree executables
20298                 if (( $(do_facet $facet lctl get_param $stats |
20299                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20300                         do_facet $facet lctl get_param $stats
20301                         error "No jobstats for $JOBVAL found on $facet::$stats"
20302                 fi
20303         done
20304 }
20305
20306 jobstats_set() {
20307         local new_jobenv=$1
20308
20309         set_persistent_param_and_check client "jobid_var" \
20310                 "$FSNAME.sys.jobid_var" $new_jobenv
20311 }
20312
20313 test_205a() { # Job stats
20314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20315         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20316                 skip "Need MDS version with at least 2.7.1"
20317         remote_mgs_nodsh && skip "remote MGS with nodsh"
20318         remote_mds_nodsh && skip "remote MDS with nodsh"
20319         remote_ost_nodsh && skip "remote OST with nodsh"
20320         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20321                 skip "Server doesn't support jobstats"
20322         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20323
20324         local old_jobenv=$($LCTL get_param -n jobid_var)
20325         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20326         stack_trap "jobstats_set $old_jobenv" EXIT
20327
20328         changelog_register
20329
20330         local old_jobid_name=$($LCTL get_param jobid_name)
20331         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20332
20333         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20334                                 mdt.*.job_cleanup_interval | head -n 1)
20335         local new_interval=5
20336         do_facet $SINGLEMDS \
20337                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20338         stack_trap "do_facet $SINGLEMDS \
20339                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20340         local start=$SECONDS
20341
20342         local cmd
20343         # mkdir
20344         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20345         verify_jobstats "$cmd" "$SINGLEMDS"
20346         # rmdir
20347         cmd="rmdir $DIR/$tdir"
20348         verify_jobstats "$cmd" "$SINGLEMDS"
20349         # mkdir on secondary MDT
20350         if [ $MDSCOUNT -gt 1 ]; then
20351                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20352                 verify_jobstats "$cmd" "mds2"
20353         fi
20354         # mknod
20355         cmd="mknod $DIR/$tfile c 1 3"
20356         verify_jobstats "$cmd" "$SINGLEMDS"
20357         # unlink
20358         cmd="rm -f $DIR/$tfile"
20359         verify_jobstats "$cmd" "$SINGLEMDS"
20360         # create all files on OST0000 so verify_jobstats can find OST stats
20361         # open & close
20362         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20363         verify_jobstats "$cmd" "$SINGLEMDS"
20364         # setattr
20365         cmd="touch $DIR/$tfile"
20366         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20367         # write
20368         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20369         verify_jobstats "$cmd" "ost1"
20370         # read
20371         cancel_lru_locks osc
20372         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20373         verify_jobstats "$cmd" "ost1"
20374         # truncate
20375         cmd="$TRUNCATE $DIR/$tfile 0"
20376         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20377         # rename
20378         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20379         verify_jobstats "$cmd" "$SINGLEMDS"
20380         # jobstats expiry - sleep until old stats should be expired
20381         local left=$((new_interval + 5 - (SECONDS - start)))
20382         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20383                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20384                         "0" $left
20385         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20386         verify_jobstats "$cmd" "$SINGLEMDS"
20387         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20388             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20389
20390         # Ensure that jobid are present in changelog (if supported by MDS)
20391         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20392                 changelog_dump | tail -10
20393                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20394                 [ $jobids -eq 9 ] ||
20395                         error "Wrong changelog jobid count $jobids != 9"
20396
20397                 # LU-5862
20398                 JOBENV="disable"
20399                 jobstats_set $JOBENV
20400                 touch $DIR/$tfile
20401                 changelog_dump | grep $tfile
20402                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20403                 [ $jobids -eq 0 ] ||
20404                         error "Unexpected jobids when jobid_var=$JOBENV"
20405         fi
20406
20407         # test '%j' access to environment variable - if supported
20408         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20409                 JOBENV="JOBCOMPLEX"
20410                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20411
20412                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20413         fi
20414
20415         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20416                 JOBENV="JOBCOMPLEX"
20417                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20418
20419                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20420         fi
20421
20422         # test '%j' access to per-session jobid - if supported
20423         if lctl list_param jobid_this_session > /dev/null 2>&1
20424         then
20425                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20426                 lctl set_param jobid_this_session=$USER
20427
20428                 JOBENV="JOBCOMPLEX"
20429                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20430
20431                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20432         fi
20433 }
20434 run_test 205a "Verify job stats"
20435
20436 # LU-13117, LU-13597, LU-16599
20437 test_205b() {
20438         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20439                 skip "Need MDS version at least 2.13.54.91"
20440
20441         local job_stats="mdt.*.job_stats"
20442         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20443
20444         do_facet mds1 $LCTL set_param $job_stats=clear
20445
20446         # Setting jobid_var to USER might not be supported
20447         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20448         $LCTL set_param jobid_var=USER || true
20449         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20450         $LCTL set_param jobid_name="%j.%e.%u"
20451
20452         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20453         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20454                 { do_facet mds1 $LCTL get_param $job_stats;
20455                   error "Unexpected jobid found"; }
20456         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20457                 { do_facet mds1 $LCTL get_param $job_stats;
20458                   error "wrong job_stats format found"; }
20459
20460         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20461                 echo "MDS does not yet escape jobid" && return 0
20462
20463         mkdir_on_mdt0 $DIR/$tdir
20464         $LCTL set_param jobid_var=TEST205b
20465         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20466         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20467                       awk '/has\\x20sp/ {print $3}')
20468         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20469                   error "jobid not escaped"; }
20470
20471         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20472                 # need to run such a command on mds1:
20473                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20474                 #
20475                 # there might be multiple MDTs on single mds server, so need to
20476                 # specifiy MDT0000. Or the command will fail due to other MDTs
20477                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20478                         error "cannot clear escaped jobid in job_stats";
20479         else
20480                 echo "MDS does not support clearing escaped jobid"
20481         fi
20482 }
20483 run_test 205b "Verify job stats jobid and output format"
20484
20485 # LU-13733
20486 test_205c() {
20487         $LCTL set_param llite.*.stats=0
20488         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20489         $LCTL get_param llite.*.stats
20490         $LCTL get_param llite.*.stats | grep \
20491                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20492                         error "wrong client stats format found"
20493 }
20494 run_test 205c "Verify client stats format"
20495
20496 test_205d() {
20497         local file=$DIR/$tdir/$tfile
20498
20499         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20500                 skip "need lustre >= 2.15.53 for lljobstat"
20501         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20502                 skip "need lustre >= 2.15.53 for lljobstat"
20503         verify_yaml_available || skip_env "YAML verification not installed"
20504
20505         test_mkdir -i 0 $DIR/$tdir
20506         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20507         stack_trap "rm -rf $DIR/$tdir"
20508
20509         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20510                 error "failed to write data to $file"
20511         mv $file $file.2
20512
20513         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20514         echo -n 'verify rename_stats...'
20515         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20516                 verify_yaml || error "rename_stats is not valid YAML"
20517         echo " OK"
20518
20519         echo -n 'verify mdt job_stats...'
20520         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20521                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20522         echo " OK"
20523
20524         echo -n 'verify ost job_stats...'
20525         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20526                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20527         echo " OK"
20528 }
20529 run_test 205d "verify the format of some stats files"
20530
20531 test_205e() {
20532         local ops_comma
20533         local file=$DIR/$tdir/$tfile
20534         local -a cli_params
20535
20536         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20537                 skip "need lustre >= 2.15.53 for lljobstat"
20538         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20539                 skip "need lustre >= 2.15.53 for lljobstat"
20540         verify_yaml_available || skip_env "YAML verification not installed"
20541
20542         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20543         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20544         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20545
20546         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20547         stack_trap "rm -rf $DIR/$tdir"
20548
20549         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20550                 error "failed to create $file on ost1"
20551         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20552                 error "failed to write data to $file"
20553
20554         do_facet mds1 "$LCTL get_param *.*.job_stats"
20555         do_facet ost1 "$LCTL get_param *.*.job_stats"
20556
20557         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20558         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20559                 error "The output of lljobstat is not an valid YAML"
20560
20561         # verify that job dd.0 does exist and has some ops on ost1
20562         # typically this line is like:
20563         # - 205e.dd.0:            {ops: 20, ...}
20564         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20565                     awk '$2=="205e.dd.0:" {print $4}')
20566
20567         (( ${ops_comma%,} >= 10 )) ||
20568                 error "cannot find job 205e.dd.0 with ops >= 10"
20569 }
20570 run_test 205e "verify the output of lljobstat"
20571
20572 test_205f() {
20573         verify_yaml_available || skip_env "YAML verification not installed"
20574
20575         # check both qos_ost_weights and qos_mdt_weights
20576         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20577         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20578                 error "qos_ost_weights is not valid YAML"
20579 }
20580 run_test 205f "verify qos_ost_weights YAML format "
20581
20582 __test_205_jobstats_dump() {
20583         local -a pids
20584         local nbr_instance=$1
20585
20586         while true; do
20587                 if (( ${#pids[@]} >= nbr_instance )); then
20588                         wait ${pids[@]}
20589                         pids=()
20590                 fi
20591
20592                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20593                 pids+=( $! )
20594         done
20595 }
20596
20597 __test_205_cleanup() {
20598         kill $@
20599         # Clear all job entries
20600         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20601 }
20602
20603 test_205g() {
20604         local -a mds1_params
20605         local -a cli_params
20606         local pids
20607         local interval=5
20608
20609         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20610         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20611         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20612
20613         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20614         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20615         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20616
20617         # start jobs loop
20618         export TEST205G_ID=205g
20619         stack_trap "unset TEST205G_ID" EXIT
20620         while true; do
20621                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20622         done & pids="$! "
20623
20624         __test_205_jobstats_dump 4 & pids+="$! "
20625         stack_trap "__test_205_cleanup $pids" EXIT INT
20626
20627         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20628 }
20629 run_test 205g "stress test for job_stats procfile"
20630
20631 test_205h() {
20632         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20633                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20634         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20635
20636         local dir=$DIR/$tdir
20637         local f=$dir/$tfile
20638         local f2=$dir/$tfile-2
20639         local f3=$dir/$tfile-3
20640         local subdir=$DIR/dir
20641         local val
20642
20643         local mdts=$(comma_list $(mdts_nodes))
20644         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20645         local client_saved=$($LCTL get_param -n jobid_var)
20646
20647         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20648         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20649
20650         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20651                 error "failed to set job_xattr parameter to user.job"
20652         $LCTL set_param jobid_var=procname.uid ||
20653                 error "failed to set jobid_var parameter"
20654
20655         test_mkdir $dir
20656
20657         touch $f
20658         val=$(getfattr -n user.job $f | grep user.job)
20659         [[ $val = user.job=\"touch.0\" ]] ||
20660                 error "expected user.job=\"touch.0\", got '$val'"
20661
20662         mkdir $subdir
20663         val=$(getfattr -n user.job $subdir | grep user.job)
20664         [[ $val = user.job=\"mkdir.0\" ]] ||
20665                 error "expected user.job=\"mkdir.0\", got '$val'"
20666
20667         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20668                 error "failed to set job_xattr parameter to NONE"
20669
20670         touch $f2
20671         val=$(getfattr -d $f2)
20672         [[ -z $val ]] ||
20673                 error "expected no user xattr, got '$val'"
20674
20675         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20676                 error "failed to set job_xattr parameter to trusted.job"
20677
20678         touch $f3
20679         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20680         [[ $val = trusted.job=\"touch.0\" ]] ||
20681                 error "expected trusted.job=\"touch.0\", got '$val'"
20682 }
20683 run_test 205h "check jobid xattr is stored correctly"
20684
20685 test_205i() {
20686         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20687                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20688
20689         local mdts=$(comma_list $(mdts_nodes))
20690         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20691
20692         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20693
20694         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20695                 error "failed to set mdt.*.job_xattr to user.1234567"
20696
20697         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20698                 error "failed to reject too long job_xattr name"
20699
20700         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20701                 error "failed to reject job_xattr name in bad format"
20702
20703         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20704                 error "failed to reject job_xattr name with invalid character"
20705
20706         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20707                         xargs $LCTL set_param" &&
20708                 error "failed to reject job_xattr name with non-ascii character"
20709
20710         return 0
20711 }
20712 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20713
20714 # LU-1480, LU-1773 and LU-1657
20715 test_206() {
20716         mkdir -p $DIR/$tdir
20717         $LFS setstripe -c -1 $DIR/$tdir
20718 #define OBD_FAIL_LOV_INIT 0x1403
20719         $LCTL set_param fail_loc=0xa0001403
20720         $LCTL set_param fail_val=1
20721         touch $DIR/$tdir/$tfile || true
20722 }
20723 run_test 206 "fail lov_init_raid0() doesn't lbug"
20724
20725 test_207a() {
20726         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20727         local fsz=`stat -c %s $DIR/$tfile`
20728         cancel_lru_locks mdc
20729
20730         # do not return layout in getattr intent
20731 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20732         $LCTL set_param fail_loc=0x170
20733         local sz=`stat -c %s $DIR/$tfile`
20734
20735         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20736
20737         rm -rf $DIR/$tfile
20738 }
20739 run_test 207a "can refresh layout at glimpse"
20740
20741 test_207b() {
20742         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20743         local cksum=`md5sum $DIR/$tfile`
20744         local fsz=`stat -c %s $DIR/$tfile`
20745         cancel_lru_locks mdc
20746         cancel_lru_locks osc
20747
20748         # do not return layout in getattr intent
20749 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20750         $LCTL set_param fail_loc=0x171
20751
20752         # it will refresh layout after the file is opened but before read issues
20753         echo checksum is "$cksum"
20754         echo "$cksum" |md5sum -c --quiet || error "file differs"
20755
20756         rm -rf $DIR/$tfile
20757 }
20758 run_test 207b "can refresh layout at open"
20759
20760 test_208() {
20761         # FIXME: in this test suite, only RD lease is used. This is okay
20762         # for now as only exclusive open is supported. After generic lease
20763         # is done, this test suite should be revised. - Jinshan
20764
20765         remote_mds_nodsh && skip "remote MDS with nodsh"
20766         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20767                 skip "Need MDS version at least 2.4.52"
20768
20769         echo "==== test 1: verify get lease work"
20770         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20771
20772         echo "==== test 2: verify lease can be broken by upcoming open"
20773         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20774         local PID=$!
20775         sleep 2
20776
20777         $MULTIOP $DIR/$tfile oO_RDWR:c
20778         kill -USR1 $PID && wait $PID || error "break lease error"
20779
20780         echo "==== test 3: verify lease can't be granted if an open already exists"
20781         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20782         local PID=$!
20783         sleep 2
20784
20785         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20786         kill -USR1 $PID && wait $PID || error "open file error"
20787
20788         echo "==== test 4: lease can sustain over recovery"
20789         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20790         PID=$!
20791         sleep 2
20792
20793         fail mds1
20794
20795         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20796
20797         echo "==== test 5: lease broken can't be regained by replay"
20798         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20799         PID=$!
20800         sleep 2
20801
20802         # open file to break lease and then recovery
20803         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20804         fail mds1
20805
20806         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20807
20808         rm -f $DIR/$tfile
20809 }
20810 run_test 208 "Exclusive open"
20811
20812 test_209() {
20813         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20814                 skip_env "must have disp_stripe"
20815
20816         touch $DIR/$tfile
20817         sync; sleep 5; sync;
20818
20819         echo 3 > /proc/sys/vm/drop_caches
20820         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20821                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20822         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20823
20824         # open/close 500 times
20825         for i in $(seq 500); do
20826                 cat $DIR/$tfile
20827         done
20828
20829         echo 3 > /proc/sys/vm/drop_caches
20830         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20831                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20832         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20833
20834         echo "before: $req_before, after: $req_after"
20835         [ $((req_after - req_before)) -ge 300 ] &&
20836                 error "open/close requests are not freed"
20837         return 0
20838 }
20839 run_test 209 "read-only open/close requests should be freed promptly"
20840
20841 test_210() {
20842         local pid
20843
20844         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20845         pid=$!
20846         sleep 1
20847
20848         $LFS getstripe $DIR/$tfile
20849         kill -USR1 $pid
20850         wait $pid || error "multiop failed"
20851
20852         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20853         pid=$!
20854         sleep 1
20855
20856         $LFS getstripe $DIR/$tfile
20857         kill -USR1 $pid
20858         wait $pid || error "multiop failed"
20859 }
20860 run_test 210 "lfs getstripe does not break leases"
20861
20862 function test_211() {
20863         local PID
20864         local id
20865         local rc
20866
20867         stack_trap "rm -f $DIR/$tfile" EXIT
20868         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20869                 error "can't create file"
20870         $LFS mirror extend -N $DIR/$tfile ||
20871                 error "can't create a replica"
20872         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20873         $LFS getstripe $DIR/$tfile
20874         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20875         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20876
20877         $MULTIOP $DIR/$tfile OeW_E+eUc &
20878         PID=$!
20879         sleep 0.3
20880
20881         id=$($LFS getstripe $DIR/$tfile |
20882                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20883         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20884                 error "removed last in-sync replica?"
20885
20886         kill -USR1 $PID
20887         wait $PID
20888         (( $? == 0 )) || error "failed split broke the lease"
20889 }
20890 run_test 211 "failed mirror split doesn't break write lease"
20891
20892 test_212() {
20893         size=`date +%s`
20894         size=$((size % 8192 + 1))
20895         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20896         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20897         rm -f $DIR/f212 $DIR/f212.xyz
20898 }
20899 run_test 212 "Sendfile test ============================================"
20900
20901 test_213() {
20902         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20903         cancel_lru_locks osc
20904         lctl set_param fail_loc=0x8000040f
20905         # generate a read lock
20906         cat $DIR/$tfile > /dev/null
20907         # write to the file, it will try to cancel the above read lock.
20908         cat /etc/hosts >> $DIR/$tfile
20909 }
20910 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20911
20912 test_214() { # for bug 20133
20913         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20914         for (( i=0; i < 340; i++ )) ; do
20915                 touch $DIR/$tdir/d214c/a$i
20916         done
20917
20918         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20919         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20920         ls $DIR/d214c || error "ls $DIR/d214c failed"
20921         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20922         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20923 }
20924 run_test 214 "hash-indexed directory test - bug 20133"
20925
20926 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20927 create_lnet_proc_files() {
20928         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20929 }
20930
20931 # counterpart of create_lnet_proc_files
20932 remove_lnet_proc_files() {
20933         rm -f $TMP/lnet_$1.sys
20934 }
20935
20936 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20937 # 3rd arg as regexp for body
20938 check_lnet_proc_stats() {
20939         local l=$(cat "$TMP/lnet_$1" |wc -l)
20940         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20941
20942         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20943 }
20944
20945 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20946 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20947 # optional and can be regexp for 2nd line (lnet.routes case)
20948 check_lnet_proc_entry() {
20949         local blp=2          # blp stands for 'position of 1st line of body'
20950         [ -z "$5" ] || blp=3 # lnet.routes case
20951
20952         local l=$(cat "$TMP/lnet_$1" |wc -l)
20953         # subtracting one from $blp because the body can be empty
20954         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20955
20956         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20957                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20958
20959         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20960                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20961
20962         # bail out if any unexpected line happened
20963         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20964         [ "$?" != 0 ] || error "$2 misformatted"
20965 }
20966
20967 test_215() { # for bugs 18102, 21079, 21517
20968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20969
20970         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20971         local P='[1-9][0-9]*'           # positive numeric
20972         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20973         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20974         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20975         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20976
20977         local L1 # regexp for 1st line
20978         local L2 # regexp for 2nd line (optional)
20979         local BR # regexp for the rest (body)
20980
20981         # lnet.stats should look as 11 space-separated non-negative numerics
20982         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20983         create_lnet_proc_files "stats"
20984         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20985         remove_lnet_proc_files "stats"
20986
20987         # lnet.routes should look like this:
20988         # Routing disabled/enabled
20989         # net hops priority state router
20990         # where net is a string like tcp0, hops > 0, priority >= 0,
20991         # state is up/down,
20992         # router is a string like 192.168.1.1@tcp2
20993         L1="^Routing (disabled|enabled)$"
20994         L2="^net +hops +priority +state +router$"
20995         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20996         create_lnet_proc_files "routes"
20997         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20998         remove_lnet_proc_files "routes"
20999
21000         # lnet.routers should look like this:
21001         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21002         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21003         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21004         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21005         L1="^ref +rtr_ref +alive +router$"
21006         BR="^$P +$P +(up|down) +$NID$"
21007         create_lnet_proc_files "routers"
21008         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21009         remove_lnet_proc_files "routers"
21010
21011         # lnet.peers should look like this:
21012         # nid refs state last max rtr min tx min queue
21013         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21014         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21015         # numeric (0 or >0 or <0), queue >= 0.
21016         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21017         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21018         create_lnet_proc_files "peers"
21019         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21020         remove_lnet_proc_files "peers"
21021
21022         # lnet.buffers  should look like this:
21023         # pages count credits min
21024         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21025         L1="^pages +count +credits +min$"
21026         BR="^ +$N +$N +$I +$I$"
21027         create_lnet_proc_files "buffers"
21028         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21029         remove_lnet_proc_files "buffers"
21030
21031         # lnet.nis should look like this:
21032         # nid status alive refs peer rtr max tx min
21033         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21034         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21035         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21036         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21037         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21038         create_lnet_proc_files "nis"
21039         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21040         remove_lnet_proc_files "nis"
21041
21042         # can we successfully write to lnet.stats?
21043         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21044 }
21045 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21046
21047 test_216() { # bug 20317
21048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21049         remote_ost_nodsh && skip "remote OST with nodsh"
21050
21051         local node
21052         local facets=$(get_facets OST)
21053         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21054
21055         save_lustre_params client "osc.*.contention_seconds" > $p
21056         save_lustre_params $facets \
21057                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21058         save_lustre_params $facets \
21059                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21060         save_lustre_params $facets \
21061                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21062         clear_stats osc.*.osc_stats
21063
21064         # agressive lockless i/o settings
21065         do_nodes $(comma_list $(osts_nodes)) \
21066                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21067                         ldlm.namespaces.filter-*.contended_locks=0 \
21068                         ldlm.namespaces.filter-*.contention_seconds=60"
21069         lctl set_param -n osc.*.contention_seconds=60
21070
21071         $DIRECTIO write $DIR/$tfile 0 10 4096
21072         $CHECKSTAT -s 40960 $DIR/$tfile
21073
21074         # disable lockless i/o
21075         do_nodes $(comma_list $(osts_nodes)) \
21076                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21077                         ldlm.namespaces.filter-*.contended_locks=32 \
21078                         ldlm.namespaces.filter-*.contention_seconds=0"
21079         lctl set_param -n osc.*.contention_seconds=0
21080         clear_stats osc.*.osc_stats
21081
21082         dd if=/dev/zero of=$DIR/$tfile count=0
21083         $CHECKSTAT -s 0 $DIR/$tfile
21084
21085         restore_lustre_params <$p
21086         rm -f $p
21087         rm $DIR/$tfile
21088 }
21089 run_test 216 "check lockless direct write updates file size and kms correctly"
21090
21091 test_217() { # bug 22430
21092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21093
21094         local node
21095
21096         for node in $(nodes_list); do
21097                 local nid=$(host_nids_address $node $NETTYPE)
21098                 local node_ip=$(do_node $node getent ahostsv4 $node |
21099                                 awk '{ print $1; exit; }')
21100
21101                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21102                 # if hostname matches any NID, use hostname for better testing
21103                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21104                         echo "lctl ping node $node@$NETTYPE"
21105                         lctl ping $node@$NETTYPE
21106                 else # otherwise, at least test 'lctl ping' is working
21107                         echo "lctl ping nid $(h2nettype $nid)"
21108                         lctl ping $(h2nettype $nid)
21109                         echo "skipping $node (no hyphen detected)"
21110                 fi
21111         done
21112 }
21113 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21114
21115 test_218() {
21116         # do directio so as not to populate the page cache
21117         log "creating a 10 Mb file"
21118         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21119                 error "multiop failed while creating a file"
21120         log "starting reads"
21121         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21122         log "truncating the file"
21123         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21124                 error "multiop failed while truncating the file"
21125         log "killing dd"
21126         kill %+ || true # reads might have finished
21127         echo "wait until dd is finished"
21128         wait
21129         log "removing the temporary file"
21130         rm -rf $DIR/$tfile || error "tmp file removal failed"
21131 }
21132 run_test 218 "parallel read and truncate should not deadlock"
21133
21134 test_219() {
21135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21136
21137         # write one partial page
21138         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21139         # set no grant so vvp_io_commit_write will do sync write
21140         $LCTL set_param fail_loc=0x411
21141         # write a full page at the end of file
21142         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21143
21144         $LCTL set_param fail_loc=0
21145         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21146         $LCTL set_param fail_loc=0x411
21147         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21148
21149         # LU-4201
21150         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21151         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21152 }
21153 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21154
21155 test_220() { #LU-325
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         remote_ost_nodsh && skip "remote OST with nodsh"
21158         remote_mds_nodsh && skip "remote MDS with nodsh"
21159         remote_mgs_nodsh && skip "remote MGS with nodsh"
21160
21161         local OSTIDX=0
21162
21163         # create on MDT0000 so the last_id and next_id are correct
21164         mkdir_on_mdt0 $DIR/$tdir
21165         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21166         OST=${OST%_UUID}
21167
21168         # on the mdt's osc
21169         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21170         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21171                         osp.$mdtosc_proc1.prealloc_last_id)
21172         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21173                         osp.$mdtosc_proc1.prealloc_next_id)
21174
21175         $LFS df -i
21176
21177         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21178         #define OBD_FAIL_OST_ENOINO              0x229
21179         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21180         create_pool $FSNAME.$TESTNAME || return 1
21181         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21182
21183         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21184
21185         MDSOBJS=$((last_id - next_id))
21186         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21187
21188         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21189         echo "OST still has $count kbytes free"
21190
21191         echo "create $MDSOBJS files @next_id..."
21192         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21193
21194         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21195                         osp.$mdtosc_proc1.prealloc_last_id)
21196         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21197                         osp.$mdtosc_proc1.prealloc_next_id)
21198
21199         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21200         $LFS df -i
21201
21202         echo "cleanup..."
21203
21204         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21205         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21206
21207         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21208                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21209         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21210                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21211         echo "unlink $MDSOBJS files @$next_id..."
21212         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21213 }
21214 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21215
21216 test_221() {
21217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21218
21219         dd if=`which date` of=$MOUNT/date oflag=sync
21220         chmod +x $MOUNT/date
21221
21222         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21223         $LCTL set_param fail_loc=0x80001401
21224
21225         $MOUNT/date > /dev/null
21226         rm -f $MOUNT/date
21227 }
21228 run_test 221 "make sure fault and truncate race to not cause OOM"
21229
21230 test_222a () {
21231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21232
21233         rm -rf $DIR/$tdir
21234         test_mkdir $DIR/$tdir
21235         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21236         createmany -o $DIR/$tdir/$tfile 10
21237         cancel_lru_locks mdc
21238         cancel_lru_locks osc
21239         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21240         $LCTL set_param fail_loc=0x31a
21241         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21242         $LCTL set_param fail_loc=0
21243         rm -r $DIR/$tdir
21244 }
21245 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21246
21247 test_222b () {
21248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21249
21250         rm -rf $DIR/$tdir
21251         test_mkdir $DIR/$tdir
21252         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21253         createmany -o $DIR/$tdir/$tfile 10
21254         cancel_lru_locks mdc
21255         cancel_lru_locks osc
21256         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21257         $LCTL set_param fail_loc=0x31a
21258         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21259         $LCTL set_param fail_loc=0
21260 }
21261 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21262
21263 test_223 () {
21264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21265
21266         rm -rf $DIR/$tdir
21267         test_mkdir $DIR/$tdir
21268         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21269         createmany -o $DIR/$tdir/$tfile 10
21270         cancel_lru_locks mdc
21271         cancel_lru_locks osc
21272         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21273         $LCTL set_param fail_loc=0x31b
21274         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21275         $LCTL set_param fail_loc=0
21276         rm -r $DIR/$tdir
21277 }
21278 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21279
21280 test_224a() { # LU-1039, MRP-303
21281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21282         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21283         $LCTL set_param fail_loc=0x508
21284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21285         $LCTL set_param fail_loc=0
21286         df $DIR
21287 }
21288 run_test 224a "Don't panic on bulk IO failure"
21289
21290 test_224bd_sub() { # LU-1039, MRP-303
21291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21292         local timeout=$1
21293
21294         shift
21295         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21296
21297         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21298
21299         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21300         cancel_lru_locks osc
21301         set_checksums 0
21302         stack_trap "set_checksums $ORIG_CSUM" EXIT
21303         local at_max_saved=0
21304
21305         # adaptive timeouts may prevent seeing the issue
21306         if at_is_enabled; then
21307                 at_max_saved=$(at_max_get mds)
21308                 at_max_set 0 mds client
21309                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21310         fi
21311
21312         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21313         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21314         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21315
21316         do_facet ost1 $LCTL set_param fail_loc=0
21317         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21318         df $DIR
21319 }
21320
21321 test_224b() {
21322         test_224bd_sub 3 error "dd failed"
21323 }
21324 run_test 224b "Don't panic on bulk IO failure"
21325
21326 test_224c() { # LU-6441
21327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21328         remote_mds_nodsh && skip "remote MDS with nodsh"
21329
21330         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21331         save_writethrough $p
21332         set_cache writethrough on
21333
21334         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21335         local at_max=$($LCTL get_param -n at_max)
21336         local timeout=$($LCTL get_param -n timeout)
21337         local test_at="at_max"
21338         local param_at="$FSNAME.sys.at_max"
21339         local test_timeout="timeout"
21340         local param_timeout="$FSNAME.sys.timeout"
21341
21342         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21343
21344         set_persistent_param_and_check client "$test_at" "$param_at" 0
21345         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21346
21347         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21348         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21349         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21350         stack_trap "rm -f $DIR/$tfile"
21351         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21352         sync
21353         do_facet ost1 "$LCTL set_param fail_loc=0"
21354
21355         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21356         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21357                 $timeout
21358
21359         $LCTL set_param -n $pages_per_rpc
21360         restore_lustre_params < $p
21361         rm -f $p
21362 }
21363 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21364
21365 test_224d() { # LU-11169
21366         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21367 }
21368 run_test 224d "Don't corrupt data on bulk IO timeout"
21369
21370 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21371 test_225a () {
21372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21373         if [ -z ${MDSSURVEY} ]; then
21374                 skip_env "mds-survey not found"
21375         fi
21376         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21377                 skip "Need MDS version at least 2.2.51"
21378
21379         local mds=$(facet_host $SINGLEMDS)
21380         local target=$(do_nodes $mds 'lctl dl' |
21381                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21382
21383         local cmd1="file_count=1000 thrhi=4"
21384         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21385         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21386         local cmd="$cmd1 $cmd2 $cmd3"
21387
21388         rm -f ${TMP}/mds_survey*
21389         echo + $cmd
21390         eval $cmd || error "mds-survey with zero-stripe failed"
21391         cat ${TMP}/mds_survey*
21392         rm -f ${TMP}/mds_survey*
21393 }
21394 run_test 225a "Metadata survey sanity with zero-stripe"
21395
21396 test_225b () {
21397         if [ -z ${MDSSURVEY} ]; then
21398                 skip_env "mds-survey not found"
21399         fi
21400         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21401                 skip "Need MDS version at least 2.2.51"
21402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21403         remote_mds_nodsh && skip "remote MDS with nodsh"
21404         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21405                 skip_env "Need to mount OST to test"
21406         fi
21407
21408         local mds=$(facet_host $SINGLEMDS)
21409         local target=$(do_nodes $mds 'lctl dl' |
21410                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21411
21412         local cmd1="file_count=1000 thrhi=4"
21413         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21414         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21415         local cmd="$cmd1 $cmd2 $cmd3"
21416
21417         rm -f ${TMP}/mds_survey*
21418         echo + $cmd
21419         eval $cmd || error "mds-survey with stripe_count failed"
21420         cat ${TMP}/mds_survey*
21421         rm -f ${TMP}/mds_survey*
21422 }
21423 run_test 225b "Metadata survey sanity with stripe_count = 1"
21424
21425 mcreate_path2fid () {
21426         local mode=$1
21427         local major=$2
21428         local minor=$3
21429         local name=$4
21430         local desc=$5
21431         local path=$DIR/$tdir/$name
21432         local fid
21433         local rc
21434         local fid_path
21435
21436         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21437                 error "cannot create $desc"
21438
21439         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21440         rc=$?
21441         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21442
21443         fid_path=$($LFS fid2path $MOUNT $fid)
21444         rc=$?
21445         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21446
21447         [ "$path" == "$fid_path" ] ||
21448                 error "fid2path returned $fid_path, expected $path"
21449
21450         echo "pass with $path and $fid"
21451 }
21452
21453 test_226a () {
21454         rm -rf $DIR/$tdir
21455         mkdir -p $DIR/$tdir
21456
21457         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21458         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21459         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21460         mcreate_path2fid 0040666 0 0 dir "directory"
21461         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21462         mcreate_path2fid 0100666 0 0 file "regular file"
21463         mcreate_path2fid 0120666 0 0 link "symbolic link"
21464         mcreate_path2fid 0140666 0 0 sock "socket"
21465 }
21466 run_test 226a "call path2fid and fid2path on files of all type"
21467
21468 test_226b () {
21469         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21470
21471         local MDTIDX=1
21472
21473         rm -rf $DIR/$tdir
21474         mkdir -p $DIR/$tdir
21475         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21476                 error "create remote directory failed"
21477         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21478         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21479                                 "character special file (null)"
21480         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21481                                 "character special file (no device)"
21482         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21483         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21484                                 "block special file (loop)"
21485         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21486         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21487         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21488 }
21489 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21490
21491 test_226c () {
21492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21493         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21494                 skip "Need MDS version at least 2.13.55"
21495
21496         local submnt=/mnt/submnt
21497         local srcfile=/etc/passwd
21498         local dstfile=$submnt/passwd
21499         local path
21500         local fid
21501
21502         rm -rf $DIR/$tdir
21503         rm -rf $submnt
21504         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21505                 error "create remote directory failed"
21506         mkdir -p $submnt || error "create $submnt failed"
21507         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21508                 error "mount $submnt failed"
21509         stack_trap "umount $submnt" EXIT
21510
21511         cp $srcfile $dstfile
21512         fid=$($LFS path2fid $dstfile)
21513         path=$($LFS fid2path $submnt "$fid")
21514         [ "$path" = "$dstfile" ] ||
21515                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21516 }
21517 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21518
21519 test_226d () {
21520         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21521                 skip "Need client at least version 2.15.57"
21522
21523         # Define First test dataset
21524         local testdirs_01=$DIR/$tdir
21525         local testdata_01=$testdirs_01/${tdir}_01
21526         local testresult_01=${tdir}_01
21527         # Define Second test dataset
21528         local testdirs_02=$DIR/$tdir/$tdir
21529         local testdata_02=$testdirs_02/${tdir}_02
21530         local testresult_02=${tdir}_02
21531         # Define third test dataset (top level)
21532         local testdata_03=$DIR/${tdir}_03
21533         local testresult_03=${tdir}_03
21534
21535         # Create first test dataset
21536         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21537         touch $testdata_01 || error "cannot create file $testdata_01"
21538
21539         # Create second test dataset
21540         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21541         touch $testdata_02 || error "cannot create file $testdata_02"
21542
21543         # Create third test dataset
21544         touch $testdata_03 || error "cannot create file $testdata_03"
21545
21546         local fid01=$($LFS getstripe -F "$testdata_01") ||
21547                 error "getstripe failed on $testdata_01"
21548         local fid02=$($LFS getstripe -F "$testdata_02") ||
21549                 error "getstripe failed on $testdata_01"
21550         local fid03=$($LFS getstripe -F "$testdata_03") ||
21551                 error "getstripe failed on $testdata_03"
21552
21553         # Verify only -n option
21554         local out1=$($LFS fid2path -n $DIR $fid01) ||
21555                 error "fid2path failed on $fid01"
21556         local out2=$($LFS fid2path -n $DIR $fid02) ||
21557                 error "fid2path failed on $fid02"
21558         local out3=$($LFS fid2path -n $DIR $fid03) ||
21559                 error "fid2path failed on $fid03"
21560
21561         [[ "$out1" == "$testresult_01" ]] ||
21562                 error "fid2path failed: Expected $testresult_01 got $out1"
21563         [[ "$out2" == "$testresult_02" ]] ||
21564                 error "fid2path failed: Expected $testresult_02 got $out2"
21565         [[ "$out3" == "$testresult_03" ]] ||
21566                 error "fid2path failed: Expected $testresult_03 got $out3"
21567
21568         # Verify with option -fn together
21569         out1=$($LFS fid2path -fn $DIR $fid01) ||
21570                 error "fid2path -fn failed on $fid01"
21571         out2=$($LFS fid2path -fn $DIR $fid02) ||
21572                 error "fid2path -fn failed on $fid02"
21573         out3=$($LFS fid2path -fn $DIR $fid03) ||
21574                 error "fid2path -fn failed on $fid03"
21575
21576         local tmpout=$(echo $out1 | cut -d" " -f2)
21577         [[ "$tmpout" == "$testresult_01" ]] ||
21578                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21579
21580         tmpout=$(echo $out2 | cut -d" " -f2)
21581         [[ "$tmpout" == "$testresult_02" ]] ||
21582                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21583
21584         tmpout=$(echo $out3 | cut -d" " -f2)
21585         [[ "$tmpout" == "$testresult_03" ]] ||
21586                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21587 }
21588 run_test 226d "verify fid2path with -n and -fn option"
21589
21590 test_226e () {
21591         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21592                 skip "Need client at least version 2.15.56"
21593
21594         # Define filename with 'newline' and a space
21595         local testfile="Test"$'\n'"file 01"
21596         # Define link name with multiple 'newline' and a space
21597         local linkfile="Link"$'\n'"file "$'\n'"01"
21598         # Remove prior hard link
21599         rm -f $DIR/"$linkfile"
21600
21601         # Create file
21602         touch $DIR/"$testfile"
21603         # Create link
21604         ln $DIR/"$testfile" $DIR/"$linkfile"
21605
21606         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21607                 error "getstripe failed on $DIR/$testfile"
21608
21609         # Call with -0 option
21610         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21611                 echo "FILE:" | grep -c "FILE:")
21612
21613         # With -0 option the output should be exactly 2 lines.
21614         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21615 }
21616 run_test 226e "Verify path2fid -0 option with newline and space"
21617
21618 # LU-1299 Executing or running ldd on a truncated executable does not
21619 # cause an out-of-memory condition.
21620 test_227() {
21621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21622         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21623
21624         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21625         chmod +x $MOUNT/date
21626
21627         $MOUNT/date > /dev/null
21628         ldd $MOUNT/date > /dev/null
21629         rm -f $MOUNT/date
21630 }
21631 run_test 227 "running truncated executable does not cause OOM"
21632
21633 # LU-1512 try to reuse idle OI blocks
21634 test_228a() {
21635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21636         remote_mds_nodsh && skip "remote MDS with nodsh"
21637         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21638
21639         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21640         local myDIR=$DIR/$tdir
21641
21642         mkdir -p $myDIR
21643         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21644         $LCTL set_param fail_loc=0x80001002
21645         createmany -o $myDIR/t- 10000
21646         $LCTL set_param fail_loc=0
21647         # The guard is current the largest FID holder
21648         touch $myDIR/guard
21649         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21650                     tr -d '[')
21651         local IDX=$(($SEQ % 64))
21652
21653         do_facet $SINGLEMDS sync
21654         # Make sure journal flushed.
21655         sleep 6
21656         local blk1=$(do_facet $SINGLEMDS \
21657                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21658                      grep Blockcount | awk '{print $4}')
21659
21660         # Remove old files, some OI blocks will become idle.
21661         unlinkmany $myDIR/t- 10000
21662         # Create new files, idle OI blocks should be reused.
21663         createmany -o $myDIR/t- 2000
21664         do_facet $SINGLEMDS sync
21665         # Make sure journal flushed.
21666         sleep 6
21667         local blk2=$(do_facet $SINGLEMDS \
21668                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21669                      grep Blockcount | awk '{print $4}')
21670
21671         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21672 }
21673 run_test 228a "try to reuse idle OI blocks"
21674
21675 test_228b() {
21676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21677         remote_mds_nodsh && skip "remote MDS with nodsh"
21678         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21679
21680         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21681         local myDIR=$DIR/$tdir
21682
21683         mkdir -p $myDIR
21684         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21685         $LCTL set_param fail_loc=0x80001002
21686         createmany -o $myDIR/t- 10000
21687         $LCTL set_param fail_loc=0
21688         # The guard is current the largest FID holder
21689         touch $myDIR/guard
21690         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21691                     tr -d '[')
21692         local IDX=$(($SEQ % 64))
21693
21694         do_facet $SINGLEMDS sync
21695         # Make sure journal flushed.
21696         sleep 6
21697         local blk1=$(do_facet $SINGLEMDS \
21698                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21699                      grep Blockcount | awk '{print $4}')
21700
21701         # Remove old files, some OI blocks will become idle.
21702         unlinkmany $myDIR/t- 10000
21703
21704         # stop the MDT
21705         stop $SINGLEMDS || error "Fail to stop MDT."
21706         # remount the MDT
21707         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21708                 error "Fail to start MDT."
21709
21710         client_up || error "Fail to df."
21711         # Create new files, idle OI blocks should be reused.
21712         createmany -o $myDIR/t- 2000
21713         do_facet $SINGLEMDS sync
21714         # Make sure journal flushed.
21715         sleep 6
21716         local blk2=$(do_facet $SINGLEMDS \
21717                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21718                      grep Blockcount | awk '{print $4}')
21719
21720         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21721 }
21722 run_test 228b "idle OI blocks can be reused after MDT restart"
21723
21724 #LU-1881
21725 test_228c() {
21726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21727         remote_mds_nodsh && skip "remote MDS with nodsh"
21728         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21729
21730         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21731         local myDIR=$DIR/$tdir
21732
21733         mkdir -p $myDIR
21734         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21735         $LCTL set_param fail_loc=0x80001002
21736         # 20000 files can guarantee there are index nodes in the OI file
21737         createmany -o $myDIR/t- 20000
21738         $LCTL set_param fail_loc=0
21739         # The guard is current the largest FID holder
21740         touch $myDIR/guard
21741         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21742                     tr -d '[')
21743         local IDX=$(($SEQ % 64))
21744
21745         do_facet $SINGLEMDS sync
21746         # Make sure journal flushed.
21747         sleep 6
21748         local blk1=$(do_facet $SINGLEMDS \
21749                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21750                      grep Blockcount | awk '{print $4}')
21751
21752         # Remove old files, some OI blocks will become idle.
21753         unlinkmany $myDIR/t- 20000
21754         rm -f $myDIR/guard
21755         # The OI file should become empty now
21756
21757         # Create new files, idle OI blocks should be reused.
21758         createmany -o $myDIR/t- 2000
21759         do_facet $SINGLEMDS sync
21760         # Make sure journal flushed.
21761         sleep 6
21762         local blk2=$(do_facet $SINGLEMDS \
21763                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21764                      grep Blockcount | awk '{print $4}')
21765
21766         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21767 }
21768 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21769
21770 test_229() { # LU-2482, LU-3448
21771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21772         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21773         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21774                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21775
21776         rm -f $DIR/$tfile
21777
21778         # Create a file with a released layout and stripe count 2.
21779         $MULTIOP $DIR/$tfile H2c ||
21780                 error "failed to create file with released layout"
21781
21782         $LFS getstripe -v $DIR/$tfile
21783
21784         local pattern=$($LFS getstripe -L $DIR/$tfile)
21785         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21786
21787         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21788                 error "getstripe"
21789         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21790         stat $DIR/$tfile || error "failed to stat released file"
21791
21792         chown $RUNAS_ID $DIR/$tfile ||
21793                 error "chown $RUNAS_ID $DIR/$tfile failed"
21794
21795         chgrp $RUNAS_ID $DIR/$tfile ||
21796                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21797
21798         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21799         rm $DIR/$tfile || error "failed to remove released file"
21800 }
21801 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21802
21803 test_230a() {
21804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21806         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21807                 skip "Need MDS version at least 2.11.52"
21808
21809         local MDTIDX=1
21810
21811         test_mkdir $DIR/$tdir
21812         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21813         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21814         [ $mdt_idx -ne 0 ] &&
21815                 error "create local directory on wrong MDT $mdt_idx"
21816
21817         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21818                         error "create remote directory failed"
21819         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21820         [ $mdt_idx -ne $MDTIDX ] &&
21821                 error "create remote directory on wrong MDT $mdt_idx"
21822
21823         createmany -o $DIR/$tdir/test_230/t- 10 ||
21824                 error "create files on remote directory failed"
21825         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21826         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21827         rm -r $DIR/$tdir || error "unlink remote directory failed"
21828 }
21829 run_test 230a "Create remote directory and files under the remote directory"
21830
21831 test_230b() {
21832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21834         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21835                 skip "Need MDS version at least 2.11.52"
21836
21837         local MDTIDX=1
21838         local mdt_index
21839         local i
21840         local file
21841         local pid
21842         local stripe_count
21843         local migrate_dir=$DIR/$tdir/migrate_dir
21844         local other_dir=$DIR/$tdir/other_dir
21845
21846         test_mkdir $DIR/$tdir
21847         test_mkdir -i0 -c1 $migrate_dir
21848         test_mkdir -i0 -c1 $other_dir
21849         for ((i=0; i<10; i++)); do
21850                 mkdir -p $migrate_dir/dir_${i}
21851                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21852                         error "create files under remote dir failed $i"
21853         done
21854
21855         cp /etc/passwd $migrate_dir/$tfile
21856         cp /etc/passwd $other_dir/$tfile
21857         chattr +SAD $migrate_dir
21858         chattr +SAD $migrate_dir/$tfile
21859
21860         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21861         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21862         local old_dir_mode=$(stat -c%f $migrate_dir)
21863         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21864
21865         mkdir -p $migrate_dir/dir_default_stripe2
21866         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21867         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21868
21869         mkdir -p $other_dir
21870         ln $migrate_dir/$tfile $other_dir/luna
21871         ln $migrate_dir/$tfile $migrate_dir/sofia
21872         ln $other_dir/$tfile $migrate_dir/david
21873         ln -s $migrate_dir/$tfile $other_dir/zachary
21874         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21875         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21876
21877         local len
21878         local lnktgt
21879
21880         # inline symlink
21881         for len in 58 59 60; do
21882                 lnktgt=$(str_repeat 'l' $len)
21883                 touch $migrate_dir/$lnktgt
21884                 ln -s $lnktgt $migrate_dir/${len}char_ln
21885         done
21886
21887         # PATH_MAX
21888         for len in 4094 4095; do
21889                 lnktgt=$(str_repeat 'l' $len)
21890                 ln -s $lnktgt $migrate_dir/${len}char_ln
21891         done
21892
21893         # NAME_MAX
21894         for len in 254 255; do
21895                 touch $migrate_dir/$(str_repeat 'l' $len)
21896         done
21897
21898         $LFS migrate -m $MDTIDX $migrate_dir ||
21899                 error "fails on migrating remote dir to MDT1"
21900
21901         echo "migratate to MDT1, then checking.."
21902         for ((i = 0; i < 10; i++)); do
21903                 for file in $(find $migrate_dir/dir_${i}); do
21904                         mdt_index=$($LFS getstripe -m $file)
21905                         # broken symlink getstripe will fail
21906                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21907                                 error "$file is not on MDT${MDTIDX}"
21908                 done
21909         done
21910
21911         # the multiple link file should still in MDT0
21912         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21913         [ $mdt_index == 0 ] ||
21914                 error "$file is not on MDT${MDTIDX}"
21915
21916         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21917         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21918                 error " expect $old_dir_flag get $new_dir_flag"
21919
21920         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21921         [ "$old_file_flag" = "$new_file_flag" ] ||
21922                 error " expect $old_file_flag get $new_file_flag"
21923
21924         local new_dir_mode=$(stat -c%f $migrate_dir)
21925         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21926                 error "expect mode $old_dir_mode get $new_dir_mode"
21927
21928         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21929         [ "$old_file_mode" = "$new_file_mode" ] ||
21930                 error "expect mode $old_file_mode get $new_file_mode"
21931
21932         diff /etc/passwd $migrate_dir/$tfile ||
21933                 error "$tfile different after migration"
21934
21935         diff /etc/passwd $other_dir/luna ||
21936                 error "luna different after migration"
21937
21938         diff /etc/passwd $migrate_dir/sofia ||
21939                 error "sofia different after migration"
21940
21941         diff /etc/passwd $migrate_dir/david ||
21942                 error "david different after migration"
21943
21944         diff /etc/passwd $other_dir/zachary ||
21945                 error "zachary different after migration"
21946
21947         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21948                 error "${tfile}_ln different after migration"
21949
21950         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21951                 error "${tfile}_ln_other different after migration"
21952
21953         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21954         [ $stripe_count = 2 ] ||
21955                 error "dir strpe_count $d != 2 after migration."
21956
21957         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21958         [ $stripe_count = 2 ] ||
21959                 error "file strpe_count $d != 2 after migration."
21960
21961         #migrate back to MDT0
21962         MDTIDX=0
21963
21964         $LFS migrate -m $MDTIDX $migrate_dir ||
21965                 error "fails on migrating remote dir to MDT0"
21966
21967         echo "migrate back to MDT0, checking.."
21968         for file in $(find $migrate_dir); do
21969                 mdt_index=$($LFS getstripe -m $file)
21970                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21971                         error "$file is not on MDT${MDTIDX}"
21972         done
21973
21974         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21975         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21976                 error " expect $old_dir_flag get $new_dir_flag"
21977
21978         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21979         [ "$old_file_flag" = "$new_file_flag" ] ||
21980                 error " expect $old_file_flag get $new_file_flag"
21981
21982         local new_dir_mode=$(stat -c%f $migrate_dir)
21983         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21984                 error "expect mode $old_dir_mode get $new_dir_mode"
21985
21986         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21987         [ "$old_file_mode" = "$new_file_mode" ] ||
21988                 error "expect mode $old_file_mode get $new_file_mode"
21989
21990         diff /etc/passwd ${migrate_dir}/$tfile ||
21991                 error "$tfile different after migration"
21992
21993         diff /etc/passwd ${other_dir}/luna ||
21994                 error "luna different after migration"
21995
21996         diff /etc/passwd ${migrate_dir}/sofia ||
21997                 error "sofia different after migration"
21998
21999         diff /etc/passwd ${other_dir}/zachary ||
22000                 error "zachary different after migration"
22001
22002         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22003                 error "${tfile}_ln different after migration"
22004
22005         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22006                 error "${tfile}_ln_other different after migration"
22007
22008         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22009         [ $stripe_count = 2 ] ||
22010                 error "dir strpe_count $d != 2 after migration."
22011
22012         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22013         [ $stripe_count = 2 ] ||
22014                 error "file strpe_count $d != 2 after migration."
22015
22016         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22017 }
22018 run_test 230b "migrate directory"
22019
22020 test_230c() {
22021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22023         remote_mds_nodsh && skip "remote MDS with nodsh"
22024         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22025                 skip "Need MDS version at least 2.11.52"
22026
22027         local MDTIDX=1
22028         local total=3
22029         local mdt_index
22030         local file
22031         local migrate_dir=$DIR/$tdir/migrate_dir
22032
22033         #If migrating directory fails in the middle, all entries of
22034         #the directory is still accessiable.
22035         test_mkdir $DIR/$tdir
22036         test_mkdir -i0 -c1 $migrate_dir
22037         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22038         stat $migrate_dir
22039         createmany -o $migrate_dir/f $total ||
22040                 error "create files under ${migrate_dir} failed"
22041
22042         # fail after migrating top dir, and this will fail only once, so the
22043         # first sub file migration will fail (currently f3), others succeed.
22044         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22045         do_facet mds1 lctl set_param fail_loc=0x1801
22046         local t=$(ls $migrate_dir | wc -l)
22047         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22048                 error "migrate should fail"
22049         local u=$(ls $migrate_dir | wc -l)
22050         [ "$u" == "$t" ] || error "$u != $t during migration"
22051
22052         # add new dir/file should succeed
22053         mkdir $migrate_dir/dir ||
22054                 error "mkdir failed under migrating directory"
22055         touch $migrate_dir/file ||
22056                 error "create file failed under migrating directory"
22057
22058         # add file with existing name should fail
22059         for file in $migrate_dir/f*; do
22060                 stat $file > /dev/null || error "stat $file failed"
22061                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22062                         error "open(O_CREAT|O_EXCL) $file should fail"
22063                 $MULTIOP $file m && error "create $file should fail"
22064                 touch $DIR/$tdir/remote_dir/$tfile ||
22065                         error "touch $tfile failed"
22066                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22067                         error "link $file should fail"
22068                 mdt_index=$($LFS getstripe -m $file)
22069                 if [ $mdt_index == 0 ]; then
22070                         # file failed to migrate is not allowed to rename to
22071                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22072                                 error "rename to $file should fail"
22073                 else
22074                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22075                                 error "rename to $file failed"
22076                 fi
22077                 echo hello >> $file || error "write $file failed"
22078         done
22079
22080         # resume migration with different options should fail
22081         $LFS migrate -m 0 $migrate_dir &&
22082                 error "migrate -m 0 $migrate_dir should fail"
22083
22084         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22085                 error "migrate -c 2 $migrate_dir should fail"
22086
22087         # resume migration should succeed
22088         $LFS migrate -m $MDTIDX $migrate_dir ||
22089                 error "migrate $migrate_dir failed"
22090
22091         echo "Finish migration, then checking.."
22092         for file in $(find $migrate_dir); do
22093                 mdt_index=$($LFS getstripe -m $file)
22094                 [ $mdt_index == $MDTIDX ] ||
22095                         error "$file is not on MDT${MDTIDX}"
22096         done
22097
22098         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22099 }
22100 run_test 230c "check directory accessiblity if migration failed"
22101
22102 test_230d() {
22103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22105         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22106                 skip "Need MDS version at least 2.11.52"
22107         # LU-11235
22108         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22109
22110         local migrate_dir=$DIR/$tdir/migrate_dir
22111         local old_index
22112         local new_index
22113         local old_count
22114         local new_count
22115         local new_hash
22116         local mdt_index
22117         local i
22118         local j
22119
22120         old_index=$((RANDOM % MDSCOUNT))
22121         old_count=$((MDSCOUNT - old_index))
22122         new_index=$((RANDOM % MDSCOUNT))
22123         new_count=$((MDSCOUNT - new_index))
22124         new_hash=1 # for all_char
22125
22126         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22127         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22128
22129         test_mkdir $DIR/$tdir
22130         test_mkdir -i $old_index -c $old_count $migrate_dir
22131
22132         for ((i=0; i<100; i++)); do
22133                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22134                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22135                         error "create files under remote dir failed $i"
22136         done
22137
22138         echo -n "Migrate from MDT$old_index "
22139         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22140         echo -n "to MDT$new_index"
22141         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22142         echo
22143
22144         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22145         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22146                 error "migrate remote dir error"
22147
22148         echo "Finish migration, then checking.."
22149         for file in $(find $migrate_dir -maxdepth 1); do
22150                 mdt_index=$($LFS getstripe -m $file)
22151                 if [ $mdt_index -lt $new_index ] ||
22152                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22153                         error "$file is on MDT$mdt_index"
22154                 fi
22155         done
22156
22157         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22158 }
22159 run_test 230d "check migrate big directory"
22160
22161 test_230e() {
22162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22164         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22165                 skip "Need MDS version at least 2.11.52"
22166
22167         local i
22168         local j
22169         local a_fid
22170         local b_fid
22171
22172         mkdir_on_mdt0 $DIR/$tdir
22173         mkdir $DIR/$tdir/migrate_dir
22174         mkdir $DIR/$tdir/other_dir
22175         touch $DIR/$tdir/migrate_dir/a
22176         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22177         ls $DIR/$tdir/other_dir
22178
22179         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22180                 error "migrate dir fails"
22181
22182         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22183         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22184
22185         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22186         [ $mdt_index == 0 ] || error "a is not on MDT0"
22187
22188         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22189                 error "migrate dir fails"
22190
22191         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22192         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22193
22194         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22195         [ $mdt_index == 1 ] || error "a is not on MDT1"
22196
22197         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22198         [ $mdt_index == 1 ] || error "b is not on MDT1"
22199
22200         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22201         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22202
22203         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22204
22205         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22206 }
22207 run_test 230e "migrate mulitple local link files"
22208
22209 test_230f() {
22210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22212         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22213                 skip "Need MDS version at least 2.11.52"
22214
22215         local a_fid
22216         local ln_fid
22217
22218         mkdir -p $DIR/$tdir
22219         mkdir $DIR/$tdir/migrate_dir
22220         $LFS mkdir -i1 $DIR/$tdir/other_dir
22221         touch $DIR/$tdir/migrate_dir/a
22222         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22223         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22224         ls $DIR/$tdir/other_dir
22225
22226         # a should be migrated to MDT1, since no other links on MDT0
22227         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22228                 error "#1 migrate dir fails"
22229         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22230         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22231         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22232         [ $mdt_index == 1 ] || error "a is not on MDT1"
22233
22234         # a should stay on MDT1, because it is a mulitple link file
22235         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22236                 error "#2 migrate dir fails"
22237         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22238         [ $mdt_index == 1 ] || error "a is not on MDT1"
22239
22240         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22241                 error "#3 migrate dir fails"
22242
22243         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22244         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22245         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22246
22247         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22248         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22249
22250         # a should be migrated to MDT0, since no other links on MDT1
22251         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22252                 error "#4 migrate dir fails"
22253         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22254         [ $mdt_index == 0 ] || error "a is not on MDT0"
22255
22256         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22257 }
22258 run_test 230f "migrate mulitple remote link files"
22259
22260 test_230g() {
22261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22263         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22264                 skip "Need MDS version at least 2.11.52"
22265
22266         mkdir -p $DIR/$tdir/migrate_dir
22267
22268         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22269                 error "migrating dir to non-exist MDT succeeds"
22270         true
22271 }
22272 run_test 230g "migrate dir to non-exist MDT"
22273
22274 test_230h() {
22275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22277         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22278                 skip "Need MDS version at least 2.11.52"
22279
22280         local mdt_index
22281
22282         mkdir -p $DIR/$tdir/migrate_dir
22283
22284         $LFS migrate -m1 $DIR &&
22285                 error "migrating mountpoint1 should fail"
22286
22287         $LFS migrate -m1 $DIR/$tdir/.. &&
22288                 error "migrating mountpoint2 should fail"
22289
22290         # same as mv
22291         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22292                 error "migrating $tdir/migrate_dir/.. should fail"
22293
22294         true
22295 }
22296 run_test 230h "migrate .. and root"
22297
22298 test_230i() {
22299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22301         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22302                 skip "Need MDS version at least 2.11.52"
22303
22304         mkdir -p $DIR/$tdir/migrate_dir
22305
22306         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22307                 error "migration fails with a tailing slash"
22308
22309         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22310                 error "migration fails with two tailing slashes"
22311 }
22312 run_test 230i "lfs migrate -m tolerates trailing slashes"
22313
22314 test_230j() {
22315         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22316         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22317                 skip "Need MDS version at least 2.11.52"
22318
22319         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22320         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22321                 error "create $tfile failed"
22322         cat /etc/passwd > $DIR/$tdir/$tfile
22323
22324         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22325
22326         cmp /etc/passwd $DIR/$tdir/$tfile ||
22327                 error "DoM file mismatch after migration"
22328 }
22329 run_test 230j "DoM file data not changed after dir migration"
22330
22331 test_230k() {
22332         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22333         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22334                 skip "Need MDS version at least 2.11.56"
22335
22336         local total=20
22337         local files_on_starting_mdt=0
22338
22339         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22340         $LFS getdirstripe $DIR/$tdir
22341         for i in $(seq $total); do
22342                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22343                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22344                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22345         done
22346
22347         echo "$files_on_starting_mdt files on MDT0"
22348
22349         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22350         $LFS getdirstripe $DIR/$tdir
22351
22352         files_on_starting_mdt=0
22353         for i in $(seq $total); do
22354                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22355                         error "file $tfile.$i mismatch after migration"
22356                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22357                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22358         done
22359
22360         echo "$files_on_starting_mdt files on MDT1 after migration"
22361         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22362
22363         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22364         $LFS getdirstripe $DIR/$tdir
22365
22366         files_on_starting_mdt=0
22367         for i in $(seq $total); do
22368                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22369                         error "file $tfile.$i mismatch after 2nd migration"
22370                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22371                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22372         done
22373
22374         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22375         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22376
22377         true
22378 }
22379 run_test 230k "file data not changed after dir migration"
22380
22381 test_230l() {
22382         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22383         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22384                 skip "Need MDS version at least 2.11.56"
22385
22386         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22387         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22388                 error "create files under remote dir failed $i"
22389         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22390 }
22391 run_test 230l "readdir between MDTs won't crash"
22392
22393 test_230m() {
22394         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22395         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22396                 skip "Need MDS version at least 2.11.56"
22397
22398         local MDTIDX=1
22399         local mig_dir=$DIR/$tdir/migrate_dir
22400         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22401         local shortstr="b"
22402         local val
22403
22404         echo "Creating files and dirs with xattrs"
22405         test_mkdir $DIR/$tdir
22406         test_mkdir -i0 -c1 $mig_dir
22407         mkdir $mig_dir/dir
22408         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22409                 error "cannot set xattr attr1 on dir"
22410         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22411                 error "cannot set xattr attr2 on dir"
22412         touch $mig_dir/dir/f0
22413         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22414                 error "cannot set xattr attr1 on file"
22415         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22416                 error "cannot set xattr attr2 on file"
22417         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22418         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22419         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22420         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22421         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22422         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22423         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22424         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22425         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22426
22427         echo "Migrating to MDT1"
22428         $LFS migrate -m $MDTIDX $mig_dir ||
22429                 error "fails on migrating dir to MDT1"
22430
22431         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22432         echo "Checking xattrs"
22433         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22434         [ "$val" = $longstr ] ||
22435                 error "expecting xattr1 $longstr on dir, found $val"
22436         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22437         [ "$val" = $shortstr ] ||
22438                 error "expecting xattr2 $shortstr on dir, found $val"
22439         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22440         [ "$val" = $longstr ] ||
22441                 error "expecting xattr1 $longstr on file, found $val"
22442         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22443         [ "$val" = $shortstr ] ||
22444                 error "expecting xattr2 $shortstr on file, found $val"
22445 }
22446 run_test 230m "xattrs not changed after dir migration"
22447
22448 test_230n() {
22449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22450         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22451                 skip "Need MDS version at least 2.13.53"
22452
22453         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22454         cat /etc/hosts > $DIR/$tdir/$tfile
22455         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22456         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22457
22458         cmp /etc/hosts $DIR/$tdir/$tfile ||
22459                 error "File data mismatch after migration"
22460 }
22461 run_test 230n "Dir migration with mirrored file"
22462
22463 test_230o() {
22464         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22465         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22466                 skip "Need MDS version at least 2.13.52"
22467
22468         local mdts=$(comma_list $(mdts_nodes))
22469         local timeout=100
22470         local restripe_status
22471         local delta
22472         local i
22473
22474         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22475
22476         # in case "crush" hash type is not set
22477         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22478
22479         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22480                            mdt.*MDT0000.enable_dir_restripe)
22481         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22482         stack_trap "do_nodes $mdts $LCTL set_param \
22483                     mdt.*.enable_dir_restripe=$restripe_status"
22484
22485         mkdir $DIR/$tdir
22486         createmany -m $DIR/$tdir/f 100 ||
22487                 error "create files under remote dir failed $i"
22488         createmany -d $DIR/$tdir/d 100 ||
22489                 error "create dirs under remote dir failed $i"
22490
22491         for i in $(seq 2 $MDSCOUNT); do
22492                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22493                 $LFS setdirstripe -c $i $DIR/$tdir ||
22494                         error "split -c $i $tdir failed"
22495                 wait_update $HOSTNAME \
22496                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22497                         error "dir split not finished"
22498                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22499                         awk '/migrate/ {sum += $2} END { print sum }')
22500                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22501                 # delta is around total_files/stripe_count
22502                 (( $delta < 200 / (i - 1) + 4 )) ||
22503                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22504         done
22505 }
22506 run_test 230o "dir split"
22507
22508 test_230p() {
22509         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22510         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22511                 skip "Need MDS version at least 2.13.52"
22512
22513         local mdts=$(comma_list $(mdts_nodes))
22514         local timeout=100
22515         local restripe_status
22516         local delta
22517         local c
22518
22519         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22520
22521         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22522
22523         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22524                            mdt.*MDT0000.enable_dir_restripe)
22525         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22526         stack_trap "do_nodes $mdts $LCTL set_param \
22527                     mdt.*.enable_dir_restripe=$restripe_status"
22528
22529         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22530         createmany -m $DIR/$tdir/f 100 ||
22531                 error "create files under remote dir failed"
22532         createmany -d $DIR/$tdir/d 100 ||
22533                 error "create dirs under remote dir failed"
22534
22535         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22536                 local mdt_hash="crush"
22537
22538                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22539                 $LFS setdirstripe -c $c $DIR/$tdir ||
22540                         error "split -c $c $tdir failed"
22541                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22542                         mdt_hash="$mdt_hash,fixed"
22543                 elif [ $c -eq 1 ]; then
22544                         mdt_hash="none"
22545                 fi
22546                 wait_update $HOSTNAME \
22547                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22548                         error "dir merge not finished"
22549                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22550                         awk '/migrate/ {sum += $2} END { print sum }')
22551                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22552                 # delta is around total_files/stripe_count
22553                 (( delta < 200 / c + 4 )) ||
22554                         error "$delta files migrated >= $((200 / c + 4))"
22555         done
22556 }
22557 run_test 230p "dir merge"
22558
22559 test_230q() {
22560         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22561         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22562                 skip "Need MDS version at least 2.13.52"
22563
22564         local mdts=$(comma_list $(mdts_nodes))
22565         local saved_threshold=$(do_facet mds1 \
22566                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22567         local saved_delta=$(do_facet mds1 \
22568                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22569         local threshold=100
22570         local delta=2
22571         local total=0
22572         local stripe_count=0
22573         local stripe_index
22574         local nr_files
22575         local create
22576
22577         # test with fewer files on ZFS
22578         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22579
22580         stack_trap "do_nodes $mdts $LCTL set_param \
22581                     mdt.*.dir_split_count=$saved_threshold"
22582         stack_trap "do_nodes $mdts $LCTL set_param \
22583                     mdt.*.dir_split_delta=$saved_delta"
22584         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22585         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22586         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22587         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22588         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22589         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22590
22591         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22592         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22593
22594         create=$((threshold * 3 / 2))
22595         while [ $stripe_count -lt $MDSCOUNT ]; do
22596                 createmany -m $DIR/$tdir/f $total $create ||
22597                         error "create sub files failed"
22598                 stat $DIR/$tdir > /dev/null
22599                 total=$((total + create))
22600                 stripe_count=$((stripe_count + delta))
22601                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22602
22603                 wait_update $HOSTNAME \
22604                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22605                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22606
22607                 wait_update $HOSTNAME \
22608                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22609                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22610
22611                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22612                 echo "$nr_files/$total files on MDT$stripe_index after split"
22613                 # allow 10% margin of imbalance with crush hash
22614                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22615                         error "$nr_files files on MDT$stripe_index after split"
22616
22617                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22618                 [ $nr_files -eq $total ] ||
22619                         error "total sub files $nr_files != $total"
22620         done
22621
22622         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22623
22624         echo "fixed layout directory won't auto split"
22625         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22626         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22627                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22628         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22629                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22630 }
22631 run_test 230q "dir auto split"
22632
22633 test_230r() {
22634         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22635         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22636         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22637                 skip "Need MDS version at least 2.13.54"
22638
22639         # maximum amount of local locks:
22640         # parent striped dir - 2 locks
22641         # new stripe in parent to migrate to - 1 lock
22642         # source and target - 2 locks
22643         # Total 5 locks for regular file
22644         mkdir -p $DIR/$tdir
22645         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22646         touch $DIR/$tdir/dir1/eee
22647
22648         # create 4 hardlink for 4 more locks
22649         # Total: 9 locks > RS_MAX_LOCKS (8)
22650         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22651         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22652         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22653         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22654         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22655         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22656         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22657         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22658
22659         cancel_lru_locks mdc
22660
22661         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22662                 error "migrate dir fails"
22663
22664         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22665 }
22666 run_test 230r "migrate with too many local locks"
22667
22668 test_230s() {
22669         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22670                 skip "Need MDS version at least 2.14.52"
22671
22672         local mdts=$(comma_list $(mdts_nodes))
22673         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22674                                 mdt.*MDT0000.enable_dir_restripe)
22675
22676         stack_trap "do_nodes $mdts $LCTL set_param \
22677                     mdt.*.enable_dir_restripe=$restripe_status"
22678
22679         local st
22680         for st in 0 1; do
22681                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22682                 test_mkdir $DIR/$tdir
22683                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22684                         error "$LFS mkdir should return EEXIST if target exists"
22685                 rmdir $DIR/$tdir
22686         done
22687 }
22688 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22689
22690 test_230t()
22691 {
22692         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22693         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22694                 skip "Need MDS version at least 2.14.50"
22695
22696         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22697         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22698         $LFS project -p 1 -s $DIR/$tdir ||
22699                 error "set $tdir project id failed"
22700         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22701                 error "set subdir project id failed"
22702         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22703 }
22704 run_test 230t "migrate directory with project ID set"
22705
22706 test_230u()
22707 {
22708         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22709         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22710                 skip "Need MDS version at least 2.14.53"
22711
22712         local count
22713
22714         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22715         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22716         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22717         for i in $(seq 0 $((MDSCOUNT - 1))); do
22718                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22719                 echo "$count dirs migrated to MDT$i"
22720         done
22721         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22722         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22723 }
22724 run_test 230u "migrate directory by QOS"
22725
22726 test_230v()
22727 {
22728         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22729         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22730                 skip "Need MDS version at least 2.14.53"
22731
22732         local count
22733
22734         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22735         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22736         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22737         for i in $(seq 0 $((MDSCOUNT - 1))); do
22738                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22739                 echo "$count subdirs migrated to MDT$i"
22740                 (( i == 3 )) && (( count > 0 )) &&
22741                         error "subdir shouldn't be migrated to MDT3"
22742         done
22743         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22744         (( count == 3 )) || error "dirs migrated to $count MDTs"
22745 }
22746 run_test 230v "subdir migrated to the MDT where its parent is located"
22747
22748 test_230w() {
22749         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22750         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22751                 skip "Need MDS version at least 2.15.0"
22752
22753         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22754         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22755         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22756
22757         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22758                 error "migrate failed"
22759
22760         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22761                 error "$tdir stripe count mismatch"
22762
22763         for i in $(seq 0 9); do
22764                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22765                         error "d$i is striped"
22766         done
22767 }
22768 run_test 230w "non-recursive mode dir migration"
22769
22770 test_230x() {
22771         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22772         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22773                 skip "Need MDS version at least 2.15.0"
22774
22775         mkdir -p $DIR/$tdir || error "mkdir failed"
22776         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22777
22778         local mdt_name=$(mdtname_from_index 0)
22779         local low=$(do_facet mds2 $LCTL get_param -n \
22780                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22781         local high=$(do_facet mds2 $LCTL get_param -n \
22782                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22783         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22784         local maxage=$(do_facet mds2 $LCTL get_param -n \
22785                 osp.*$mdt_name-osp-MDT0001.maxage)
22786
22787         stack_trap "do_facet mds2 $LCTL set_param -n \
22788                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22789                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22790         stack_trap "do_facet mds2 $LCTL set_param -n \
22791                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22792
22793         do_facet mds2 $LCTL set_param -n \
22794                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22795         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22796         sleep 4
22797         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22798                 error "migrate $tdir should fail"
22799
22800         do_facet mds2 $LCTL set_param -n \
22801                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22802         do_facet mds2 $LCTL set_param -n \
22803                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22804         sleep 4
22805         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22806                 error "migrate failed"
22807         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22808                 error "$tdir stripe count mismatch"
22809 }
22810 run_test 230x "dir migration check space"
22811
22812 test_230y() {
22813         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22814         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22815                 skip "Need MDS version at least 2.15.55.45"
22816
22817         local pid
22818
22819         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22820         $LFS getdirstripe $DIR/$tdir
22821         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22822         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22823         pid=$!
22824         sleep 1
22825
22826         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22827         do_facet mds2 lctl set_param fail_loc=0x1802
22828
22829         wait $pid
22830         do_facet mds2 lctl set_param fail_loc=0
22831         $LFS getdirstripe $DIR/$tdir
22832         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22833         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22834 }
22835 run_test 230y "unlink dir with bad hash type"
22836
22837 test_230z() {
22838         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22839         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22840                 skip "Need MDS version at least 2.15.55.45"
22841
22842         local pid
22843
22844         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22845         $LFS getdirstripe $DIR/$tdir
22846         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22847         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22848         pid=$!
22849         sleep 1
22850
22851         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22852         do_facet mds2 lctl set_param fail_loc=0x1802
22853
22854         wait $pid
22855         do_facet mds2 lctl set_param fail_loc=0
22856         $LFS getdirstripe $DIR/$tdir
22857
22858         # resume migration
22859         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22860                 error "resume migration failed"
22861         $LFS getdirstripe $DIR/$tdir
22862         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22863                 error "migration is not finished"
22864 }
22865 run_test 230z "resume dir migration with bad hash type"
22866
22867 test_231a()
22868 {
22869         # For simplicity this test assumes that max_pages_per_rpc
22870         # is the same across all OSCs
22871         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22872         local bulk_size=$((max_pages * PAGE_SIZE))
22873         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22874                                        head -n 1)
22875
22876         mkdir -p $DIR/$tdir
22877         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22878                 error "failed to set stripe with -S ${brw_size}M option"
22879         stack_trap "rm -rf $DIR/$tdir"
22880
22881         # clear the OSC stats
22882         $LCTL set_param osc.*.stats=0 &>/dev/null
22883         stop_writeback
22884
22885         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22886         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22887                 oflag=direct &>/dev/null || error "dd failed"
22888
22889         sync; sleep 1; sync # just to be safe
22890         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22891         if [ x$nrpcs != "x1" ]; then
22892                 $LCTL get_param osc.*.stats
22893                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22894         fi
22895
22896         start_writeback
22897         # Drop the OSC cache, otherwise we will read from it
22898         cancel_lru_locks osc
22899
22900         # clear the OSC stats
22901         $LCTL set_param osc.*.stats=0 &>/dev/null
22902
22903         # Client reads $bulk_size.
22904         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22905                 iflag=direct &>/dev/null || error "dd failed"
22906
22907         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22908         if [ x$nrpcs != "x1" ]; then
22909                 $LCTL get_param osc.*.stats
22910                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22911         fi
22912 }
22913 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22914
22915 test_231b() {
22916         mkdir -p $DIR/$tdir
22917         stack_trap "rm -rf $DIR/$tdir"
22918         local i
22919         for i in {0..1023}; do
22920                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22921                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22922                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22923         done
22924         sync
22925 }
22926 run_test 231b "must not assert on fully utilized OST request buffer"
22927
22928 test_232a() {
22929         mkdir -p $DIR/$tdir
22930         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22931
22932         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22933         do_facet ost1 $LCTL set_param fail_loc=0x31c
22934
22935         # ignore dd failure
22936         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22937         stack_trap "rm -f $DIR/$tdir/$tfile"
22938
22939         do_facet ost1 $LCTL set_param fail_loc=0
22940         umount_client $MOUNT || error "umount failed"
22941         mount_client $MOUNT || error "mount failed"
22942         stop ost1 || error "cannot stop ost1"
22943         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22944 }
22945 run_test 232a "failed lock should not block umount"
22946
22947 test_232b() {
22948         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22949                 skip "Need MDS version at least 2.10.58"
22950
22951         mkdir -p $DIR/$tdir
22952         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22953         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22954         stack_trap "rm -f $DIR/$tdir/$tfile"
22955         sync
22956         cancel_lru_locks osc
22957
22958         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22959         do_facet ost1 $LCTL set_param fail_loc=0x31c
22960
22961         # ignore failure
22962         $LFS data_version $DIR/$tdir/$tfile || true
22963
22964         do_facet ost1 $LCTL set_param fail_loc=0
22965         umount_client $MOUNT || error "umount failed"
22966         mount_client $MOUNT || error "mount failed"
22967         stop ost1 || error "cannot stop ost1"
22968         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22969 }
22970 run_test 232b "failed data version lock should not block umount"
22971
22972 test_233a() {
22973         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22974                 skip "Need MDS version at least 2.3.64"
22975         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22976
22977         local fid=$($LFS path2fid $MOUNT)
22978
22979         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22980                 error "cannot access $MOUNT using its FID '$fid'"
22981 }
22982 run_test 233a "checking that OBF of the FS root succeeds"
22983
22984 test_233b() {
22985         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22986                 skip "Need MDS version at least 2.5.90"
22987         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22988
22989         local fid=$($LFS path2fid $MOUNT/.lustre)
22990
22991         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22992                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22993
22994         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22995         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22996                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22997 }
22998 run_test 233b "checking that OBF of the FS .lustre succeeds"
22999
23000 test_234() {
23001         local p="$TMP/sanityN-$TESTNAME.parameters"
23002         save_lustre_params client "llite.*.xattr_cache" > $p
23003         lctl set_param llite.*.xattr_cache 1 ||
23004                 skip_env "xattr cache is not supported"
23005
23006         mkdir -p $DIR/$tdir || error "mkdir failed"
23007         touch $DIR/$tdir/$tfile || error "touch failed"
23008         # OBD_FAIL_LLITE_XATTR_ENOMEM
23009         $LCTL set_param fail_loc=0x1405
23010         getfattr -n user.attr $DIR/$tdir/$tfile &&
23011                 error "getfattr should have failed with ENOMEM"
23012         $LCTL set_param fail_loc=0x0
23013         rm -rf $DIR/$tdir
23014
23015         restore_lustre_params < $p
23016         rm -f $p
23017 }
23018 run_test 234 "xattr cache should not crash on ENOMEM"
23019
23020 test_235() {
23021         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23022                 skip "Need MDS version at least 2.4.52"
23023
23024         flock_deadlock $DIR/$tfile
23025         local RC=$?
23026         case $RC in
23027                 0)
23028                 ;;
23029                 124) error "process hangs on a deadlock"
23030                 ;;
23031                 *) error "error executing flock_deadlock $DIR/$tfile"
23032                 ;;
23033         esac
23034 }
23035 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23036
23037 #LU-2935
23038 test_236() {
23039         check_swap_layouts_support
23040
23041         local ref1=/etc/passwd
23042         local ref2=/etc/group
23043         local file1=$DIR/$tdir/f1
23044         local file2=$DIR/$tdir/f2
23045
23046         test_mkdir -c1 $DIR/$tdir
23047         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23048         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23049         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23050         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23051         local fd=$(free_fd)
23052         local cmd="exec $fd<>$file2"
23053         eval $cmd
23054         rm $file2
23055         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23056                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23057         cmd="exec $fd>&-"
23058         eval $cmd
23059         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23060
23061         #cleanup
23062         rm -rf $DIR/$tdir
23063 }
23064 run_test 236 "Layout swap on open unlinked file"
23065
23066 # LU-4659 linkea consistency
23067 test_238() {
23068         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23069                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23070                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23071                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23072
23073         touch $DIR/$tfile
23074         ln $DIR/$tfile $DIR/$tfile.lnk
23075         touch $DIR/$tfile.new
23076         mv $DIR/$tfile.new $DIR/$tfile
23077         local fid1=$($LFS path2fid $DIR/$tfile)
23078         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23079         local path1=$($LFS fid2path $FSNAME "$fid1")
23080         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23081         local path2=$($LFS fid2path $FSNAME "$fid2")
23082         [ $tfile.lnk == $path2 ] ||
23083                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23084         rm -f $DIR/$tfile*
23085 }
23086 run_test 238 "Verify linkea consistency"
23087
23088 test_239A() { # was test_239
23089         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23090                 skip "Need MDS version at least 2.5.60"
23091
23092         local list=$(comma_list $(mdts_nodes))
23093
23094         mkdir -p $DIR/$tdir
23095         createmany -o $DIR/$tdir/f- 5000
23096         unlinkmany $DIR/$tdir/f- 5000
23097         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23098                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23099         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23100                         osp.*MDT*.sync_in_flight" | calc_sum)
23101         [ "$changes" -eq 0 ] || error "$changes not synced"
23102 }
23103 run_test 239A "osp_sync test"
23104
23105 test_239a() { #LU-5297
23106         remote_mds_nodsh && skip "remote MDS with nodsh"
23107
23108         touch $DIR/$tfile
23109         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23110         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23111         chgrp $RUNAS_GID $DIR/$tfile
23112         wait_delete_completed
23113 }
23114 run_test 239a "process invalid osp sync record correctly"
23115
23116 test_239b() { #LU-5297
23117         remote_mds_nodsh && skip "remote MDS with nodsh"
23118
23119         touch $DIR/$tfile1
23120         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23121         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23122         chgrp $RUNAS_GID $DIR/$tfile1
23123         wait_delete_completed
23124         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23125         touch $DIR/$tfile2
23126         chgrp $RUNAS_GID $DIR/$tfile2
23127         wait_delete_completed
23128 }
23129 run_test 239b "process osp sync record with ENOMEM error correctly"
23130
23131 test_240() {
23132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23133         remote_mds_nodsh && skip "remote MDS with nodsh"
23134
23135         mkdir -p $DIR/$tdir
23136
23137         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23138                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23139         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23140                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23141
23142         umount_client $MOUNT || error "umount failed"
23143         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23144         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23145         mount_client $MOUNT || error "failed to mount client"
23146
23147         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23148         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23149 }
23150 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23151
23152 test_241_bio() {
23153         local count=$1
23154         local bsize=$2
23155
23156         for LOOP in $(seq $count); do
23157                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23158                 cancel_lru_locks $OSC || true
23159         done
23160 }
23161
23162 test_241_dio() {
23163         local count=$1
23164         local bsize=$2
23165
23166         for LOOP in $(seq $1); do
23167                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23168                         2>/dev/null
23169         done
23170 }
23171
23172 test_241a() { # was test_241
23173         local bsize=$PAGE_SIZE
23174
23175         (( bsize < 40960 )) && bsize=40960
23176         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23177         ls -la $DIR/$tfile
23178         cancel_lru_locks $OSC
23179         test_241_bio 1000 $bsize &
23180         PID=$!
23181         test_241_dio 1000 $bsize
23182         wait $PID
23183 }
23184 run_test 241a "bio vs dio"
23185
23186 test_241b() {
23187         local bsize=$PAGE_SIZE
23188
23189         (( bsize < 40960 )) && bsize=40960
23190         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23191         ls -la $DIR/$tfile
23192         test_241_dio 1000 $bsize &
23193         PID=$!
23194         test_241_dio 1000 $bsize
23195         wait $PID
23196 }
23197 run_test 241b "dio vs dio"
23198
23199 test_242() {
23200         remote_mds_nodsh && skip "remote MDS with nodsh"
23201
23202         mkdir_on_mdt0 $DIR/$tdir
23203         touch $DIR/$tdir/$tfile
23204
23205         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23206         do_facet mds1 lctl set_param fail_loc=0x105
23207         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23208
23209         do_facet mds1 lctl set_param fail_loc=0
23210         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23211 }
23212 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23213
23214 test_243()
23215 {
23216         test_mkdir $DIR/$tdir
23217         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23218 }
23219 run_test 243 "various group lock tests"
23220
23221 test_244a()
23222 {
23223         test_mkdir $DIR/$tdir
23224         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23225         sendfile_grouplock $DIR/$tdir/$tfile || \
23226                 error "sendfile+grouplock failed"
23227         rm -rf $DIR/$tdir
23228 }
23229 run_test 244a "sendfile with group lock tests"
23230
23231 test_244b()
23232 {
23233         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23234
23235         local threads=50
23236         local size=$((1024*1024))
23237
23238         test_mkdir $DIR/$tdir
23239         for i in $(seq 1 $threads); do
23240                 local file=$DIR/$tdir/file_$((i / 10))
23241                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23242                 local pids[$i]=$!
23243         done
23244         for i in $(seq 1 $threads); do
23245                 wait ${pids[$i]}
23246         done
23247 }
23248 run_test 244b "multi-threaded write with group lock"
23249
23250 test_245a() {
23251         local flagname="multi_mod_rpcs"
23252         local connect_data_name="max_mod_rpcs"
23253         local out
23254
23255         # check if multiple modify RPCs flag is set
23256         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23257                 grep "connect_flags:")
23258         echo "$out"
23259
23260         echo "$out" | grep -qw $flagname
23261         if [ $? -ne 0 ]; then
23262                 echo "connect flag $flagname is not set"
23263                 return
23264         fi
23265
23266         # check if multiple modify RPCs data is set
23267         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23268         echo "$out"
23269
23270         echo "$out" | grep -qw $connect_data_name ||
23271                 error "import should have connect data $connect_data_name"
23272 }
23273 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23274
23275 test_245b() {
23276         local flagname="multi_mod_rpcs"
23277         local connect_data_name="max_mod_rpcs"
23278         local out
23279
23280         remote_mds_nodsh && skip "remote MDS with nodsh"
23281         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23282
23283         # check if multiple modify RPCs flag is set
23284         out=$(do_facet mds1 \
23285               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23286               grep "connect_flags:")
23287         echo "$out"
23288
23289         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23290
23291         # check if multiple modify RPCs data is set
23292         out=$(do_facet mds1 \
23293               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23294
23295         [[ "$out" =~ $connect_data_name ]] ||
23296                 {
23297                         echo "$out"
23298                         error "missing connect data $connect_data_name"
23299                 }
23300 }
23301 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23302
23303 cleanup_247() {
23304         local submount=$1
23305
23306         trap 0
23307         umount_client $submount
23308         rmdir $submount
23309 }
23310
23311 test_247a() {
23312         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23313                 grep -q subtree ||
23314                 skip_env "Fileset feature is not supported"
23315
23316         local submount=${MOUNT}_$tdir
23317
23318         mkdir $MOUNT/$tdir
23319         mkdir -p $submount || error "mkdir $submount failed"
23320         FILESET="$FILESET/$tdir" mount_client $submount ||
23321                 error "mount $submount failed"
23322         trap "cleanup_247 $submount" EXIT
23323         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23324         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23325                 error "read $MOUNT/$tdir/$tfile failed"
23326         cleanup_247 $submount
23327 }
23328 run_test 247a "mount subdir as fileset"
23329
23330 test_247b() {
23331         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23332                 skip_env "Fileset feature is not supported"
23333
23334         local submount=${MOUNT}_$tdir
23335
23336         rm -rf $MOUNT/$tdir
23337         mkdir -p $submount || error "mkdir $submount failed"
23338         SKIP_FILESET=1
23339         FILESET="$FILESET/$tdir" mount_client $submount &&
23340                 error "mount $submount should fail"
23341         rmdir $submount
23342 }
23343 run_test 247b "mount subdir that dose not exist"
23344
23345 test_247c() {
23346         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23347                 skip_env "Fileset feature is not supported"
23348
23349         local submount=${MOUNT}_$tdir
23350
23351         mkdir -p $MOUNT/$tdir/dir1
23352         mkdir -p $submount || error "mkdir $submount failed"
23353         trap "cleanup_247 $submount" EXIT
23354         FILESET="$FILESET/$tdir" mount_client $submount ||
23355                 error "mount $submount failed"
23356         local fid=$($LFS path2fid $MOUNT/)
23357         $LFS fid2path $submount $fid && error "fid2path should fail"
23358         cleanup_247 $submount
23359 }
23360 run_test 247c "running fid2path outside subdirectory root"
23361
23362 test_247d() {
23363         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23364                 skip "Fileset feature is not supported"
23365
23366         local submount=${MOUNT}_$tdir
23367
23368         mkdir -p $MOUNT/$tdir/dir1
23369         mkdir -p $submount || error "mkdir $submount failed"
23370         FILESET="$FILESET/$tdir" mount_client $submount ||
23371                 error "mount $submount failed"
23372         trap "cleanup_247 $submount" EXIT
23373
23374         local td=$submount/dir1
23375         local fid=$($LFS path2fid $td)
23376         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23377
23378         # check that we get the same pathname back
23379         local rootpath
23380         local found
23381         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23382                 echo "$rootpath $fid"
23383                 found=$($LFS fid2path $rootpath "$fid")
23384                 [ -n "$found" ] || error "fid2path should succeed"
23385                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23386         done
23387         # check wrong root path format
23388         rootpath=$submount"_wrong"
23389         found=$($LFS fid2path $rootpath "$fid")
23390         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23391
23392         cleanup_247 $submount
23393 }
23394 run_test 247d "running fid2path inside subdirectory root"
23395
23396 # LU-8037
23397 test_247e() {
23398         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23399                 grep -q subtree ||
23400                 skip "Fileset feature is not supported"
23401
23402         local submount=${MOUNT}_$tdir
23403
23404         mkdir $MOUNT/$tdir
23405         mkdir -p $submount || error "mkdir $submount failed"
23406         FILESET="$FILESET/.." mount_client $submount &&
23407                 error "mount $submount should fail"
23408         rmdir $submount
23409 }
23410 run_test 247e "mount .. as fileset"
23411
23412 test_247f() {
23413         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23414         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23415                 skip "Need at least version 2.14.50.162"
23416         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23417                 skip "Fileset feature is not supported"
23418
23419         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23420         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23421                 error "mkdir remote failed"
23422         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23423                 error "mkdir remote/subdir failed"
23424         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23425                 error "mkdir striped failed"
23426         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23427
23428         local submount=${MOUNT}_$tdir
23429
23430         mkdir -p $submount || error "mkdir $submount failed"
23431         stack_trap "rmdir $submount"
23432
23433         local dir
23434         local fileset=$FILESET
23435         local mdts=$(comma_list $(mdts_nodes))
23436
23437         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23438         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23439                 $tdir/striped/subdir $tdir/striped/.; do
23440                 FILESET="$fileset/$dir" mount_client $submount ||
23441                         error "mount $dir failed"
23442                 umount_client $submount
23443         done
23444 }
23445 run_test 247f "mount striped or remote directory as fileset"
23446
23447 test_subdir_mount_lock()
23448 {
23449         local testdir=$1
23450         local submount=${MOUNT}_$(basename $testdir)
23451
23452         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23453
23454         mkdir -p $submount || error "mkdir $submount failed"
23455         stack_trap "rmdir $submount"
23456
23457         FILESET="$fileset/$testdir" mount_client $submount ||
23458                 error "mount $FILESET failed"
23459         stack_trap "umount $submount"
23460
23461         local mdts=$(comma_list $(mdts_nodes))
23462
23463         local nrpcs
23464
23465         stat $submount > /dev/null || error "stat $submount failed"
23466         cancel_lru_locks $MDC
23467         stat $submount > /dev/null || error "stat $submount failed"
23468         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23469         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23470         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23471         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23472                 awk '/getattr/ {sum += $2} END {print sum}')
23473
23474         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23475 }
23476
23477 test_247g() {
23478         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23479
23480         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23481                 error "mkdir $tdir failed"
23482         test_subdir_mount_lock $tdir
23483 }
23484 run_test 247g "striped directory submount revalidate ROOT from cache"
23485
23486 test_247h() {
23487         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23488         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23489                 skip "Need MDS version at least 2.15.51"
23490
23491         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23492         test_subdir_mount_lock $tdir
23493         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23494         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23495                 error "mkdir $tdir.1 failed"
23496         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23497 }
23498 run_test 247h "remote directory submount revalidate ROOT from cache"
23499
23500 test_248a() {
23501         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23502         [ -z "$fast_read_sav" ] && skip "no fast read support"
23503
23504         # create a large file for fast read verification
23505         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23506
23507         # make sure the file is created correctly
23508         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23509                 { rm -f $DIR/$tfile; skip "file creation error"; }
23510
23511         echo "Test 1: verify that fast read is 4 times faster on cache read"
23512
23513         # small read with fast read enabled
23514         $LCTL set_param -n llite.*.fast_read=1
23515         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23516                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23517                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23518         # small read with fast read disabled
23519         $LCTL set_param -n llite.*.fast_read=0
23520         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23521                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23522                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23523
23524         # verify that fast read is 4 times faster for cache read
23525         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23526                 error_not_in_vm "fast read was not 4 times faster: " \
23527                            "$t_fast vs $t_slow"
23528
23529         echo "Test 2: verify the performance between big and small read"
23530         $LCTL set_param -n llite.*.fast_read=1
23531
23532         # 1k non-cache read
23533         cancel_lru_locks osc
23534         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23535                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23536                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23537
23538         # 1M non-cache read
23539         cancel_lru_locks osc
23540         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23541                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23542                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23543
23544         # verify that big IO is not 4 times faster than small IO
23545         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23546                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23547
23548         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23549         rm -f $DIR/$tfile
23550 }
23551 run_test 248a "fast read verification"
23552
23553 test_248b() {
23554         # Default short_io_bytes=16384, try both smaller and larger sizes.
23555         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23556         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23557         echo "bs=53248 count=113 normal buffered write"
23558         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23559                 error "dd of initial data file failed"
23560         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23561
23562         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23563         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23564                 error "dd with sync normal writes failed"
23565         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23566
23567         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23568         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23569                 error "dd with sync small writes failed"
23570         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23571
23572         cancel_lru_locks osc
23573
23574         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23575         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23576         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23577         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23578                 iflag=direct || error "dd with O_DIRECT small read failed"
23579         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23580         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23581                 error "compare $TMP/$tfile.1 failed"
23582
23583         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23584         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23585
23586         # just to see what the maximum tunable value is, and test parsing
23587         echo "test invalid parameter 2MB"
23588         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23589                 error "too-large short_io_bytes allowed"
23590         echo "test maximum parameter 512KB"
23591         # if we can set a larger short_io_bytes, run test regardless of version
23592         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23593                 # older clients may not allow setting it this large, that's OK
23594                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23595                         skip "Need at least client version 2.13.50"
23596                 error "medium short_io_bytes failed"
23597         fi
23598         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23599         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23600
23601         echo "test large parameter 64KB"
23602         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23603         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23604
23605         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23606         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23607                 error "dd with sync large writes failed"
23608         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23609
23610         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23611         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23612         num=$((113 * 4096 / PAGE_SIZE))
23613         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23614         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23615                 error "dd with O_DIRECT large writes failed"
23616         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23617                 error "compare $DIR/$tfile.3 failed"
23618
23619         cancel_lru_locks osc
23620
23621         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23622         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23623                 error "dd with O_DIRECT large read failed"
23624         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23625                 error "compare $TMP/$tfile.2 failed"
23626
23627         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23628         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23629                 error "dd with O_DIRECT large read failed"
23630         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23631                 error "compare $TMP/$tfile.3 failed"
23632 }
23633 run_test 248b "test short_io read and write for both small and large sizes"
23634
23635 test_249() { # LU-7890
23636         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23637                 skip "Need at least version 2.8.54"
23638
23639         rm -f $DIR/$tfile
23640         $LFS setstripe -c 1 $DIR/$tfile
23641         # Offset 2T == 4k * 512M
23642         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23643                 error "dd to 2T offset failed"
23644 }
23645 run_test 249 "Write above 2T file size"
23646
23647 test_250() {
23648         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23649          && skip "no 16TB file size limit on ZFS"
23650
23651         $LFS setstripe -c 1 $DIR/$tfile
23652         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23653         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23654         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23655         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23656                 conv=notrunc,fsync && error "append succeeded"
23657         return 0
23658 }
23659 run_test 250 "Write above 16T limit"
23660
23661 test_251() {
23662         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23663
23664         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23665         #Skip once - writing the first stripe will succeed
23666         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23667         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23668                 error "short write happened"
23669
23670         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23671         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23672                 error "short read happened"
23673
23674         rm -f $DIR/$tfile
23675 }
23676 run_test 251 "Handling short read and write correctly"
23677
23678 test_252() {
23679         remote_mds_nodsh && skip "remote MDS with nodsh"
23680         remote_ost_nodsh && skip "remote OST with nodsh"
23681         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23682                 skip_env "ldiskfs only test"
23683         fi
23684
23685         local tgt
23686         local dev
23687         local out
23688         local uuid
23689         local num
23690         local gen
23691
23692         # check lr_reader on OST0000
23693         tgt=ost1
23694         dev=$(facet_device $tgt)
23695         out=$(do_facet $tgt $LR_READER $dev)
23696         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23697         echo "$out"
23698         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23699         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23700                 error "Invalid uuid returned by $LR_READER on target $tgt"
23701         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23702
23703         # check lr_reader -c on MDT0000
23704         tgt=mds1
23705         dev=$(facet_device $tgt)
23706         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23707                 skip "$LR_READER does not support additional options"
23708         fi
23709         out=$(do_facet $tgt $LR_READER -c $dev)
23710         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23711         echo "$out"
23712         num=$(echo "$out" | grep -c "mdtlov")
23713         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23714                 error "Invalid number of mdtlov clients returned by $LR_READER"
23715         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23716
23717         # check lr_reader -cr on MDT0000
23718         out=$(do_facet $tgt $LR_READER -cr $dev)
23719         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23720         echo "$out"
23721         echo "$out" | grep -q "^reply_data:$" ||
23722                 error "$LR_READER should have returned 'reply_data' section"
23723         num=$(echo "$out" | grep -c "client_generation")
23724         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23725 }
23726 run_test 252 "check lr_reader tool"
23727
23728 test_253() {
23729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23730         remote_mds_nodsh && skip "remote MDS with nodsh"
23731         remote_mgs_nodsh && skip "remote MGS with nodsh"
23732
23733         local ostidx=0
23734         local rc=0
23735         local ost_name=$(ostname_from_index $ostidx)
23736
23737         # on the mdt's osc
23738         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23739         do_facet $SINGLEMDS $LCTL get_param -n \
23740                 osp.$mdtosc_proc1.reserved_mb_high ||
23741                 skip  "remote MDS does not support reserved_mb_high"
23742
23743         rm -rf $DIR/$tdir
23744         wait_mds_ost_sync
23745         wait_delete_completed
23746         mkdir $DIR/$tdir
23747         stack_trap "rm -rf $DIR/$tdir"
23748
23749         pool_add $TESTNAME || error "Pool creation failed"
23750         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23751
23752         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23753                 error "Setstripe failed"
23754
23755         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23756
23757         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23758                     grep "watermarks")
23759         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23760
23761         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23762                         osp.$mdtosc_proc1.prealloc_status)
23763         echo "prealloc_status $oa_status"
23764
23765         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23766                 error "File creation should fail"
23767
23768         #object allocation was stopped, but we still able to append files
23769         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23770                 oflag=append || error "Append failed"
23771
23772         rm -f $DIR/$tdir/$tfile.0
23773
23774         # For this test, we want to delete the files we created to go out of
23775         # space but leave the watermark, so we remain nearly out of space
23776         ost_watermarks_enospc_delete_files $tfile $ostidx
23777
23778         wait_delete_completed
23779
23780         sleep_maxage
23781
23782         for i in $(seq 10 12); do
23783                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23784                         2>/dev/null || error "File creation failed after rm"
23785         done
23786
23787         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23788                         osp.$mdtosc_proc1.prealloc_status)
23789         echo "prealloc_status $oa_status"
23790
23791         if (( oa_status != 0 )); then
23792                 error "Object allocation still disable after rm"
23793         fi
23794 }
23795 run_test 253 "Check object allocation limit"
23796
23797 test_254() {
23798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23799         remote_mds_nodsh && skip "remote MDS with nodsh"
23800
23801         local mdt=$(facet_svc $SINGLEMDS)
23802
23803         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23804                 skip "MDS does not support changelog_size"
23805
23806         local cl_user
23807
23808         changelog_register || error "changelog_register failed"
23809
23810         changelog_clear 0 || error "changelog_clear failed"
23811
23812         local size1=$(do_facet $SINGLEMDS \
23813                       $LCTL get_param -n mdd.$mdt.changelog_size)
23814         echo "Changelog size $size1"
23815
23816         rm -rf $DIR/$tdir
23817         $LFS mkdir -i 0 $DIR/$tdir
23818         # change something
23819         mkdir -p $DIR/$tdir/pics/2008/zachy
23820         touch $DIR/$tdir/pics/2008/zachy/timestamp
23821         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23822         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23823         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23824         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23825         rm $DIR/$tdir/pics/desktop.jpg
23826
23827         local size2=$(do_facet $SINGLEMDS \
23828                       $LCTL get_param -n mdd.$mdt.changelog_size)
23829         echo "Changelog size after work $size2"
23830
23831         (( $size2 > $size1 )) ||
23832                 error "new Changelog size=$size2 less than old size=$size1"
23833 }
23834 run_test 254 "Check changelog size"
23835
23836 ladvise_no_type()
23837 {
23838         local type=$1
23839         local file=$2
23840
23841         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23842                 awk -F: '{print $2}' | grep $type > /dev/null
23843         if [ $? -ne 0 ]; then
23844                 return 0
23845         fi
23846         return 1
23847 }
23848
23849 ladvise_no_ioctl()
23850 {
23851         local file=$1
23852
23853         lfs ladvise -a willread $file > /dev/null 2>&1
23854         if [ $? -eq 0 ]; then
23855                 return 1
23856         fi
23857
23858         lfs ladvise -a willread $file 2>&1 |
23859                 grep "Inappropriate ioctl for device" > /dev/null
23860         if [ $? -eq 0 ]; then
23861                 return 0
23862         fi
23863         return 1
23864 }
23865
23866 percent() {
23867         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23868 }
23869
23870 # run a random read IO workload
23871 # usage: random_read_iops <filename> <filesize> <iosize>
23872 random_read_iops() {
23873         local file=$1
23874         local fsize=$2
23875         local iosize=${3:-4096}
23876
23877         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23878                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23879 }
23880
23881 drop_file_oss_cache() {
23882         local file="$1"
23883         local nodes="$2"
23884
23885         $LFS ladvise -a dontneed $file 2>/dev/null ||
23886                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23887 }
23888
23889 ladvise_willread_performance()
23890 {
23891         local repeat=10
23892         local average_origin=0
23893         local average_cache=0
23894         local average_ladvise=0
23895
23896         for ((i = 1; i <= $repeat; i++)); do
23897                 echo "Iter $i/$repeat: reading without willread hint"
23898                 cancel_lru_locks osc
23899                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23900                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23901                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23902                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23903
23904                 cancel_lru_locks osc
23905                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23906                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23907                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23908
23909                 cancel_lru_locks osc
23910                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23911                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23912                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23913                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23914                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23915         done
23916         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23917         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23918         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23919
23920         speedup_cache=$(percent $average_cache $average_origin)
23921         speedup_ladvise=$(percent $average_ladvise $average_origin)
23922
23923         echo "Average uncached read: $average_origin"
23924         echo "Average speedup with OSS cached read: " \
23925                 "$average_cache = +$speedup_cache%"
23926         echo "Average speedup with ladvise willread: " \
23927                 "$average_ladvise = +$speedup_ladvise%"
23928
23929         local lowest_speedup=20
23930         if (( ${average_cache%.*} < $lowest_speedup )); then
23931                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23932                      " got $average_cache%. Skipping ladvise willread check."
23933                 return 0
23934         fi
23935
23936         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23937         # it is still good to run until then to exercise 'ladvise willread'
23938         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23939                 [ "$ost1_FSTYPE" = "zfs" ] &&
23940                 echo "osd-zfs does not support dontneed or drop_caches" &&
23941                 return 0
23942
23943         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23944         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23945                 error_not_in_vm "Speedup with willread is less than " \
23946                         "$lowest_speedup%, got $average_ladvise%"
23947 }
23948
23949 test_255a() {
23950         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23951                 skip "lustre < 2.8.54 does not support ladvise "
23952         remote_ost_nodsh && skip "remote OST with nodsh"
23953
23954         stack_trap "rm -f $DIR/$tfile"
23955         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23956
23957         ladvise_no_type willread $DIR/$tfile &&
23958                 skip "willread ladvise is not supported"
23959
23960         ladvise_no_ioctl $DIR/$tfile &&
23961                 skip "ladvise ioctl is not supported"
23962
23963         local size_mb=100
23964         local size=$((size_mb * 1048576))
23965         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23966                 error "dd to $DIR/$tfile failed"
23967
23968         lfs ladvise -a willread $DIR/$tfile ||
23969                 error "Ladvise failed with no range argument"
23970
23971         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23972                 error "Ladvise failed with no -l or -e argument"
23973
23974         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23975                 error "Ladvise failed with only -e argument"
23976
23977         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23978                 error "Ladvise failed with only -l argument"
23979
23980         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23981                 error "End offset should not be smaller than start offset"
23982
23983         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23984                 error "End offset should not be equal to start offset"
23985
23986         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23987                 error "Ladvise failed with overflowing -s argument"
23988
23989         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23990                 error "Ladvise failed with overflowing -e argument"
23991
23992         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23993                 error "Ladvise failed with overflowing -l argument"
23994
23995         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23996                 error "Ladvise succeeded with conflicting -l and -e arguments"
23997
23998         echo "Synchronous ladvise should wait"
23999         local delay=8
24000 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24001         do_nodes $(comma_list $(osts_nodes)) \
24002                 $LCTL set_param fail_val=$delay fail_loc=0x237
24003         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24004                 $LCTL set_param fail_loc=0"
24005
24006         local start_ts=$SECONDS
24007         lfs ladvise -a willread $DIR/$tfile ||
24008                 error "Ladvise failed with no range argument"
24009         local end_ts=$SECONDS
24010         local inteval_ts=$((end_ts - start_ts))
24011
24012         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24013                 error "Synchronous advice didn't wait reply"
24014         fi
24015
24016         echo "Asynchronous ladvise shouldn't wait"
24017         local start_ts=$SECONDS
24018         lfs ladvise -a willread -b $DIR/$tfile ||
24019                 error "Ladvise failed with no range argument"
24020         local end_ts=$SECONDS
24021         local inteval_ts=$((end_ts - start_ts))
24022
24023         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24024                 error "Asynchronous advice blocked"
24025         fi
24026
24027         ladvise_willread_performance
24028 }
24029 run_test 255a "check 'lfs ladvise -a willread'"
24030
24031 facet_meminfo() {
24032         local facet=$1
24033         local info=$2
24034
24035         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24036 }
24037
24038 test_255b() {
24039         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24040                 skip "lustre < 2.8.54 does not support ladvise "
24041         remote_ost_nodsh && skip "remote OST with nodsh"
24042
24043         stack_trap "rm -f $DIR/$tfile"
24044         lfs setstripe -c 1 -i 0 $DIR/$tfile
24045
24046         ladvise_no_type dontneed $DIR/$tfile &&
24047                 skip "dontneed ladvise is not supported"
24048
24049         ladvise_no_ioctl $DIR/$tfile &&
24050                 skip "ladvise ioctl is not supported"
24051
24052         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24053                 [ "$ost1_FSTYPE" = "zfs" ] &&
24054                 skip "zfs-osd does not support 'ladvise dontneed'"
24055
24056         local size_mb=100
24057         local size=$((size_mb * 1048576))
24058         # In order to prevent disturbance of other processes, only check 3/4
24059         # of the memory usage
24060         local kibibytes=$((size_mb * 1024 * 3 / 4))
24061
24062         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24063                 error "dd to $DIR/$tfile failed"
24064
24065         #force write to complete before dropping OST cache & checking memory
24066         sync
24067
24068         local total=$(facet_meminfo ost1 MemTotal)
24069         echo "Total memory: $total KiB"
24070
24071         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24072         local before_read=$(facet_meminfo ost1 Cached)
24073         echo "Cache used before read: $before_read KiB"
24074
24075         lfs ladvise -a willread $DIR/$tfile ||
24076                 error "Ladvise willread failed"
24077         local after_read=$(facet_meminfo ost1 Cached)
24078         echo "Cache used after read: $after_read KiB"
24079
24080         lfs ladvise -a dontneed $DIR/$tfile ||
24081                 error "Ladvise dontneed again failed"
24082         local no_read=$(facet_meminfo ost1 Cached)
24083         echo "Cache used after dontneed ladvise: $no_read KiB"
24084
24085         if [ $total -lt $((before_read + kibibytes)) ]; then
24086                 echo "Memory is too small, abort checking"
24087                 return 0
24088         fi
24089
24090         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24091                 error "Ladvise willread should use more memory" \
24092                         "than $kibibytes KiB"
24093         fi
24094
24095         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24096                 error "Ladvise dontneed should release more memory" \
24097                         "than $kibibytes KiB"
24098         fi
24099 }
24100 run_test 255b "check 'lfs ladvise -a dontneed'"
24101
24102 test_255c() {
24103         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24104                 skip "lustre < 2.10.50 does not support lockahead"
24105
24106         local ost1_imp=$(get_osc_import_name client ost1)
24107         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24108                          cut -d'.' -f2)
24109         local count
24110         local new_count
24111         local difference
24112         local i
24113         local rc
24114
24115         test_mkdir -p $DIR/$tdir
24116         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24117
24118         #test 10 returns only success/failure
24119         i=10
24120         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24121         rc=$?
24122         if [ $rc -eq 255 ]; then
24123                 error "Ladvise test${i} failed, ${rc}"
24124         fi
24125
24126         #test 11 counts lock enqueue requests, all others count new locks
24127         i=11
24128         count=$(do_facet ost1 \
24129                 $LCTL get_param -n ost.OSS.ost.stats)
24130         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24131
24132         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24133         rc=$?
24134         if [ $rc -eq 255 ]; then
24135                 error "Ladvise test${i} failed, ${rc}"
24136         fi
24137
24138         new_count=$(do_facet ost1 \
24139                 $LCTL get_param -n ost.OSS.ost.stats)
24140         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24141                    awk '{ print $2 }')
24142
24143         difference="$((new_count - count))"
24144         if [ $difference -ne $rc ]; then
24145                 error "Ladvise test${i}, bad enqueue count, returned " \
24146                       "${rc}, actual ${difference}"
24147         fi
24148
24149         for i in $(seq 12 21); do
24150                 # If we do not do this, we run the risk of having too many
24151                 # locks and starting lock cancellation while we are checking
24152                 # lock counts.
24153                 cancel_lru_locks osc
24154
24155                 count=$($LCTL get_param -n \
24156                        ldlm.namespaces.$imp_name.lock_unused_count)
24157
24158                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24159                 rc=$?
24160                 if [ $rc -eq 255 ]; then
24161                         error "Ladvise test ${i} failed, ${rc}"
24162                 fi
24163
24164                 new_count=$($LCTL get_param -n \
24165                        ldlm.namespaces.$imp_name.lock_unused_count)
24166                 difference="$((new_count - count))"
24167
24168                 # Test 15 output is divided by 100 to map down to valid return
24169                 if [ $i -eq 15 ]; then
24170                         rc="$((rc * 100))"
24171                 fi
24172
24173                 if [ $difference -ne $rc ]; then
24174                         error "Ladvise test ${i}, bad lock count, returned " \
24175                               "${rc}, actual ${difference}"
24176                 fi
24177         done
24178
24179         #test 22 returns only success/failure
24180         i=22
24181         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24182         rc=$?
24183         if [ $rc -eq 255 ]; then
24184                 error "Ladvise test${i} failed, ${rc}"
24185         fi
24186 }
24187 run_test 255c "suite of ladvise lockahead tests"
24188
24189 test_256() {
24190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24191         remote_mds_nodsh && skip "remote MDS with nodsh"
24192         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24193         changelog_users $SINGLEMDS | grep "^cl" &&
24194                 skip "active changelog user"
24195
24196         local cl_user
24197         local cat_sl
24198         local mdt_dev
24199
24200         mdt_dev=$(facet_device $SINGLEMDS)
24201         echo $mdt_dev
24202
24203         changelog_register || error "changelog_register failed"
24204
24205         rm -rf $DIR/$tdir
24206         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24207
24208         changelog_clear 0 || error "changelog_clear failed"
24209
24210         # change something
24211         touch $DIR/$tdir/{1..10}
24212
24213         # stop the MDT
24214         stop $SINGLEMDS || error "Fail to stop MDT"
24215
24216         # remount the MDT
24217         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24218                 error "Fail to start MDT"
24219
24220         #after mount new plainllog is used
24221         touch $DIR/$tdir/{11..19}
24222         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24223         stack_trap "rm -f $tmpfile"
24224         cat_sl=$(do_facet $SINGLEMDS "sync; \
24225                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24226                  llog_reader $tmpfile | grep -c type=1064553b")
24227         do_facet $SINGLEMDS llog_reader $tmpfile
24228
24229         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24230
24231         changelog_clear 0 || error "changelog_clear failed"
24232
24233         cat_sl=$(do_facet $SINGLEMDS "sync; \
24234                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24235                  llog_reader $tmpfile | grep -c type=1064553b")
24236
24237         if (( cat_sl == 2 )); then
24238                 error "Empty plain llog was not deleted from changelog catalog"
24239         elif (( cat_sl != 1 )); then
24240                 error "Active plain llog shouldn't be deleted from catalog"
24241         fi
24242 }
24243 run_test 256 "Check llog delete for empty and not full state"
24244
24245 test_257() {
24246         remote_mds_nodsh && skip "remote MDS with nodsh"
24247         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24248                 skip "Need MDS version at least 2.8.55"
24249
24250         test_mkdir $DIR/$tdir
24251
24252         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24253                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24254         stat $DIR/$tdir
24255
24256 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24257         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24258         local facet=mds$((mdtidx + 1))
24259         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24260         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24261
24262         stop $facet || error "stop MDS failed"
24263         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24264                 error "start MDS fail"
24265         wait_recovery_complete $facet
24266 }
24267 run_test 257 "xattr locks are not lost"
24268
24269 # Verify we take the i_mutex when security requires it
24270 test_258a() {
24271 #define OBD_FAIL_IMUTEX_SEC 0x141c
24272         $LCTL set_param fail_loc=0x141c
24273         touch $DIR/$tfile
24274         chmod u+s $DIR/$tfile
24275         chmod a+rwx $DIR/$tfile
24276         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24277         RC=$?
24278         if [ $RC -ne 0 ]; then
24279                 error "error, failed to take i_mutex, rc=$?"
24280         fi
24281         rm -f $DIR/$tfile
24282 }
24283 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24284
24285 # Verify we do NOT take the i_mutex in the normal case
24286 test_258b() {
24287 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24288         $LCTL set_param fail_loc=0x141d
24289         touch $DIR/$tfile
24290         chmod a+rwx $DIR
24291         chmod a+rw $DIR/$tfile
24292         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24293         RC=$?
24294         if [ $RC -ne 0 ]; then
24295                 error "error, took i_mutex unnecessarily, rc=$?"
24296         fi
24297         rm -f $DIR/$tfile
24298
24299 }
24300 run_test 258b "verify i_mutex security behavior"
24301
24302 test_259() {
24303         local file=$DIR/$tfile
24304         local before
24305         local after
24306
24307         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24308
24309         stack_trap "rm -f $file" EXIT
24310
24311         wait_delete_completed
24312         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24313         echo "before: $before"
24314
24315         $LFS setstripe -i 0 -c 1 $file
24316         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24317         sync_all_data
24318         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24319         echo "after write: $after"
24320
24321 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24322         do_facet ost1 $LCTL set_param fail_loc=0x2301
24323         $TRUNCATE $file 0
24324         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24325         echo "after truncate: $after"
24326
24327         stop ost1
24328         do_facet ost1 $LCTL set_param fail_loc=0
24329         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24330         sleep 2
24331         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24332         echo "after restart: $after"
24333         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24334                 error "missing truncate?"
24335
24336         return 0
24337 }
24338 run_test 259 "crash at delayed truncate"
24339
24340 test_260() {
24341 #define OBD_FAIL_MDC_CLOSE               0x806
24342         $LCTL set_param fail_loc=0x80000806
24343         touch $DIR/$tfile
24344
24345 }
24346 run_test 260 "Check mdc_close fail"
24347
24348 ### Data-on-MDT sanity tests ###
24349 test_270a() {
24350         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24351                 skip "Need MDS version at least 2.10.55 for DoM"
24352
24353         # create DoM file
24354         local dom=$DIR/$tdir/dom_file
24355         local tmp=$DIR/$tdir/tmp_file
24356
24357         mkdir_on_mdt0 $DIR/$tdir
24358
24359         # basic checks for DoM component creation
24360         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24361                 error "Can set MDT layout to non-first entry"
24362
24363         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24364                 error "Can define multiple entries as MDT layout"
24365
24366         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24367
24368         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24369         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24370         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24371
24372         local mdtidx=$($LFS getstripe -m $dom)
24373         local mdtname=MDT$(printf %04x $mdtidx)
24374         local facet=mds$((mdtidx + 1))
24375         local space_check=1
24376
24377         # Skip free space checks with ZFS
24378         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24379
24380         # write
24381         sync
24382         local size_tmp=$((65536 * 3))
24383         local mdtfree1=$(do_facet $facet \
24384                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24385
24386         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24387         # check also direct IO along write
24388         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24389         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24390         sync
24391         cmp $tmp $dom || error "file data is different"
24392         [ $(stat -c%s $dom) == $size_tmp ] ||
24393                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24394         if [ $space_check == 1 ]; then
24395                 local mdtfree2=$(do_facet $facet \
24396                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24397
24398                 # increase in usage from by $size_tmp
24399                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24400                         error "MDT free space wrong after write: " \
24401                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24402         fi
24403
24404         # truncate
24405         local size_dom=10000
24406
24407         $TRUNCATE $dom $size_dom
24408         [ $(stat -c%s $dom) == $size_dom ] ||
24409                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24410         if [ $space_check == 1 ]; then
24411                 mdtfree1=$(do_facet $facet \
24412                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24413                 # decrease in usage from $size_tmp to new $size_dom
24414                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24415                   $(((size_tmp - size_dom) / 1024)) ] ||
24416                         error "MDT free space is wrong after truncate: " \
24417                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24418         fi
24419
24420         # append
24421         cat $tmp >> $dom
24422         sync
24423         size_dom=$((size_dom + size_tmp))
24424         [ $(stat -c%s $dom) == $size_dom ] ||
24425                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24426         if [ $space_check == 1 ]; then
24427                 mdtfree2=$(do_facet $facet \
24428                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24429                 # increase in usage by $size_tmp from previous
24430                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24431                         error "MDT free space is wrong after append: " \
24432                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24433         fi
24434
24435         # delete
24436         rm $dom
24437         if [ $space_check == 1 ]; then
24438                 mdtfree1=$(do_facet $facet \
24439                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24440                 # decrease in usage by $size_dom from previous
24441                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24442                         error "MDT free space is wrong after removal: " \
24443                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24444         fi
24445
24446         # combined striping
24447         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24448                 error "Can't create DoM + OST striping"
24449
24450         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24451         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24452         # check also direct IO along write
24453         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24454         sync
24455         cmp $tmp $dom || error "file data is different"
24456         [ $(stat -c%s $dom) == $size_tmp ] ||
24457                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24458         rm $dom $tmp
24459
24460         return 0
24461 }
24462 run_test 270a "DoM: basic functionality tests"
24463
24464 test_270b() {
24465         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24466                 skip "Need MDS version at least 2.10.55"
24467
24468         local dom=$DIR/$tdir/dom_file
24469         local max_size=1048576
24470
24471         mkdir -p $DIR/$tdir
24472         $LFS setstripe -E $max_size -L mdt $dom
24473
24474         # truncate over the limit
24475         $TRUNCATE $dom $(($max_size + 1)) &&
24476                 error "successful truncate over the maximum size"
24477         # write over the limit
24478         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24479                 error "successful write over the maximum size"
24480         # append over the limit
24481         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24482         echo "12345" >> $dom && error "successful append over the maximum size"
24483         rm $dom
24484
24485         return 0
24486 }
24487 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24488
24489 test_270c() {
24490         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24491                 skip "Need MDS version at least 2.10.55"
24492
24493         mkdir -p $DIR/$tdir
24494         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24495
24496         # check files inherit DoM EA
24497         touch $DIR/$tdir/first
24498         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24499                 error "bad pattern"
24500         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24501                 error "bad stripe count"
24502         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24503                 error "bad stripe size"
24504
24505         # check directory inherits DoM EA and uses it as default
24506         mkdir $DIR/$tdir/subdir
24507         touch $DIR/$tdir/subdir/second
24508         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24509                 error "bad pattern in sub-directory"
24510         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24511                 error "bad stripe count in sub-directory"
24512         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24513                 error "bad stripe size in sub-directory"
24514         return 0
24515 }
24516 run_test 270c "DoM: DoM EA inheritance tests"
24517
24518 test_270d() {
24519         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24520                 skip "Need MDS version at least 2.10.55"
24521
24522         mkdir -p $DIR/$tdir
24523         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24524
24525         # inherit default DoM striping
24526         mkdir $DIR/$tdir/subdir
24527         touch $DIR/$tdir/subdir/f1
24528
24529         # change default directory striping
24530         $LFS setstripe -c 1 $DIR/$tdir/subdir
24531         touch $DIR/$tdir/subdir/f2
24532         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24533                 error "wrong default striping in file 2"
24534         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24535                 error "bad pattern in file 2"
24536         return 0
24537 }
24538 run_test 270d "DoM: change striping from DoM to RAID0"
24539
24540 test_270e() {
24541         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24542                 skip "Need MDS version at least 2.10.55"
24543
24544         mkdir -p $DIR/$tdir/dom
24545         mkdir -p $DIR/$tdir/norm
24546         DOMFILES=20
24547         NORMFILES=10
24548         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24549         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24550
24551         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24552         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24553
24554         # find DoM files by layout
24555         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24556         [ $NUM -eq  $DOMFILES ] ||
24557                 error "lfs find -L: found $NUM, expected $DOMFILES"
24558         echo "Test 1: lfs find 20 DOM files by layout: OK"
24559
24560         # there should be 1 dir with default DOM striping
24561         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24562         [ $NUM -eq  1 ] ||
24563                 error "lfs find -L: found $NUM, expected 1 dir"
24564         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24565
24566         # find DoM files by stripe size
24567         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24568         [ $NUM -eq  $DOMFILES ] ||
24569                 error "lfs find -S: found $NUM, expected $DOMFILES"
24570         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24571
24572         # find files by stripe offset except DoM files
24573         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24574         [ $NUM -eq  $NORMFILES ] ||
24575                 error "lfs find -i: found $NUM, expected $NORMFILES"
24576         echo "Test 5: lfs find no DOM files by stripe index: OK"
24577         return 0
24578 }
24579 run_test 270e "DoM: lfs find with DoM files test"
24580
24581 test_270f() {
24582         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24583                 skip "Need MDS version at least 2.10.55"
24584
24585         local mdtname=${FSNAME}-MDT0000-mdtlov
24586         local dom=$DIR/$tdir/dom_file
24587         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24588                                                 lod.$mdtname.dom_stripesize)
24589         local dom_limit=131072
24590
24591         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24592         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24593                                                 lod.$mdtname.dom_stripesize)
24594         [ ${dom_limit} -eq ${dom_current} ] ||
24595                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24596
24597         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24598         $LFS setstripe -d $DIR/$tdir
24599         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24600                 error "Can't set directory default striping"
24601
24602         # exceed maximum stripe size
24603         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24604                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24605         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24606                 error "Able to create DoM component size more than LOD limit"
24607
24608         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24609         dom_current=$(do_facet mds1 $LCTL get_param -n \
24610                                                 lod.$mdtname.dom_stripesize)
24611         [ 0 -eq ${dom_current} ] ||
24612                 error "Can't set zero DoM stripe limit"
24613         rm $dom
24614
24615         # attempt to create DoM file on server with disabled DoM should
24616         # remove DoM entry from layout and be succeed
24617         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24618                 error "Can't create DoM file (DoM is disabled)"
24619         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24620                 error "File has DoM component while DoM is disabled"
24621         rm $dom
24622
24623         # attempt to create DoM file with only DoM stripe should return error
24624         $LFS setstripe -E $dom_limit -L mdt $dom &&
24625                 error "Able to create DoM-only file while DoM is disabled"
24626
24627         # too low values to be aligned with smallest stripe size 64K
24628         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24629         dom_current=$(do_facet mds1 $LCTL get_param -n \
24630                                                 lod.$mdtname.dom_stripesize)
24631         [ 30000 -eq ${dom_current} ] &&
24632                 error "Can set too small DoM stripe limit"
24633
24634         # 64K is a minimal stripe size in Lustre, expect limit of that size
24635         [ 65536 -eq ${dom_current} ] ||
24636                 error "Limit is not set to 64K but ${dom_current}"
24637
24638         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24639         dom_current=$(do_facet mds1 $LCTL get_param -n \
24640                                                 lod.$mdtname.dom_stripesize)
24641         echo $dom_current
24642         [ 2147483648 -eq ${dom_current} ] &&
24643                 error "Can set too large DoM stripe limit"
24644
24645         do_facet mds1 $LCTL set_param -n \
24646                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24647         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24648                 error "Can't create DoM component size after limit change"
24649         do_facet mds1 $LCTL set_param -n \
24650                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24651         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24652                 error "Can't create DoM file after limit decrease"
24653         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24654                 error "Can create big DoM component after limit decrease"
24655         touch ${dom}_def ||
24656                 error "Can't create file with old default layout"
24657
24658         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24659         return 0
24660 }
24661 run_test 270f "DoM: maximum DoM stripe size checks"
24662
24663 test_270g() {
24664         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24665                 skip "Need MDS version at least 2.13.52"
24666         local dom=$DIR/$tdir/$tfile
24667
24668         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24669         local lodname=${FSNAME}-MDT0000-mdtlov
24670
24671         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24672         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24673         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24674         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24675
24676         local dom_limit=1024
24677         local dom_threshold="50%"
24678
24679         $LFS setstripe -d $DIR/$tdir
24680         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24681                 error "Can't set directory default striping"
24682
24683         do_facet mds1 $LCTL set_param -n \
24684                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24685         # set 0 threshold and create DOM file to change tunable stripesize
24686         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24687         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24688                 error "Failed to create $dom file"
24689         # now tunable dom_cur_stripesize should reach maximum
24690         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24691                                         lod.${lodname}.dom_stripesize_cur_kb)
24692         [[ $dom_current == $dom_limit ]] ||
24693                 error "Current DOM stripesize is not maximum"
24694         rm $dom
24695
24696         # set threshold for further tests
24697         do_facet mds1 $LCTL set_param -n \
24698                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24699         echo "DOM threshold is $dom_threshold free space"
24700         local dom_def
24701         local dom_set
24702         # Spoof bfree to exceed threshold
24703         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24704         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24705         for spfree in 40 20 0 15 30 55; do
24706                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24707                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24708                         error "Failed to create $dom file"
24709                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24710                                         lod.${lodname}.dom_stripesize_cur_kb)
24711                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24712                 [[ $dom_def != $dom_current ]] ||
24713                         error "Default stripe size was not changed"
24714                 if (( spfree > 0 )) ; then
24715                         dom_set=$($LFS getstripe -S $dom)
24716                         (( dom_set == dom_def * 1024 )) ||
24717                                 error "DOM component size is still old"
24718                 else
24719                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24720                                 error "DoM component is set with no free space"
24721                 fi
24722                 rm $dom
24723                 dom_current=$dom_def
24724         done
24725 }
24726 run_test 270g "DoM: default DoM stripe size depends on free space"
24727
24728 test_270h() {
24729         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24730                 skip "Need MDS version at least 2.13.53"
24731
24732         local mdtname=${FSNAME}-MDT0000-mdtlov
24733         local dom=$DIR/$tdir/$tfile
24734         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24735
24736         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24737         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24738
24739         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24740         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24741                 error "can't create OST file"
24742         # mirrored file with DOM entry in the second mirror
24743         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24744                 error "can't create mirror with DoM component"
24745
24746         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24747
24748         # DOM component in the middle and has other enries in the same mirror,
24749         # should succeed but lost DoM component
24750         $LFS setstripe --copy=${dom}_1 $dom ||
24751                 error "Can't create file from OST|DOM mirror layout"
24752         # check new file has no DoM layout after all
24753         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24754                 error "File has DoM component while DoM is disabled"
24755 }
24756 run_test 270h "DoM: DoM stripe removal when disabled on server"
24757
24758 test_270i() {
24759         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24760                 skip "Need MDS version at least 2.14.54"
24761
24762         mkdir $DIR/$tdir
24763         # DoM with plain layout
24764         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24765                 error "default plain layout with DoM must fail"
24766         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24767                 error "setstripe plain file layout with DoM must fail"
24768         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24769                 error "default DoM layout with bad striping must fail"
24770         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24771                 error "setstripe to DoM layout with bad striping must fail"
24772         return 0
24773 }
24774 run_test 270i "DoM: setting invalid DoM striping should fail"
24775
24776 test_270j() {
24777         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24778                 skip "Need MDS version at least 2.15.55.203"
24779
24780         local dom=$DIR/$tdir/$tfile
24781         local odv
24782         local ndv
24783
24784         mkdir -p $DIR/$tdir
24785
24786         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24787
24788         odv=$($LFS data_version $dom)
24789         chmod 666 $dom
24790         mv $dom ${dom}_moved
24791         link ${dom}_moved $dom
24792         setfattr -n user.attrx -v "some_attr" $dom
24793         ndv=$($LFS data_version $dom)
24794         (( $ndv == $odv )) ||
24795                 error "data version was changed by metadata operations"
24796
24797         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24798                 error "failed to write data into $dom"
24799         cancel_lru_locks mdc
24800         ndv=$($LFS data_version $dom)
24801         (( $ndv != $odv )) ||
24802                 error "data version wasn't changed on write"
24803
24804         odv=$ndv
24805         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24806         ndv=$($LFS data_version $dom)
24807         (( $ndv != $odv )) ||
24808                 error "data version wasn't changed on truncate down"
24809
24810         odv=$ndv
24811         $TRUNCATE $dom 25000
24812         ndv=$($LFS data_version $dom)
24813         (( $ndv != $odv )) ||
24814                 error "data version wasn't changed on truncate up"
24815
24816         # check also fallocate for ldiskfs
24817         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24818                 odv=$ndv
24819                 fallocate -l 1048576 $dom
24820                 ndv=$($LFS data_version $dom)
24821                 (( $ndv != $odv )) ||
24822                         error "data version wasn't changed on fallocate"
24823
24824                 odv=$ndv
24825                 fallocate -p --offset 4096 -l 4096 $dom
24826                 ndv=$($LFS data_version $dom)
24827                 (( $ndv != $odv )) ||
24828                         error "data version wasn't changed on fallocate punch"
24829         fi
24830 }
24831 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24832
24833 test_271a() {
24834         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24835                 skip "Need MDS version at least 2.10.55"
24836
24837         local dom=$DIR/$tdir/dom
24838
24839         mkdir -p $DIR/$tdir
24840
24841         $LFS setstripe -E 1024K -L mdt $dom
24842
24843         lctl set_param -n mdc.*.stats=clear
24844         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24845         cat $dom > /dev/null
24846         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24847         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24848         ls $dom
24849         rm -f $dom
24850 }
24851 run_test 271a "DoM: data is cached for read after write"
24852
24853 test_271b() {
24854         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24855                 skip "Need MDS version at least 2.10.55"
24856
24857         local dom=$DIR/$tdir/dom
24858
24859         mkdir -p $DIR/$tdir
24860
24861         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24862
24863         lctl set_param -n mdc.*.stats=clear
24864         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24865         cancel_lru_locks mdc
24866         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24867         # second stat to check size is cached on client
24868         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24869         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24870         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24871         rm -f $dom
24872 }
24873 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24874
24875 test_271ba() {
24876         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24877                 skip "Need MDS version at least 2.10.55"
24878
24879         local dom=$DIR/$tdir/dom
24880
24881         mkdir -p $DIR/$tdir
24882
24883         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24884
24885         lctl set_param -n mdc.*.stats=clear
24886         lctl set_param -n osc.*.stats=clear
24887         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24888         cancel_lru_locks mdc
24889         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24890         # second stat to check size is cached on client
24891         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24892         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24893         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24894         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24895         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24896         rm -f $dom
24897 }
24898 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24899
24900
24901 get_mdc_stats() {
24902         local mdtidx=$1
24903         local param=$2
24904         local mdt=MDT$(printf %04x $mdtidx)
24905
24906         if [ -z $param ]; then
24907                 lctl get_param -n mdc.*$mdt*.stats
24908         else
24909                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24910         fi
24911 }
24912
24913 test_271c() {
24914         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24915                 skip "Need MDS version at least 2.10.55"
24916
24917         local dom=$DIR/$tdir/dom
24918
24919         mkdir -p $DIR/$tdir
24920
24921         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24922
24923         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24924         local facet=mds$((mdtidx + 1))
24925
24926         cancel_lru_locks mdc
24927         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24928         createmany -o $dom 1000
24929         lctl set_param -n mdc.*.stats=clear
24930         smalliomany -w $dom 1000 200
24931         get_mdc_stats $mdtidx
24932         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24933         # Each file has 1 open, 1 IO enqueues, total 2000
24934         # but now we have also +1 getxattr for security.capability, total 3000
24935         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24936         unlinkmany $dom 1000
24937
24938         cancel_lru_locks mdc
24939         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24940         createmany -o $dom 1000
24941         lctl set_param -n mdc.*.stats=clear
24942         smalliomany -w $dom 1000 200
24943         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24944         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24945         # for OPEN and IO lock.
24946         [ $((enq - enq_2)) -ge 1000 ] ||
24947                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24948         unlinkmany $dom 1000
24949         return 0
24950 }
24951 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24952
24953 cleanup_271def_tests() {
24954         trap 0
24955         rm -f $1
24956 }
24957
24958 test_271d() {
24959         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24960                 skip "Need MDS version at least 2.10.57"
24961
24962         local dom=$DIR/$tdir/dom
24963         local tmp=$TMP/$tfile
24964         trap "cleanup_271def_tests $tmp" EXIT
24965
24966         mkdir -p $DIR/$tdir
24967
24968         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24969
24970         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24971
24972         cancel_lru_locks mdc
24973         dd if=/dev/urandom of=$tmp bs=1000 count=1
24974         dd if=$tmp of=$dom bs=1000 count=1
24975         cancel_lru_locks mdc
24976
24977         cat /etc/hosts >> $tmp
24978         lctl set_param -n mdc.*.stats=clear
24979
24980         # append data to the same file it should update local page
24981         echo "Append to the same page"
24982         cat /etc/hosts >> $dom
24983         local num=$(get_mdc_stats $mdtidx ost_read)
24984         local ra=$(get_mdc_stats $mdtidx req_active)
24985         local rw=$(get_mdc_stats $mdtidx req_waittime)
24986
24987         [ -z $num ] || error "$num READ RPC occured"
24988         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24989         echo "... DONE"
24990
24991         # compare content
24992         cmp $tmp $dom || error "file miscompare"
24993
24994         cancel_lru_locks mdc
24995         lctl set_param -n mdc.*.stats=clear
24996
24997         echo "Open and read file"
24998         cat $dom > /dev/null
24999         local num=$(get_mdc_stats $mdtidx ost_read)
25000         local ra=$(get_mdc_stats $mdtidx req_active)
25001         local rw=$(get_mdc_stats $mdtidx req_waittime)
25002
25003         [ -z $num ] || error "$num READ RPC occured"
25004         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25005         echo "... DONE"
25006
25007         # compare content
25008         cmp $tmp $dom || error "file miscompare"
25009
25010         return 0
25011 }
25012 run_test 271d "DoM: read on open (1K file in reply buffer)"
25013
25014 test_271f() {
25015         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25016                 skip "Need MDS version at least 2.10.57"
25017
25018         local dom=$DIR/$tdir/dom
25019         local tmp=$TMP/$tfile
25020         trap "cleanup_271def_tests $tmp" EXIT
25021
25022         mkdir -p $DIR/$tdir
25023
25024         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25025
25026         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25027
25028         cancel_lru_locks mdc
25029         dd if=/dev/urandom of=$tmp bs=265000 count=1
25030         dd if=$tmp of=$dom bs=265000 count=1
25031         cancel_lru_locks mdc
25032         cat /etc/hosts >> $tmp
25033         lctl set_param -n mdc.*.stats=clear
25034
25035         echo "Append to the same page"
25036         cat /etc/hosts >> $dom
25037         local num=$(get_mdc_stats $mdtidx ost_read)
25038         local ra=$(get_mdc_stats $mdtidx req_active)
25039         local rw=$(get_mdc_stats $mdtidx req_waittime)
25040
25041         [ -z $num ] || error "$num READ RPC occured"
25042         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25043         echo "... DONE"
25044
25045         # compare content
25046         cmp $tmp $dom || error "file miscompare"
25047
25048         cancel_lru_locks mdc
25049         lctl set_param -n mdc.*.stats=clear
25050
25051         echo "Open and read file"
25052         cat $dom > /dev/null
25053         local num=$(get_mdc_stats $mdtidx ost_read)
25054         local ra=$(get_mdc_stats $mdtidx req_active)
25055         local rw=$(get_mdc_stats $mdtidx req_waittime)
25056
25057         [ -z $num ] && num=0
25058         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25059         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25060         echo "... DONE"
25061
25062         # compare content
25063         cmp $tmp $dom || error "file miscompare"
25064
25065         return 0
25066 }
25067 run_test 271f "DoM: read on open (200K file and read tail)"
25068
25069 test_271g() {
25070         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25071                 skip "Skipping due to old client or server version"
25072
25073         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25074         # to get layout
25075         $CHECKSTAT -t file $DIR1/$tfile
25076
25077         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25078         MULTIOP_PID=$!
25079         sleep 1
25080         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25081         $LCTL set_param fail_loc=0x80000314
25082         rm $DIR1/$tfile || error "Unlink fails"
25083         RC=$?
25084         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25085         [ $RC -eq 0 ] || error "Failed write to stale object"
25086 }
25087 run_test 271g "Discard DoM data vs client flush race"
25088
25089 test_272a() {
25090         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25091                 skip "Need MDS version at least 2.11.50"
25092
25093         local dom=$DIR/$tdir/dom
25094         mkdir -p $DIR/$tdir
25095
25096         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25097         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25098                 error "failed to write data into $dom"
25099         local old_md5=$(md5sum $dom)
25100
25101         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25102                 error "failed to migrate to the same DoM component"
25103
25104         local new_md5=$(md5sum $dom)
25105
25106         [ "$old_md5" == "$new_md5" ] ||
25107                 error "md5sum differ: $old_md5, $new_md5"
25108
25109         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25110                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25111 }
25112 run_test 272a "DoM migration: new layout with the same DOM component"
25113
25114 test_272b() {
25115         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25116                 skip "Need MDS version at least 2.11.50"
25117
25118         local dom=$DIR/$tdir/dom
25119         mkdir -p $DIR/$tdir
25120         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25121         stack_trap "rm -rf $DIR/$tdir"
25122
25123         local mdtidx=$($LFS getstripe -m $dom)
25124         local mdtname=MDT$(printf %04x $mdtidx)
25125         local facet=mds$((mdtidx + 1))
25126
25127         local mdtfree1=$(do_facet $facet \
25128                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25129         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25130                 error "failed to write data into $dom"
25131         local old_md5=$(md5sum $dom)
25132         cancel_lru_locks mdc
25133         local mdtfree1=$(do_facet $facet \
25134                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25135
25136         $LFS migrate -c2 $dom ||
25137                 error "failed to migrate to the new composite layout"
25138         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25139                 error "MDT stripe was not removed"
25140         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25141                 error "$dir1 shouldn't have DATAVER EA"
25142
25143         cancel_lru_locks mdc
25144         local new_md5=$(md5sum $dom)
25145         [ "$old_md5" == "$new_md5" ] ||
25146                 error "$old_md5 != $new_md5"
25147
25148         # Skip free space checks with ZFS
25149         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25150                 local mdtfree2=$(do_facet $facet \
25151                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25152                 [ $mdtfree2 -gt $mdtfree1 ] ||
25153                         error "MDT space is not freed after migration"
25154         fi
25155         return 0
25156 }
25157 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25158
25159 test_272c() {
25160         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25161                 skip "Need MDS version at least 2.11.50"
25162
25163         local dom=$DIR/$tdir/$tfile
25164         mkdir -p $DIR/$tdir
25165         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25166         stack_trap "rm -rf $DIR/$tdir"
25167
25168         local mdtidx=$($LFS getstripe -m $dom)
25169         local mdtname=MDT$(printf %04x $mdtidx)
25170         local facet=mds$((mdtidx + 1))
25171
25172         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25173                 error "failed to write data into $dom"
25174         local old_md5=$(md5sum $dom)
25175         cancel_lru_locks mdc
25176         local mdtfree1=$(do_facet $facet \
25177                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25178
25179         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25180                 error "failed to migrate to the new composite layout"
25181         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25182                 error "MDT stripe was not removed"
25183
25184         cancel_lru_locks mdc
25185         local new_md5=$(md5sum $dom)
25186         [ "$old_md5" == "$new_md5" ] ||
25187                 error "$old_md5 != $new_md5"
25188
25189         # Skip free space checks with ZFS
25190         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25191                 local mdtfree2=$(do_facet $facet \
25192                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25193                 [ $mdtfree2 -gt $mdtfree1 ] ||
25194                         error "MDS space is not freed after migration"
25195         fi
25196         return 0
25197 }
25198 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25199
25200 test_272d() {
25201         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25202                 skip "Need MDS version at least 2.12.55"
25203
25204         local dom=$DIR/$tdir/$tfile
25205         mkdir -p $DIR/$tdir
25206         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25207
25208         local mdtidx=$($LFS getstripe -m $dom)
25209         local mdtname=MDT$(printf %04x $mdtidx)
25210         local facet=mds$((mdtidx + 1))
25211
25212         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25213                 error "failed to write data into $dom"
25214         local old_md5=$(md5sum $dom)
25215         cancel_lru_locks mdc
25216         local mdtfree1=$(do_facet $facet \
25217                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25218
25219         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25220                 error "failed mirroring to the new composite layout"
25221         $LFS mirror resync $dom ||
25222                 error "failed mirror resync"
25223         $LFS mirror split --mirror-id 1 -d $dom ||
25224                 error "failed mirror split"
25225
25226         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25227                 error "MDT stripe was not removed"
25228
25229         cancel_lru_locks mdc
25230         local new_md5=$(md5sum $dom)
25231         [ "$old_md5" == "$new_md5" ] ||
25232                 error "$old_md5 != $new_md5"
25233
25234         # Skip free space checks with ZFS
25235         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25236                 local mdtfree2=$(do_facet $facet \
25237                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25238                 [ $mdtfree2 -gt $mdtfree1 ] ||
25239                         error "MDS space is not freed after DOM mirror deletion"
25240         fi
25241         return 0
25242 }
25243 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25244
25245 test_272e() {
25246         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25247                 skip "Need MDS version at least 2.12.55"
25248
25249         local dom=$DIR/$tdir/$tfile
25250         mkdir -p $DIR/$tdir
25251         $LFS setstripe -c 2 $dom
25252
25253         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25254                 error "failed to write data into $dom"
25255         local old_md5=$(md5sum $dom)
25256         cancel_lru_locks
25257
25258         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25259                 error "failed mirroring to the DOM layout"
25260         $LFS mirror resync $dom ||
25261                 error "failed mirror resync"
25262         $LFS mirror split --mirror-id 1 -d $dom ||
25263                 error "failed mirror split"
25264
25265         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25266                 error "MDT stripe wasn't set"
25267
25268         cancel_lru_locks
25269         local new_md5=$(md5sum $dom)
25270         [ "$old_md5" == "$new_md5" ] ||
25271                 error "$old_md5 != $new_md5"
25272
25273         return 0
25274 }
25275 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25276
25277 test_272f() {
25278         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25279                 skip "Need MDS version at least 2.12.55"
25280
25281         local dom=$DIR/$tdir/$tfile
25282         mkdir -p $DIR/$tdir
25283         $LFS setstripe -c 2 $dom
25284
25285         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25286                 error "failed to write data into $dom"
25287         local old_md5=$(md5sum $dom)
25288         cancel_lru_locks
25289
25290         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25291                 error "failed migrating to the DOM file"
25292
25293         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25294                 error "MDT stripe wasn't set"
25295
25296         cancel_lru_locks
25297         local new_md5=$(md5sum $dom)
25298         [ "$old_md5" != "$new_md5" ] &&
25299                 error "$old_md5 != $new_md5"
25300
25301         return 0
25302 }
25303 run_test 272f "DoM migration: OST-striped file to DOM file"
25304
25305 test_273a() {
25306         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25307                 skip "Need MDS version at least 2.11.50"
25308
25309         # Layout swap cannot be done if either file has DOM component,
25310         # this will never be supported, migration should be used instead
25311
25312         local dom=$DIR/$tdir/$tfile
25313         mkdir -p $DIR/$tdir
25314
25315         $LFS setstripe -c2 ${dom}_plain
25316         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25317         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25318                 error "can swap layout with DoM component"
25319         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25320                 error "can swap layout with DoM component"
25321
25322         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25323         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25324                 error "can swap layout with DoM component"
25325         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25326                 error "can swap layout with DoM component"
25327         return 0
25328 }
25329 run_test 273a "DoM: layout swapping should fail with DOM"
25330
25331 test_273b() {
25332         mkdir -p $DIR/$tdir
25333         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25334
25335 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25336         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25337
25338         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25339 }
25340 run_test 273b "DoM: race writeback and object destroy"
25341
25342 test_273c() {
25343         mkdir -p $DIR/$tdir
25344         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25345
25346         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25347         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25348
25349         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25350 }
25351 run_test 273c "race writeback and object destroy"
25352
25353 test_275() {
25354         remote_ost_nodsh && skip "remote OST with nodsh"
25355         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25356                 skip "Need OST version >= 2.10.57"
25357
25358         local file=$DIR/$tfile
25359         local oss
25360
25361         oss=$(comma_list $(osts_nodes))
25362
25363         dd if=/dev/urandom of=$file bs=1M count=2 ||
25364                 error "failed to create a file"
25365         stack_trap "rm -f $file"
25366         cancel_lru_locks osc
25367
25368         #lock 1
25369         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25370                 error "failed to read a file"
25371
25372 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25373         $LCTL set_param fail_loc=0x8000031f
25374
25375         cancel_lru_locks osc &
25376         sleep 1
25377
25378 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25379         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25380         #IO takes another lock, but matches the PENDING one
25381         #and places it to the IO RPC
25382         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25383                 error "failed to read a file with PENDING lock"
25384 }
25385 run_test 275 "Read on a canceled duplicate lock"
25386
25387 test_276() {
25388         remote_ost_nodsh && skip "remote OST with nodsh"
25389         local pid
25390
25391         do_facet ost1 "(while true; do \
25392                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25393                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25394         pid=$!
25395
25396         for LOOP in $(seq 20); do
25397                 stop ost1
25398                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25399         done
25400         kill -9 $pid
25401         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25402                 rm $TMP/sanity_276_pid"
25403 }
25404 run_test 276 "Race between mount and obd_statfs"
25405
25406 test_277() {
25407         $LCTL set_param ldlm.namespaces.*.lru_size=0
25408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25409         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25410                           awk '/^used_mb/ { print $2 }')
25411         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25412         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25413                 oflag=direct conv=notrunc
25414         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25415                     awk '/^used_mb/ { print $2 }')
25416         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25417 }
25418 run_test 277 "Direct IO shall drop page cache"
25419
25420 test_278() {
25421         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25422         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25423         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25424                 skip "needs the same host for mdt1 mdt2" && return
25425
25426         local pid1
25427         local pid2
25428
25429 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25430         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25431         stop mds2 &
25432         pid2=$!
25433
25434         stop mds1
25435
25436         echo "Starting MDTs"
25437         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25438         wait $pid2
25439 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25440 #will return NULL
25441         do_facet mds2 $LCTL set_param fail_loc=0
25442
25443         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25444         wait_recovery_complete mds2
25445 }
25446 run_test 278 "Race starting MDS between MDTs stop/start"
25447
25448 test_280() {
25449         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25450                 skip "Need MGS version at least 2.13.52"
25451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25452         combined_mgs_mds || skip "needs combined MGS/MDT"
25453
25454         umount_client $MOUNT
25455 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25456         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25457
25458         mount_client $MOUNT &
25459         sleep 1
25460         stop mgs || error "stop mgs failed"
25461         #for a race mgs would crash
25462         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25463         # make sure we unmount client before remounting
25464         wait
25465         umount_client $MOUNT
25466         mount_client $MOUNT || error "mount client failed"
25467 }
25468 run_test 280 "Race between MGS umount and client llog processing"
25469
25470 cleanup_test_300() {
25471         trap 0
25472         umask $SAVE_UMASK
25473 }
25474 test_striped_dir() {
25475         local mdt_index=$1
25476         local stripe_count
25477         local stripe_index
25478
25479         mkdir -p $DIR/$tdir
25480
25481         SAVE_UMASK=$(umask)
25482         trap cleanup_test_300 RETURN EXIT
25483
25484         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25485                                                 $DIR/$tdir/striped_dir ||
25486                 error "set striped dir error"
25487
25488         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25489         [ "$mode" = "755" ] || error "expect 755 got $mode"
25490
25491         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25492                 error "getdirstripe failed"
25493         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25494         if [ "$stripe_count" != "2" ]; then
25495                 error "1:stripe_count is $stripe_count, expect 2"
25496         fi
25497         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25498         if [ "$stripe_count" != "2" ]; then
25499                 error "2:stripe_count is $stripe_count, expect 2"
25500         fi
25501
25502         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25503         if [ "$stripe_index" != "$mdt_index" ]; then
25504                 error "stripe_index is $stripe_index, expect $mdt_index"
25505         fi
25506
25507         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25508                 error "nlink error after create striped dir"
25509
25510         mkdir $DIR/$tdir/striped_dir/a
25511         mkdir $DIR/$tdir/striped_dir/b
25512
25513         stat $DIR/$tdir/striped_dir/a ||
25514                 error "create dir under striped dir failed"
25515         stat $DIR/$tdir/striped_dir/b ||
25516                 error "create dir under striped dir failed"
25517
25518         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25519                 error "nlink error after mkdir"
25520
25521         rmdir $DIR/$tdir/striped_dir/a
25522         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25523                 error "nlink error after rmdir"
25524
25525         rmdir $DIR/$tdir/striped_dir/b
25526         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25527                 error "nlink error after rmdir"
25528
25529         chattr +i $DIR/$tdir/striped_dir
25530         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25531                 error "immutable flags not working under striped dir!"
25532         chattr -i $DIR/$tdir/striped_dir
25533
25534         rmdir $DIR/$tdir/striped_dir ||
25535                 error "rmdir striped dir error"
25536
25537         cleanup_test_300
25538
25539         true
25540 }
25541
25542 test_300a() {
25543         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25544                 skip "skipped for lustre < 2.7.0"
25545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25546         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25547
25548         test_striped_dir 0 || error "failed on striped dir on MDT0"
25549         test_striped_dir 1 || error "failed on striped dir on MDT0"
25550 }
25551 run_test 300a "basic striped dir sanity test"
25552
25553 test_300b() {
25554         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25555                 skip "skipped for lustre < 2.7.0"
25556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25558
25559         local i
25560         local mtime1
25561         local mtime2
25562         local mtime3
25563
25564         test_mkdir $DIR/$tdir || error "mkdir fail"
25565         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25566                 error "set striped dir error"
25567         for i in {0..9}; do
25568                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25569                 sleep 1
25570                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25571                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25572                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25573                 sleep 1
25574                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25575                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25576                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25577         done
25578         true
25579 }
25580 run_test 300b "check ctime/mtime for striped dir"
25581
25582 test_300c() {
25583         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25584                 skip "skipped for lustre < 2.7.0"
25585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25586         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25587
25588         local file_count
25589
25590         mkdir_on_mdt0 $DIR/$tdir
25591         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25592                 error "set striped dir error"
25593
25594         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25595                 error "chown striped dir failed"
25596
25597         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25598                 error "create 5k files failed"
25599
25600         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25601
25602         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25603
25604         rm -rf $DIR/$tdir
25605 }
25606 run_test 300c "chown && check ls under striped directory"
25607
25608 test_300d() {
25609         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25610                 skip "skipped for lustre < 2.7.0"
25611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25613
25614         local stripe_count
25615         local file
25616
25617         mkdir -p $DIR/$tdir
25618         $LFS setstripe -c 2 $DIR/$tdir
25619
25620         #local striped directory
25621         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25622                 error "set striped dir error"
25623         #look at the directories for debug purposes
25624         ls -l $DIR/$tdir
25625         $LFS getdirstripe $DIR/$tdir
25626         ls -l $DIR/$tdir/striped_dir
25627         $LFS getdirstripe $DIR/$tdir/striped_dir
25628         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25629                 error "create 10 files failed"
25630
25631         #remote striped directory
25632         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25633                 error "set striped dir error"
25634         #look at the directories for debug purposes
25635         ls -l $DIR/$tdir
25636         $LFS getdirstripe $DIR/$tdir
25637         ls -l $DIR/$tdir/remote_striped_dir
25638         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25639         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25640                 error "create 10 files failed"
25641
25642         for file in $(find $DIR/$tdir); do
25643                 stripe_count=$($LFS getstripe -c $file)
25644                 [ $stripe_count -eq 2 ] ||
25645                         error "wrong stripe $stripe_count for $file"
25646         done
25647
25648         rm -rf $DIR/$tdir
25649 }
25650 run_test 300d "check default stripe under striped directory"
25651
25652 test_300e() {
25653         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25654                 skip "Need MDS version at least 2.7.55"
25655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25657
25658         local stripe_count
25659         local file
25660
25661         mkdir -p $DIR/$tdir
25662
25663         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25664                 error "set striped dir error"
25665
25666         touch $DIR/$tdir/striped_dir/a
25667         touch $DIR/$tdir/striped_dir/b
25668         touch $DIR/$tdir/striped_dir/c
25669
25670         mkdir $DIR/$tdir/striped_dir/dir_a
25671         mkdir $DIR/$tdir/striped_dir/dir_b
25672         mkdir $DIR/$tdir/striped_dir/dir_c
25673
25674         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25675                 error "set striped adir under striped dir error"
25676
25677         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25678                 error "set striped bdir under striped dir error"
25679
25680         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25681                 error "set striped cdir under striped dir error"
25682
25683         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25684                 error "rename dir under striped dir fails"
25685
25686         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25687                 error "rename dir under different stripes fails"
25688
25689         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25690                 error "rename file under striped dir should succeed"
25691
25692         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25693                 error "rename dir under striped dir should succeed"
25694
25695         rm -rf $DIR/$tdir
25696 }
25697 run_test 300e "check rename under striped directory"
25698
25699 test_300f() {
25700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25701         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25702         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25703                 skip "Need MDS version at least 2.7.55"
25704
25705         local stripe_count
25706         local file
25707
25708         rm -rf $DIR/$tdir
25709         mkdir -p $DIR/$tdir
25710
25711         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25712                 error "set striped dir error"
25713
25714         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25715                 error "set striped dir error"
25716
25717         touch $DIR/$tdir/striped_dir/a
25718         mkdir $DIR/$tdir/striped_dir/dir_a
25719         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25720                 error "create striped dir under striped dir fails"
25721
25722         touch $DIR/$tdir/striped_dir1/b
25723         mkdir $DIR/$tdir/striped_dir1/dir_b
25724         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25725                 error "create striped dir under striped dir fails"
25726
25727         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25728                 error "rename dir under different striped dir should fail"
25729
25730         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25731                 error "rename striped dir under diff striped dir should fail"
25732
25733         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25734                 error "rename file under diff striped dirs fails"
25735
25736         rm -rf $DIR/$tdir
25737 }
25738 run_test 300f "check rename cross striped directory"
25739
25740 test_300_check_default_striped_dir()
25741 {
25742         local dirname=$1
25743         local default_count=$2
25744         local default_index=$3
25745         local stripe_count
25746         local stripe_index
25747         local dir_stripe_index
25748         local dir
25749
25750         echo "checking $dirname $default_count $default_index"
25751         $LFS setdirstripe -D -c $default_count -i $default_index \
25752                                 -H all_char $DIR/$tdir/$dirname ||
25753                 error "set default stripe on striped dir error"
25754         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25755         [ $stripe_count -eq $default_count ] ||
25756                 error "expect $default_count get $stripe_count for $dirname"
25757
25758         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25759         [ $stripe_index -eq $default_index ] ||
25760                 error "expect $default_index get $stripe_index for $dirname"
25761
25762         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25763                                                 error "create dirs failed"
25764
25765         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25766         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25767         for dir in $(find $DIR/$tdir/$dirname/*); do
25768                 stripe_count=$($LFS getdirstripe -c $dir)
25769                 (( $stripe_count == $default_count )) ||
25770                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25771                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25772                 error "stripe count $default_count != $stripe_count for $dir"
25773
25774                 stripe_index=$($LFS getdirstripe -i $dir)
25775                 [ $default_index -eq -1 ] ||
25776                         [ $stripe_index -eq $default_index ] ||
25777                         error "$stripe_index != $default_index for $dir"
25778
25779                 #check default stripe
25780                 stripe_count=$($LFS getdirstripe -D -c $dir)
25781                 [ $stripe_count -eq $default_count ] ||
25782                 error "default count $default_count != $stripe_count for $dir"
25783
25784                 stripe_index=$($LFS getdirstripe -D -i $dir)
25785                 [ $stripe_index -eq $default_index ] ||
25786                 error "default index $default_index != $stripe_index for $dir"
25787         done
25788         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25789 }
25790
25791 test_300g() {
25792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25794                 skip "Need MDS version at least 2.7.55"
25795
25796         local dir
25797         local stripe_count
25798         local stripe_index
25799
25800         mkdir_on_mdt0 $DIR/$tdir
25801         mkdir $DIR/$tdir/normal_dir
25802
25803         #Checking when client cache stripe index
25804         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25805         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25806                 error "create striped_dir failed"
25807
25808         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25809                 error "create dir0 fails"
25810         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25811         [ $stripe_index -eq 0 ] ||
25812                 error "dir0 expect index 0 got $stripe_index"
25813
25814         mkdir $DIR/$tdir/striped_dir/dir1 ||
25815                 error "create dir1 fails"
25816         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25817         [ $stripe_index -eq 1 ] ||
25818                 error "dir1 expect index 1 got $stripe_index"
25819
25820         #check default stripe count/stripe index
25821         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25822         test_300_check_default_striped_dir normal_dir 1 0
25823         test_300_check_default_striped_dir normal_dir -1 1
25824         test_300_check_default_striped_dir normal_dir 2 -1
25825
25826         #delete default stripe information
25827         echo "delete default stripeEA"
25828         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25829                 error "set default stripe on striped dir error"
25830
25831         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25832         for dir in $(find $DIR/$tdir/normal_dir/*); do
25833                 stripe_count=$($LFS getdirstripe -c $dir)
25834                 [ $stripe_count -eq 0 ] ||
25835                         error "expect 1 get $stripe_count for $dir"
25836         done
25837 }
25838 run_test 300g "check default striped directory for normal directory"
25839
25840 test_300h() {
25841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25842         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25843                 skip "Need MDS version at least 2.7.55"
25844
25845         local dir
25846         local stripe_count
25847
25848         mkdir $DIR/$tdir
25849         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25850                 error "set striped dir error"
25851
25852         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25853         test_300_check_default_striped_dir striped_dir 1 0
25854         test_300_check_default_striped_dir striped_dir -1 1
25855         test_300_check_default_striped_dir striped_dir 2 -1
25856
25857         #delete default stripe information
25858         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25859                 error "set default stripe on striped dir error"
25860
25861         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25862         for dir in $(find $DIR/$tdir/striped_dir/*); do
25863                 stripe_count=$($LFS getdirstripe -c $dir)
25864                 [ $stripe_count -eq 0 ] ||
25865                         error "expect 1 get $stripe_count for $dir"
25866         done
25867 }
25868 run_test 300h "check default striped directory for striped directory"
25869
25870 test_300i() {
25871         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25872         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25873         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25874                 skip "Need MDS version at least 2.7.55"
25875
25876         local stripe_count
25877         local file
25878
25879         mkdir $DIR/$tdir
25880
25881         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25882                 error "set striped dir error"
25883
25884         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25885                 error "create files under striped dir failed"
25886
25887         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25888                 error "set striped hashdir error"
25889
25890         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25891                 error "create dir0 under hash dir failed"
25892         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25893                 error "create dir1 under hash dir failed"
25894         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25895                 error "create dir2 under hash dir failed"
25896
25897         # unfortunately, we need to umount to clear dir layout cache for now
25898         # once we fully implement dir layout, we can drop this
25899         umount_client $MOUNT || error "umount failed"
25900         mount_client $MOUNT || error "mount failed"
25901
25902         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25903         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25904         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25905
25906         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25907                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25908                         error "create crush2 dir $tdir/hashdir/d3 failed"
25909                 $LFS find -H crush2 $DIR/$tdir/hashdir
25910                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25911                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25912
25913                 # mkdir with an invalid hash type (hash=fail_val) from client
25914                 # should be replaced on MDS with a valid (default) hash type
25915                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25916                 $LCTL set_param fail_loc=0x1901 fail_val=99
25917                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25918
25919                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25920                 local expect=$(do_facet mds1 \
25921                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25922                 [[ $hash == $expect ]] ||
25923                         error "d99 hash '$hash' != expected hash '$expect'"
25924         fi
25925
25926         #set the stripe to be unknown hash type on read
25927         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25928         $LCTL set_param fail_loc=0x1901 fail_val=99
25929         for ((i = 0; i < 10; i++)); do
25930                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25931                         error "stat f-$i failed"
25932                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25933         done
25934
25935         touch $DIR/$tdir/striped_dir/f0 &&
25936                 error "create under striped dir with unknown hash should fail"
25937
25938         $LCTL set_param fail_loc=0
25939
25940         umount_client $MOUNT || error "umount failed"
25941         mount_client $MOUNT || error "mount failed"
25942
25943         return 0
25944 }
25945 run_test 300i "client handle unknown hash type striped directory"
25946
25947 test_300j() {
25948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25950         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25951                 skip "Need MDS version at least 2.7.55"
25952
25953         local stripe_count
25954         local file
25955
25956         mkdir $DIR/$tdir
25957
25958         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25959         $LCTL set_param fail_loc=0x1702
25960         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25961                 error "set striped dir error"
25962
25963         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25964                 error "create files under striped dir failed"
25965
25966         $LCTL set_param fail_loc=0
25967
25968         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25969
25970         return 0
25971 }
25972 run_test 300j "test large update record"
25973
25974 test_300k() {
25975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25977         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25978                 skip "Need MDS version at least 2.7.55"
25979
25980         # this test needs a huge transaction
25981         local kb
25982         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25983              osd*.$FSNAME-MDT0000.kbytestotal")
25984         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25985
25986         local stripe_count
25987         local file
25988
25989         mkdir $DIR/$tdir
25990
25991         #define OBD_FAIL_LARGE_STRIPE   0x1703
25992         $LCTL set_param fail_loc=0x1703
25993         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25994                 error "set striped dir error"
25995         $LCTL set_param fail_loc=0
25996
25997         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25998                 error "getstripeddir fails"
25999         rm -rf $DIR/$tdir/striped_dir ||
26000                 error "unlink striped dir fails"
26001
26002         return 0
26003 }
26004 run_test 300k "test large striped directory"
26005
26006 test_300l() {
26007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26009         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26010                 skip "Need MDS version at least 2.7.55"
26011
26012         local stripe_index
26013
26014         test_mkdir -p $DIR/$tdir/striped_dir
26015         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26016                         error "chown $RUNAS_ID failed"
26017         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26018                 error "set default striped dir failed"
26019
26020         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26021         $LCTL set_param fail_loc=0x80000158
26022         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26023
26024         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26025         [ $stripe_index -eq 1 ] ||
26026                 error "expect 1 get $stripe_index for $dir"
26027 }
26028 run_test 300l "non-root user to create dir under striped dir with stale layout"
26029
26030 test_300m() {
26031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26032         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26033         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26034                 skip "Need MDS version at least 2.7.55"
26035
26036         mkdir -p $DIR/$tdir/striped_dir
26037         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26038                 error "set default stripes dir error"
26039
26040         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26041
26042         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26043         [ $stripe_count -eq 0 ] ||
26044                         error "expect 0 get $stripe_count for a"
26045
26046         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26047                 error "set default stripes dir error"
26048
26049         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26050
26051         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26052         [ $stripe_count -eq 0 ] ||
26053                         error "expect 0 get $stripe_count for b"
26054
26055         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26056                 error "set default stripes dir error"
26057
26058         mkdir $DIR/$tdir/striped_dir/c &&
26059                 error "default stripe_index is invalid, mkdir c should fails"
26060
26061         rm -rf $DIR/$tdir || error "rmdir fails"
26062 }
26063 run_test 300m "setstriped directory on single MDT FS"
26064
26065 cleanup_300n() {
26066         local list=$(comma_list $(mdts_nodes))
26067
26068         trap 0
26069         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26070 }
26071
26072 test_300n() {
26073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26075         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26076                 skip "Need MDS version at least 2.7.55"
26077         remote_mds_nodsh && skip "remote MDS with nodsh"
26078
26079         local stripe_index
26080         local list=$(comma_list $(mdts_nodes))
26081
26082         trap cleanup_300n RETURN EXIT
26083         mkdir -p $DIR/$tdir
26084         chmod 777 $DIR/$tdir
26085         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26086                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26087                 error "create striped dir succeeds with gid=0"
26088
26089         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26090         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26091                 error "create striped dir fails with gid=-1"
26092
26093         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26094         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26095                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26096                 error "set default striped dir succeeds with gid=0"
26097
26098
26099         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26100         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26101                 error "set default striped dir fails with gid=-1"
26102
26103
26104         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26105         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26106                                         error "create test_dir fails"
26107         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26108                                         error "create test_dir1 fails"
26109         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26110                                         error "create test_dir2 fails"
26111         cleanup_300n
26112 }
26113 run_test 300n "non-root user to create dir under striped dir with default EA"
26114
26115 test_300o() {
26116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26118         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26119                 skip "Need MDS version at least 2.7.55"
26120
26121         local numfree1
26122         local numfree2
26123
26124         mkdir -p $DIR/$tdir
26125
26126         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26127         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26128         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26129                 skip "not enough free inodes $numfree1 $numfree2"
26130         fi
26131
26132         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26133         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26134         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26135                 skip "not enough free space $numfree1 $numfree2"
26136         fi
26137
26138         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26139                 error "setdirstripe fails"
26140
26141         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26142                 error "create dirs fails"
26143
26144         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26145         ls $DIR/$tdir/striped_dir > /dev/null ||
26146                 error "ls striped dir fails"
26147         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26148                 error "unlink big striped dir fails"
26149 }
26150 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26151
26152 test_300p() {
26153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26155         remote_mds_nodsh && skip "remote MDS with nodsh"
26156
26157         mkdir_on_mdt0 $DIR/$tdir
26158
26159         #define OBD_FAIL_OUT_ENOSPC     0x1704
26160         do_facet mds2 lctl set_param fail_loc=0x80001704
26161         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26162                  && error "create striped directory should fail"
26163
26164         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26165
26166         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26167         true
26168 }
26169 run_test 300p "create striped directory without space"
26170
26171 test_300q() {
26172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26173         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26174
26175         local fd=$(free_fd)
26176         local cmd="exec $fd<$tdir"
26177         cd $DIR
26178         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26179         eval $cmd
26180         cmd="exec $fd<&-"
26181         trap "eval $cmd" EXIT
26182         cd $tdir || error "cd $tdir fails"
26183         rmdir  ../$tdir || error "rmdir $tdir fails"
26184         mkdir local_dir && error "create dir succeeds"
26185         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26186         eval $cmd
26187         return 0
26188 }
26189 run_test 300q "create remote directory under orphan directory"
26190
26191 test_300r() {
26192         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26193                 skip "Need MDS version at least 2.7.55" && return
26194         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26195
26196         mkdir $DIR/$tdir
26197
26198         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26199                 error "set striped dir error"
26200
26201         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26202                 error "getstripeddir fails"
26203
26204         local stripe_count
26205         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26206                       awk '/lmv_stripe_count:/ { print $2 }')
26207
26208         [ $MDSCOUNT -ne $stripe_count ] &&
26209                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26210
26211         rm -rf $DIR/$tdir/striped_dir ||
26212                 error "unlink striped dir fails"
26213 }
26214 run_test 300r "test -1 striped directory"
26215
26216 test_300s_helper() {
26217         local count=$1
26218
26219         local stripe_dir=$DIR/$tdir/striped_dir.$count
26220
26221         $LFS mkdir -c $count $stripe_dir ||
26222                 error "lfs mkdir -c error"
26223
26224         $LFS getdirstripe $stripe_dir ||
26225                 error "lfs getdirstripe fails"
26226
26227         local stripe_count
26228         stripe_count=$($LFS getdirstripe $stripe_dir |
26229                       awk '/lmv_stripe_count:/ { print $2 }')
26230
26231         [ $count -ne $stripe_count ] &&
26232                 error_noexit "bad stripe count $stripe_count expected $count"
26233
26234         local dupe_stripes
26235         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26236                 awk '/0x/ {count[$1] += 1}; END {
26237                         for (idx in count) {
26238                                 if (count[idx]>1) {
26239                                         print "index " idx " count " count[idx]
26240                                 }
26241                         }
26242                 }')
26243
26244         if [[ -n "$dupe_stripes" ]] ; then
26245                 lfs getdirstripe $stripe_dir
26246                 error_noexit "Dupe MDT above: $dupe_stripes "
26247         fi
26248
26249         rm -rf $stripe_dir ||
26250                 error_noexit "unlink $stripe_dir fails"
26251 }
26252
26253 test_300s() {
26254         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26255                 skip "Need MDS version at least 2.7.55" && return
26256         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26257
26258         mkdir $DIR/$tdir
26259         for count in $(seq 2 $MDSCOUNT); do
26260                 test_300s_helper $count
26261         done
26262 }
26263 run_test 300s "test lfs mkdir -c without -i"
26264
26265 test_300t() {
26266         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26267                 skip "need MDS 2.14.55 or later"
26268         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26269
26270         local testdir="$DIR/$tdir/striped_dir"
26271         local dir1=$testdir/dir1
26272         local dir2=$testdir/dir2
26273
26274         mkdir -p $testdir
26275
26276         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26277                 error "failed to set default stripe count for $testdir"
26278
26279         mkdir $dir1
26280         local stripe_count=$($LFS getdirstripe -c $dir1)
26281
26282         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26283
26284         local max_count=$((MDSCOUNT - 1))
26285         local mdts=$(comma_list $(mdts_nodes))
26286
26287         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26288         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26289
26290         mkdir $dir2
26291         stripe_count=$($LFS getdirstripe -c $dir2)
26292
26293         (( $stripe_count == $max_count )) || error "wrong stripe count"
26294 }
26295 run_test 300t "test max_mdt_stripecount"
26296
26297 prepare_remote_file() {
26298         mkdir $DIR/$tdir/src_dir ||
26299                 error "create remote source failed"
26300
26301         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26302                  error "cp to remote source failed"
26303         touch $DIR/$tdir/src_dir/a
26304
26305         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26306                 error "create remote target dir failed"
26307
26308         touch $DIR/$tdir/tgt_dir/b
26309
26310         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26311                 error "rename dir cross MDT failed!"
26312
26313         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26314                 error "src_child still exists after rename"
26315
26316         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26317                 error "missing file(a) after rename"
26318
26319         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26320                 error "diff after rename"
26321 }
26322
26323 test_310a() {
26324         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26326
26327         local remote_file=$DIR/$tdir/tgt_dir/b
26328
26329         mkdir -p $DIR/$tdir
26330
26331         prepare_remote_file || error "prepare remote file failed"
26332
26333         #open-unlink file
26334         $OPENUNLINK $remote_file $remote_file ||
26335                 error "openunlink $remote_file failed"
26336         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26337 }
26338 run_test 310a "open unlink remote file"
26339
26340 test_310b() {
26341         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26343
26344         local remote_file=$DIR/$tdir/tgt_dir/b
26345
26346         mkdir -p $DIR/$tdir
26347
26348         prepare_remote_file || error "prepare remote file failed"
26349
26350         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26351         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26352         $CHECKSTAT -t file $remote_file || error "check file failed"
26353 }
26354 run_test 310b "unlink remote file with multiple links while open"
26355
26356 test_310c() {
26357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26358         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26359
26360         local remote_file=$DIR/$tdir/tgt_dir/b
26361
26362         mkdir -p $DIR/$tdir
26363
26364         prepare_remote_file || error "prepare remote file failed"
26365
26366         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26367         multiop_bg_pause $remote_file O_uc ||
26368                         error "mulitop failed for remote file"
26369         MULTIPID=$!
26370         $MULTIOP $DIR/$tfile Ouc
26371         kill -USR1 $MULTIPID
26372         wait $MULTIPID
26373 }
26374 run_test 310c "open-unlink remote file with multiple links"
26375
26376 #LU-4825
26377 test_311() {
26378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26379         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26380         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26381                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26382         remote_mds_nodsh && skip "remote MDS with nodsh"
26383
26384         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26385         local mdts=$(comma_list $(mdts_nodes))
26386
26387         mkdir -p $DIR/$tdir
26388         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26389         createmany -o $DIR/$tdir/$tfile. 1000
26390
26391         # statfs data is not real time, let's just calculate it
26392         old_iused=$((old_iused + 1000))
26393
26394         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26395                         osp.*OST0000*MDT0000.create_count")
26396         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26397                                 osp.*OST0000*MDT0000.max_create_count")
26398         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26399
26400         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26401         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26402         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26403
26404         unlinkmany $DIR/$tdir/$tfile. 1000
26405
26406         do_nodes $mdts "$LCTL set_param -n \
26407                         osp.*OST0000*.max_create_count=$max_count"
26408         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26409                 do_nodes $mdts "$LCTL set_param -n \
26410                                 osp.*OST0000*.create_count=$count"
26411         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26412                         grep "=0" && error "create_count is zero"
26413
26414         local new_iused
26415         for i in $(seq 120); do
26416                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26417                 # system may be too busy to destroy all objs in time, use
26418                 # a somewhat small value to not fail autotest
26419                 [ $((old_iused - new_iused)) -gt 400 ] && break
26420                 sleep 1
26421         done
26422
26423         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26424         [ $((old_iused - new_iused)) -gt 400 ] ||
26425                 error "objs not destroyed after unlink"
26426 }
26427 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26428
26429 zfs_get_objid()
26430 {
26431         local ost=$1
26432         local tf=$2
26433         local fid=($($LFS getstripe $tf | grep 0x))
26434         local seq=${fid[3]#0x}
26435         local objid=${fid[1]}
26436
26437         local vdevdir=$(dirname $(facet_vdevice $ost))
26438         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26439         local zfs_zapid=$(do_facet $ost $cmd |
26440                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26441                           awk '/Object/{getline; print $1}')
26442         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26443                           awk "/$objid = /"'{printf $3}')
26444
26445         echo $zfs_objid
26446 }
26447
26448 zfs_object_blksz() {
26449         local ost=$1
26450         local objid=$2
26451
26452         local vdevdir=$(dirname $(facet_vdevice $ost))
26453         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26454         local blksz=$(do_facet $ost $cmd $objid |
26455                       awk '/dblk/{getline; printf $4}')
26456
26457         case "${blksz: -1}" in
26458                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26459                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26460                 *) ;;
26461         esac
26462
26463         echo $blksz
26464 }
26465
26466 test_312() { # LU-4856
26467         remote_ost_nodsh && skip "remote OST with nodsh"
26468         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26469
26470         local max_blksz=$(do_facet ost1 \
26471                           $ZFS get -p recordsize $(facet_device ost1) |
26472                           awk '!/VALUE/{print $3}')
26473         local tf=$DIR/$tfile
26474
26475         $LFS setstripe -c1 $tf
26476         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26477
26478         # Get ZFS object id
26479         local zfs_objid=$(zfs_get_objid $facet $tf)
26480         # block size change by sequential overwrite
26481         local bs
26482
26483         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26484                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26485
26486                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26487                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26488         done
26489         rm -f $tf
26490
26491         $LFS setstripe -c1 $tf
26492         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26493
26494         # block size change by sequential append write
26495         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26496         zfs_objid=$(zfs_get_objid $facet $tf)
26497         local count
26498
26499         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26500                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26501                         oflag=sync conv=notrunc
26502
26503                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26504                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26505                         error "blksz error, actual $blksz, " \
26506                                 "expected: 2 * $count * $PAGE_SIZE"
26507         done
26508         rm -f $tf
26509
26510         # random write
26511         $LFS setstripe -c1 $tf
26512         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26513         zfs_objid=$(zfs_get_objid $facet $tf)
26514
26515         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26516         blksz=$(zfs_object_blksz $facet $zfs_objid)
26517         (( blksz == PAGE_SIZE )) ||
26518                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26519
26520         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26521         blksz=$(zfs_object_blksz $facet $zfs_objid)
26522         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26523
26524         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26525         blksz=$(zfs_object_blksz $facet $zfs_objid)
26526         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26527 }
26528 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26529
26530 test_313() {
26531         remote_ost_nodsh && skip "remote OST with nodsh"
26532
26533         local file=$DIR/$tfile
26534
26535         rm -f $file
26536         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26537
26538         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26539         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26540         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26541                 error "write should failed"
26542         do_facet ost1 "$LCTL set_param fail_loc=0"
26543         rm -f $file
26544 }
26545 run_test 313 "io should fail after last_rcvd update fail"
26546
26547 test_314() {
26548         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26549
26550         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26551         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26552         rm -f $DIR/$tfile
26553         wait_delete_completed
26554         do_facet ost1 "$LCTL set_param fail_loc=0"
26555 }
26556 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26557
26558 test_315() { # LU-618
26559         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26560
26561         local file=$DIR/$tfile
26562         rm -f $file
26563
26564         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26565                 error "multiop file write failed"
26566         $MULTIOP $file oO_RDONLY:r4063232_c &
26567         PID=$!
26568
26569         sleep 2
26570
26571         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26572         kill -USR1 $PID
26573
26574         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26575         rm -f $file
26576 }
26577 run_test 315 "read should be accounted"
26578
26579 test_316() {
26580         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26581         large_xattr_enabled || skip "ea_inode feature disabled"
26582
26583         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26584         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26585         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26586         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26587
26588         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26589 }
26590 run_test 316 "lfs migrate of file with large_xattr enabled"
26591
26592 test_317() {
26593         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26594                 skip "Need MDS version at least 2.11.53"
26595         if [ "$ost1_FSTYPE" == "zfs" ]; then
26596                 skip "LU-10370: no implementation for ZFS"
26597         fi
26598
26599         local trunc_sz
26600         local grant_blk_size
26601
26602         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26603                         awk '/grant_block_size:/ { print $2; exit; }')
26604         #
26605         # Create File of size 5M. Truncate it to below size's and verify
26606         # blocks count.
26607         #
26608         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26609                 error "Create file $DIR/$tfile failed"
26610         stack_trap "rm -f $DIR/$tfile" EXIT
26611
26612         for trunc_sz in 2097152 4097 4000 509 0; do
26613                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26614                         error "truncate $tfile to $trunc_sz failed"
26615                 local sz=$(stat --format=%s $DIR/$tfile)
26616                 local blk=$(stat --format=%b $DIR/$tfile)
26617                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26618                                      grant_blk_size) * 8))
26619
26620                 if [[ $blk -ne $trunc_blk ]]; then
26621                         $(which stat) $DIR/$tfile
26622                         error "Expected Block $trunc_blk got $blk for $tfile"
26623                 fi
26624
26625                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26626                         error "Expected Size $trunc_sz got $sz for $tfile"
26627         done
26628
26629         #
26630         # sparse file test
26631         # Create file with a hole and write actual 65536 bytes which aligned
26632         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26633         #
26634         local bs=65536
26635         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26636                 error "Create file : $DIR/$tfile"
26637
26638         #
26639         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26640         # blocks. The block count must drop to 8.
26641         #
26642         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26643                 ((bs - grant_blk_size) + 1)))
26644         $TRUNCATE $DIR/$tfile $trunc_sz ||
26645                 error "truncate $tfile to $trunc_sz failed"
26646
26647         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26648         sz=$(stat --format=%s $DIR/$tfile)
26649         blk=$(stat --format=%b $DIR/$tfile)
26650
26651         if [[ $blk -ne $trunc_bsz ]]; then
26652                 $(which stat) $DIR/$tfile
26653                 error "Expected Block $trunc_bsz got $blk for $tfile"
26654         fi
26655
26656         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26657                 error "Expected Size $trunc_sz got $sz for $tfile"
26658 }
26659 run_test 317 "Verify blocks get correctly update after truncate"
26660
26661 test_318() {
26662         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26663         local old_max_active=$($LCTL get_param -n \
26664                             ${llite_name}.max_read_ahead_async_active \
26665                             2>/dev/null)
26666
26667         $LCTL set_param llite.*.max_read_ahead_async_active=256
26668         local max_active=$($LCTL get_param -n \
26669                            ${llite_name}.max_read_ahead_async_active \
26670                            2>/dev/null)
26671         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26672
26673         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26674                 error "set max_read_ahead_async_active should succeed"
26675
26676         $LCTL set_param llite.*.max_read_ahead_async_active=512
26677         max_active=$($LCTL get_param -n \
26678                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26679         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26680
26681         # restore @max_active
26682         [ $old_max_active -ne 0 ] && $LCTL set_param \
26683                 llite.*.max_read_ahead_async_active=$old_max_active
26684
26685         local old_threshold=$($LCTL get_param -n \
26686                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26687         local max_per_file_mb=$($LCTL get_param -n \
26688                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26689
26690         local invalid=$(($max_per_file_mb + 1))
26691         $LCTL set_param \
26692                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26693                         && error "set $invalid should fail"
26694
26695         local valid=$(($invalid - 1))
26696         $LCTL set_param \
26697                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26698                         error "set $valid should succeed"
26699         local threshold=$($LCTL get_param -n \
26700                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26701         [ $threshold -eq $valid ] || error \
26702                 "expect threshold $valid got $threshold"
26703         $LCTL set_param \
26704                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26705 }
26706 run_test 318 "Verify async readahead tunables"
26707
26708 test_319() {
26709         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26710
26711         local before=$(date +%s)
26712         local evict
26713         local mdir=$DIR/$tdir
26714         local file=$mdir/xxx
26715
26716         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26717         touch $file
26718
26719 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26720         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26721         $LFS migrate -m1 $mdir &
26722
26723         sleep 1
26724         dd if=$file of=/dev/null
26725         wait
26726         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26727           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26728
26729         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26730 }
26731 run_test 319 "lost lease lock on migrate error"
26732
26733 test_360() {
26734         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26735                 skip "Need OST version at least 2.15.58.96"
26736         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26737
26738         check_set_fallocate_or_skip
26739         local param="osd-ldiskfs.delayed_unlink_mb"
26740         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
26741
26742         do_facet ost1 "$LCTL set_param $param=1MiB"
26743         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
26744
26745         mkdir $DIR/$tdir/
26746         do_facet ost1 $LCTL set_param debug=+inode
26747         do_facet ost1 $LCTL clear
26748         local files=100
26749
26750         for ((i = 0; i < $files; i++)); do
26751                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26752                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26753         done
26754         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26755
26756         for ((i = 0; i < $files; i++)); do
26757                 unlink $DIR/$tdir/$tfile.$i ||
26758                         error "unlink $DIR/$tdir/$tfile.$i failed"
26759         done
26760
26761         local count=0
26762         local loop
26763
26764         for (( loop = 0; loop < 30 && count < min; loop++)); do
26765                 sleep 1
26766                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26767                 echo "Count[$loop]: $count"
26768         done
26769         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26770 }
26771 run_test 360 "ldiskfs unlink in a separate thread"
26772
26773 test_398a() { # LU-4198
26774         local ost1_imp=$(get_osc_import_name client ost1)
26775         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26776                          cut -d'.' -f2)
26777
26778         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26779         stack_trap "rm -f $DIR/$tfile"
26780         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26781
26782         # request a new lock on client
26783         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26784
26785         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26786         local lock_count=$($LCTL get_param -n \
26787                            ldlm.namespaces.$imp_name.lru_size)
26788         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26789
26790         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26791
26792         # no lock cached, should use lockless DIO and not enqueue new lock
26793         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26794         lock_count=$($LCTL get_param -n \
26795                      ldlm.namespaces.$imp_name.lru_size)
26796         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26797
26798         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26799
26800         # no lock cached, should use locked DIO append
26801         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26802                 conv=notrunc || error "DIO append failed"
26803         lock_count=$($LCTL get_param -n \
26804                      ldlm.namespaces.$imp_name.lru_size)
26805         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26806 }
26807 run_test 398a "direct IO should cancel lock otherwise lockless"
26808
26809 test_398b() { # LU-4198
26810         local before=$(date +%s)
26811         local njobs=4
26812         local size=48
26813
26814         which fio || skip_env "no fio installed"
26815         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26816         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26817
26818         # Single page, multiple pages, stripe size, 4*stripe size
26819         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26820                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26821                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26822                         --numjobs=$njobs --fallocate=none \
26823                         --iodepth=16 --allow_file_create=0 \
26824                         --size=$((size/njobs))M \
26825                         --filename=$DIR/$tfile &
26826                 bg_pid=$!
26827
26828                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26829                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26830                         --numjobs=$njobs --fallocate=none \
26831                         --iodepth=16 --allow_file_create=0 \
26832                         --size=$((size/njobs))M \
26833                         --filename=$DIR/$tfile || true
26834                 wait $bg_pid
26835         done
26836
26837         evict=$(do_facet client $LCTL get_param \
26838                 osc.$FSNAME-OST*-osc-*/state |
26839             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26840
26841         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26842                 (do_facet client $LCTL get_param \
26843                         osc.$FSNAME-OST*-osc-*/state;
26844                     error "eviction happened: $evict before:$before")
26845
26846         rm -f $DIR/$tfile
26847 }
26848 run_test 398b "DIO and buffer IO race"
26849
26850 test_398c() { # LU-4198
26851         local ost1_imp=$(get_osc_import_name client ost1)
26852         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26853                          cut -d'.' -f2)
26854
26855         which fio || skip_env "no fio installed"
26856
26857         saved_debug=$($LCTL get_param -n debug)
26858         $LCTL set_param debug=0
26859
26860         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26861         ((size /= 1024)) # by megabytes
26862         ((size /= 2)) # write half of the OST at most
26863         [ $size -gt 40 ] && size=40 #reduce test time anyway
26864
26865         $LFS setstripe -c 1 $DIR/$tfile
26866
26867         # it seems like ldiskfs reserves more space than necessary if the
26868         # writing blocks are not mapped, so it extends the file firstly
26869         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26870         cancel_lru_locks osc
26871
26872         # clear and verify rpc_stats later
26873         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26874
26875         local njobs=4
26876         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26877         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26878                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26879                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26880                 --filename=$DIR/$tfile
26881         [ $? -eq 0 ] || error "fio write error"
26882
26883         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26884                 error "Locks were requested while doing AIO"
26885
26886         # get the percentage of 1-page I/O
26887         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26888                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26889                 awk '{print $7}')
26890         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26891
26892         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26893         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26894                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26895                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26896                 --filename=$DIR/$tfile
26897         [ $? -eq 0 ] || error "fio mixed read write error"
26898
26899         echo "AIO with large block size ${size}M"
26900         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26901                 --numjobs=1 --fallocate=none --ioengine=libaio \
26902                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26903                 --filename=$DIR/$tfile
26904         [ $? -eq 0 ] || error "fio large block size failed"
26905
26906         rm -f $DIR/$tfile
26907         $LCTL set_param debug="$saved_debug"
26908 }
26909 run_test 398c "run fio to test AIO"
26910
26911 test_398d() { #  LU-13846
26912         which aiocp || skip_env "no aiocp installed"
26913         local aio_file=$DIR/$tfile.aio
26914
26915         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26916
26917         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26918         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26919         stack_trap "rm -f $DIR/$tfile $aio_file"
26920
26921         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26922
26923         # test memory unaligned aio
26924         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26925                 error "unaligned aio failed"
26926         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26927
26928         rm -f $DIR/$tfile $aio_file
26929 }
26930 run_test 398d "run aiocp to verify block size > stripe size"
26931
26932 test_398e() {
26933         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26934         touch $DIR/$tfile.new
26935         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26936 }
26937 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26938
26939 test_398f() { #  LU-14687
26940         which aiocp || skip_env "no aiocp installed"
26941         local aio_file=$DIR/$tfile.aio
26942
26943         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26944
26945         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26946         stack_trap "rm -f $DIR/$tfile $aio_file"
26947
26948         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26949         $LCTL set_param fail_loc=0x1418
26950         # make sure we don't crash and fail properly
26951         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26952                 error "aio with page allocation failure succeeded"
26953         $LCTL set_param fail_loc=0
26954         diff $DIR/$tfile $aio_file
26955         [[ $? != 0 ]] || error "no diff after failed aiocp"
26956 }
26957 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26958
26959 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26960 # stripe and i/o size must be > stripe size
26961 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26962 # single RPC in flight.  This test shows async DIO submission is working by
26963 # showing multiple RPCs in flight.
26964 test_398g() { #  LU-13798
26965         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26966
26967         # We need to do some i/o first to acquire enough grant to put our RPCs
26968         # in flight; otherwise a new connection may not have enough grant
26969         # available
26970         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26971                 error "parallel dio failed"
26972         stack_trap "rm -f $DIR/$tfile"
26973
26974         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26975         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26976         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26977         stack_trap "$LCTL set_param -n $pages_per_rpc"
26978
26979         # Recreate file so it's empty
26980         rm -f $DIR/$tfile
26981         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26982         #Pause rpc completion to guarantee we see multiple rpcs in flight
26983         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26984         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26985         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26986
26987         # Clear rpc stats
26988         $LCTL set_param osc.*.rpc_stats=c
26989
26990         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26991                 error "parallel dio failed"
26992         stack_trap "rm -f $DIR/$tfile"
26993
26994         $LCTL get_param osc.*-OST0000-*.rpc_stats
26995         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26996                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26997                 grep "8:" | awk '{print $8}')
26998         # We look at the "8 rpcs in flight" field, and verify A) it is present
26999         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27000         # as expected for an 8M DIO to a file with 1M stripes.
27001         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
27002
27003         # Verify turning off parallel dio works as expected
27004         # Clear rpc stats
27005         $LCTL set_param osc.*.rpc_stats=c
27006         $LCTL set_param llite.*.parallel_dio=0
27007         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27008
27009         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27010                 error "dio with parallel dio disabled failed"
27011
27012         # Ideally, we would see only one RPC in flight here, but there is an
27013         # unavoidable race between i/o completion and RPC in flight counting,
27014         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27015         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27016         # So instead we just verify it's always < 8.
27017         $LCTL get_param osc.*-OST0000-*.rpc_stats
27018         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27019                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27020                 grep '^$' -B1 | grep . | awk '{print $1}')
27021         [ $ret != "8:" ] ||
27022                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27023 }
27024 run_test 398g "verify parallel dio async RPC submission"
27025
27026 test_398h() { #  LU-13798
27027         local dio_file=$DIR/$tfile.dio
27028
27029         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27030
27031         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27032         stack_trap "rm -f $DIR/$tfile $dio_file"
27033
27034         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27035                 error "parallel dio failed"
27036         diff $DIR/$tfile $dio_file
27037         [[ $? == 0 ]] || error "file diff after aiocp"
27038 }
27039 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27040
27041 test_398i() { #  LU-13798
27042         local dio_file=$DIR/$tfile.dio
27043
27044         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27045
27046         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27047         stack_trap "rm -f $DIR/$tfile $dio_file"
27048
27049         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27050         $LCTL set_param fail_loc=0x1418
27051         # make sure we don't crash and fail properly
27052         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27053                 error "parallel dio page allocation failure succeeded"
27054         diff $DIR/$tfile $dio_file
27055         [[ $? != 0 ]] || error "no diff after failed aiocp"
27056 }
27057 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27058
27059 test_398j() { #  LU-13798
27060         # Stripe size > RPC size but less than i/o size tests split across
27061         # stripes and RPCs for individual i/o op
27062         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27063
27064         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27065         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27066         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27067         stack_trap "$LCTL set_param -n $pages_per_rpc"
27068
27069         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27070                 error "parallel dio write failed"
27071         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27072
27073         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27074                 error "parallel dio read failed"
27075         diff $DIR/$tfile $DIR/$tfile.2
27076         [[ $? == 0 ]] || error "file diff after parallel dio read"
27077 }
27078 run_test 398j "test parallel dio where stripe size > rpc_size"
27079
27080 test_398k() { #  LU-13798
27081         wait_delete_completed
27082         wait_mds_ost_sync
27083
27084         # 4 stripe file; we will cause out of space on OST0
27085         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27086
27087         # Fill OST0 (if it's not too large)
27088         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27089                    head -n1)
27090         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27091                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27092         fi
27093         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27094         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27095                 error "dd should fill OST0"
27096         stack_trap "rm -f $DIR/$tfile.1"
27097
27098         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27099         err=$?
27100
27101         ls -la $DIR/$tfile
27102         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27103                 error "file is not 0 bytes in size"
27104
27105         # dd above should not succeed, but don't error until here so we can
27106         # get debug info above
27107         [[ $err != 0 ]] ||
27108                 error "parallel dio write with enospc succeeded"
27109         stack_trap "rm -f $DIR/$tfile"
27110 }
27111 run_test 398k "test enospc on first stripe"
27112
27113 test_398l() { #  LU-13798
27114         wait_delete_completed
27115         wait_mds_ost_sync
27116
27117         # 4 stripe file; we will cause out of space on OST0
27118         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27119         # happens on the second i/o chunk we issue
27120         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27121
27122         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27123         stack_trap "rm -f $DIR/$tfile"
27124
27125         # Fill OST0 (if it's not too large)
27126         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27127                    head -n1)
27128         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27129                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27130         fi
27131         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27132         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27133                 error "dd should fill OST0"
27134         stack_trap "rm -f $DIR/$tfile.1"
27135
27136         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27137         err=$?
27138         stack_trap "rm -f $DIR/$tfile.2"
27139
27140         # Check that short write completed as expected
27141         ls -la $DIR/$tfile.2
27142         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27143                 error "file is not 1M in size"
27144
27145         # dd above should not succeed, but don't error until here so we can
27146         # get debug info above
27147         [[ $err != 0 ]] ||
27148                 error "parallel dio write with enospc succeeded"
27149
27150         # Truncate source file to same length as output file and diff them
27151         $TRUNCATE $DIR/$tfile 1048576
27152         diff $DIR/$tfile $DIR/$tfile.2
27153         [[ $? == 0 ]] || error "data incorrect after short write"
27154 }
27155 run_test 398l "test enospc on intermediate stripe/RPC"
27156
27157 test_398m() { #  LU-13798
27158         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27159
27160         # Set up failure on OST0, the first stripe:
27161         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27162         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27163         # OST0 is on ost1, OST1 is on ost2.
27164         # So this fail_val specifies OST0
27165         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27166         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27167
27168         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27169                 error "parallel dio write with failure on first stripe succeeded"
27170         stack_trap "rm -f $DIR/$tfile"
27171         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27172
27173         # Place data in file for read
27174         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27175                 error "parallel dio write failed"
27176
27177         # Fail read on OST0, first stripe
27178         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27179         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27180         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27181                 error "parallel dio read with error on first stripe succeeded"
27182         rm -f $DIR/$tfile.2
27183         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27184
27185         # Switch to testing on OST1, second stripe
27186         # Clear file contents, maintain striping
27187         echo > $DIR/$tfile
27188         # Set up failure on OST1, second stripe:
27189         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27190         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27191
27192         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27193                 error "parallel dio write with failure on second stripe succeeded"
27194         stack_trap "rm -f $DIR/$tfile"
27195         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27196
27197         # Place data in file for read
27198         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27199                 error "parallel dio write failed"
27200
27201         # Fail read on OST1, second stripe
27202         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27203         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27204         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27205                 error "parallel dio read with error on second stripe succeeded"
27206         rm -f $DIR/$tfile.2
27207         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27208 }
27209 run_test 398m "test RPC failures with parallel dio"
27210
27211 # Parallel submission of DIO should not cause problems for append, but it's
27212 # important to verify.
27213 test_398n() { #  LU-13798
27214         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27215
27216         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27217                 error "dd to create source file failed"
27218         stack_trap "rm -f $DIR/$tfile"
27219
27220         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27221                 error "parallel dio write with failure on second stripe succeeded"
27222         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27223         diff $DIR/$tfile $DIR/$tfile.1
27224         [[ $? == 0 ]] || error "data incorrect after append"
27225
27226 }
27227 run_test 398n "test append with parallel DIO"
27228
27229 test_398o() {
27230         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27231 }
27232 run_test 398o "right kms with DIO"
27233
27234 test_398p()
27235 {
27236         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27237         which aiocp || skip_env "no aiocp installed"
27238
27239         local stripe_size=$((1024 * 1024)) #1 MiB
27240         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27241         local file_size=$((25 * stripe_size))
27242
27243         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27244         stack_trap "rm -f $DIR/$tfile*"
27245         # Just a bit bigger than the largest size in the test set below
27246         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27247                 error "buffered i/o to create file failed"
27248
27249         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27250                 $((stripe_size * 4)); do
27251
27252                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27253
27254                 echo "bs: $bs, file_size $file_size"
27255                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27256                         $DIR/$tfile.1 $DIR/$tfile.2 &
27257                 pid_dio1=$!
27258                 # Buffered I/O with similar but not the same block size
27259                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27260                         conv=notrunc &
27261                 pid_bio2=$!
27262                 wait $pid_dio1
27263                 rc1=$?
27264                 wait $pid_bio2
27265                 rc2=$?
27266                 if (( rc1 != 0 )); then
27267                         error "aio copy 1 w/bsize $bs failed: $rc1"
27268                 fi
27269                 if (( rc2 != 0 )); then
27270                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27271                 fi
27272
27273                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27274                         error "size incorrect"
27275                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27276                         error "files differ, bsize $bs"
27277                 rm -f $DIR/$tfile.2
27278         done
27279 }
27280 run_test 398p "race aio with buffered i/o"
27281
27282 test_398q()
27283 {
27284         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27285
27286         local stripe_size=$((1024 * 1024)) #1 MiB
27287         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27288         local file_size=$((25 * stripe_size))
27289
27290         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27291         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27292
27293         # Just a bit bigger than the largest size in the test set below
27294         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27295                 error "buffered i/o to create file failed"
27296
27297         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27298                 $((stripe_size * 4)); do
27299
27300                 echo "bs: $bs, file_size $file_size"
27301                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27302                         conv=notrunc oflag=direct iflag=direct &
27303                 pid_dio1=$!
27304                 # Buffered I/O with similar but not the same block size
27305                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27306                         conv=notrunc &
27307                 pid_bio2=$!
27308                 wait $pid_dio1
27309                 rc1=$?
27310                 wait $pid_bio2
27311                 rc2=$?
27312                 if (( rc1 != 0 )); then
27313                         error "dio copy 1 w/bsize $bs failed: $rc1"
27314                 fi
27315                 if (( rc2 != 0 )); then
27316                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27317                 fi
27318
27319                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27320                         error "size incorrect"
27321                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27322                         error "files differ, bsize $bs"
27323         done
27324
27325         rm -f $DIR/$tfile*
27326 }
27327 run_test 398q "race dio with buffered i/o"
27328
27329 test_fake_rw() {
27330         local read_write=$1
27331         if [ "$read_write" = "write" ]; then
27332                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27333         elif [ "$read_write" = "read" ]; then
27334                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27335         else
27336                 error "argument error"
27337         fi
27338
27339         # turn off debug for performance testing
27340         local saved_debug=$($LCTL get_param -n debug)
27341         $LCTL set_param debug=0
27342
27343         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27344
27345         # get ost1 size - $FSNAME-OST0000
27346         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27347         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27348         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27349
27350         if [ "$read_write" = "read" ]; then
27351                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27352         fi
27353
27354         local start_time=$(date +%s.%N)
27355         $dd_cmd bs=1M count=$blocks oflag=sync ||
27356                 error "real dd $read_write error"
27357         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27358
27359         if [ "$read_write" = "write" ]; then
27360                 rm -f $DIR/$tfile
27361         fi
27362
27363         # define OBD_FAIL_OST_FAKE_RW           0x238
27364         do_facet ost1 $LCTL set_param fail_loc=0x238
27365
27366         local start_time=$(date +%s.%N)
27367         $dd_cmd bs=1M count=$blocks oflag=sync ||
27368                 error "fake dd $read_write error"
27369         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27370
27371         if [ "$read_write" = "write" ]; then
27372                 # verify file size
27373                 cancel_lru_locks osc
27374                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27375                         error "$tfile size not $blocks MB"
27376         fi
27377         do_facet ost1 $LCTL set_param fail_loc=0
27378
27379         echo "fake $read_write $duration_fake vs. normal $read_write" \
27380                 "$duration in seconds"
27381         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27382                 error_not_in_vm "fake write is slower"
27383
27384         $LCTL set_param -n debug="$saved_debug"
27385         rm -f $DIR/$tfile
27386 }
27387 test_399a() { # LU-7655 for OST fake write
27388         remote_ost_nodsh && skip "remote OST with nodsh"
27389
27390         test_fake_rw write
27391 }
27392 run_test 399a "fake write should not be slower than normal write"
27393
27394 test_399b() { # LU-8726 for OST fake read
27395         remote_ost_nodsh && skip "remote OST with nodsh"
27396         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27397                 skip_env "ldiskfs only test"
27398         fi
27399
27400         test_fake_rw read
27401 }
27402 run_test 399b "fake read should not be slower than normal read"
27403
27404 test_400a() { # LU-1606, was conf-sanity test_74
27405         if ! which $CC > /dev/null 2>&1; then
27406                 skip_env "$CC is not installed"
27407         fi
27408
27409         local extra_flags=''
27410         local out=$TMP/$tfile
27411         local prefix=/usr/include/lustre
27412         local prog
27413
27414         # Oleg removes .c files in his test rig so test if any c files exist
27415         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27416                 skip_env "Needed .c test files are missing"
27417
27418         if ! [[ -d $prefix ]]; then
27419                 # Assume we're running in tree and fixup the include path.
27420                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27421                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27422                 extra_flags+=" -L$LUSTRE/utils/.libs"
27423         fi
27424
27425         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27426                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27427                         error "client api broken"
27428         done
27429         rm -f $out
27430 }
27431 run_test 400a "Lustre client api program can compile and link"
27432
27433 test_400b() { # LU-1606, LU-5011
27434         local header
27435         local out=$TMP/$tfile
27436         local prefix=/usr/include/linux/lustre
27437
27438         # We use a hard coded prefix so that this test will not fail
27439         # when run in tree. There are headers in lustre/include/lustre/
27440         # that are not packaged (like lustre_idl.h) and have more
27441         # complicated include dependencies (like config.h and lnet/types.h).
27442         # Since this test about correct packaging we just skip them when
27443         # they don't exist (see below) rather than try to fixup cppflags.
27444
27445         if ! which $CC > /dev/null 2>&1; then
27446                 skip_env "$CC is not installed"
27447         fi
27448
27449         for header in $prefix/*.h; do
27450                 if ! [[ -f "$header" ]]; then
27451                         continue
27452                 fi
27453
27454                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27455                         continue # lustre_ioctl.h is internal header
27456                 fi
27457
27458                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27459                         error "cannot compile '$header'"
27460         done
27461         rm -f $out
27462 }
27463 run_test 400b "packaged headers can be compiled"
27464
27465 test_401a() { #LU-7437
27466         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27467         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27468
27469         #count the number of parameters by "list_param -R"
27470         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27471         #count the number of parameters by listing proc files
27472         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27473         echo "proc_dirs='$proc_dirs'"
27474         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27475         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27476                       sort -u | wc -l)
27477
27478         [ $params -eq $procs ] ||
27479                 error "found $params parameters vs. $procs proc files"
27480
27481         # test the list_param -D option only returns directories
27482         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27483         #count the number of parameters by listing proc directories
27484         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27485                 sort -u | wc -l)
27486
27487         [ $params -eq $procs ] ||
27488                 error "found $params parameters vs. $procs proc files"
27489 }
27490 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27491
27492 test_401b() {
27493         # jobid_var may not allow arbitrary values, so use jobid_name
27494         # if available
27495         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27496                 local testname=jobid_name tmp='testing%p'
27497         else
27498                 local testname=jobid_var tmp=testing
27499         fi
27500
27501         local save=$($LCTL get_param -n $testname)
27502
27503         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27504                 error "no error returned when setting bad parameters"
27505
27506         local jobid_new=$($LCTL get_param -n foe $testname baz)
27507         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27508
27509         $LCTL set_param -n fog=bam $testname=$save bat=fog
27510         local jobid_old=$($LCTL get_param -n foe $testname bag)
27511         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27512 }
27513 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27514
27515 test_401c() {
27516         # jobid_var may not allow arbitrary values, so use jobid_name
27517         # if available
27518         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27519                 local testname=jobid_name
27520         else
27521                 local testname=jobid_var
27522         fi
27523
27524         local jobid_var_old=$($LCTL get_param -n $testname)
27525         local jobid_var_new
27526
27527         $LCTL set_param $testname= &&
27528                 error "no error returned for 'set_param a='"
27529
27530         jobid_var_new=$($LCTL get_param -n $testname)
27531         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27532                 error "$testname was changed by setting without value"
27533
27534         $LCTL set_param $testname &&
27535                 error "no error returned for 'set_param a'"
27536
27537         jobid_var_new=$($LCTL get_param -n $testname)
27538         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27539                 error "$testname was changed by setting without value"
27540 }
27541 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27542
27543 test_401d() {
27544         # jobid_var may not allow arbitrary values, so use jobid_name
27545         # if available
27546         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27547                 local testname=jobid_name new_value='foo=bar%p'
27548         else
27549                 local testname=jobid_var new_valuie=foo=bar
27550         fi
27551
27552         local jobid_var_old=$($LCTL get_param -n $testname)
27553         local jobid_var_new
27554
27555         $LCTL set_param $testname=$new_value ||
27556                 error "'set_param a=b' did not accept a value containing '='"
27557
27558         jobid_var_new=$($LCTL get_param -n $testname)
27559         [[ "$jobid_var_new" == "$new_value" ]] ||
27560                 error "'set_param a=b' failed on a value containing '='"
27561
27562         # Reset the $testname to test the other format
27563         $LCTL set_param $testname=$jobid_var_old
27564         jobid_var_new=$($LCTL get_param -n $testname)
27565         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27566                 error "failed to reset $testname"
27567
27568         $LCTL set_param $testname $new_value ||
27569                 error "'set_param a b' did not accept a value containing '='"
27570
27571         jobid_var_new=$($LCTL get_param -n $testname)
27572         [[ "$jobid_var_new" == "$new_value" ]] ||
27573                 error "'set_param a b' failed on a value containing '='"
27574
27575         $LCTL set_param $testname $jobid_var_old
27576         jobid_var_new=$($LCTL get_param -n $testname)
27577         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27578                 error "failed to reset $testname"
27579 }
27580 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27581
27582 test_401e() { # LU-14779
27583         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27584                 error "lctl list_param MGC* failed"
27585         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27586         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27587                 error "lctl get_param lru_size failed"
27588 }
27589 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27590
27591 test_402() {
27592         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27593         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27594                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27595         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27596                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27597                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27598         remote_mds_nodsh && skip "remote MDS with nodsh"
27599
27600         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27601 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27602         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27603         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27604                 echo "Touch failed - OK"
27605 }
27606 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27607
27608 test_403() {
27609         local file1=$DIR/$tfile.1
27610         local file2=$DIR/$tfile.2
27611         local tfile=$TMP/$tfile
27612
27613         rm -f $file1 $file2 $tfile
27614
27615         touch $file1
27616         ln $file1 $file2
27617
27618         # 30 sec OBD_TIMEOUT in ll_getattr()
27619         # right before populating st_nlink
27620         $LCTL set_param fail_loc=0x80001409
27621         stat -c %h $file1 > $tfile &
27622
27623         # create an alias, drop all locks and reclaim the dentry
27624         < $file2
27625         cancel_lru_locks mdc
27626         cancel_lru_locks osc
27627         sysctl -w vm.drop_caches=2
27628
27629         wait
27630
27631         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27632
27633         rm -f $tfile $file1 $file2
27634 }
27635 run_test 403 "i_nlink should not drop to zero due to aliasing"
27636
27637 test_404() { # LU-6601
27638         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27639                 skip "Need server version newer than 2.8.52"
27640         remote_mds_nodsh && skip "remote MDS with nodsh"
27641
27642         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27643                 awk '/osp .*-osc-MDT/ { print $4}')
27644
27645         local osp
27646         for osp in $mosps; do
27647                 echo "Deactivate: " $osp
27648                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27649                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27650                         awk -vp=$osp '$4 == p { print $2 }')
27651                 [ $stat = IN ] || {
27652                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27653                         error "deactivate error"
27654                 }
27655                 echo "Activate: " $osp
27656                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27657                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27658                         awk -vp=$osp '$4 == p { print $2 }')
27659                 [ $stat = UP ] || {
27660                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27661                         error "activate error"
27662                 }
27663         done
27664 }
27665 run_test 404 "validate manual {de}activated works properly for OSPs"
27666
27667 test_405() {
27668         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27669         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27670                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27671                         skip "Layout swap lock is not supported"
27672
27673         check_swap_layouts_support
27674         check_swap_layout_no_dom $DIR
27675
27676         test_mkdir $DIR/$tdir
27677         swap_lock_test -d $DIR/$tdir ||
27678                 error "One layout swap locked test failed"
27679 }
27680 run_test 405 "Various layout swap lock tests"
27681
27682 test_406() {
27683         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27684         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27685         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27687         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27688                 skip "Need MDS version at least 2.8.50"
27689
27690         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27691         local test_pool=$TESTNAME
27692
27693         pool_add $test_pool || error "pool_add failed"
27694         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27695                 error "pool_add_targets failed"
27696
27697         save_layout_restore_at_exit $MOUNT
27698
27699         # parent set default stripe count only, child will stripe from both
27700         # parent and fs default
27701         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27702                 error "setstripe $MOUNT failed"
27703         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27704         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27705         for i in $(seq 10); do
27706                 local f=$DIR/$tdir/$tfile.$i
27707                 touch $f || error "touch failed"
27708                 local count=$($LFS getstripe -c $f)
27709                 [ $count -eq $OSTCOUNT ] ||
27710                         error "$f stripe count $count != $OSTCOUNT"
27711                 local offset=$($LFS getstripe -i $f)
27712                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27713                 local size=$($LFS getstripe -S $f)
27714                 [ $size -eq $((def_stripe_size * 2)) ] ||
27715                         error "$f stripe size $size != $((def_stripe_size * 2))"
27716                 local pool=$($LFS getstripe -p $f)
27717                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27718         done
27719
27720         # change fs default striping, delete parent default striping, now child
27721         # will stripe from new fs default striping only
27722         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27723                 error "change $MOUNT default stripe failed"
27724         $LFS setstripe -c 0 $DIR/$tdir ||
27725                 error "delete $tdir default stripe failed"
27726         for i in $(seq 11 20); do
27727                 local f=$DIR/$tdir/$tfile.$i
27728                 touch $f || error "touch $f failed"
27729                 local count=$($LFS getstripe -c $f)
27730                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27731                 local offset=$($LFS getstripe -i $f)
27732                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27733                 local size=$($LFS getstripe -S $f)
27734                 [ $size -eq $def_stripe_size ] ||
27735                         error "$f stripe size $size != $def_stripe_size"
27736                 local pool=$($LFS getstripe -p $f)
27737                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27738         done
27739
27740         unlinkmany $DIR/$tdir/$tfile. 1 20
27741
27742         local f=$DIR/$tdir/$tfile
27743         pool_remove_all_targets $test_pool $f
27744         pool_remove $test_pool $f
27745 }
27746 run_test 406 "DNE support fs default striping"
27747
27748 test_407() {
27749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27750         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27751                 skip "Need MDS version at least 2.8.55"
27752         remote_mds_nodsh && skip "remote MDS with nodsh"
27753
27754         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27755                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27756         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27757                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27758         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27759
27760         #define OBD_FAIL_DT_TXN_STOP    0x2019
27761         for idx in $(seq $MDSCOUNT); do
27762                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27763         done
27764         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27765         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27766                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27767         true
27768 }
27769 run_test 407 "transaction fail should cause operation fail"
27770
27771 test_408() {
27772         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27773
27774         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27775         lctl set_param fail_loc=0x8000040a
27776         # let ll_prepare_partial_page() fail
27777         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27778
27779         rm -f $DIR/$tfile
27780
27781         # create at least 100 unused inodes so that
27782         # shrink_icache_memory(0) should not return 0
27783         touch $DIR/$tfile-{0..100}
27784         rm -f $DIR/$tfile-{0..100}
27785         sync
27786
27787         echo 2 > /proc/sys/vm/drop_caches
27788 }
27789 run_test 408 "drop_caches should not hang due to page leaks"
27790
27791 test_409()
27792 {
27793         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27794
27795         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27796         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27797         touch $DIR/$tdir/guard || error "(2) Fail to create"
27798
27799         local PREFIX=$(str_repeat 'A' 128)
27800         echo "Create 1K hard links start at $(date)"
27801         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27802                 error "(3) Fail to hard link"
27803
27804         echo "Links count should be right although linkEA overflow"
27805         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27806         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27807         [ $linkcount -eq 1001 ] ||
27808                 error "(5) Unexpected hard links count: $linkcount"
27809
27810         echo "List all links start at $(date)"
27811         ls -l $DIR/$tdir/foo > /dev/null ||
27812                 error "(6) Fail to list $DIR/$tdir/foo"
27813
27814         echo "Unlink hard links start at $(date)"
27815         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27816                 error "(7) Fail to unlink"
27817         echo "Unlink hard links finished at $(date)"
27818 }
27819 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27820
27821 test_410()
27822 {
27823         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27824                 skip "Need client version at least 2.9.59"
27825         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27826                 skip "Need MODULES build"
27827
27828         # Create a file, and stat it from the kernel
27829         local testfile=$DIR/$tfile
27830         touch $testfile
27831
27832         local run_id=$RANDOM
27833         local my_ino=$(stat --format "%i" $testfile)
27834
27835         # Try to insert the module. This will always fail as the
27836         # module is designed to not be inserted.
27837         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27838             &> /dev/null
27839
27840         # Anything but success is a test failure
27841         dmesg | grep -q \
27842             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27843             error "no inode match"
27844 }
27845 run_test 410 "Test inode number returned from kernel thread"
27846
27847 cleanup_test411_cgroup() {
27848         trap 0
27849         cat $1/memory.stat
27850         rmdir "$1"
27851 }
27852
27853 test_411a() {
27854         local cg_basedir=/sys/fs/cgroup/memory
27855         # LU-9966
27856         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27857                 skip "no setup for cgroup"
27858
27859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27860                 error "test file creation failed"
27861         cancel_lru_locks osc
27862
27863         # Create a very small memory cgroup to force a slab allocation error
27864         local cgdir=$cg_basedir/osc_slab_alloc
27865         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27866         trap "cleanup_test411_cgroup $cgdir" EXIT
27867         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27868         echo 1M > $cgdir/memory.limit_in_bytes
27869
27870         # Should not LBUG, just be killed by oom-killer
27871         # dd will return 0 even allocation failure in some environment.
27872         # So don't check return value
27873         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27874         cleanup_test411_cgroup $cgdir
27875
27876         return 0
27877 }
27878 run_test 411a "Slab allocation error with cgroup does not LBUG"
27879
27880 test_411b() {
27881         local cg_basedir=/sys/fs/cgroup/memory
27882         # LU-9966
27883         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27884                 skip "no setup for cgroup"
27885         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27886         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27887         # limit, so we have 384M in cgroup
27888         # (arm) this seems to hit OOM more often than x86, so 1024M
27889         if [[ $(uname -m) = aarch64 ]]; then
27890                 local memlimit_mb=1024
27891         else
27892                 local memlimit_mb=384
27893         fi
27894
27895         # Create a cgroup and set memory limit
27896         # (tfile is used as an easy way to get a recognizable cgroup name)
27897         local cgdir=$cg_basedir/$tfile
27898         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27899         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27900         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27901
27902         echo "writing first file"
27903         # Write a file 4x the memory limit in size
27904         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27905                 error "(1) failed to write successfully"
27906
27907         sync
27908         cancel_lru_locks osc
27909
27910         rm -f $DIR/$tfile
27911         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27912
27913         # Try writing at a larger block size
27914         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27915         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27916         # need *some* memory to do IO in)
27917         echo "writing at larger block size"
27918         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27919                 error "(3) failed to write successfully"
27920
27921         sync
27922         cancel_lru_locks osc
27923         rm -f $DIR/$tfile
27924         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27925
27926         # Try writing multiple files at once
27927         echo "writing multiple files"
27928         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27929         local pid1=$!
27930         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27931         local pid2=$!
27932         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27933         local pid3=$!
27934         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27935         local pid4=$!
27936
27937         wait $pid1
27938         local rc1=$?
27939         wait $pid2
27940         local rc2=$?
27941         wait $pid3
27942         local rc3=$?
27943         wait $pid4
27944         local rc4=$?
27945         if (( rc1 != 0)); then
27946                 error "error $rc1 writing to file from $pid1"
27947         fi
27948         if (( rc2 != 0)); then
27949                 error "error $rc2 writing to file from $pid2"
27950         fi
27951         if (( rc3 != 0)); then
27952                 error "error $rc3 writing to file from $pid3"
27953         fi
27954         if (( rc4 != 0)); then
27955                 error "error $rc4 writing to file from $pid4"
27956         fi
27957
27958         sync
27959         cancel_lru_locks osc
27960
27961         # These files can be large-ish (~1 GiB total), so delete them rather
27962         # than leave for later cleanup
27963         rm -f $DIR/$tfile.*
27964         return 0
27965 }
27966 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27967
27968 test_412() {
27969         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27970         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27971                 skip "Need server version at least 2.10.55"
27972
27973         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27974                 error "mkdir failed"
27975         $LFS getdirstripe $DIR/$tdir
27976         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27977         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27978                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27979         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27980         [ $stripe_count -eq 2 ] ||
27981                 error "expect 2 get $stripe_count"
27982
27983         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27984
27985         local index
27986         local index2
27987
27988         # subdirs should be on the same MDT as parent
27989         for i in $(seq 0 $((MDSCOUNT - 1))); do
27990                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27991                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27992                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27993                 (( index == i )) || error "mdt$i/sub on MDT$index"
27994         done
27995
27996         # stripe offset -1, ditto
27997         for i in {1..10}; do
27998                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27999                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28000                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28001                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28002                 (( index == index2 )) ||
28003                         error "qos$i on MDT$index, sub on MDT$index2"
28004         done
28005
28006         local testdir=$DIR/$tdir/inherit
28007
28008         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28009         # inherit 2 levels
28010         for i in 1 2; do
28011                 testdir=$testdir/s$i
28012                 mkdir $testdir || error "mkdir $testdir failed"
28013                 index=$($LFS getstripe -m $testdir)
28014                 (( index == 1 )) ||
28015                         error "$testdir on MDT$index"
28016         done
28017
28018         # not inherit any more
28019         testdir=$testdir/s3
28020         mkdir $testdir || error "mkdir $testdir failed"
28021         getfattr -d -m dmv $testdir | grep dmv &&
28022                 error "default LMV set on $testdir" || true
28023 }
28024 run_test 412 "mkdir on specific MDTs"
28025
28026 TEST413_COUNT=${TEST413_COUNT:-200}
28027
28028 #
28029 # set_maxage() is used by test_413 only.
28030 # This is a helper function to set maxage. Does not return any value.
28031 # Input: maxage to set
28032 #
28033 set_maxage() {
28034         local lmv_qos_maxage
28035         local lod_qos_maxage
28036         local new_maxage=$1
28037
28038         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28039         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28040         stack_trap "$LCTL set_param \
28041                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28042         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28043                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28044         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28045                 lod.*.mdt_qos_maxage=$new_maxage
28046         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28047                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28048 }
28049
28050 generate_uneven_mdts() {
28051         local threshold=$1
28052         local ffree
28053         local bavail
28054         local max
28055         local min
28056         local max_index
28057         local min_index
28058         local tmp
28059         local i
28060
28061         echo
28062         echo "Check for uneven MDTs: "
28063
28064         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28065         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28066         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28067
28068         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28069         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28070         max_index=0
28071         min_index=0
28072         for ((i = 1; i < ${#ffree[@]}; i++)); do
28073                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28074                 if [ $tmp -gt $max ]; then
28075                         max=$tmp
28076                         max_index=$i
28077                 fi
28078                 if [ $tmp -lt $min ]; then
28079                         min=$tmp
28080                         min_index=$i
28081                 fi
28082         done
28083
28084         (( min > 0 )) || skip "low space on MDT$min_index"
28085         (( ${ffree[min_index]} > 0 )) ||
28086                 skip "no free files on MDT$min_index"
28087         (( ${ffree[min_index]} < 10000000 )) ||
28088                 skip "too many free files on MDT$min_index"
28089
28090         # Check if we need to generate uneven MDTs
28091         local diff=$(((max - min) * 100 / min))
28092         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28093         local testdir # individual folder within $testdirp
28094         local start
28095         local cmd
28096
28097         # fallocate is faster to consume space on MDT, if available
28098         if check_fallocate_supported mds$((min_index + 1)); then
28099                 cmd="fallocate -l 128K "
28100         else
28101                 cmd="dd if=/dev/zero bs=128K count=1 of="
28102         fi
28103
28104         echo "using cmd $cmd"
28105         for (( i = 0; diff < threshold; i++ )); do
28106                 testdir=${testdirp}/$i
28107                 [ -d $testdir ] && continue
28108
28109                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28110
28111                 mkdir -p $testdirp
28112                 # generate uneven MDTs, create till $threshold% diff
28113                 echo -n "weight diff=$diff% must be > $threshold% ..."
28114                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28115                 $LFS mkdir -i $min_index $testdir ||
28116                         error "mkdir $testdir failed"
28117                 $LFS setstripe -E 1M -L mdt $testdir ||
28118                         error "setstripe $testdir failed"
28119                 start=$SECONDS
28120                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28121                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28122                 done
28123                 sync; sleep 1; sync
28124
28125                 # wait for QOS to update
28126                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28127
28128                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28129                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28130                 max=$(((${ffree[max_index]} >> 8) *
28131                         (${bavail[max_index]} * bsize >> 16)))
28132                 min=$(((${ffree[min_index]} >> 8) *
28133                         (${bavail[min_index]} * bsize >> 16)))
28134                 (( min > 0 )) || skip "low space on MDT$min_index"
28135                 diff=$(((max - min) * 100 / min))
28136         done
28137
28138         echo "MDT filesfree available: ${ffree[*]}"
28139         echo "MDT blocks available: ${bavail[*]}"
28140         echo "weight diff=$diff%"
28141 }
28142
28143 test_qos_mkdir() {
28144         local mkdir_cmd=$1
28145         local stripe_count=$2
28146         local mdts=$(comma_list $(mdts_nodes))
28147
28148         local testdir
28149         local lmv_qos_prio_free
28150         local lmv_qos_threshold_rr
28151         local lod_qos_prio_free
28152         local lod_qos_threshold_rr
28153         local total
28154         local count
28155         local i
28156
28157         # @total is total directories created if it's testing plain
28158         # directories, otherwise it's total stripe object count for
28159         # striped directories test.
28160         # remote/striped directory unlinking is slow on zfs and may
28161         # timeout, test with fewer directories
28162         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28163
28164         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28165         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28166         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28167                 head -n1)
28168         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28169         stack_trap "$LCTL set_param \
28170                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28171         stack_trap "$LCTL set_param \
28172                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28173
28174         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28175                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28176         lod_qos_prio_free=${lod_qos_prio_free%%%}
28177         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28178                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28179         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28180         stack_trap "do_nodes $mdts $LCTL set_param \
28181                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28182         stack_trap "do_nodes $mdts $LCTL set_param \
28183                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28184
28185         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28186         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28187
28188         testdir=$DIR/$tdir-s$stripe_count/rr
28189
28190         local stripe_index=$($LFS getstripe -m $testdir)
28191         local test_mkdir_rr=true
28192
28193         getfattr -d -m dmv -e hex $testdir | grep dmv
28194         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28195                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28196                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28197                         test_mkdir_rr=false
28198         fi
28199
28200         echo
28201         $test_mkdir_rr &&
28202                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28203                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28204
28205         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28206         for (( i = 0; i < total / stripe_count; i++ )); do
28207                 eval $mkdir_cmd $testdir/subdir$i ||
28208                         error "$mkdir_cmd subdir$i failed"
28209         done
28210
28211         for (( i = 0; i < $MDSCOUNT; i++ )); do
28212                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28213                 echo "$count directories created on MDT$i"
28214                 if $test_mkdir_rr; then
28215                         (( count == total / stripe_count / MDSCOUNT )) ||
28216                                 error "subdirs are not evenly distributed"
28217                 elif (( i == stripe_index )); then
28218                         (( count == total / stripe_count )) ||
28219                                 error "$count subdirs created on MDT$i"
28220                 else
28221                         (( count == 0 )) ||
28222                                 error "$count subdirs created on MDT$i"
28223                 fi
28224
28225                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28226                         count=$($LFS getdirstripe $testdir/* |
28227                                 grep -c -P "^\s+$i\t")
28228                         echo "$count stripes created on MDT$i"
28229                         # deviation should < 5% of average
28230                         delta=$((count - total / MDSCOUNT))
28231                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28232                                 error "stripes are not evenly distributed"
28233                 fi
28234         done
28235
28236         echo
28237         echo "Check for uneven MDTs: "
28238
28239         local ffree
28240         local bavail
28241         local max
28242         local min
28243         local max_index
28244         local min_index
28245         local tmp
28246
28247         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28248         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28249         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28250
28251         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28252         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28253         max_index=0
28254         min_index=0
28255         for ((i = 1; i < ${#ffree[@]}; i++)); do
28256                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28257                 if [ $tmp -gt $max ]; then
28258                         max=$tmp
28259                         max_index=$i
28260                 fi
28261                 if [ $tmp -lt $min ]; then
28262                         min=$tmp
28263                         min_index=$i
28264                 fi
28265         done
28266         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28267
28268         (( min > 0 )) || skip "low space on MDT$min_index"
28269         (( ${ffree[min_index]} < 10000000 )) ||
28270                 skip "too many free files on MDT$min_index"
28271
28272         generate_uneven_mdts 120
28273
28274         echo "MDT filesfree available: ${ffree[*]}"
28275         echo "MDT blocks available: ${bavail[*]}"
28276         echo "weight diff=$(((max - min) * 100 / min))%"
28277         echo
28278         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28279
28280         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28281         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28282         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28283         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28284         # decrease statfs age, so that it can be updated in time
28285         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28286         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28287
28288         sleep 1
28289
28290         testdir=$DIR/$tdir-s$stripe_count/qos
28291
28292         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28293         for (( i = 0; i < total / stripe_count; i++ )); do
28294                 eval $mkdir_cmd $testdir/subdir$i ||
28295                         error "$mkdir_cmd subdir$i failed"
28296         done
28297
28298         max=0
28299         for (( i = 0; i < $MDSCOUNT; i++ )); do
28300                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28301                 (( count > max )) && max=$count
28302                 echo "$count directories created on MDT$i : curmax=$max"
28303         done
28304
28305         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28306
28307         # D-value should > 10% of average
28308         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28309                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28310
28311         # ditto for stripes
28312         if (( stripe_count > 1 )); then
28313                 max=0
28314                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28315                         count=$($LFS getdirstripe $testdir/* |
28316                                 grep -c -P "^\s+$i\t")
28317                         (( count > max )) && max=$count
28318                         echo "$count stripes created on MDT$i"
28319                 done
28320
28321                 min=$($LFS getdirstripe $testdir/* |
28322                         grep -c -P "^\s+$min_index\t")
28323                 (( max - min > total / MDSCOUNT / 10 )) ||
28324                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28325         fi
28326 }
28327
28328 most_full_mdt() {
28329         local ffree
28330         local bavail
28331         local bsize
28332         local min
28333         local min_index
28334         local tmp
28335
28336         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28337         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28338         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28339
28340         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28341         min_index=0
28342         for ((i = 1; i < ${#ffree[@]}; i++)); do
28343                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28344                 (( tmp < min )) && min=$tmp && min_index=$i
28345         done
28346
28347         echo -n $min_index
28348 }
28349
28350 test_413a() {
28351         [ $MDSCOUNT -lt 2 ] &&
28352                 skip "We need at least 2 MDTs for this test"
28353
28354         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28355                 skip "Need server version at least 2.12.52"
28356
28357         local stripe_max=$((MDSCOUNT - 1))
28358         local stripe_count
28359
28360         # let caller set maxage for latest result
28361         set_maxage 1
28362
28363         # fill MDT unevenly
28364         generate_uneven_mdts 120
28365
28366         # test 4-stripe directory at most, otherwise it's too slow
28367         # We are being very defensive. Although Autotest uses 4 MDTs.
28368         # We make sure stripe_max does not go over 4.
28369         (( stripe_max > 4 )) && stripe_max=4
28370         # unlinking striped directory is slow on zfs, and may timeout, only test
28371         # plain directory
28372         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28373         for stripe_count in $(seq 1 $stripe_max); do
28374                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28375                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28376                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28377                         error "mkdir failed"
28378                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28379         done
28380 }
28381 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28382
28383 test_413b() {
28384         [ $MDSCOUNT -lt 2 ] &&
28385                 skip "We need at least 2 MDTs for this test"
28386
28387         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28388                 skip "Need server version at least 2.12.52"
28389
28390         local stripe_max=$((MDSCOUNT - 1))
28391         local testdir
28392         local stripe_count
28393
28394         # let caller set maxage for latest result
28395         set_maxage 1
28396
28397         # fill MDT unevenly
28398         generate_uneven_mdts 120
28399
28400         # test 4-stripe directory at most, otherwise it's too slow
28401         # We are being very defensive. Although Autotest uses 4 MDTs.
28402         # We make sure stripe_max does not go over 4.
28403         (( stripe_max > 4 )) && stripe_max=4
28404         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28405         for stripe_count in $(seq 1 $stripe_max); do
28406                 testdir=$DIR/$tdir-s$stripe_count
28407                 mkdir $testdir || error "mkdir $testdir failed"
28408                 mkdir $testdir/rr || error "mkdir rr failed"
28409                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28410                         error "mkdir qos failed"
28411                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28412                         $testdir/rr || error "setdirstripe rr failed"
28413                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28414                         error "setdirstripe failed"
28415                 test_qos_mkdir "mkdir" $stripe_count
28416         done
28417 }
28418 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28419
28420 test_413c() {
28421         (( $MDSCOUNT >= 2 )) ||
28422                 skip "We need at least 2 MDTs for this test"
28423
28424         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28425                 skip "Need server version at least 2.14.51"
28426
28427         local testdir
28428         local inherit
28429         local inherit_rr
28430         local lmv_qos_maxage
28431         local lod_qos_maxage
28432
28433         # let caller set maxage for latest result
28434         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28435         $LCTL set_param lmv.*.qos_maxage=1
28436         stack_trap "$LCTL set_param \
28437                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28438         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28439                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28440         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28441                 lod.*.mdt_qos_maxage=1
28442         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28443                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28444
28445         # fill MDT unevenly
28446         generate_uneven_mdts 120
28447
28448         testdir=$DIR/${tdir}-s1
28449         mkdir $testdir || error "mkdir $testdir failed"
28450         mkdir $testdir/rr || error "mkdir rr failed"
28451         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28452         # default max_inherit is -1, default max_inherit_rr is 0
28453         $LFS setdirstripe -D -c 1 $testdir/rr ||
28454                 error "setdirstripe rr failed"
28455         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28456                 error "setdirstripe qos failed"
28457         test_qos_mkdir "mkdir" 1
28458
28459         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28460         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28461         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28462         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28463         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28464
28465         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28466         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28467         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28468         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28469         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28470         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28471         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28472                 error "level2 shouldn't have default LMV" || true
28473 }
28474 run_test 413c "mkdir with default LMV max inherit rr"
28475
28476 test_413d() {
28477         (( MDSCOUNT >= 2 )) ||
28478                 skip "We need at least 2 MDTs for this test"
28479
28480         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28481                 skip "Need server version at least 2.14.51"
28482
28483         local lmv_qos_threshold_rr
28484
28485         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28486                 head -n1)
28487         stack_trap "$LCTL set_param \
28488                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28489
28490         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28491         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28492         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28493                 error "$tdir shouldn't have default LMV"
28494         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28495                 error "mkdir sub failed"
28496
28497         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28498
28499         (( count == 100 )) || error "$count subdirs on MDT0"
28500 }
28501 run_test 413d "inherit ROOT default LMV"
28502
28503 test_413e() {
28504         (( MDSCOUNT >= 2 )) ||
28505                 skip "We need at least 2 MDTs for this test"
28506         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28507                 skip "Need server version at least 2.14.55"
28508
28509         local testdir=$DIR/$tdir
28510         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28511         local max_inherit
28512         local sub_max_inherit
28513
28514         mkdir -p $testdir || error "failed to create $testdir"
28515
28516         # set default max-inherit to -1 if stripe count is 0 or 1
28517         $LFS setdirstripe -D -c 1 $testdir ||
28518                 error "failed to set default LMV"
28519         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28520         (( max_inherit == -1 )) ||
28521                 error "wrong max_inherit value $max_inherit"
28522
28523         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28524         $LFS setdirstripe -D -c -1 $testdir ||
28525                 error "failed to set default LMV"
28526         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28527         (( max_inherit > 0 )) ||
28528                 error "wrong max_inherit value $max_inherit"
28529
28530         # and the subdir will decrease the max_inherit by 1
28531         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28532         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28533         (( sub_max_inherit == max_inherit - 1)) ||
28534                 error "wrong max-inherit of subdir $sub_max_inherit"
28535
28536         # check specified --max-inherit and warning message
28537         stack_trap "rm -f $tmpfile"
28538         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28539                 error "failed to set default LMV"
28540         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28541         (( max_inherit == -1 )) ||
28542                 error "wrong max_inherit value $max_inherit"
28543
28544         # check the warning messages
28545         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28546                 error "failed to detect warning string"
28547         fi
28548 }
28549 run_test 413e "check default max-inherit value"
28550
28551 test_fs_dmv_inherit()
28552 {
28553         local testdir=$DIR/$tdir
28554
28555         local count
28556         local inherit
28557         local inherit_rr
28558
28559         for i in 1 2; do
28560                 mkdir $testdir || error "mkdir $testdir failed"
28561                 count=$($LFS getdirstripe -D -c $testdir)
28562                 (( count == 1 )) ||
28563                         error "$testdir default LMV count mismatch $count != 1"
28564                 inherit=$($LFS getdirstripe -D -X $testdir)
28565                 (( inherit == 3 - i )) ||
28566                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28567                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28568                 (( inherit_rr == 3 - i )) ||
28569                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28570                 testdir=$testdir/sub
28571         done
28572
28573         mkdir $testdir || error "mkdir $testdir failed"
28574         count=$($LFS getdirstripe -D -c $testdir)
28575         (( count == 0 )) ||
28576                 error "$testdir default LMV count not zero: $count"
28577 }
28578
28579 test_413f() {
28580         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28581
28582         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28583                 skip "Need server version at least 2.14.55"
28584
28585         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28586                 error "dump $DIR default LMV failed"
28587         stack_trap "setfattr --restore=$TMP/dmv.ea"
28588
28589         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28590                 error "set $DIR default LMV failed"
28591
28592         test_fs_dmv_inherit
28593 }
28594 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28595
28596 test_413g() {
28597         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28598
28599         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28600         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28601                 error "dump $DIR default LMV failed"
28602         stack_trap "setfattr --restore=$TMP/dmv.ea"
28603
28604         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28605                 error "set $DIR default LMV failed"
28606
28607         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28608                 error "mount $MOUNT2 failed"
28609         stack_trap "umount_client $MOUNT2"
28610
28611         local saved_DIR=$DIR
28612
28613         export DIR=$MOUNT2
28614
28615         stack_trap "export DIR=$saved_DIR"
28616
28617         # first check filesystem-wide default LMV inheritance
28618         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28619
28620         # then check subdirs are spread to all MDTs
28621         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28622
28623         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28624
28625         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28626 }
28627 run_test 413g "enforce ROOT default LMV on subdir mount"
28628
28629 test_413h() {
28630         (( MDSCOUNT >= 2 )) ||
28631                 skip "We need at least 2 MDTs for this test"
28632
28633         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28634                 skip "Need server version at least 2.15.50.6"
28635
28636         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28637
28638         stack_trap "$LCTL set_param \
28639                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28640         $LCTL set_param lmv.*.qos_maxage=1
28641
28642         local depth=5
28643         local rr_depth=4
28644         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28645         local count=$((MDSCOUNT * 20))
28646
28647         generate_uneven_mdts 50
28648
28649         mkdir -p $dir || error "mkdir $dir failed"
28650         stack_trap "rm -rf $dir"
28651         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28652                 --max-inherit-rr=$rr_depth $dir
28653
28654         for ((d=0; d < depth + 2; d++)); do
28655                 log "dir=$dir:"
28656                 for ((sub=0; sub < count; sub++)); do
28657                         mkdir $dir/d$sub
28658                 done
28659                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28660                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28661                 # subdirs within $rr_depth should be created round-robin
28662                 if (( d < rr_depth )); then
28663                         (( ${num[0]} != count )) ||
28664                                 error "all objects created on MDT ${num[1]}"
28665                 fi
28666
28667                 dir=$dir/d0
28668         done
28669 }
28670 run_test 413h "don't stick to parent for round-robin dirs"
28671
28672 test_413i() {
28673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28674
28675         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28676                 skip "Need server version at least 2.14.55"
28677
28678         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28679                 error "dump $DIR default LMV failed"
28680         stack_trap "setfattr --restore=$TMP/dmv.ea"
28681
28682         local testdir=$DIR/$tdir
28683         local def_max_rr=1
28684         local def_max=3
28685         local count
28686
28687         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28688                 --max-inherit-rr=$def_max_rr $DIR ||
28689                 error "set $DIR default LMV failed"
28690
28691         for i in $(seq 2 3); do
28692                 def_max=$((def_max - 1))
28693                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28694
28695                 mkdir $testdir
28696                 # RR is decremented and keeps zeroed once exhausted
28697                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28698                 (( count == def_max_rr )) ||
28699                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28700
28701                 # max-inherit is decremented
28702                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28703                 (( count == def_max )) ||
28704                         error_noexit "$testdir: max-inherit $count != $def_max"
28705
28706                 testdir=$testdir/d$i
28707         done
28708
28709         # d3 is the last inherited from ROOT, no inheritance anymore
28710         # i.e. no the default layout anymore
28711         mkdir -p $testdir/d4/d5
28712         count=$($LFS getdirstripe -D --max-inherit $testdir)
28713         (( count == -1 )) ||
28714                 error_noexit "$testdir: max-inherit $count != -1"
28715
28716         local p_count=$($LFS getdirstripe -i $testdir)
28717
28718         for i in $(seq 4 5); do
28719                 testdir=$testdir/d$i
28720
28721                 # the root default layout is not applied once exhausted
28722                 count=$($LFS getdirstripe -i $testdir)
28723                 (( count == p_count )) ||
28724                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28725         done
28726
28727         $LFS setdirstripe -i 0 $DIR/d2
28728         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28729         (( count == -1 )) ||
28730                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28731 }
28732 run_test 413i "check default layout inheritance"
28733
28734 test_413j()
28735 {
28736         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28737
28738         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28739         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
28740                 error "setdirstripe $tdir failed"
28741
28742         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
28743                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28744
28745         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
28746         # setfattr dmv calls setdirstripe -D
28747         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
28748                 error "setfattr sub failed"
28749         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
28750                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28751
28752         [ $value == $value2 ] || error "dmv mismatch"
28753
28754         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
28755
28756         # do not allow remove dmv by setfattr -x
28757         do_nodes $(comma_list $(mdts_nodes)) \
28758                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28759         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28760         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
28761
28762         # allow remove dmv by setfattr -x
28763         do_nodes $(comma_list $(mdts_nodes)) \
28764                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
28765         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28766         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
28767         do_nodes $(comma_list $(mdts_nodes)) \
28768                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28769 }
28770 run_test 413j "set default LMV by setxattr"
28771
28772 test_413z() {
28773         local pids=""
28774         local subdir
28775         local pid
28776
28777         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28778                 unlinkmany $subdir/f. $TEST413_COUNT &
28779                 pids="$pids $!"
28780         done
28781
28782         for pid in $pids; do
28783                 wait $pid
28784         done
28785
28786         true
28787 }
28788 run_test 413z "413 test cleanup"
28789
28790 test_414() {
28791 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28792         $LCTL set_param fail_loc=0x80000521
28793         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28794         rm -f $DIR/$tfile
28795 }
28796 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28797
28798 test_415() {
28799         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28800         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28801                 skip "Need server version at least 2.11.52"
28802
28803         # LU-11102
28804         local total=500
28805         local max=120
28806
28807         # this test may be slow on ZFS
28808         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28809
28810         # though this test is designed for striped directory, let's test normal
28811         # directory too since lock is always saved as CoS lock.
28812         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28813         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28814         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28815         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28816         wait_delete_completed_mds
28817
28818         # run a loop without concurrent touch to measure rename duration.
28819         # only for test debug/robustness, NOT part of COS functional test.
28820         local start_time=$SECONDS
28821         for ((i = 0; i < total; i++)); do
28822                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28823                         > /dev/null
28824         done
28825         local baseline=$((SECONDS - start_time))
28826         echo "rename $total files without 'touch' took $baseline sec"
28827
28828         (
28829                 while true; do
28830                         touch $DIR/$tdir
28831                 done
28832         ) &
28833         local setattr_pid=$!
28834
28835         # rename files back to original name so unlinkmany works
28836         start_time=$SECONDS
28837         for ((i = 0; i < total; i++)); do
28838                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28839                         > /dev/null
28840         done
28841         local duration=$((SECONDS - start_time))
28842
28843         kill -9 $setattr_pid
28844
28845         echo "rename $total files with 'touch' took $duration sec"
28846         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28847         (( duration <= max )) ||
28848                 error_not_in_vm "rename took $duration > $max sec"
28849 }
28850 run_test 415 "lock revoke is not missing"
28851
28852 test_416() {
28853         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28854                 skip "Need server version at least 2.11.55"
28855
28856         # define OBD_FAIL_OSD_TXN_START    0x19a
28857         do_facet mds1 lctl set_param fail_loc=0x19a
28858
28859         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28860
28861         true
28862 }
28863 run_test 416 "transaction start failure won't cause system hung"
28864
28865 cleanup_417() {
28866         trap 0
28867         do_nodes $(comma_list $(mdts_nodes)) \
28868                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28869         do_nodes $(comma_list $(mdts_nodes)) \
28870                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28871         do_nodes $(comma_list $(mdts_nodes)) \
28872                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28873 }
28874
28875 test_417() {
28876         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28877         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28878                 skip "Need MDS version at least 2.11.56"
28879
28880         trap cleanup_417 RETURN EXIT
28881
28882         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28883         do_nodes $(comma_list $(mdts_nodes)) \
28884                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28885         $LFS migrate -m 0 $DIR/$tdir.1 &&
28886                 error "migrate dir $tdir.1 should fail"
28887
28888         do_nodes $(comma_list $(mdts_nodes)) \
28889                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28890         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28891                 error "create remote dir $tdir.2 should fail"
28892
28893         do_nodes $(comma_list $(mdts_nodes)) \
28894                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28895         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28896                 error "create striped dir $tdir.3 should fail"
28897         true
28898 }
28899 run_test 417 "disable remote dir, striped dir and dir migration"
28900
28901 # Checks that the outputs of df [-i] and lfs df [-i] match
28902 #
28903 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28904 check_lfs_df() {
28905         local dir=$2
28906         local inodes
28907         local df_out
28908         local lfs_df_out
28909         local count
28910         local passed=false
28911
28912         # blocks or inodes
28913         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28914
28915         for count in {1..100}; do
28916                 do_nodes "$CLIENTS" \
28917                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28918                 sync; sleep 0.2
28919
28920                 # read the lines of interest
28921                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28922                         error "df $inodes $dir | tail -n +2 failed"
28923                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28924                         error "lfs df $inodes $dir | grep summary: failed"
28925
28926                 # skip first substrings of each output as they are different
28927                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28928                 # compare the two outputs
28929                 passed=true
28930                 #  skip "available" on MDT until LU-13997 is fixed.
28931                 #for i in {1..5}; do
28932                 for i in 1 2 4 5; do
28933                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28934                 done
28935                 $passed && break
28936         done
28937
28938         if ! $passed; then
28939                 df -P $inodes $dir
28940                 echo
28941                 lfs df $inodes $dir
28942                 error "df and lfs df $1 output mismatch: "      \
28943                       "df ${inodes}: ${df_out[*]}, "            \
28944                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28945         fi
28946 }
28947
28948 test_418() {
28949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28950
28951         local dir=$DIR/$tdir
28952         local numfiles=$((RANDOM % 4096 + 2))
28953         local numblocks=$((RANDOM % 256 + 1))
28954
28955         wait_delete_completed
28956         test_mkdir $dir
28957
28958         # check block output
28959         check_lfs_df blocks $dir
28960         # check inode output
28961         check_lfs_df inodes $dir
28962
28963         # create a single file and retest
28964         echo "Creating a single file and testing"
28965         createmany -o $dir/$tfile- 1 &>/dev/null ||
28966                 error "creating 1 file in $dir failed"
28967         check_lfs_df blocks $dir
28968         check_lfs_df inodes $dir
28969
28970         # create a random number of files
28971         echo "Creating $((numfiles - 1)) files and testing"
28972         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28973                 error "creating $((numfiles - 1)) files in $dir failed"
28974
28975         # write a random number of blocks to the first test file
28976         echo "Writing $numblocks 4K blocks and testing"
28977         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28978                 count=$numblocks &>/dev/null ||
28979                 error "dd to $dir/${tfile}-0 failed"
28980
28981         # retest
28982         check_lfs_df blocks $dir
28983         check_lfs_df inodes $dir
28984
28985         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28986                 error "unlinking $numfiles files in $dir failed"
28987 }
28988 run_test 418 "df and lfs df outputs match"
28989
28990 test_419()
28991 {
28992         local dir=$DIR/$tdir
28993
28994         mkdir -p $dir
28995         touch $dir/file
28996
28997         cancel_lru_locks mdc
28998
28999         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29000         $LCTL set_param fail_loc=0x1410
29001         cat $dir/file
29002         $LCTL set_param fail_loc=0
29003         rm -rf $dir
29004 }
29005 run_test 419 "Verify open file by name doesn't crash kernel"
29006
29007 test_420()
29008 {
29009         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29010                 skip "Need MDS version at least 2.12.53"
29011
29012         local SAVE_UMASK=$(umask)
29013         local dir=$DIR/$tdir
29014         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29015
29016         mkdir -p $dir
29017         umask 0000
29018         mkdir -m03777 $dir/testdir
29019         ls -dn $dir/testdir
29020         # Need to remove trailing '.' when SELinux is enabled
29021         local dirperms=$(ls -dn $dir/testdir |
29022                          awk '{ sub(/\.$/, "", $1); print $1}')
29023         [ $dirperms == "drwxrwsrwt" ] ||
29024                 error "incorrect perms on $dir/testdir"
29025
29026         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29027                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29028         ls -n $dir/testdir/testfile
29029         local fileperms=$(ls -n $dir/testdir/testfile |
29030                           awk '{ sub(/\.$/, "", $1); print $1}')
29031         [ $fileperms == "-rwxr-xr-x" ] ||
29032                 error "incorrect perms on $dir/testdir/testfile"
29033
29034         umask $SAVE_UMASK
29035 }
29036 run_test 420 "clear SGID bit on non-directories for non-members"
29037
29038 test_421a() {
29039         local cnt
29040         local fid1
29041         local fid2
29042
29043         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29044                 skip "Need MDS version at least 2.12.54"
29045
29046         test_mkdir $DIR/$tdir
29047         createmany -o $DIR/$tdir/f 3
29048         cnt=$(ls -1 $DIR/$tdir | wc -l)
29049         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29050
29051         fid1=$(lfs path2fid $DIR/$tdir/f1)
29052         fid2=$(lfs path2fid $DIR/$tdir/f2)
29053         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29054
29055         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29056         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29057
29058         cnt=$(ls -1 $DIR/$tdir | wc -l)
29059         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29060
29061         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29062         createmany -o $DIR/$tdir/f 3
29063         cnt=$(ls -1 $DIR/$tdir | wc -l)
29064         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29065
29066         fid1=$(lfs path2fid $DIR/$tdir/f1)
29067         fid2=$(lfs path2fid $DIR/$tdir/f2)
29068         echo "remove using fsname $FSNAME"
29069         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29070
29071         cnt=$(ls -1 $DIR/$tdir | wc -l)
29072         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29073 }
29074 run_test 421a "simple rm by fid"
29075
29076 test_421b() {
29077         local cnt
29078         local FID1
29079         local FID2
29080
29081         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29082                 skip "Need MDS version at least 2.12.54"
29083
29084         test_mkdir $DIR/$tdir
29085         createmany -o $DIR/$tdir/f 3
29086         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29087         MULTIPID=$!
29088
29089         FID1=$(lfs path2fid $DIR/$tdir/f1)
29090         FID2=$(lfs path2fid $DIR/$tdir/f2)
29091         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29092
29093         kill -USR1 $MULTIPID
29094         wait
29095
29096         cnt=$(ls $DIR/$tdir | wc -l)
29097         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29098 }
29099 run_test 421b "rm by fid on open file"
29100
29101 test_421c() {
29102         local cnt
29103         local FIDS
29104
29105         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29106                 skip "Need MDS version at least 2.12.54"
29107
29108         test_mkdir $DIR/$tdir
29109         createmany -o $DIR/$tdir/f 3
29110         touch $DIR/$tdir/$tfile
29111         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29112         cnt=$(ls -1 $DIR/$tdir | wc -l)
29113         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29114
29115         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29116         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29117
29118         cnt=$(ls $DIR/$tdir | wc -l)
29119         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29120 }
29121 run_test 421c "rm by fid against hardlinked files"
29122
29123 test_421d() {
29124         local cnt
29125         local FIDS
29126
29127         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29128                 skip "Need MDS version at least 2.12.54"
29129
29130         test_mkdir $DIR/$tdir
29131         createmany -o $DIR/$tdir/f 4097
29132         cnt=$(ls -1 $DIR/$tdir | wc -l)
29133         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29134
29135         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29136         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29137
29138         cnt=$(ls $DIR/$tdir | wc -l)
29139         rm -rf $DIR/$tdir
29140         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29141 }
29142 run_test 421d "rmfid en masse"
29143
29144 test_421e() {
29145         local cnt
29146         local FID
29147
29148         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29149         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29150                 skip "Need MDS version at least 2.12.54"
29151
29152         mkdir -p $DIR/$tdir
29153         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29154         createmany -o $DIR/$tdir/striped_dir/f 512
29155         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29156         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29157
29158         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29159                 sed "s/[/][^:]*://g")
29160         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29161
29162         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29163         rm -rf $DIR/$tdir
29164         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29165 }
29166 run_test 421e "rmfid in DNE"
29167
29168 test_421f() {
29169         local cnt
29170         local FID
29171
29172         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29173                 skip "Need MDS version at least 2.12.54"
29174
29175         test_mkdir $DIR/$tdir
29176         touch $DIR/$tdir/f
29177         cnt=$(ls -1 $DIR/$tdir | wc -l)
29178         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29179
29180         FID=$(lfs path2fid $DIR/$tdir/f)
29181         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29182         # rmfid should fail
29183         cnt=$(ls -1 $DIR/$tdir | wc -l)
29184         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29185
29186         chmod a+rw $DIR/$tdir
29187         ls -la $DIR/$tdir
29188         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29189         # rmfid should fail
29190         cnt=$(ls -1 $DIR/$tdir | wc -l)
29191         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29192
29193         rm -f $DIR/$tdir/f
29194         $RUNAS touch $DIR/$tdir/f
29195         FID=$(lfs path2fid $DIR/$tdir/f)
29196         echo "rmfid as root"
29197         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29198         cnt=$(ls -1 $DIR/$tdir | wc -l)
29199         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29200
29201         rm -f $DIR/$tdir/f
29202         $RUNAS touch $DIR/$tdir/f
29203         cnt=$(ls -1 $DIR/$tdir | wc -l)
29204         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29205         FID=$(lfs path2fid $DIR/$tdir/f)
29206         # rmfid w/o user_fid2path mount option should fail
29207         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29208         cnt=$(ls -1 $DIR/$tdir | wc -l)
29209         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29210
29211         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29212         stack_trap "rmdir $tmpdir"
29213         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29214                 error "failed to mount client'"
29215         stack_trap "umount_client $tmpdir"
29216
29217         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29218         # rmfid should succeed
29219         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29220         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29221
29222         # rmfid shouldn't allow to remove files due to dir's permission
29223         chmod a+rwx $tmpdir/$tdir
29224         touch $tmpdir/$tdir/f
29225         ls -la $tmpdir/$tdir
29226         FID=$(lfs path2fid $tmpdir/$tdir/f)
29227         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29228         return 0
29229 }
29230 run_test 421f "rmfid checks permissions"
29231
29232 test_421g() {
29233         local cnt
29234         local FIDS
29235
29236         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29237         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29238                 skip "Need MDS version at least 2.12.54"
29239
29240         mkdir -p $DIR/$tdir
29241         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29242         createmany -o $DIR/$tdir/striped_dir/f 512
29243         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29244         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29245
29246         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29247                 sed "s/[/][^:]*://g")
29248
29249         rm -f $DIR/$tdir/striped_dir/f1*
29250         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29251         removed=$((512 - cnt))
29252
29253         # few files have been just removed, so we expect
29254         # rmfid to fail on their fids
29255         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29256         [ $removed != $errors ] && error "$errors != $removed"
29257
29258         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29259         rm -rf $DIR/$tdir
29260         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29261 }
29262 run_test 421g "rmfid to return errors properly"
29263
29264 test_421h() {
29265         local mount_other
29266         local mount_ret
29267         local rmfid_ret
29268         local old_fid
29269         local fidA
29270         local fidB
29271         local fidC
29272         local fidD
29273
29274         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29275                 skip "Need MDS version at least 2.15.53"
29276
29277         test_mkdir $DIR/$tdir
29278         test_mkdir $DIR/$tdir/subdir
29279         touch $DIR/$tdir/subdir/file0
29280         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29281         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29282         rm -f $DIR/$tdir/subdir/file0
29283         touch $DIR/$tdir/subdir/fileA
29284         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29285         echo File $DIR/$tdir/subdir/fileA FID $fidA
29286         touch $DIR/$tdir/subdir/fileB
29287         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29288         echo File $DIR/$tdir/subdir/fileB FID $fidB
29289         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29290         touch $DIR/$tdir/subdir/fileC
29291         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29292         echo File $DIR/$tdir/subdir/fileC FID $fidC
29293         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29294         touch $DIR/$tdir/fileD
29295         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29296         echo File $DIR/$tdir/fileD FID $fidD
29297
29298         # mount another client mount point with subdirectory mount
29299         export FILESET=/$tdir/subdir
29300         mount_other=${MOUNT}_other
29301         mount_client $mount_other ${MOUNT_OPTS}
29302         mount_ret=$?
29303         export FILESET=""
29304         (( mount_ret == 0 )) || error "mount $mount_other failed"
29305
29306         echo Removing FIDs:
29307         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29308         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29309         rmfid_ret=$?
29310
29311         umount_client $mount_other || error "umount $mount_other failed"
29312
29313         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29314
29315         # fileA should have been deleted
29316         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29317
29318         # fileB should have been deleted
29319         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29320
29321         # fileC should not have been deleted, fid also exists outside of fileset
29322         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29323
29324         # fileD should not have been deleted, it exists outside of fileset
29325         stat $DIR/$tdir/fileD || error "fileD deleted"
29326 }
29327 run_test 421h "rmfid with fileset mount"
29328
29329 test_422() {
29330         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29331         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29332         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29333         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29334         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29335
29336         local amc=$(at_max_get client)
29337         local amo=$(at_max_get mds1)
29338         local timeout=`lctl get_param -n timeout`
29339
29340         at_max_set 0 client
29341         at_max_set 0 mds1
29342
29343 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29344         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29345                         fail_val=$(((2*timeout + 10)*1000))
29346         touch $DIR/$tdir/d3/file &
29347         sleep 2
29348 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29349         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29350                         fail_val=$((2*timeout + 5))
29351         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29352         local pid=$!
29353         sleep 1
29354         kill -9 $pid
29355         sleep $((2 * timeout))
29356         echo kill $pid
29357         kill -9 $pid
29358         lctl mark touch
29359         touch $DIR/$tdir/d2/file3
29360         touch $DIR/$tdir/d2/file4
29361         touch $DIR/$tdir/d2/file5
29362
29363         wait
29364         at_max_set $amc client
29365         at_max_set $amo mds1
29366
29367         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29368         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29369                 error "Watchdog is always throttled"
29370 }
29371 run_test 422 "kill a process with RPC in progress"
29372
29373 stat_test() {
29374     df -h $MOUNT &
29375     df -h $MOUNT &
29376     df -h $MOUNT &
29377     df -h $MOUNT &
29378     df -h $MOUNT &
29379     df -h $MOUNT &
29380 }
29381
29382 test_423() {
29383     local _stats
29384     # ensure statfs cache is expired
29385     sleep 2;
29386
29387     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29388     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29389
29390     return 0
29391 }
29392 run_test 423 "statfs should return a right data"
29393
29394 test_424() {
29395 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29396         $LCTL set_param fail_loc=0x80000522
29397         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29398         rm -f $DIR/$tfile
29399 }
29400 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29401
29402 test_425() {
29403         test_mkdir -c -1 $DIR/$tdir
29404         $LFS setstripe -c -1 $DIR/$tdir
29405
29406         lru_resize_disable "" 100
29407         stack_trap "lru_resize_enable" EXIT
29408
29409         sleep 5
29410
29411         for i in $(seq $((MDSCOUNT * 125))); do
29412                 local t=$DIR/$tdir/$tfile_$i
29413
29414                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29415                         error_noexit "Create file $t"
29416         done
29417         stack_trap "rm -rf $DIR/$tdir" EXIT
29418
29419         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29420                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29421                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29422
29423                 [ $lock_count -le $lru_size ] ||
29424                         error "osc lock count $lock_count > lru size $lru_size"
29425         done
29426
29427         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29428                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29429                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29430
29431                 [ $lock_count -le $lru_size ] ||
29432                         error "mdc lock count $lock_count > lru size $lru_size"
29433         done
29434 }
29435 run_test 425 "lock count should not exceed lru size"
29436
29437 test_426() {
29438         splice-test -r $DIR/$tfile
29439         splice-test -rd $DIR/$tfile
29440         splice-test $DIR/$tfile
29441         splice-test -d $DIR/$tfile
29442 }
29443 run_test 426 "splice test on Lustre"
29444
29445 test_427() {
29446         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29447         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29448                 skip "Need MDS version at least 2.12.4"
29449         local log
29450
29451         mkdir $DIR/$tdir
29452         mkdir $DIR/$tdir/1
29453         mkdir $DIR/$tdir/2
29454         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29455         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29456
29457         $LFS getdirstripe $DIR/$tdir/1/dir
29458
29459         #first setfattr for creating updatelog
29460         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29461
29462 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29463         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29464         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29465         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29466
29467         sleep 2
29468         fail mds2
29469         wait_recovery_complete mds2 $((2*TIMEOUT))
29470
29471         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29472         echo $log | grep "get update log failed" &&
29473                 error "update log corruption is detected" || true
29474 }
29475 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29476
29477 test_428() {
29478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29479         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29480                               awk '/^max_cached_mb/ { print $2 }')
29481         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29482
29483         $LCTL set_param -n llite.*.max_cached_mb=64
29484
29485         mkdir $DIR/$tdir
29486         $LFS setstripe -c 1 $DIR/$tdir
29487         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29488         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29489         #test write
29490         for f in $(seq 4); do
29491                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29492         done
29493         wait
29494
29495         cancel_lru_locks osc
29496         # Test read
29497         for f in $(seq 4); do
29498                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29499         done
29500         wait
29501 }
29502 run_test 428 "large block size IO should not hang"
29503
29504 test_429() { # LU-7915 / LU-10948
29505         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29506         local testfile=$DIR/$tfile
29507         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29508         local new_flag=1
29509         local first_rpc
29510         local second_rpc
29511         local third_rpc
29512
29513         $LCTL get_param $ll_opencache_threshold_count ||
29514                 skip "client does not have opencache parameter"
29515
29516         set_opencache $new_flag
29517         stack_trap "restore_opencache"
29518         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29519                 error "enable opencache failed"
29520         touch $testfile
29521         # drop MDC DLM locks
29522         cancel_lru_locks mdc
29523         # clear MDC RPC stats counters
29524         $LCTL set_param $mdc_rpcstats=clear
29525
29526         # According to the current implementation, we need to run 3 times
29527         # open & close file to verify if opencache is enabled correctly.
29528         # 1st, RPCs are sent for lookup/open and open handle is released on
29529         #      close finally.
29530         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29531         #      so open handle won't be released thereafter.
29532         # 3rd, No RPC is sent out.
29533         $MULTIOP $testfile oc || error "multiop failed"
29534         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29535         echo "1st: $first_rpc RPCs in flight"
29536
29537         $MULTIOP $testfile oc || error "multiop failed"
29538         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29539         echo "2nd: $second_rpc RPCs in flight"
29540
29541         $MULTIOP $testfile oc || error "multiop failed"
29542         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29543         echo "3rd: $third_rpc RPCs in flight"
29544
29545         #verify no MDC RPC is sent
29546         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29547 }
29548 run_test 429 "verify if opencache flag on client side does work"
29549
29550 lseek_test_430() {
29551         local offset
29552         local file=$1
29553
29554         # data at [200K, 400K)
29555         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29556                 error "256K->512K dd fails"
29557         # data at [2M, 3M)
29558         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29559                 error "2M->3M dd fails"
29560         # data at [4M, 5M)
29561         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29562                 error "4M->5M dd fails"
29563         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29564         # start at first component hole #1
29565         printf "Seeking hole from 1000 ... "
29566         offset=$(lseek_test -l 1000 $file)
29567         echo $offset
29568         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29569         printf "Seeking data from 1000 ... "
29570         offset=$(lseek_test -d 1000 $file)
29571         echo $offset
29572         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29573
29574         # start at first component data block
29575         printf "Seeking hole from 300000 ... "
29576         offset=$(lseek_test -l 300000 $file)
29577         echo $offset
29578         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29579         printf "Seeking data from 300000 ... "
29580         offset=$(lseek_test -d 300000 $file)
29581         echo $offset
29582         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29583
29584         # start at the first component but beyond end of object size
29585         printf "Seeking hole from 1000000 ... "
29586         offset=$(lseek_test -l 1000000 $file)
29587         echo $offset
29588         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29589         printf "Seeking data from 1000000 ... "
29590         offset=$(lseek_test -d 1000000 $file)
29591         echo $offset
29592         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29593
29594         # start at second component stripe 2 (empty file)
29595         printf "Seeking hole from 1500000 ... "
29596         offset=$(lseek_test -l 1500000 $file)
29597         echo $offset
29598         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29599         printf "Seeking data from 1500000 ... "
29600         offset=$(lseek_test -d 1500000 $file)
29601         echo $offset
29602         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29603
29604         # start at second component stripe 1 (all data)
29605         printf "Seeking hole from 3000000 ... "
29606         offset=$(lseek_test -l 3000000 $file)
29607         echo $offset
29608         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29609         printf "Seeking data from 3000000 ... "
29610         offset=$(lseek_test -d 3000000 $file)
29611         echo $offset
29612         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29613
29614         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29615                 error "2nd dd fails"
29616         echo "Add data block at 640K...1280K"
29617
29618         # start at before new data block, in hole
29619         printf "Seeking hole from 600000 ... "
29620         offset=$(lseek_test -l 600000 $file)
29621         echo $offset
29622         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29623         printf "Seeking data from 600000 ... "
29624         offset=$(lseek_test -d 600000 $file)
29625         echo $offset
29626         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29627
29628         # start at the first component new data block
29629         printf "Seeking hole from 1000000 ... "
29630         offset=$(lseek_test -l 1000000 $file)
29631         echo $offset
29632         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29633         printf "Seeking data from 1000000 ... "
29634         offset=$(lseek_test -d 1000000 $file)
29635         echo $offset
29636         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29637
29638         # start at second component stripe 2, new data
29639         printf "Seeking hole from 1200000 ... "
29640         offset=$(lseek_test -l 1200000 $file)
29641         echo $offset
29642         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29643         printf "Seeking data from 1200000 ... "
29644         offset=$(lseek_test -d 1200000 $file)
29645         echo $offset
29646         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29647
29648         # start beyond file end
29649         printf "Using offset > filesize ... "
29650         lseek_test -l 4000000 $file && error "lseek should fail"
29651         printf "Using offset > filesize ... "
29652         lseek_test -d 4000000 $file && error "lseek should fail"
29653
29654         printf "Done\n\n"
29655 }
29656
29657 test_430a() {
29658         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29659                 skip "MDT does not support SEEK_HOLE"
29660
29661         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29662                 skip "OST does not support SEEK_HOLE"
29663
29664         local file=$DIR/$tdir/$tfile
29665
29666         mkdir -p $DIR/$tdir
29667
29668         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29669         # OST stripe #1 will have continuous data at [1M, 3M)
29670         # OST stripe #2 is empty
29671         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29672         lseek_test_430 $file
29673         rm $file
29674         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29675         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29676         lseek_test_430 $file
29677         rm $file
29678         $LFS setstripe -c2 -S 512K $file
29679         echo "Two stripes, stripe size 512K"
29680         lseek_test_430 $file
29681         rm $file
29682         # FLR with stale mirror
29683         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29684                        -N -c2 -S 1M $file
29685         echo "Mirrored file:"
29686         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29687         echo "Plain 2 stripes 1M"
29688         lseek_test_430 $file
29689         rm $file
29690 }
29691 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29692
29693 test_430b() {
29694         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29695                 skip "OST does not support SEEK_HOLE"
29696
29697         local offset
29698         local file=$DIR/$tdir/$tfile
29699
29700         mkdir -p $DIR/$tdir
29701         # Empty layout lseek should fail
29702         $MCREATE $file
29703         # seek from 0
29704         printf "Seeking hole from 0 ... "
29705         lseek_test -l 0 $file && error "lseek should fail"
29706         printf "Seeking data from 0 ... "
29707         lseek_test -d 0 $file && error "lseek should fail"
29708         rm $file
29709
29710         # 1M-hole file
29711         $LFS setstripe -E 1M -c2 -E eof $file
29712         $TRUNCATE $file 1048576
29713         printf "Seeking hole from 1000000 ... "
29714         offset=$(lseek_test -l 1000000 $file)
29715         echo $offset
29716         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29717         printf "Seeking data from 1000000 ... "
29718         lseek_test -d 1000000 $file && error "lseek should fail"
29719         rm $file
29720
29721         # full component followed by non-inited one
29722         $LFS setstripe -E 1M -c2 -E eof $file
29723         dd if=/dev/urandom of=$file bs=1M count=1
29724         printf "Seeking hole from 1000000 ... "
29725         offset=$(lseek_test -l 1000000 $file)
29726         echo $offset
29727         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29728         printf "Seeking hole from 1048576 ... "
29729         lseek_test -l 1048576 $file && error "lseek should fail"
29730         # init second component and truncate back
29731         echo "123" >> $file
29732         $TRUNCATE $file 1048576
29733         printf "Seeking hole from 1000000 ... "
29734         offset=$(lseek_test -l 1000000 $file)
29735         echo $offset
29736         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29737         printf "Seeking hole from 1048576 ... "
29738         lseek_test -l 1048576 $file && error "lseek should fail"
29739         # boundary checks for big values
29740         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29741         offset=$(lseek_test -d 0 $file.10g)
29742         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29743         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29744         offset=$(lseek_test -d 0 $file.100g)
29745         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29746         return 0
29747 }
29748 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29749
29750 test_430c() {
29751         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29752                 skip "OST does not support SEEK_HOLE"
29753
29754         local file=$DIR/$tdir/$tfile
29755         local start
29756
29757         mkdir -p $DIR/$tdir
29758         stack_trap "rm -f $file $file.tmp"
29759         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29760
29761         # cp version 8.33+ prefers lseek over fiemap
29762         local ver=$(cp --version | awk '{ print $4; exit; }')
29763
29764         echo "cp $ver installed"
29765         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29766                 start=$SECONDS
29767                 time cp -v $file $file.tmp || error "cp $file failed"
29768                 (( SECONDS - start < 5 )) || {
29769                         strace cp $file $file.tmp |&
29770                                 grep -E "open|read|seek|FIEMAP" |
29771                                 grep -A 100 $file
29772                         error "cp: too long runtime $((SECONDS - start))"
29773                 }
29774         else
29775                 echo "cp test skipped due to $ver < 8.33"
29776         fi
29777
29778         # tar version 1.29+ supports SEEK_HOLE/DATA
29779         ver=$(tar --version | awk '{ print $4; exit; }')
29780         echo "tar $ver installed"
29781         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29782                 start=$SECONDS
29783                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29784                 (( SECONDS - start < 5 )) || {
29785                         strace tar cf $file.tmp --sparse $file |&
29786                                 grep -E "open|read|seek|FIEMAP" |
29787                                 grep -A 100 $file
29788                         error "tar: too long runtime $((SECONDS - start))"
29789                 }
29790         else
29791                 echo "tar test skipped due to $ver < 1.29"
29792         fi
29793 }
29794 run_test 430c "lseek: external tools check"
29795
29796 test_431() { # LU-14187
29797         local file=$DIR/$tdir/$tfile
29798
29799         mkdir -p $DIR/$tdir
29800         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29801         dd if=/dev/urandom of=$file bs=4k count=1
29802         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29803         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29804         #define OBD_FAIL_OST_RESTART_IO 0x251
29805         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29806         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29807         cp $file $file.0
29808         cancel_lru_locks
29809         sync_all_data
29810         echo 3 > /proc/sys/vm/drop_caches
29811         diff  $file $file.0 || error "data diff"
29812 }
29813 run_test 431 "Restart transaction for IO"
29814
29815 cleanup_test_432() {
29816         do_facet mgs $LCTL nodemap_activate 0
29817         wait_nm_sync active
29818 }
29819
29820 test_432() {
29821         local tmpdir=$TMP/dir432
29822
29823         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29824                 skip "Need MDS version at least 2.14.52"
29825
29826         stack_trap cleanup_test_432 EXIT
29827         mkdir $DIR/$tdir
29828         mkdir $tmpdir
29829
29830         do_facet mgs $LCTL nodemap_activate 1
29831         wait_nm_sync active
29832         do_facet mgs $LCTL nodemap_modify --name default \
29833                 --property admin --value 1
29834         do_facet mgs $LCTL nodemap_modify --name default \
29835                 --property trusted --value 1
29836         cancel_lru_locks mdc
29837         wait_nm_sync default admin_nodemap
29838         wait_nm_sync default trusted_nodemap
29839
29840         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29841                grep -ci "Operation not permitted") -ne 0 ]; then
29842                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29843         fi
29844 }
29845 run_test 432 "mv dir from outside Lustre"
29846
29847 test_433() {
29848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29849
29850         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29851                 skip "inode cache not supported"
29852
29853         $LCTL set_param llite.*.inode_cache=0
29854         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29855
29856         local count=256
29857         local before
29858         local after
29859
29860         cancel_lru_locks mdc
29861         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29862         createmany -m $DIR/$tdir/f $count
29863         createmany -d $DIR/$tdir/d $count
29864         ls -l $DIR/$tdir > /dev/null
29865         stack_trap "rm -rf $DIR/$tdir"
29866
29867         before=$(num_objects)
29868         cancel_lru_locks mdc
29869         after=$(num_objects)
29870
29871         # sometimes even @before is less than 2 * count
29872         while (( before - after < count )); do
29873                 sleep 1
29874                 after=$(num_objects)
29875                 wait=$((wait + 1))
29876                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29877                 if (( wait > 60 )); then
29878                         error "inode slab grew from $before to $after"
29879                 fi
29880         done
29881
29882         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29883 }
29884 run_test 433 "ldlm lock cancel releases dentries and inodes"
29885
29886 test_434() {
29887         local file
29888         local getxattr_count
29889         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29890         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29891
29892         [[ $(getenforce) == "Disabled" ]] ||
29893                 skip "lsm selinux module have to be disabled for this test"
29894
29895         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29896                 error "fail to create $DIR/$tdir/ on MDT0000"
29897
29898         touch $DIR/$tdir/$tfile-{001..100}
29899
29900         # disable the xattr cache
29901         save_lustre_params client "llite.*.xattr_cache" > $p
29902         lctl set_param llite.*.xattr_cache=0
29903         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29904
29905         # clear clients mdc stats
29906         clear_stats $mdc_stat_param ||
29907                 error "fail to clear stats on mdc MDT0000"
29908
29909         for file in $DIR/$tdir/$tfile-{001..100}; do
29910                 getfattr -n security.selinux $file |&
29911                         grep -q "Operation not supported" ||
29912                         error "getxattr on security.selinux should return EOPNOTSUPP"
29913         done
29914
29915         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29916         (( getxattr_count < 100 )) ||
29917                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29918 }
29919 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29920
29921 test_440() {
29922         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29923                 source $LUSTRE/scripts/bash-completion/lustre
29924         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29925                 source /usr/share/bash-completion/completions/lustre
29926         else
29927                 skip "bash completion scripts not found"
29928         fi
29929
29930         local lctl_completions
29931         local lfs_completions
29932
29933         lctl_completions=$(_lustre_cmds lctl)
29934         if [[ ! $lctl_completions =~ "get_param" ]]; then
29935                 error "lctl bash completion failed"
29936         fi
29937
29938         lfs_completions=$(_lustre_cmds lfs)
29939         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29940                 error "lfs bash completion failed"
29941         fi
29942 }
29943 run_test 440 "bash completion for lfs, lctl"
29944
29945 prep_801() {
29946         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29947         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29948                 skip "Need server version at least 2.9.55"
29949
29950         start_full_debug_logging
29951 }
29952
29953 post_801() {
29954         stop_full_debug_logging
29955 }
29956
29957 barrier_stat() {
29958         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29959                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29960                            awk '/The barrier for/ { print $7 }')
29961                 echo $st
29962         else
29963                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29964                 echo \'$st\'
29965         fi
29966 }
29967
29968 barrier_expired() {
29969         local expired
29970
29971         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29972                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29973                           awk '/will be expired/ { print $7 }')
29974         else
29975                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29976         fi
29977
29978         echo $expired
29979 }
29980
29981 test_801a() {
29982         prep_801
29983
29984         echo "Start barrier_freeze at: $(date)"
29985         #define OBD_FAIL_BARRIER_DELAY          0x2202
29986         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29987         # Do not reduce barrier time - See LU-11873
29988         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29989
29990         sleep 2
29991         local b_status=$(barrier_stat)
29992         echo "Got barrier status at: $(date)"
29993         [ "$b_status" = "'freezing_p1'" ] ||
29994                 error "(1) unexpected barrier status $b_status"
29995
29996         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29997         wait
29998         b_status=$(barrier_stat)
29999         [ "$b_status" = "'frozen'" ] ||
30000                 error "(2) unexpected barrier status $b_status"
30001
30002         local expired=$(barrier_expired)
30003         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30004         sleep $((expired + 3))
30005
30006         b_status=$(barrier_stat)
30007         [ "$b_status" = "'expired'" ] ||
30008                 error "(3) unexpected barrier status $b_status"
30009
30010         # Do not reduce barrier time - See LU-11873
30011         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30012                 error "(4) fail to freeze barrier"
30013
30014         b_status=$(barrier_stat)
30015         [ "$b_status" = "'frozen'" ] ||
30016                 error "(5) unexpected barrier status $b_status"
30017
30018         echo "Start barrier_thaw at: $(date)"
30019         #define OBD_FAIL_BARRIER_DELAY          0x2202
30020         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30021         do_facet mgs $LCTL barrier_thaw $FSNAME &
30022
30023         sleep 2
30024         b_status=$(barrier_stat)
30025         echo "Got barrier status at: $(date)"
30026         [ "$b_status" = "'thawing'" ] ||
30027                 error "(6) unexpected barrier status $b_status"
30028
30029         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30030         wait
30031         b_status=$(barrier_stat)
30032         [ "$b_status" = "'thawed'" ] ||
30033                 error "(7) unexpected barrier status $b_status"
30034
30035         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30036         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30037         do_facet mgs $LCTL barrier_freeze $FSNAME
30038
30039         b_status=$(barrier_stat)
30040         [ "$b_status" = "'failed'" ] ||
30041                 error "(8) unexpected barrier status $b_status"
30042
30043         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30044         do_facet mgs $LCTL barrier_thaw $FSNAME
30045
30046         post_801
30047 }
30048 run_test 801a "write barrier user interfaces and stat machine"
30049
30050 test_801b() {
30051         prep_801
30052
30053         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30054         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30055         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30056         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30057         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30058
30059         cancel_lru_locks mdc
30060
30061         # 180 seconds should be long enough
30062         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30063
30064         local b_status=$(barrier_stat)
30065         [ "$b_status" = "'frozen'" ] ||
30066                 error "(6) unexpected barrier status $b_status"
30067
30068         mkdir $DIR/$tdir/d0/d10 &
30069         mkdir_pid=$!
30070
30071         touch $DIR/$tdir/d1/f13 &
30072         touch_pid=$!
30073
30074         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30075         ln_pid=$!
30076
30077         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30078         mv_pid=$!
30079
30080         rm -f $DIR/$tdir/d4/f12 &
30081         rm_pid=$!
30082
30083         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30084
30085         # To guarantee taht the 'stat' is not blocked
30086         b_status=$(barrier_stat)
30087         [ "$b_status" = "'frozen'" ] ||
30088                 error "(8) unexpected barrier status $b_status"
30089
30090         # let above commands to run at background
30091         sleep 5
30092
30093         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30094         ps -p $touch_pid || error "(10) touch should be blocked"
30095         ps -p $ln_pid || error "(11) link should be blocked"
30096         ps -p $mv_pid || error "(12) rename should be blocked"
30097         ps -p $rm_pid || error "(13) unlink should be blocked"
30098
30099         b_status=$(barrier_stat)
30100         [ "$b_status" = "'frozen'" ] ||
30101                 error "(14) unexpected barrier status $b_status"
30102
30103         do_facet mgs $LCTL barrier_thaw $FSNAME
30104         b_status=$(barrier_stat)
30105         [ "$b_status" = "'thawed'" ] ||
30106                 error "(15) unexpected barrier status $b_status"
30107
30108         wait $mkdir_pid || error "(16) mkdir should succeed"
30109         wait $touch_pid || error "(17) touch should succeed"
30110         wait $ln_pid || error "(18) link should succeed"
30111         wait $mv_pid || error "(19) rename should succeed"
30112         wait $rm_pid || error "(20) unlink should succeed"
30113
30114         post_801
30115 }
30116 run_test 801b "modification will be blocked by write barrier"
30117
30118 test_801c() {
30119         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30120
30121         prep_801
30122
30123         stop mds2 || error "(1) Fail to stop mds2"
30124
30125         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30126
30127         local b_status=$(barrier_stat)
30128         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30129                 do_facet mgs $LCTL barrier_thaw $FSNAME
30130                 error "(2) unexpected barrier status $b_status"
30131         }
30132
30133         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30134                 error "(3) Fail to rescan barrier bitmap"
30135
30136         # Do not reduce barrier time - See LU-11873
30137         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30138
30139         b_status=$(barrier_stat)
30140         [ "$b_status" = "'frozen'" ] ||
30141                 error "(4) unexpected barrier status $b_status"
30142
30143         do_facet mgs $LCTL barrier_thaw $FSNAME
30144         b_status=$(barrier_stat)
30145         [ "$b_status" = "'thawed'" ] ||
30146                 error "(5) unexpected barrier status $b_status"
30147
30148         local devname=$(mdsdevname 2)
30149
30150         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30151
30152         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30153                 error "(7) Fail to rescan barrier bitmap"
30154
30155         post_801
30156 }
30157 run_test 801c "rescan barrier bitmap"
30158
30159 test_802b() {
30160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30161         remote_mds_nodsh && skip "remote MDS with nodsh"
30162
30163         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30164                 skip "readonly option not available"
30165
30166         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30167
30168         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30169                 error "(2) Fail to copy"
30170
30171         # write back all cached data before setting MDT to readonly
30172         cancel_lru_locks
30173         sync_all_data
30174
30175         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30176         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30177
30178         echo "Modify should be refused"
30179         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30180
30181         echo "Read should be allowed"
30182         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30183                 error "(7) Read should succeed under ro mode"
30184
30185         # disable readonly
30186         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30187 }
30188 run_test 802b "be able to set MDTs to readonly"
30189
30190 test_803a() {
30191         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30192         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30193                 skip "MDS needs to be newer than 2.10.54"
30194
30195         mkdir_on_mdt0 $DIR/$tdir
30196         # Create some objects on all MDTs to trigger related logs objects
30197         for idx in $(seq $MDSCOUNT); do
30198                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30199                         $DIR/$tdir/dir${idx} ||
30200                         error "Fail to create $DIR/$tdir/dir${idx}"
30201         done
30202
30203         wait_delete_completed # ensure old test cleanups are finished
30204         sleep 3
30205         echo "before create:"
30206         $LFS df -i $MOUNT
30207         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30208
30209         for i in {1..10}; do
30210                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30211                         error "Fail to create $DIR/$tdir/foo$i"
30212         done
30213
30214         # sync ZFS-on-MDS to refresh statfs data
30215         wait_zfs_commit mds1
30216         sleep 3
30217         echo "after create:"
30218         $LFS df -i $MOUNT
30219         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30220
30221         # allow for an llog to be cleaned up during the test
30222         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30223                 error "before ($before_used) + 10 > after ($after_used)"
30224
30225         for i in {1..10}; do
30226                 rm -rf $DIR/$tdir/foo$i ||
30227                         error "Fail to remove $DIR/$tdir/foo$i"
30228         done
30229
30230         # sync ZFS-on-MDS to refresh statfs data
30231         wait_zfs_commit mds1
30232         wait_delete_completed
30233         sleep 3 # avoid MDT return cached statfs
30234         echo "after unlink:"
30235         $LFS df -i $MOUNT
30236         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30237
30238         # allow for an llog to be created during the test
30239         [ $after_used -le $((before_used + 1)) ] ||
30240                 error "after ($after_used) > before ($before_used) + 1"
30241 }
30242 run_test 803a "verify agent object for remote object"
30243
30244 test_803b() {
30245         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30246         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30247                 skip "MDS needs to be newer than 2.13.56"
30248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30249
30250         for i in $(seq 0 $((MDSCOUNT - 1))); do
30251                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30252         done
30253
30254         local before=0
30255         local after=0
30256
30257         local tmp
30258
30259         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30260         for i in $(seq 0 $((MDSCOUNT - 1))); do
30261                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30262                         awk '/getattr/ { print $2 }')
30263                 before=$((before + tmp))
30264         done
30265         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30266         for i in $(seq 0 $((MDSCOUNT - 1))); do
30267                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30268                         awk '/getattr/ { print $2 }')
30269                 after=$((after + tmp))
30270         done
30271
30272         [ $before -eq $after ] || error "getattr count $before != $after"
30273 }
30274 run_test 803b "remote object can getattr from cache"
30275
30276 test_804() {
30277         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30278         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30279                 skip "MDS needs to be newer than 2.10.54"
30280         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30281
30282         mkdir -p $DIR/$tdir
30283         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30284                 error "Fail to create $DIR/$tdir/dir0"
30285
30286         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30287         local dev=$(mdsdevname 2)
30288
30289         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30290                 grep ${fid} || error "NOT found agent entry for dir0"
30291
30292         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30293                 error "Fail to create $DIR/$tdir/dir1"
30294
30295         touch $DIR/$tdir/dir1/foo0 ||
30296                 error "Fail to create $DIR/$tdir/dir1/foo0"
30297         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30298         local rc=0
30299
30300         for idx in $(seq $MDSCOUNT); do
30301                 dev=$(mdsdevname $idx)
30302                 do_facet mds${idx} \
30303                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30304                         grep ${fid} && rc=$idx
30305         done
30306
30307         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30308                 error "Fail to rename foo0 to foo1"
30309         if [ $rc -eq 0 ]; then
30310                 for idx in $(seq $MDSCOUNT); do
30311                         dev=$(mdsdevname $idx)
30312                         do_facet mds${idx} \
30313                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30314                         grep ${fid} && rc=$idx
30315                 done
30316         fi
30317
30318         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30319                 error "Fail to rename foo1 to foo2"
30320         if [ $rc -eq 0 ]; then
30321                 for idx in $(seq $MDSCOUNT); do
30322                         dev=$(mdsdevname $idx)
30323                         do_facet mds${idx} \
30324                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30325                         grep ${fid} && rc=$idx
30326                 done
30327         fi
30328
30329         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30330
30331         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30332                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30333         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30334                 error "Fail to rename foo2 to foo0"
30335         unlink $DIR/$tdir/dir1/foo0 ||
30336                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30337         rm -rf $DIR/$tdir/dir0 ||
30338                 error "Fail to rm $DIR/$tdir/dir0"
30339
30340         for idx in $(seq $MDSCOUNT); do
30341                 rc=0
30342
30343                 stop mds${idx}
30344                 dev=$(mdsdevname $idx)
30345                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30346                         rc=$?
30347                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30348                         error "mount mds$idx failed"
30349                 df $MOUNT > /dev/null 2>&1
30350
30351                 # e2fsck should not return error
30352                 [ $rc -eq 0 ] ||
30353                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30354         done
30355 }
30356 run_test 804 "verify agent entry for remote entry"
30357
30358 cleanup_805() {
30359         do_facet $SINGLEMDS zfs set quota=$old $fsset
30360         unlinkmany $DIR/$tdir/f- 1000000
30361         trap 0
30362 }
30363
30364 test_805() {
30365         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30366         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30367         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30368                 skip "netfree not implemented before 0.7"
30369         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30370                 skip "Need MDS version at least 2.10.57"
30371
30372         local fsset
30373         local freekb
30374         local usedkb
30375         local old
30376         local quota
30377         local pref="osd-zfs.$FSNAME-MDT0000."
30378
30379         # limit available space on MDS dataset to meet nospace issue
30380         # quickly. then ZFS 0.7.2 can use reserved space if asked
30381         # properly (using netfree flag in osd_declare_destroy()
30382         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30383         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30384                 gawk '{print $3}')
30385         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30386         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30387         let "usedkb=usedkb-freekb"
30388         let "freekb=freekb/2"
30389         if let "freekb > 5000"; then
30390                 let "freekb=5000"
30391         fi
30392         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30393         trap cleanup_805 EXIT
30394         mkdir_on_mdt0 $DIR/$tdir
30395         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30396                 error "Can't set PFL layout"
30397         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30398         rm -rf $DIR/$tdir || error "not able to remove"
30399         do_facet $SINGLEMDS zfs set quota=$old $fsset
30400         trap 0
30401 }
30402 run_test 805 "ZFS can remove from full fs"
30403
30404 # Size-on-MDS test
30405 check_lsom_data()
30406 {
30407         local file=$1
30408         local expect=$(stat -c %s $file)
30409
30410         check_lsom_size $1 $expect
30411
30412         local blocks=$($LFS getsom -b $file)
30413         expect=$(stat -c %b $file)
30414         [[ $blocks == $expect ]] ||
30415                 error "$file expected blocks: $expect, got: $blocks"
30416 }
30417
30418 check_lsom_size()
30419 {
30420         local size
30421         local expect=$2
30422
30423         cancel_lru_locks mdc
30424
30425         size=$($LFS getsom -s $1)
30426         [[ $size == $expect ]] ||
30427                 error "$file expected size: $expect, got: $size"
30428 }
30429
30430 test_806() {
30431         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30432                 skip "Need MDS version at least 2.11.52"
30433
30434         local bs=1048576
30435
30436         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30437
30438         disable_opencache
30439         stack_trap "restore_opencache"
30440
30441         # single-threaded write
30442         echo "Test SOM for single-threaded write"
30443         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30444                 error "write $tfile failed"
30445         check_lsom_size $DIR/$tfile $bs
30446
30447         local num=32
30448         local size=$(($num * $bs))
30449         local offset=0
30450         local i
30451
30452         echo "Test SOM for single client multi-threaded($num) write"
30453         $TRUNCATE $DIR/$tfile 0
30454         for ((i = 0; i < $num; i++)); do
30455                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30456                 local pids[$i]=$!
30457                 offset=$((offset + $bs))
30458         done
30459         for (( i=0; i < $num; i++ )); do
30460                 wait ${pids[$i]}
30461         done
30462         check_lsom_size $DIR/$tfile $size
30463
30464         $TRUNCATE $DIR/$tfile 0
30465         for ((i = 0; i < $num; i++)); do
30466                 offset=$((offset - $bs))
30467                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30468                 local pids[$i]=$!
30469         done
30470         for (( i=0; i < $num; i++ )); do
30471                 wait ${pids[$i]}
30472         done
30473         check_lsom_size $DIR/$tfile $size
30474
30475         # multi-client writes
30476         num=$(get_node_count ${CLIENTS//,/ })
30477         size=$(($num * $bs))
30478         offset=0
30479         i=0
30480
30481         echo "Test SOM for multi-client ($num) writes"
30482         $TRUNCATE $DIR/$tfile 0
30483         for client in ${CLIENTS//,/ }; do
30484                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30485                 local pids[$i]=$!
30486                 i=$((i + 1))
30487                 offset=$((offset + $bs))
30488         done
30489         for (( i=0; i < $num; i++ )); do
30490                 wait ${pids[$i]}
30491         done
30492         check_lsom_size $DIR/$tfile $offset
30493
30494         i=0
30495         $TRUNCATE $DIR/$tfile 0
30496         for client in ${CLIENTS//,/ }; do
30497                 offset=$((offset - $bs))
30498                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30499                 local pids[$i]=$!
30500                 i=$((i + 1))
30501         done
30502         for (( i=0; i < $num; i++ )); do
30503                 wait ${pids[$i]}
30504         done
30505         check_lsom_size $DIR/$tfile $size
30506
30507         # verify SOM blocks count
30508         echo "Verify SOM block count"
30509         $TRUNCATE $DIR/$tfile 0
30510         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30511                 error "failed to write file $tfile with fdatasync and fstat"
30512         check_lsom_data $DIR/$tfile
30513
30514         $TRUNCATE $DIR/$tfile 0
30515         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30516                 error "failed to write file $tfile with fdatasync"
30517         check_lsom_data $DIR/$tfile
30518
30519         $TRUNCATE $DIR/$tfile 0
30520         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30521                 error "failed to write file $tfile with sync IO"
30522         check_lsom_data $DIR/$tfile
30523
30524         # verify truncate
30525         echo "Test SOM for truncate"
30526         # use ftruncate to sync blocks on close request
30527         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30528         check_lsom_size $DIR/$tfile 16384
30529         check_lsom_data $DIR/$tfile
30530
30531         $TRUNCATE $DIR/$tfile 1234
30532         check_lsom_size $DIR/$tfile 1234
30533         # sync blocks on the MDT
30534         $MULTIOP $DIR/$tfile oc
30535         check_lsom_data $DIR/$tfile
30536 }
30537 run_test 806 "Verify Lazy Size on MDS"
30538
30539 test_807() {
30540         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30541         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30542                 skip "Need MDS version at least 2.11.52"
30543
30544         # Registration step
30545         changelog_register || error "changelog_register failed"
30546         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30547         changelog_users $SINGLEMDS | grep -q $cl_user ||
30548                 error "User $cl_user not found in changelog_users"
30549
30550         rm -rf $DIR/$tdir || error "rm $tdir failed"
30551         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30552         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30553         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30554         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30555                 error "truncate $tdir/trunc failed"
30556
30557         local bs=1048576
30558         echo "Test SOM for single-threaded write with fsync"
30559         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30560                 error "write $tfile failed"
30561         sync;sync;sync
30562
30563         # multi-client wirtes
30564         local num=$(get_node_count ${CLIENTS//,/ })
30565         local offset=0
30566         local i=0
30567
30568         echo "Test SOM for multi-client ($num) writes"
30569         touch $DIR/$tfile || error "touch $tfile failed"
30570         $TRUNCATE $DIR/$tfile 0
30571         for client in ${CLIENTS//,/ }; do
30572                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30573                 local pids[$i]=$!
30574                 i=$((i + 1))
30575                 offset=$((offset + $bs))
30576         done
30577         for (( i=0; i < $num; i++ )); do
30578                 wait ${pids[$i]}
30579         done
30580
30581         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30582         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30583         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30584         check_lsom_data $DIR/$tdir/trunc
30585         check_lsom_data $DIR/$tdir/single_dd
30586         check_lsom_data $DIR/$tfile
30587
30588         rm -rf $DIR/$tdir
30589         # Deregistration step
30590         changelog_deregister || error "changelog_deregister failed"
30591 }
30592 run_test 807 "verify LSOM syncing tool"
30593
30594 check_som_nologged()
30595 {
30596         local lines=$($LFS changelog $FSNAME-MDT0000 |
30597                 grep 'x=trusted.som' | wc -l)
30598         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30599 }
30600
30601 test_808() {
30602         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30603                 skip "Need MDS version at least 2.11.55"
30604
30605         # Registration step
30606         changelog_register || error "changelog_register failed"
30607
30608         touch $DIR/$tfile || error "touch $tfile failed"
30609         check_som_nologged
30610
30611         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30612                 error "write $tfile failed"
30613         check_som_nologged
30614
30615         $TRUNCATE $DIR/$tfile 1234
30616         check_som_nologged
30617
30618         $TRUNCATE $DIR/$tfile 1048576
30619         check_som_nologged
30620
30621         # Deregistration step
30622         changelog_deregister || error "changelog_deregister failed"
30623 }
30624 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30625
30626 check_som_nodata()
30627 {
30628         $LFS getsom $1
30629         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30630 }
30631
30632 test_809() {
30633         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30634                 skip "Need MDS version at least 2.11.56"
30635
30636         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30637                 error "failed to create DoM-only file $DIR/$tfile"
30638         touch $DIR/$tfile || error "touch $tfile failed"
30639         check_som_nodata $DIR/$tfile
30640
30641         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30642                 error "write $tfile failed"
30643         check_som_nodata $DIR/$tfile
30644
30645         $TRUNCATE $DIR/$tfile 1234
30646         check_som_nodata $DIR/$tfile
30647
30648         $TRUNCATE $DIR/$tfile 4097
30649         check_som_nodata $DIR/$file
30650 }
30651 run_test 809 "Verify no SOM xattr store for DoM-only files"
30652
30653 test_810() {
30654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30655         $GSS && skip_env "could not run with gss"
30656         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30657                 skip "OST < 2.12.58 doesn't align checksum"
30658
30659         set_checksums 1
30660         stack_trap "set_checksums $ORIG_CSUM" EXIT
30661         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30662
30663         local csum
30664         local before
30665         local after
30666         for csum in $CKSUM_TYPES; do
30667                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30668                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30669                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30670                         eval set -- $i
30671                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30672                         before=$(md5sum $DIR/$tfile)
30673                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30674                         after=$(md5sum $DIR/$tfile)
30675                         [ "$before" == "$after" ] ||
30676                                 error "$csum: $before != $after bs=$1 seek=$2"
30677                 done
30678         done
30679 }
30680 run_test 810 "partial page writes on ZFS (LU-11663)"
30681
30682 test_812a() {
30683         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30684                 skip "OST < 2.12.51 doesn't support this fail_loc"
30685
30686         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30687         # ensure ost1 is connected
30688         stat $DIR/$tfile >/dev/null || error "can't stat"
30689         wait_osc_import_state client ost1 FULL
30690         # no locks, no reqs to let the connection idle
30691         cancel_lru_locks osc
30692
30693         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30694 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30695         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30696         wait_osc_import_state client ost1 CONNECTING
30697         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30698
30699         stat $DIR/$tfile >/dev/null || error "can't stat file"
30700 }
30701 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30702
30703 test_812b() { # LU-12378
30704         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30705                 skip "OST < 2.12.51 doesn't support this fail_loc"
30706
30707         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30708         # ensure ost1 is connected
30709         stat $DIR/$tfile >/dev/null || error "can't stat"
30710         wait_osc_import_state client ost1 FULL
30711         # no locks, no reqs to let the connection idle
30712         cancel_lru_locks osc
30713
30714         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30715 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30716         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30717         wait_osc_import_state client ost1 CONNECTING
30718         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30719
30720         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30721         wait_osc_import_state client ost1 IDLE
30722 }
30723 run_test 812b "do not drop no resend request for idle connect"
30724
30725 test_812c() {
30726         local old
30727
30728         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30729
30730         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30731         $LFS getstripe $DIR/$tfile
30732         $LCTL set_param osc.*.idle_timeout=10
30733         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30734         # ensure ost1 is connected
30735         stat $DIR/$tfile >/dev/null || error "can't stat"
30736         wait_osc_import_state client ost1 FULL
30737         # no locks, no reqs to let the connection idle
30738         cancel_lru_locks osc
30739
30740 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30741         $LCTL set_param fail_loc=0x80000533
30742         sleep 15
30743         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30744 }
30745 run_test 812c "idle import vs lock enqueue race"
30746
30747 test_813() {
30748         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30749         [ -z "$file_heat_sav" ] && skip "no file heat support"
30750
30751         local readsample
30752         local writesample
30753         local readbyte
30754         local writebyte
30755         local readsample1
30756         local writesample1
30757         local readbyte1
30758         local writebyte1
30759
30760         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30761         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30762
30763         $LCTL set_param -n llite.*.file_heat=1
30764         echo "Turn on file heat"
30765         echo "Period second: $period_second, Decay percentage: $decay_pct"
30766
30767         echo "QQQQ" > $DIR/$tfile
30768         echo "QQQQ" > $DIR/$tfile
30769         echo "QQQQ" > $DIR/$tfile
30770         cat $DIR/$tfile > /dev/null
30771         cat $DIR/$tfile > /dev/null
30772         cat $DIR/$tfile > /dev/null
30773         cat $DIR/$tfile > /dev/null
30774
30775         local out=$($LFS heat_get $DIR/$tfile)
30776
30777         $LFS heat_get $DIR/$tfile
30778         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30779         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30780         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30781         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30782
30783         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30784         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30785         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30786         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30787
30788         sleep $((period_second + 3))
30789         echo "Sleep $((period_second + 3)) seconds..."
30790         # The recursion formula to calculate the heat of the file f is as
30791         # follow:
30792         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30793         # Where Hi is the heat value in the period between time points i*I and
30794         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30795         # to the weight of Ci.
30796         out=$($LFS heat_get $DIR/$tfile)
30797         $LFS heat_get $DIR/$tfile
30798         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30799         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30800         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30801         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30802
30803         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30804                 error "read sample ($readsample) is wrong"
30805         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30806                 error "write sample ($writesample) is wrong"
30807         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30808                 error "read bytes ($readbyte) is wrong"
30809         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30810                 error "write bytes ($writebyte) is wrong"
30811
30812         echo "QQQQ" > $DIR/$tfile
30813         echo "QQQQ" > $DIR/$tfile
30814         echo "QQQQ" > $DIR/$tfile
30815         cat $DIR/$tfile > /dev/null
30816         cat $DIR/$tfile > /dev/null
30817         cat $DIR/$tfile > /dev/null
30818         cat $DIR/$tfile > /dev/null
30819
30820         sleep $((period_second + 3))
30821         echo "Sleep $((period_second + 3)) seconds..."
30822
30823         out=$($LFS heat_get $DIR/$tfile)
30824         $LFS heat_get $DIR/$tfile
30825         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30826         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30827         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30828         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30829
30830         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30831                 4 * $decay_pct) / 100") -eq 1 ] ||
30832                 error "read sample ($readsample1) is wrong"
30833         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30834                 3 * $decay_pct) / 100") -eq 1 ] ||
30835                 error "write sample ($writesample1) is wrong"
30836         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30837                 20 * $decay_pct) / 100") -eq 1 ] ||
30838                 error "read bytes ($readbyte1) is wrong"
30839         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30840                 15 * $decay_pct) / 100") -eq 1 ] ||
30841                 error "write bytes ($writebyte1) is wrong"
30842
30843         echo "Turn off file heat for the file $DIR/$tfile"
30844         $LFS heat_set -o $DIR/$tfile
30845
30846         echo "QQQQ" > $DIR/$tfile
30847         echo "QQQQ" > $DIR/$tfile
30848         echo "QQQQ" > $DIR/$tfile
30849         cat $DIR/$tfile > /dev/null
30850         cat $DIR/$tfile > /dev/null
30851         cat $DIR/$tfile > /dev/null
30852         cat $DIR/$tfile > /dev/null
30853
30854         out=$($LFS heat_get $DIR/$tfile)
30855         $LFS heat_get $DIR/$tfile
30856         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30857         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30858         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30859         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30860
30861         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30862         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30863         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30864         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30865
30866         echo "Trun on file heat for the file $DIR/$tfile"
30867         $LFS heat_set -O $DIR/$tfile
30868
30869         echo "QQQQ" > $DIR/$tfile
30870         echo "QQQQ" > $DIR/$tfile
30871         echo "QQQQ" > $DIR/$tfile
30872         cat $DIR/$tfile > /dev/null
30873         cat $DIR/$tfile > /dev/null
30874         cat $DIR/$tfile > /dev/null
30875         cat $DIR/$tfile > /dev/null
30876
30877         out=$($LFS heat_get $DIR/$tfile)
30878         $LFS heat_get $DIR/$tfile
30879         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30880         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30881         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30882         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30883
30884         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30885         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30886         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30887         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30888
30889         $LFS heat_set -c $DIR/$tfile
30890         $LCTL set_param -n llite.*.file_heat=0
30891         echo "Turn off file heat support for the Lustre filesystem"
30892
30893         echo "QQQQ" > $DIR/$tfile
30894         echo "QQQQ" > $DIR/$tfile
30895         echo "QQQQ" > $DIR/$tfile
30896         cat $DIR/$tfile > /dev/null
30897         cat $DIR/$tfile > /dev/null
30898         cat $DIR/$tfile > /dev/null
30899         cat $DIR/$tfile > /dev/null
30900
30901         out=$($LFS heat_get $DIR/$tfile)
30902         $LFS heat_get $DIR/$tfile
30903         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30904         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30905         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30906         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30907
30908         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30909         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30910         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30911         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30912
30913         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30914         rm -f $DIR/$tfile
30915 }
30916 run_test 813 "File heat verfication"
30917
30918 test_814()
30919 {
30920         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30921         echo -n y >> $DIR/$tfile
30922         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30923         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30924 }
30925 run_test 814 "sparse cp works as expected (LU-12361)"
30926
30927 test_815()
30928 {
30929         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30930         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30931 }
30932 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30933
30934 test_816() {
30935         local ost1_imp=$(get_osc_import_name client ost1)
30936         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30937                          cut -d'.' -f2)
30938
30939         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30940         # ensure ost1 is connected
30941
30942         stat $DIR/$tfile >/dev/null || error "can't stat"
30943         wait_osc_import_state client ost1 FULL
30944         # no locks, no reqs to let the connection idle
30945         cancel_lru_locks osc
30946         lru_resize_disable osc
30947         local before
30948         local now
30949         before=$($LCTL get_param -n \
30950                  ldlm.namespaces.$imp_name.lru_size)
30951
30952         wait_osc_import_state client ost1 IDLE
30953         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30954         now=$($LCTL get_param -n \
30955               ldlm.namespaces.$imp_name.lru_size)
30956         [ $before == $now ] || error "lru_size changed $before != $now"
30957 }
30958 run_test 816 "do not reset lru_resize on idle reconnect"
30959
30960 cleanup_817() {
30961         umount $tmpdir
30962         exportfs -u localhost:$DIR/nfsexp
30963         rm -rf $DIR/nfsexp
30964 }
30965
30966 test_817() {
30967         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30968
30969         mkdir -p $DIR/nfsexp
30970         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30971                 error "failed to export nfs"
30972
30973         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30974         stack_trap cleanup_817 EXIT
30975
30976         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30977                 error "failed to mount nfs to $tmpdir"
30978
30979         cp /bin/true $tmpdir
30980         $DIR/nfsexp/true || error "failed to execute 'true' command"
30981 }
30982 run_test 817 "nfsd won't cache write lock for exec file"
30983
30984 test_818() {
30985         test_mkdir -i0 -c1 $DIR/$tdir
30986         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30987         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30988         stop $SINGLEMDS
30989
30990         # restore osp-syn threads
30991         stack_trap "fail $SINGLEMDS"
30992
30993         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30994         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30995         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30996                 error "start $SINGLEMDS failed"
30997         rm -rf $DIR/$tdir
30998
30999         local testid=$(echo $TESTNAME | tr '_' ' ')
31000
31001         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31002                 grep "run LFSCK" || error "run LFSCK is not suggested"
31003 }
31004 run_test 818 "unlink with failed llog"
31005
31006 test_819a() {
31007         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31008         cancel_lru_locks osc
31009         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31010         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31011         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31012         rm -f $TDIR/$tfile
31013 }
31014 run_test 819a "too big niobuf in read"
31015
31016 test_819b() {
31017         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31018         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31020         cancel_lru_locks osc
31021         sleep 1
31022         rm -f $TDIR/$tfile
31023 }
31024 run_test 819b "too big niobuf in write"
31025
31026
31027 function test_820_start_ost() {
31028         sleep 5
31029
31030         for num in $(seq $OSTCOUNT); do
31031                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31032         done
31033 }
31034
31035 test_820() {
31036         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31037
31038         mkdir $DIR/$tdir
31039         umount_client $MOUNT || error "umount failed"
31040         for num in $(seq $OSTCOUNT); do
31041                 stop ost$num
31042         done
31043
31044         # mount client with no active OSTs
31045         # so that the client can't initialize max LOV EA size
31046         # from OSC notifications
31047         mount_client $MOUNT || error "mount failed"
31048         # delay OST starting to keep this 0 max EA size for a while
31049         test_820_start_ost &
31050
31051         # create a directory on MDS2
31052         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31053                 error "Failed to create directory"
31054         # open intent should update default EA size
31055         # see mdc_update_max_ea_from_body()
31056         # notice this is the very first RPC to MDS2
31057         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31058         ret=$?
31059         echo $out
31060         # With SSK, this situation can lead to -EPERM being returned.
31061         # In that case, simply retry.
31062         if [ $ret -ne 0 ] && $SHARED_KEY; then
31063                 if echo "$out" | grep -q "not permitted"; then
31064                         cp /etc/services $DIR/$tdir/mds2
31065                         ret=$?
31066                 fi
31067         fi
31068         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31069 }
31070 run_test 820 "update max EA from open intent"
31071
31072 test_823() {
31073         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31074         local OST_MAX_PRECREATE=20000
31075
31076         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31077                 skip "Need MDS version at least 2.14.56"
31078
31079         save_lustre_params mds1 \
31080                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31081         do_facet $SINGLEMDS "$LCTL set_param -n \
31082                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31083         do_facet $SINGLEMDS "$LCTL set_param -n \
31084                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31085
31086         stack_trap "restore_lustre_params < $p; rm $p"
31087
31088         do_facet $SINGLEMDS "$LCTL set_param -n \
31089                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31090
31091         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31092                       osp.$FSNAME-OST0000*MDT0000.create_count")
31093         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31094                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31095         local expect_count=$(((($max/2)/256) * 256))
31096
31097         log "setting create_count to 100200:"
31098         log " -result- count: $count with max: $max, expecting: $expect_count"
31099
31100         [[ $count -eq expect_count ]] ||
31101                 error "Create count not set to max precreate."
31102 }
31103 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31104
31105 test_831() {
31106         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31107                 skip "Need MDS version 2.14.56"
31108
31109         local sync_changes=$(do_facet $SINGLEMDS \
31110                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31111
31112         [ "$sync_changes" -gt 100 ] &&
31113                 skip "Sync changes $sync_changes > 100 already"
31114
31115         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31116
31117         $LFS mkdir -i 0 $DIR/$tdir
31118         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31119
31120         save_lustre_params mds1 \
31121                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31122         save_lustre_params mds1 \
31123                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31124
31125         do_facet mds1 "$LCTL set_param -n \
31126                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31127                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31128         stack_trap "restore_lustre_params < $p" EXIT
31129
31130         createmany -o $DIR/$tdir/f- 1000
31131         unlinkmany $DIR/$tdir/f- 1000 &
31132         local UNLINK_PID=$!
31133
31134         while sleep 1; do
31135                 sync_changes=$(do_facet mds1 \
31136                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31137                 # the check in the code is racy, fail the test
31138                 # if the value above the limit by 10.
31139                 [ $sync_changes -gt 110 ] && {
31140                         kill -2 $UNLINK_PID
31141                         wait
31142                         error "osp changes throttling failed, $sync_changes>110"
31143                 }
31144                 kill -0 $UNLINK_PID 2> /dev/null || break
31145         done
31146         wait
31147 }
31148 run_test 831 "throttling unlink/setattr queuing on OSP"
31149
31150 test_832() {
31151         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31152         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31153                 skip "Need MDS version 2.15.52+"
31154         is_rmentry_supported || skip "rm_entry not supported"
31155
31156         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31157         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31158         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31159                 error "mkdir remote_dir failed"
31160         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31161                 error "mkdir striped_dir failed"
31162         touch $DIR/$tdir/file || error "touch file failed"
31163         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31164         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31165 }
31166 run_test 832 "lfs rm_entry"
31167
31168 test_833() {
31169         local file=$DIR/$tfile
31170
31171         stack_trap "rm -f $file" EXIT
31172         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31173
31174         local wpid
31175         local rpid
31176         local rpid2
31177
31178         # Buffered I/O write
31179         (
31180                 while [ ! -e $DIR/sanity.833.lck ]; do
31181                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31182                                 error "failed to write $file"
31183                         sleep 0.$((RANDOM % 4 + 1))
31184                 done
31185         )&
31186         wpid=$!
31187
31188         # Buffered I/O read
31189         (
31190                 while [ ! -e $DIR/sanity.833.lck ]; do
31191                         dd if=$file of=/dev/null bs=1M count=50 ||
31192                                 error "failed to read $file"
31193                         sleep 0.$((RANDOM % 4 + 1))
31194                 done
31195         )&
31196         rpid=$!
31197
31198         # Direct I/O read
31199         (
31200                 while [ ! -e $DIR/sanity.833.lck ]; do
31201                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31202                                 error "failed to read $file in direct I/O mode"
31203                         sleep 0.$((RANDOM % 4 + 1))
31204                 done
31205         )&
31206         rpid2=$!
31207
31208         sleep 30
31209         touch $DIR/sanity.833.lck
31210         wait $wpid || error "$?: buffered write failed"
31211         wait $rpid || error "$?: buffered read failed"
31212         wait $rpid2 || error "$?: direct read failed"
31213 }
31214 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31215
31216 test_850() {
31217         local dir=$DIR/$tdir
31218         local file=$dir/$tfile
31219         local statsfile=$dir/all_job_stats.txt
31220
31221         test_mkdir -p $dir || error "failed to create dir $dir"
31222         echo "abcdefg" > $file || error "failed to create file $file"
31223
31224         # read job_stats in the living system
31225         lljobstat -n 1 ||
31226                 error "failed to run lljobstat on living system"
31227
31228         $LCTL get_param *.*.job_stats > $statsfile
31229         lljobstat --statsfile=$statsfile ||
31230                 error "failed to run lljobstat on file $statsfile"
31231 }
31232 run_test 850 "lljobstat can parse living and aggregated job_stats"
31233
31234 #
31235 # tests that do cleanup/setup should be run at the end
31236 #
31237
31238 test_900() {
31239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31240         local ls
31241
31242         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31243         $LCTL set_param fail_loc=0x903
31244
31245         cancel_lru_locks MGC
31246
31247         FAIL_ON_ERROR=true cleanup
31248         FAIL_ON_ERROR=true setup
31249 }
31250 run_test 900 "umount should not race with any mgc requeue thread"
31251
31252 # LUS-6253/LU-11185
31253 test_901() {
31254         local old
31255         local count
31256         local oldc
31257         local newc
31258         local olds
31259         local news
31260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31261
31262         # some get_param have a bug to handle dot in param name
31263         cancel_lru_locks MGC
31264         old=$(mount -t lustre | wc -l)
31265         # 1 config+sptlrpc
31266         # 2 params
31267         # 3 nodemap
31268         # 4 IR
31269         old=$((old * 4))
31270         oldc=0
31271         count=0
31272         while [ $old -ne $oldc ]; do
31273                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31274                 sleep 1
31275                 ((count++))
31276                 if [ $count -ge $TIMEOUT ]; then
31277                         error "too large timeout"
31278                 fi
31279         done
31280         umount_client $MOUNT || error "umount failed"
31281         mount_client $MOUNT || error "mount failed"
31282         cancel_lru_locks MGC
31283         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31284
31285         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31286
31287         return 0
31288 }
31289 run_test 901 "don't leak a mgc lock on client umount"
31290
31291 # LU-13377
31292 test_902() {
31293         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31294                 skip "client does not have LU-13377 fix"
31295         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31296         $LCTL set_param fail_loc=0x1415
31297         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31298         cancel_lru_locks osc
31299         rm -f $DIR/$tfile
31300 }
31301 run_test 902 "test short write doesn't hang lustre"
31302
31303 # LU-14711
31304 test_903() {
31305         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31306         echo "blah" > $DIR/${tfile}-2
31307         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31308         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31309         $LCTL set_param fail_loc=0x417 fail_val=20
31310
31311         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31312         sleep 1 # To start the destroy
31313         wait_destroy_complete 150 || error "Destroy taking too long"
31314         cat $DIR/$tfile > /dev/null || error "Evicted"
31315 }
31316 run_test 903 "Test long page discard does not cause evictions"
31317
31318 test_904() {
31319         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31320         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31321                 grep -q project || skip "skip project quota not supported"
31322
31323         local testfile="$DIR/$tdir/$tfile"
31324         local xattr="trusted.projid"
31325         local projid
31326         local mdts=$(comma_list $(mdts_nodes))
31327         local saved=$(do_facet mds1 $LCTL get_param -n \
31328                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31329
31330         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31331         stack_trap "do_nodes $mdts $LCTL set_param \
31332                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31333
31334         mkdir -p $DIR/$tdir
31335         touch $testfile
31336         #hide projid xattr on server
31337         $LFS project -p 1 $testfile ||
31338                 error "set $testfile project id failed"
31339         getfattr -m - $testfile | grep $xattr &&
31340                 error "do not show trusted.projid when disabled on server"
31341         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31342         #should be hidden when projid is 0
31343         $LFS project -p 0 $testfile ||
31344                 error "set $testfile project id failed"
31345         getfattr -m - $testfile | grep $xattr &&
31346                 error "do not show trusted.projid with project ID 0"
31347
31348         #still can getxattr explicitly
31349         projid=$(getfattr -n $xattr $testfile |
31350                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31351         [ $projid == "0" ] ||
31352                 error "projid expected 0 not $projid"
31353
31354         #set the projid via setxattr
31355         setfattr -n $xattr -v "1000" $testfile ||
31356                 error "setattr failed with $?"
31357         projid=($($LFS project $testfile))
31358         [ ${projid[0]} == "1000" ] ||
31359                 error "projid expected 1000 not $projid"
31360
31361         #check the new projid via getxattr
31362         $LFS project -p 1001 $testfile ||
31363                 error "set $testfile project id failed"
31364         getfattr -m - $testfile | grep $xattr ||
31365                 error "should show trusted.projid when project ID != 0"
31366         projid=$(getfattr -n $xattr $testfile |
31367                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31368         [ $projid == "1001" ] ||
31369                 error "projid expected 1001 not $projid"
31370
31371         #try to set invalid projid
31372         setfattr -n $xattr -v "4294967295" $testfile &&
31373                 error "set invalid projid should fail"
31374
31375         #remove the xattr means setting projid to 0
31376         setfattr -x $xattr $testfile ||
31377                 error "setfattr failed with $?"
31378         projid=($($LFS project $testfile))
31379         [ ${projid[0]} == "0" ] ||
31380                 error "projid expected 0 not $projid"
31381
31382         #should be hidden when parent has inherit flag and same projid
31383         $LFS project -srp 1002 $DIR/$tdir ||
31384                 error "set $tdir project id failed"
31385         getfattr -m - $testfile | grep $xattr &&
31386                 error "do not show trusted.projid with inherit flag"
31387
31388         #still can getxattr explicitly
31389         projid=$(getfattr -n $xattr $testfile |
31390                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31391         [ $projid == "1002" ] ||
31392                 error "projid expected 1002 not $projid"
31393 }
31394 run_test 904 "virtual project ID xattr"
31395
31396 # LU-8582
31397 test_905() {
31398         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31399                 skip "need OST version >= 2.15.50.220 for fail_loc"
31400
31401         remote_ost_nodsh && skip "remote OST with nodsh"
31402         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31403
31404         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31405
31406         #define OBD_FAIL_OST_OPCODE 0x253
31407         # OST_LADVISE = 21
31408         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31409         $LFS ladvise -a willread $DIR/$tfile &&
31410                 error "unexpected success of ladvise with fault injection"
31411         $LFS ladvise -a willread $DIR/$tfile |&
31412                 grep -q "Operation not supported"
31413         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31414 }
31415 run_test 905 "bad or new opcode should not stuck client"
31416
31417 test_906() {
31418         grep -q io_uring_setup /proc/kallsyms ||
31419                 skip "Client OS does not support io_uring I/O engine"
31420         io_uring_probe || skip "kernel does not support io_uring fully"
31421         which fio || skip_env "no fio installed"
31422         fio --enghelp | grep -q io_uring ||
31423                 skip_env "fio does not support io_uring I/O engine"
31424
31425         local file=$DIR/$tfile
31426         local ioengine="io_uring"
31427         local numjobs=2
31428         local size=50M
31429
31430         fio --name=seqwrite --ioengine=$ioengine        \
31431                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31432                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31433                 error "fio seqwrite $file failed"
31434
31435         fio --name=seqread --ioengine=$ioengine \
31436                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31437                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31438                 error "fio seqread $file failed"
31439
31440         rm -f $file || error "rm -f $file failed"
31441 }
31442 run_test 906 "Simple test for io_uring I/O engine via fio"
31443
31444 test_907() {
31445         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31446
31447         # set stripe size to max rpc size
31448         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31449         $LFS getstripe $DIR/$tfile
31450 #define OBD_FAIL_OST_EROFS               0x216
31451         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31452
31453         local bs=$((max_pages * PAGE_SIZE / 16))
31454
31455         # write full one stripe and one block
31456         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31457
31458         rm $DIR/$tfile || error "rm failed"
31459 }
31460 run_test 907 "write rpc error during unlink"
31461
31462
31463 complete_test $SECONDS
31464 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31465 check_and_cleanup_lustre
31466 if [ "$I_MOUNTED" != "yes" ]; then
31467         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31468 fi
31469 exit_status